From 559570683c673ced64681c48463d8b35e0bc851c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 25 Oct 2021 19:11:55 +0200 Subject: [PATCH 1/2] Fix weights on hard-coded XCM fragments --- xcm/pallet-xcm/src/lib.rs | 286 +++++++++++++++++++++++++----------- xcm/pallet-xcm/src/tests.rs | 178 +++++++++++++++++++++- 2 files changed, 379 insertions(+), 85 deletions(-) diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs index 6456f9ee36b9..d2a0a2f1b579 100644 --- a/xcm/pallet-xcm/src/lib.rs +++ b/xcm/pallet-xcm/src/lib.rs @@ -473,7 +473,9 @@ pub mod pallet { /// Teleport some assets from the local chain to some destination chain. /// - /// Fee payment on the destination side is made from the first asset listed in the `assets` vector. + /// Fee payment on the destination side is made from the first asset listed in the `assets` vector and + /// fee-weight is calculated locally and thus remote weights are assumed to be equal to + /// local weights. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send @@ -506,54 +508,15 @@ pub mod pallet { assets: Box, fee_asset_item: u32, ) -> DispatchResult { - let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; - let dest = MultiLocation::try_from(*dest).map_err(|()| Error::::BadVersion)?; - let beneficiary = - MultiLocation::try_from(*beneficiary).map_err(|()| Error::::BadVersion)?; - let assets = MultiAssets::try_from(*assets).map_err(|()| Error::::BadVersion)?; - - ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); - let value = (origin_location, assets.drain()); - ensure!(T::XcmTeleportFilter::contains(&value), Error::::Filtered); - let (origin_location, assets) = value; - let inv_dest = T::LocationInverter::invert_location(&dest) - .map_err(|()| Error::::DestinationNotInvertible)?; - let fees = assets - .get(fee_asset_item as usize) - .ok_or(Error::::Empty)? - .clone() - .reanchored(&inv_dest) - .map_err(|_| Error::::CannotReanchor)?; - let max_assets = assets.len() as u32; - let assets = assets.into(); - let mut remote_message = Xcm(vec![ - BuyExecution { fees, weight_limit: Limited(0) }, - DepositAsset { assets: Wild(All), max_assets, beneficiary }, - ]); - // use local weight for remote message and hope for the best. - let remote_weight = T::Weigher::weight(&mut remote_message) - .map_err(|()| Error::::UnweighableMessage)?; - if let Some(BuyExecution { weight_limit: Limited(ref mut limit), .. }) = - remote_message.0.get_mut(0) - { - *limit = remote_weight; - } - let mut message = Xcm(vec![ - WithdrawAsset(assets), - InitiateTeleport { assets: Wild(All), dest, xcm: remote_message.into() }, - ]); - let weight = - T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; - let outcome = - T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); - Self::deposit_event(Event::Attempted(outcome)); - Ok(()) + Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, None) } /// Transfer some assets from the local chain to the sovereign account of a destination chain and forward /// a notification XCM. /// - /// Fee payment on the destination side is made from the first asset listed in the `assets` vector. + /// Fee payment on the destination side is made from the first asset listed in the `assets` vector and + /// fee-weight is calculated locally and thus remote weights are assumed to be equal to + /// local weights. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send @@ -583,45 +546,7 @@ pub mod pallet { assets: Box, fee_asset_item: u32, ) -> DispatchResult { - let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; - let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; - - ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); - let value = (origin_location, assets.drain()); - ensure!(T::XcmReserveTransferFilter::contains(&value), Error::::Filtered); - let (origin_location, assets) = value; - let inv_dest = T::LocationInverter::invert_location(&dest) - .map_err(|()| Error::::DestinationNotInvertible)?; - let fees = assets - .get(fee_asset_item as usize) - .ok_or(Error::::Empty)? - .clone() - .reanchored(&inv_dest) - .map_err(|_| Error::::CannotReanchor)?; - let max_assets = assets.len() as u32; - let assets = assets.into(); - let mut remote_message = Xcm(vec![ - BuyExecution { fees, weight_limit: Limited(0) }, - DepositAsset { assets: Wild(All), max_assets, beneficiary }, - ]); - // use local weight for remote message and hope for the best. - let remote_weight = T::Weigher::weight(&mut remote_message) - .map_err(|()| Error::::UnweighableMessage)?; - if let Some(BuyExecution { weight_limit: Limited(ref mut limit), .. }) = - remote_message.0.get_mut(0) - { - *limit = remote_weight; - } - let mut message = - Xcm(vec![TransferReserveAsset { assets, dest, xcm: remote_message.into() }]); - let weight = - T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; - let outcome = - T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); - Self::deposit_event(Event::Attempted(outcome)); - Ok(()) + Self::do_reserve_transfer_assets(origin, dest, beneficiary, assets, fee_asset_item, None) } /// Execute an XCM message from a local, signed, origin. @@ -732,9 +657,204 @@ pub mod pallet { .into() }) } + + /// Transfer some assets from the local chain to the sovereign account of a destination chain and forward + /// a notification XCM. + /// + /// Fee payment on the destination side is made from the first asset listed in the `assets` vector. + /// + /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. + /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send + /// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain. + /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be + /// an `AccountId32` value. + /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the fee on the + /// `dest` side. + /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay + /// fees. + /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. + #[pallet::weight({ + match ((*assets.clone()).try_into(), (*dest.clone()).try_into()) { + (Ok(assets), Ok(dest)) => { + use sp_std::vec; + let mut message = Xcm(vec![ + TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) } + ]); + T::Weigher::weight(&mut message).map_or(Weight::max_value(), |w| 100_000_000 + w) + }, + _ => Weight::max_value(), + } + })] + pub fn limited_reserve_transfer_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + weight_limit: WeightLimit, + ) -> DispatchResult { + Self::do_reserve_transfer_assets(origin, dest, beneficiary, assets, fee_asset_item, Some(weight_limit)) + } + + /// Teleport some assets from the local chain to some destination chain. + /// + /// Fee payment on the destination side is made from the first asset listed in the `assets` vector. + /// + /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. + /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send + /// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain. + /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be + /// an `AccountId32` value. + /// - `assets`: The assets to be withdrawn. The first item should be the currency used to to pay the fee on the + /// `dest` side. May not be empty. + /// - `dest_weight`: Equal to the total weight on `dest` of the XCM message + /// `Teleport { assets, effects: [ BuyExecution{..}, DepositAsset{..} ] }`. + /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. + #[pallet::weight({ + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); + match (maybe_assets, maybe_dest) { + (Ok(assets), Ok(dest)) => { + use sp_std::vec; + let mut message = Xcm(vec![ + WithdrawAsset(assets), + InitiateTeleport { assets: Wild(All), dest, xcm: Xcm(vec![]) }, + ]); + T::Weigher::weight(&mut message).map_or(Weight::max_value(), |w| 100_000_000 + w) + }, + _ => Weight::max_value(), + } + })] + pub fn limited_teleport_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + weight_limit: WeightLimit, + ) -> DispatchResult { + Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, Some(weight_limit)) + } } impl Pallet { + fn do_reserve_transfer_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + maybe_weight_limit: Option, + ) -> DispatchResult { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; + let beneficiary: MultiLocation = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + + ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); + let value = (origin_location, assets.drain()); + ensure!(T::XcmReserveTransferFilter::contains(&value), Error::::Filtered); + let (origin_location, assets) = value; + let inv_dest = T::LocationInverter::invert_location(&dest) + .map_err(|()| Error::::DestinationNotInvertible)?; + let fees = assets + .get(fee_asset_item as usize) + .ok_or(Error::::Empty)? + .clone() + .reanchored(&inv_dest) + .map_err(|_| Error::::CannotReanchor)?; + let max_assets = assets.len() as u32; + let assets: MultiAssets = assets.into(); + let weight_limit = match maybe_weight_limit { + Some(weight_limit) => weight_limit, + None => { + let beneficiary = beneficiary.clone(); + let fees = fees.clone(); + let mut remote_message = Xcm(vec![ + ReserveAssetDeposited(assets.clone()), + ClearOrigin, + BuyExecution { fees, weight_limit: Limited(0) }, + DepositAsset { assets: Wild(All), max_assets, beneficiary }, + ]); + // use local weight for remote message and hope for the best. + let remote_weight = T::Weigher::weight(&mut remote_message) + .map_err(|()| Error::::UnweighableMessage)?; + Limited(remote_weight) + }, + }; + let xcm = Xcm(vec![ + BuyExecution { fees, weight_limit }, + DepositAsset { assets: Wild(All), max_assets, beneficiary }, + ]); + let mut message = Xcm(vec![TransferReserveAsset { assets, dest, xcm }]); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let outcome = + T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); + Self::deposit_event(Event::Attempted(outcome)); + Ok(()) + } + + fn do_teleport_assets( + origin: OriginFor, + dest: Box, + beneficiary: Box, + assets: Box, + fee_asset_item: u32, + maybe_weight_limit: Option, + ) -> DispatchResult { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; + let beneficiary: MultiLocation = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + + ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); + let value = (origin_location, assets.drain()); + ensure!(T::XcmTeleportFilter::contains(&value), Error::::Filtered); + let (origin_location, assets) = value; + let inv_dest = T::LocationInverter::invert_location(&dest) + .map_err(|()| Error::::DestinationNotInvertible)?; + let fees = assets + .get(fee_asset_item as usize) + .ok_or(Error::::Empty)? + .clone() + .reanchored(&inv_dest) + .map_err(|_| Error::::CannotReanchor)?; + let max_assets = assets.len() as u32; + let assets: MultiAssets = assets.into(); + let weight_limit = match maybe_weight_limit { + Some(weight_limit) => weight_limit, + None => { + let beneficiary = beneficiary.clone(); + let fees = fees.clone(); + let mut remote_message = Xcm(vec![ + ReceiveTeleportedAsset(assets.clone()), + ClearOrigin, + BuyExecution { fees, weight_limit: Limited(0) }, + DepositAsset { assets: Wild(All), max_assets, beneficiary }, + ]); + // use local weight for remote message and hope for the best. + let remote_weight = T::Weigher::weight(&mut remote_message) + .map_err(|()| Error::::UnweighableMessage)?; + Limited(remote_weight) + }, + }; + let xcm = Xcm(vec![ + BuyExecution { fees, weight_limit }, + DepositAsset { assets: Wild(All), max_assets, beneficiary }, + ]); + let mut message = Xcm(vec![ + WithdrawAsset(assets), + InitiateTeleport { assets: Wild(All), dest, xcm }, + ]); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let outcome = + T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight); + Self::deposit_event(Event::Attempted(outcome)); + Ok(()) + } + /// Will always make progress, and will do its best not to use much more than `weight_cutoff` /// in doing so. pub(crate) fn check_xcm_version_change( diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs index ba5459e2c890..a9259e2155cf 100644 --- a/xcm/pallet-xcm/src/tests.rs +++ b/xcm/pallet-xcm/src/tests.rs @@ -234,7 +234,7 @@ fn teleport_assets_works() { Xcm(vec![ ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()), ClearOrigin, - buy_limited_execution((Here, SEND_AMOUNT), 2000), + buy_limited_execution((Here, SEND_AMOUNT), 4000), DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }, ]), )] @@ -248,6 +248,88 @@ fn teleport_assets_works() { }); } +/// Test `limited_teleport_assets` +/// +/// Asserts that the sender's balance is decreased as a result of execution of +/// local effects. +#[test] +fn limmited_teleport_assets_works() { + let balances = + vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = 2 * BaseXcmWeight::get(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + let dest: MultiLocation = AccountId32 { network: Any, id: BOB.into() }.into(); + assert_ok!(XcmPallet::limited_teleport_assets( + Origin::signed(ALICE), + Box::new(RelayLocation::get().into()), + Box::new(dest.clone().into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Limited(5000), + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + RelayLocation::get().into(), + Xcm(vec![ + ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()), + ClearOrigin, + buy_limited_execution((Here, SEND_AMOUNT), 5000), + DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }, + ]), + )] + ); + let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1); + let _check_v0_ok: xcm::v0::Xcm<()> = versioned_sent.try_into().unwrap(); + assert_eq!( + last_event(), + Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight))) + ); + }); +} + +/// Test `limited_teleport_assets` with unlimited weight +/// +/// Asserts that the sender's balance is decreased as a result of execution of +/// local effects. +#[test] +fn unlimmited_teleport_assets_works() { + let balances = + vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = 2 * BaseXcmWeight::get(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + let dest: MultiLocation = AccountId32 { network: Any, id: BOB.into() }.into(); + assert_ok!(XcmPallet::limited_teleport_assets( + Origin::signed(ALICE), + Box::new(RelayLocation::get().into()), + Box::new(dest.clone().into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Unlimited, + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + RelayLocation::get().into(), + Xcm(vec![ + ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()), + ClearOrigin, + buy_execution((Here, SEND_AMOUNT)), + DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }, + ]), + )] + ); + assert_eq!( + last_event(), + Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight))) + ); + }); +} + /// Test `reserve_transfer_assets` /// /// Asserts that the sender's balance is decreased and the beneficiary's balance @@ -280,7 +362,54 @@ fn reserve_transfer_assets_works() { Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, - buy_limited_execution((Parent, SEND_AMOUNT), 2000), + buy_limited_execution((Parent, SEND_AMOUNT), 4000), + DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }, + ]), + )] + ); + let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1); + let _check_v0_ok: xcm::v0::Xcm<()> = versioned_sent.try_into().unwrap(); + assert_eq!( + last_event(), + Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight))) + ); + }); +} + +/// Test `limited_reserve_transfer_assets` +/// +/// Asserts that the sender's balance is decreased and the beneficiary's balance +/// is increased. Verifies the correct message is sent and event is emitted. +#[test] +fn limited_reserve_transfer_assets_works() { + let balances = + vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get(); + let dest: MultiLocation = + Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }.into(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_ok!(XcmPallet::limited_reserve_transfer_assets( + Origin::signed(ALICE), + Box::new(Parachain(PARA_ID).into().into()), + Box::new(dest.clone().into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Limited(5000), + )); + // Alice spent amount + assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); + // Destination account (parachain account) has amount + let para_acc: AccountId = ParaId::from(PARA_ID).into_account(); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + Parachain(PARA_ID).into(), + Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + ClearOrigin, + buy_limited_execution((Parent, SEND_AMOUNT), 5000), DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }, ]), )] @@ -294,6 +423,51 @@ fn reserve_transfer_assets_works() { }); } +/// Test `limited_reserve_transfer_assets` with unlimited weight purchasing +/// +/// Asserts that the sender's balance is decreased and the beneficiary's balance +/// is increased. Verifies the correct message is sent and event is emitted. +#[test] +fn unlimited_reserve_transfer_assets_works() { + let balances = + vec![(ALICE, INITIAL_BALANCE), (ParaId::from(PARA_ID).into_account(), INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + let weight = BaseXcmWeight::get(); + let dest: MultiLocation = + Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }.into(); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_ok!(XcmPallet::limited_reserve_transfer_assets( + Origin::signed(ALICE), + Box::new(Parachain(PARA_ID).into().into()), + Box::new(dest.clone().into()), + Box::new((Here, SEND_AMOUNT).into()), + 0, + WeightLimit::Unlimited, + )); + // Alice spent amount + assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); + // Destination account (parachain account) has amount + let para_acc: AccountId = ParaId::from(PARA_ID).into_account(); + assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT); + assert_eq!( + sent_xcm(), + vec![( + Parachain(PARA_ID).into(), + Xcm(vec![ + ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), + ClearOrigin, + buy_execution((Parent, SEND_AMOUNT)), + DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }, + ]), + )] + ); + assert_eq!( + last_event(), + Event::XcmPallet(crate::Event::Attempted(Outcome::Complete(weight))) + ); + }); +} + /// Test local execution of XCM /// /// Asserts that the sender's balance is decreased and the beneficiary's balance From 6070231495d9a5d95b0de034a08251399e56af01 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 25 Oct 2021 19:38:46 +0200 Subject: [PATCH 2/2] Formatting --- xcm/pallet-xcm/src/lib.rs | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs index d2a0a2f1b579..0ae27321902a 100644 --- a/xcm/pallet-xcm/src/lib.rs +++ b/xcm/pallet-xcm/src/lib.rs @@ -546,7 +546,14 @@ pub mod pallet { assets: Box, fee_asset_item: u32, ) -> DispatchResult { - Self::do_reserve_transfer_assets(origin, dest, beneficiary, assets, fee_asset_item, None) + Self::do_reserve_transfer_assets( + origin, + dest, + beneficiary, + assets, + fee_asset_item, + None, + ) } /// Execute an XCM message from a local, signed, origin. @@ -693,7 +700,14 @@ pub mod pallet { fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { - Self::do_reserve_transfer_assets(origin, dest, beneficiary, assets, fee_asset_item, Some(weight_limit)) + Self::do_reserve_transfer_assets( + origin, + dest, + beneficiary, + assets, + fee_asset_item, + Some(weight_limit), + ) } /// Teleport some assets from the local chain to some destination chain. @@ -733,7 +747,14 @@ pub mod pallet { fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { - Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, Some(weight_limit)) + Self::do_teleport_assets( + origin, + dest, + beneficiary, + assets, + fee_asset_item, + Some(weight_limit), + ) } } @@ -748,7 +769,8 @@ pub mod pallet { ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let beneficiary: MultiLocation = + (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); @@ -805,7 +827,8 @@ pub mod pallet { ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let beneficiary: MultiLocation = + (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); @@ -843,10 +866,8 @@ pub mod pallet { BuyExecution { fees, weight_limit }, DepositAsset { assets: Wild(All), max_assets, beneficiary }, ]); - let mut message = Xcm(vec![ - WithdrawAsset(assets), - InitiateTeleport { assets: Wild(All), dest, xcm }, - ]); + let mut message = + Xcm(vec![WithdrawAsset(assets), InitiateTeleport { assets: Wild(All), dest, xcm }]); let weight = T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; let outcome =