From e15e2da9618722d7568e5292c3d0595f1eeee67d Mon Sep 17 00:00:00 2001 From: Joao pedro Santos Date: Thu, 18 Jul 2024 05:55:18 -0300 Subject: [PATCH] minor fixes --- polkadot/xcm/xcm-executor/src/lib.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 436727e7eed71..ac3a18bfcc6ce 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -855,7 +855,7 @@ impl XcmExecutor { let old_holding = self.holding.clone(); let result = Config::TransactionalProcessor::process(|| { let deposited = self.holding.saturating_take(assets); - self.deposit_assets_with_retry(deposited, beneficiary) + self.deposit_assets_with_retry(&deposited, &beneficiary) }); if Config::TransactionalProcessor::IS_TRANSACTIONAL && result.is_err() { self.holding = old_holding; @@ -880,7 +880,7 @@ impl XcmExecutor { // now take assets to deposit (excluding transport_fee) let deposited = self.holding.saturating_take(assets); - self.deposit_assets_with_retry(deposited.clone(), dest.clone())?; + self.deposit_assets_with_retry(&deposited, &dest)?; // Note that we pass `None` as `maybe_failed_bin` and drop any assets which // cannot be reanchored because we have already called `deposit_asset` on all // assets. @@ -1271,21 +1271,29 @@ impl XcmExecutor { } } + + /// Deposit `to_deposit` assets to `beneficiary`, without giving up on the first (transient) error, and + /// retrying once just in case one of the subsequently deposited assets satisfy some requirement. + /// + /// Most common transient error is: `beneficiary` account does not yet exist and the first asset(s) in + /// the (sorted) list does not satisfy ED, but a subsequent one in the list does. fn deposit_assets_with_retry( &mut self, - deposited: AssetsInHolding, - beneficiary: Location, + to_deposited: &AssetsInHolding, + beneficiary: &Location, ) -> Result<(), XcmError> { - let mut failed_deposits = Vec::with_capacity(deposited.len()); + let mut failed_deposits = Vec::with_capacity(to_deposited.len()); - for asset in deposited.into_assets_iter() { + for asset in to_deposited.assets_iter() { let asset_result = Config::AssetTransactor::deposit_asset(&asset, &beneficiary, Some(&self.context)); + // if deposit failed for asset, mark it for retry after depositing the others if asset_result.is_err() { failed_deposits.push(asset); } } + // retry previously failed deposits, this time short-circuiting on any error for asset in failed_deposits { Config::AssetTransactor::deposit_asset(&asset, &beneficiary, Some(&self.context))?; }