diff --git a/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh b/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh index 2e9cde58a47be..9fd45299f57ea 100755 --- a/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh +++ b/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh @@ -367,7 +367,7 @@ case "$1" in "$(jq --null-input '{ "V5": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": { ByGenesis: '$WESTEND_GENESIS_HASH' } }, { "Parachain": 1000 } ] } } }')" \ "$(jq --null-input '{ "V5": { "parents": 0, "interior": { "X1": [{ "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } }] } } }')" \ "$(jq --null-input '{ "V5": [ { "id": { "parents": 1, "interior": "Here" }, "fun": { "Fungible": '$amount' } } ] }')" \ - 0 \ + "$(jq --null-input '{ "V5": { "parents": 1, "interior": "Here" } }')" \ "Unlimited" ;; withdraw-reserve-assets-from-asset-hub-rococo-local) @@ -380,7 +380,7 @@ case "$1" in "$(jq --null-input '{ "V5": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": { ByGenesis: '$WESTEND_GENESIS_HASH' } }, { "Parachain": 1000 } ] } } }')" \ "$(jq --null-input '{ "V5": { "parents": 0, "interior": { "X1": [{ "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } }] } } }')" \ "$(jq --null-input '{ "V5": [ { "id": { "parents": 2, "interior": { "X1": [{ "GlobalConsensus": { ByGenesis: '$WESTEND_GENESIS_HASH' } }] } }, "fun": { "Fungible": '$amount' } } ] }')" \ - 0 \ + "$(jq --null-input '{ "V5": { "parents": 2, "interior": { "X1": [{ "GlobalConsensus": { ByGenesis: '$WESTEND_GENESIS_HASH' } }] } } }')" \ "Unlimited" ;; reserve-transfer-assets-from-asset-hub-westend-local) @@ -393,7 +393,7 @@ case "$1" in "$(jq --null-input '{ "V5": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": { ByGenesis: '$ROCOCO_GENESIS_HASH' } }, { "Parachain": 1000 } ] } } }')" \ "$(jq --null-input '{ "V5": { "parents": 0, "interior": { "X1": [{ "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } }] } } }')" \ "$(jq --null-input '{ "V5": [ { "id": { "parents": 1, "interior": "Here" }, "fun": { "Fungible": '$amount' } } ] }')" \ - 0 \ + "$(jq --null-input '{ "V5": { "parents": 1, "interior": "Here" } }')" \ "Unlimited" ;; withdraw-reserve-assets-from-asset-hub-westend-local) @@ -406,7 +406,7 @@ case "$1" in "$(jq --null-input '{ "V5": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": { ByGenesis: '$ROCOCO_GENESIS_HASH' } }, { "Parachain": 1000 } ] } } }')" \ "$(jq --null-input '{ "V5": { "parents": 0, "interior": { "X1": [{ "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } }] } } }')" \ "$(jq --null-input '{ "V5": [ { "id": { "parents": 2, "interior": { "X1": [{ "GlobalConsensus": { ByGenesis: '$ROCOCO_GENESIS_HASH' } }] } }, "fun": { "Fungible": '$amount' } } ] }')" \ - 0 \ + "$(jq --null-input '{ "V5": { "parents": 2, "interior": { "X1": [{ "GlobalConsensus": { ByGenesis: '$ROCOCO_GENESIS_HASH' } }] } } }')" \ "Unlimited" ;; claim-rewards-bridge-hub-rococo-local) diff --git a/bridges/testing/framework/utils/bridges.sh b/bridges/testing/framework/utils/bridges.sh index db56af28e4b15..1248cd4615867 100755 --- a/bridges/testing/framework/utils/bridges.sh +++ b/bridges/testing/framework/utils/bridges.sh @@ -284,7 +284,7 @@ function limited_reserve_transfer_assets() { local destination=$3 local beneficiary=$4 local assets=$5 - local fee_asset_item=$6 + local fee_asset_id=$6 local weight_limit=$7 echo " calling limited_reserve_transfer_assets:" echo " url: ${url}" @@ -292,7 +292,7 @@ function limited_reserve_transfer_assets() { echo " destination: ${destination}" echo " beneficiary: ${beneficiary}" echo " assets: ${assets}" - echo " fee_asset_item: ${fee_asset_item}" + echo " fee_asset_id: ${fee_asset_id}" echo " weight_limit: ${weight_limit}" echo "" echo "--------------------------------------------------" @@ -304,7 +304,7 @@ function limited_reserve_transfer_assets() { "${destination}" \ "${beneficiary}" \ "${assets}" \ - "${fee_asset_item}" \ + "${fee_asset_id}" \ "${weight_limit}" } diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs index 00cb9be261c1e..d5a581a5a404a 100644 --- a/cumulus/parachains/common/src/impls.rs +++ b/cumulus/parachains/common/src/impls.rs @@ -182,7 +182,7 @@ where .into(), ), Box::new((Parent, imbalance).into()), - 0, + Box::new(Parent.into()), WeightLimit::Unlimited, ); diff --git a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs index 1509be680975e..8d92eca34baa2 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs @@ -65,14 +65,13 @@ pub use crate::{ASSETS_PALLET_ID, USDT_ID}; #[macro_export] macro_rules! test_parachain_is_trusted_teleporter { - ( $sender_para:ty, vec![$( $receiver_para:ty ),+], ($assets:expr, $amount:expr), $xcm_call:ident ) => { + ( $sender_para:ty, vec![$( $receiver_para:ty ),+], ($assets:expr, $amount:expr), $fee_asset_id:expr, $xcm_call:ident ) => { $crate::macros::paste::paste! { // init Origin variables let sender = [<$sender_para Sender>]::get(); let mut para_sender_balance_before = <$sender_para as $crate::macros::Chain>::account_data_of(sender.clone()).free; let origin = <$sender_para as $crate::macros::Chain>::RuntimeOrigin::signed(sender.clone()); - let fee_asset_item = 0; let weight_limit = $crate::macros::WeightLimit::Unlimited; $( @@ -93,7 +92,7 @@ macro_rules! test_parachain_is_trusted_teleporter { dest: Box::new(para_destination.clone().into()), beneficiary: Box::new(beneficiary.clone().into()), assets: Box::new($assets.clone().into()), - fee_asset_item: fee_asset_item, + fee_asset_id: Box::new($fee_asset_id.clone().into()), weight_limit: weight_limit.clone(), }); @@ -202,13 +201,14 @@ macro_rules! test_parachain_is_trusted_teleporter { #[macro_export] macro_rules! test_relay_is_trusted_teleporter { - ( $sender_relay:ty, vec![$( $receiver_para:ty ),+], ($assets:expr, $amount:expr), $xcm_call:ident ) => { + ( $sender_relay:ty, vec![$( $receiver_para:ty ),+], $amount:expr, $xcm_call:ident ) => { $crate::macros::paste::paste! { // init Origin variables let sender = [<$sender_relay Sender>]::get(); let mut relay_sender_balance_before = <$sender_relay as $crate::macros::Chain>::account_data_of(sender.clone()).free; - let fee_asset_item = 0; + let assets: $crate::macros::Assets = ($crate::macros::Here, $amount).into(); + let fee_asset_id: $crate::macros::AssetId = ($crate::macros::Here).into(); let weight_limit = $crate::macros::WeightLimit::Unlimited; $( @@ -228,8 +228,8 @@ macro_rules! test_relay_is_trusted_teleporter { $crate::macros::pallet_xcm::Call::$xcm_call { dest: Box::new(para_destination.clone().into()), beneficiary: Box::new(beneficiary.clone().into()), - assets: Box::new($assets.clone().into()), - fee_asset_item: fee_asset_item, + assets: Box::new(assets.clone().into()), + fee_asset_id: Box::new(fee_asset_id.clone().into()), weight_limit: weight_limit.clone(), }); @@ -350,7 +350,7 @@ macro_rules! test_parachain_is_trusted_teleporter_for_relay { <$sender_para as $crate::macros::Chain>::account_data_of(sender.clone()).free; let origin = <$sender_para as $crate::macros::Chain>::RuntimeOrigin::signed(sender.clone()); let assets: $crate::macros::Assets = ($crate::macros::Parent, $amount).into(); - let fee_asset_item = 0; + let fee_asset_id: $crate::macros::AssetId = ($crate::macros::Parent).into(); let weight_limit = $crate::macros::WeightLimit::Unlimited; // We need to mint funds into the checking account of `$receiver_relay` @@ -376,7 +376,7 @@ macro_rules! test_parachain_is_trusted_teleporter_for_relay { dest: Box::new(relay_destination.clone().into()), beneficiary: Box::new(beneficiary.clone().into()), assets: Box::new(assets.clone().into()), - fee_asset_item: fee_asset_item, + fee_asset_id: Box::new(fee_asset_id.clone().into()), weight_limit: weight_limit.clone(), }); @@ -667,7 +667,7 @@ macro_rules! test_can_estimate_and_pay_exact_fees { $amount, ($asset_id, $amount).into(), None, - 0, + ($asset_id).into(), ), }; let mut test = ParaToParaThroughAHTest::new(test_args); diff --git a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs index 7a355337f11d1..69c026fc8c3e5 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs @@ -65,18 +65,18 @@ pub fn xcm_transact_unpaid_execution( } /// Helper method to get the non-fee asset used in multiple assets transfer -pub fn non_fee_asset(assets: &Assets, fee_idx: usize) -> Option<(Location, u128)> { - let asset = assets.inner().into_iter().enumerate().find(|a| a.0 != fee_idx)?.1.clone(); +pub fn non_fee_asset(assets: &Assets, fee_asset_id: &AssetId) -> Option<(Location, u128)> { + let asset = assets.inner().into_iter().find(|a| a.id != *fee_asset_id)?; let asset_amount = match asset.fun { Fungible(amount) => amount, _ => return None, }; - Some((asset.id.0, asset_amount)) + Some((asset.id.0.clone(), asset_amount)) } /// Helper method to get the fee asset used in multiple assets transfer -pub fn fee_asset(assets: &Assets, fee_idx: usize) -> Option<(Location, u128)> { - let asset = assets.get(fee_idx)?; +pub fn fee_asset(assets: &Assets, fee_asset_id: &AssetId) -> Option<(Location, u128)> { + let asset = assets.inner().iter().find(|a| a.id == *fee_asset_id)?; let asset_amount = match asset.fun { Fungible(amount) => amount, _ => return None, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs index a791c935da168..0f0825cec197e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/hybrid_transfers.rs @@ -52,8 +52,14 @@ fn para_to_para_assethub_hop_assertions(t: ParaToParaThroughAHTest) { } fn ah_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -71,8 +77,14 @@ fn ah_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { } fn para_to_ah_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -90,8 +102,14 @@ fn para_to_ah_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { } fn para_to_para_transfer_assets_through_ah(t: ParaToParaThroughAHTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let asset_hub_location: Location = PenpalA::sibling_location_of(AssetHubRococo::para_id()); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), @@ -110,8 +128,14 @@ fn para_to_para_transfer_assets_through_ah(t: ParaToParaThroughAHTest) -> Dispat } fn para_to_asset_hub_teleport_foreign_assets(t: ParaToSystemParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -129,8 +153,14 @@ fn para_to_asset_hub_teleport_foreign_assets(t: ParaToSystemParaTest) -> Dispatc } fn asset_hub_to_para_teleport_foreign_assets(t: SystemParaToParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -202,7 +232,6 @@ fn transfer_foreign_assets_from_asset_hub_to_para() { (wnd_at_rococo_parachains.clone(), foreign_amount_to_send).into(), ]; let fee_asset_id = AssetId(Parent.into()); - let fee_asset_item = assets.iter().position(|a| a.id == fee_asset_id).unwrap() as u32; // Init Test let test_args = TestContext { @@ -214,7 +243,7 @@ fn transfer_foreign_assets_from_asset_hub_to_para() { native_amount_to_send, assets.into(), None, - fee_asset_item, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(test_args); @@ -357,7 +386,6 @@ fn transfer_foreign_assets_from_para_to_asset_hub() { (wnd_at_rococo_parachains.clone(), foreign_amount_to_send).into(), ]; let fee_asset_id = AssetId(Parent.into()); - let fee_asset_item = assets.iter().position(|a| a.id == fee_asset_id).unwrap() as u32; // Init Test let test_args = TestContext { @@ -369,7 +397,7 @@ fn transfer_foreign_assets_from_para_to_asset_hub() { native_amount_to_send, assets.into(), None, - fee_asset_item, + fee_asset_id, ), }; let mut test = ParaToSystemParaTest::new(test_args); @@ -525,7 +553,6 @@ fn transfer_foreign_assets_from_para_to_para_through_asset_hub() { (wnd_at_rococo_parachains.clone(), wnd_to_send).into(), ]; let fee_asset_id: AssetId = roc_location.clone().into(); - let fee_asset_item = assets.iter().position(|a| a.id == fee_asset_id).unwrap() as u32; // Init Test let test_args = TestContext { @@ -537,7 +564,7 @@ fn transfer_foreign_assets_from_para_to_para_through_asset_hub() { roc_to_send, assets.into(), None, - fee_asset_item, + fee_asset_id, ), }; let mut test = ParaToParaThroughAHTest::new(test_args); @@ -750,8 +777,14 @@ fn transfer_native_asset_from_relay_to_para_through_asset_hub() { ); } fn transfer_assets_dispatchable(t: RelayToParaThroughAHTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let asset_hub_location = Rococo::child_location_of(AssetHubRococo::para_id()); let context = RococoUniversalLocation::get(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs index d349fb459678a..6326fceb02fbb 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs @@ -227,10 +227,10 @@ pub fn para_to_system_para_receiver_assertions(t: ParaToSystemParaTest) { Parachain(PenpalA::para_id().into()), )); - for (idx, asset) in t.args.assets.into_inner().into_iter().enumerate() { + for asset in t.args.assets.into_inner().into_iter() { let expected_id = asset.id.0.clone().try_into().unwrap(); let asset_amount = if let Fungible(a) = asset.fun { Some(a) } else { None }.unwrap(); - if idx == t.args.fee_asset_item as usize { + if asset.id == t.args.fee_asset_id { assert_expected_events!( AssetHubRococo, vec![ @@ -443,7 +443,7 @@ fn para_to_para_asset_hub_hop_assertions(t: ParaToParaThroughAHTest) { AssetHubRococo::sibling_location_of(PenpalA::para_id()), ); - let (_, asset_amount) = fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let (_, asset_amount) = fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); assert_expected_events!( AssetHubRococo, @@ -515,24 +515,13 @@ fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult { unimplemented!("Destination is not a parachain?") }; - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - Dmp::make_parachain_reachable(para_id); ::XcmPallet::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::LocalReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::LocalReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -544,23 +533,12 @@ fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult { } fn para_to_relay_reserve_transfer_assets(t: ParaToRelayTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::DestinationReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::DestinationReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -572,23 +550,12 @@ fn para_to_relay_reserve_transfer_assets(t: ParaToRelayTest) -> DispatchResult { } fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::LocalReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::LocalReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -607,29 +574,18 @@ fn para_to_para_through_asset_hub_limited_reserve_transfer_assets( bx!(t.args.dest.into()), bx!(t.args.beneficiary.into()), bx!(t.args.assets.into()), - t.args.fee_asset_item, + bx!(t.args.fee_asset_id.into()), t.args.weight_limit, ) } fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::DestinationReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::DestinationReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -647,17 +603,6 @@ fn para_to_para_through_relay_limited_reserve_transfer_assets( unimplemented!("Destination is not a parachain?") }; - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - let relay_location = VersionedLocation::from(Location::parent()); Rococo::ext_wrapper(|| { @@ -668,7 +613,7 @@ fn para_to_para_through_relay_limited_reserve_transfer_assets( bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::RemoteReserve(relay_location.clone())), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::RemoteReserve(relay_location)), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -689,7 +634,7 @@ fn reserve_transfer_native_asset_from_relay_to_asset_hub_fails() { AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); let amount_to_send: Balance = ROCOCO_ED * 1000; let assets: Assets = (Here, amount_to_send).into(); - let fee_asset_item = 0; + let fee_asset_id: AssetId = Here.into(); // this should fail Rococo::execute_with(|| { @@ -698,7 +643,7 @@ fn reserve_transfer_native_asset_from_relay_to_asset_hub_fails() { bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - fee_asset_item, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); assert_err!( @@ -725,7 +670,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_relay_fails() { let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000; let assets: Assets = (Parent, amount_to_send).into(); - let fee_asset_item = 0; + let fee_asset_id: AssetId = Parent.into(); // this should fail AssetHubRococo::execute_with(|| { @@ -735,7 +680,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_relay_fails() { bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - fee_asset_item, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); assert_err!( @@ -810,6 +755,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() { let sender = PenpalASender::get(); let amount_to_send: Balance = ROCOCO_ED * 1000; let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let asset_owner = PenpalAssetOwner::get(); let relay_native_asset_location = RelayLocation::get(); @@ -839,7 +785,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() { amount_to_send, assets.clone(), None, - 0, + fee_asset_id, ), }; let mut test = ParaToRelayTest::new(test_args); @@ -885,6 +831,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_para() { let sender = AssetHubRococoSender::get(); let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 10000; let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); // Init values for Parachain let system_para_native_asset_location = RelayLocation::get(); @@ -900,7 +847,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_para() { amount_to_send, assets.clone(), None, - 0, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(test_args); @@ -943,6 +890,7 @@ fn reserve_transfer_native_asset_from_para_to_asset_hub() { let sender = PenpalASender::get(); let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 10000; let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let system_para_native_asset_location = RelayLocation::get(); let asset_owner = PenpalAssetOwner::get(); @@ -972,7 +920,7 @@ fn reserve_transfer_native_asset_from_para_to_asset_hub() { amount_to_send, assets.clone(), None, - 0, + fee_asset_id, ), }; let mut test = ParaToSystemParaTest::new(test_args); @@ -1031,11 +979,7 @@ fn reserve_transfer_multiple_assets_from_asset_hub_to_para() { .into(), ] .into(); - let fee_asset_index = assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); AssetHubRococo::mint_asset( asset_owner_signer, RESERVABLE_ASSET_ID, @@ -1061,7 +1005,7 @@ fn reserve_transfer_multiple_assets_from_asset_hub_to_para() { asset_amount_to_send, assets, None, - fee_asset_index, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(para_test_args); @@ -1145,11 +1089,7 @@ fn reserve_transfer_multiple_assets_from_para_to_asset_hub() { (asset_location_on_penpal.clone(), asset_amount_to_send).into(), ] .into(); - let fee_asset_index = assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); // Fund Parachain's sender account with some foreign assets PenpalA::mint_foreign_asset( penpal_asset_owner_signer.clone(), @@ -1197,7 +1137,7 @@ fn reserve_transfer_multiple_assets_from_para_to_asset_hub() { asset_amount_to_send, assets, None, - fee_asset_index, + fee_asset_id, ), }; let mut test = ParaToSystemParaTest::new(para_test_args); @@ -1265,6 +1205,7 @@ fn reserve_transfer_native_asset_from_para_to_para_through_relay() { let amount_to_send: Balance = ROCOCO_ED * 10000; let asset_owner = PenpalAssetOwner::get(); let assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let relay_native_asset_location = RelayLocation::get(); let sender_as_seen_by_relay = Rococo::child_location_of(PenpalA::para_id()); let sov_of_sender_on_relay = Rococo::sovereign_account_id_of(sender_as_seen_by_relay); @@ -1287,7 +1228,14 @@ fn reserve_transfer_native_asset_from_para_to_para_through_relay() { let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), - args: TestArgs::new_para(destination, receiver.clone(), amount_to_send, assets, None, 0), + args: TestArgs::new_para( + destination, + receiver.clone(), + amount_to_send, + assets, + None, + fee_asset_id, + ), }; let mut test = ParaToParaThroughRelayTest::new(test_args); @@ -1408,6 +1356,9 @@ fn reserve_transfer_usdt_from_asset_hub_to_para() { .into()] .into(); + let fee_asset_id: AssetId = + [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(usdt_id.into())].into(); + let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), @@ -1417,7 +1368,7 @@ fn reserve_transfer_usdt_from_asset_hub_to_para() { asset_amount_to_send, assets, None, - 0, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(test_args); @@ -1612,6 +1563,7 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() { (usdt_from_asset_hub.clone(), asset_amount_to_send + fee_amount_to_send).into(); // Just to be very specific we're not including anything other than USDT. assert_eq!(assets.len(), 1); + let fee_asset_id: AssetId = usdt_from_asset_hub.clone().into(); // Give the sender enough Relay tokens to pay for local delivery fees. // TODO(https://github.com/paritytech/polkadot-sdk/issues/5160): When we support local delivery fee payment in other assets, we don't need this. @@ -1626,7 +1578,6 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() { let receiver = PenpalBReceiver::get(); // Init Test - let fee_asset_index = 0; let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), @@ -1636,7 +1587,7 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() { asset_amount_to_send, assets, None, - fee_asset_index, + fee_asset_id, ), }; let mut test = ParaToParaThroughAHTest::new(test_args); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs index 892bba89136ac..7833a072665f9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs @@ -49,8 +49,7 @@ fn penpal_to_ah_foreign_assets_sender_assertions(t: ParaToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; let system_para_native_asset_location = RelayLocation::get(); let expected_asset_id = t.args.asset_id.unwrap(); - let (_, expected_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let (_, expected_asset_amount) = non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); PenpalA::assert_xcm_pallet_attempted_complete(None); assert_expected_events!( @@ -77,8 +76,8 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { AssetHubRococo::sibling_location_of(PenpalA::para_id()), ); let (_, expected_foreign_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); - let (_, fee_asset_amount) = fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); + let (_, fee_asset_amount) = fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); AssetHubRococo::assert_xcmp_queue_success(None); @@ -109,8 +108,8 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { type RuntimeEvent = ::RuntimeEvent; AssetHubRococo::assert_xcm_pallet_attempted_complete(None); let (expected_foreign_asset_id, expected_foreign_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); - let (_, fee_asset_amount) = fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); + let (_, fee_asset_amount) = fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -137,8 +136,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { fn ah_to_penpal_foreign_assets_receiver_assertions(t: SystemParaToParaTest) { type RuntimeEvent = ::RuntimeEvent; let expected_asset_id = t.args.asset_id.unwrap(); - let (_, expected_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let (_, expected_asset_amount) = non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); let checking_account = ::PolkadotXcm::check_account(); let system_para_native_asset_location = RelayLocation::get(); @@ -174,29 +172,18 @@ fn system_para_limited_teleport_assets(t: SystemParaToRelayTest) -> DispatchResu bx!(t.args.dest.into()), bx!(t.args.beneficiary.into()), bx!(t.args.assets.into()), - t.args.fee_asset_item, + bx!(t.args.fee_asset_id.into()), t.args.weight_limit, ) } fn para_to_system_para_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::Teleport), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::DestinationReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -208,23 +195,12 @@ fn para_to_system_para_transfer_assets(t: ParaToSystemParaTest) -> DispatchResul } fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::Teleport), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::LocalReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -239,11 +215,13 @@ fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResul fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { let amount = ASSET_HUB_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin vec![BridgeHubRococo], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -252,11 +230,13 @@ fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { fn teleport_via_transfer_assets_to_other_system_parachains_works() { let amount = ASSET_HUB_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin vec![BridgeHubRococo], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -264,12 +244,11 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = ROCOCO_ED * 100; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Rococo, vec![AssetHubRococo], - (native_asset, amount), + amount, limited_teleport_assets ); @@ -284,14 +263,8 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = ROCOCO_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Rococo, - vec![AssetHubRococo], - (native_asset, amount), - transfer_assets - ); + test_relay_is_trusted_teleporter!(Rococo, vec![AssetHubRococo], amount, transfer_assets); test_parachain_is_trusted_teleporter_for_relay!( AssetHubRococo, @@ -310,11 +283,19 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() { let destination = AssetHubRococo::parent_location().into(); let beneficiary_id = RococoReceiver::get().into(); let assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let test_args = TestContext { sender: AssetHubRococoSender::get(), receiver: RococoReceiver::get(), - args: TestArgs::new_para(destination, beneficiary_id, amount_to_send, assets, None, 0), + args: TestArgs::new_para( + destination, + beneficiary_id, + amount_to_send, + assets, + None, + fee_asset_id.clone(), + ), }; let mut test = SystemParaToRelayTest::new(test_args); @@ -334,7 +315,11 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() { xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( - test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + test.args.assets.clone(), + fee_asset_id, + test.args.weight_limit, + test.args.beneficiary, + test.args.dest, ) }); @@ -369,11 +354,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using (asset_location_on_penpal.clone(), asset_amount_to_send).into(), ] .into(); - let fee_asset_index = penpal_assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); // fund Parachain's sender account PenpalA::mint_foreign_asset( @@ -417,7 +398,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using asset_amount_to_send, penpal_assets, Some(asset_id_on_penpal), - fee_asset_index, + fee_asset_id, ), }; let mut penpal_to_ah = ParaToSystemParaTest::new(penpal_to_ah_test_args); @@ -506,11 +487,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using (foreign_asset_at_asset_hub_rococo.clone(), asset_amount_to_send).into(), ] .into(); - let fee_asset_index = ah_assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); // AH to Penpal test args let ah_to_penpal_test_args = TestContext { @@ -522,7 +499,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using asset_amount_to_send, ah_assets, Some(asset_id_on_penpal), - fee_asset_index, + fee_asset_id, ), }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs index d974b1b866ed0..78f7428de38f5 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs @@ -78,7 +78,7 @@ fn spend_roc_on_asset_hub() { id: native_asset.clone().into(), fun: treasury_balance.into() }))), - fee_asset_item: 0, + fee_asset_id: bx!(native_asset.into()), })), }); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/xcm_fee_estimation.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/xcm_fee_estimation.rs index 6e3b893e3f6c7..80afd80f0ea9c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/xcm_fee_estimation.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/xcm_fee_estimation.rs @@ -105,6 +105,7 @@ fn multi_hop_works() { let amount_to_send = 1_000_000_000_000; let asset_owner = PenpalAssetOwner::get(); let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let relay_native_asset_location = Location::parent(); let sender_as_seen_by_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id()); let sov_of_sender_on_ah = AssetHubRococo::sovereign_account_id_of(sender_as_seen_by_ah.clone()); @@ -132,7 +133,7 @@ fn multi_hop_works() { amount_to_send, assets, None, - 0, + fee_asset_id, ), }; let mut test = ParaToParaThroughAHTest::new(test_args); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs index 77a4796b553b7..9d87afa654554 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/hybrid_transfers.rs @@ -62,8 +62,14 @@ fn para_to_para_assethub_hop_assertions(mut t: ParaToParaThroughAHTest) { } fn ah_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -81,8 +87,14 @@ fn ah_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { } fn para_to_ah_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -100,8 +112,14 @@ fn para_to_ah_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { } fn para_to_para_transfer_assets_through_ah(t: ParaToParaThroughAHTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let asset_hub_location: Location = PenpalA::sibling_location_of(AssetHubWestend::para_id()); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), @@ -128,8 +146,14 @@ fn para_to_para_transfer_assets_through_ah(t: ParaToParaThroughAHTest) -> Dispat } fn para_to_asset_hub_teleport_foreign_assets(t: ParaToSystemParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -147,8 +171,14 @@ fn para_to_asset_hub_teleport_foreign_assets(t: ParaToSystemParaTest) -> Dispatc } fn asset_hub_to_para_teleport_foreign_assets(t: SystemParaToParaTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let custom_xcm_on_dest = Xcm::<()>(vec![DepositAsset { assets: Wild(AllCounted(t.args.assets.len() as u32)), beneficiary: t.args.beneficiary, @@ -220,7 +250,6 @@ fn transfer_foreign_assets_from_asset_hub_to_para() { (roc_at_westend_parachains.clone(), foreign_amount_to_send).into(), ]; let fee_asset_id = AssetId(Parent.into()); - let fee_asset_item = assets.iter().position(|a| a.id == fee_asset_id).unwrap() as u32; // Init Test let test_args = TestContext { @@ -232,7 +261,7 @@ fn transfer_foreign_assets_from_asset_hub_to_para() { native_amount_to_send, assets.into(), None, - fee_asset_item, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(test_args); @@ -376,7 +405,6 @@ fn transfer_foreign_assets_from_para_to_asset_hub() { (roc_at_westend_parachains.clone(), foreign_amount_to_send).into(), ]; let fee_asset_id = AssetId(Parent.into()); - let fee_asset_item = assets.iter().position(|a| a.id == fee_asset_id).unwrap() as u32; // Init Test let test_args = TestContext { @@ -388,7 +416,7 @@ fn transfer_foreign_assets_from_para_to_asset_hub() { native_amount_to_send, assets.into(), None, - fee_asset_item, + fee_asset_id, ), }; let mut test = ParaToSystemParaTest::new(test_args); @@ -544,7 +572,6 @@ fn transfer_foreign_assets_from_para_to_para_through_asset_hub() { (roc_at_westend_parachains.clone(), roc_to_send).into(), ]; let fee_asset_id: AssetId = wnd_location.clone().into(); - let fee_asset_item = assets.iter().position(|a| a.id == fee_asset_id).unwrap() as u32; // Init Test let test_args = TestContext { @@ -556,7 +583,7 @@ fn transfer_foreign_assets_from_para_to_para_through_asset_hub() { wnd_to_send, assets.into(), None, - fee_asset_item, + fee_asset_id, ), }; let mut test = ParaToParaThroughAHTest::new(test_args); @@ -763,8 +790,14 @@ fn transfer_native_asset_from_relay_to_penpal_through_asset_hub() { ); } fn transfer_assets_dispatchable(t: RelayToParaThroughAHTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let asset_hub_location = Westend::child_location_of(AssetHubWestend::para_id()); let context = WestendUniversalLocation::get(); @@ -854,6 +887,7 @@ fn transfer_native_asset_from_penpal_to_relay_through_asset_hub() { let receiver = WestendReceiver::get(); // Init Test + let fee_asset_id: AssetId = Parent.into(); let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), @@ -863,7 +897,7 @@ fn transfer_native_asset_from_penpal_to_relay_through_asset_hub() { amount_to_send, (Parent, amount_to_send).into(), None, - 0, + fee_asset_id, ), }; let mut test = PenpalToRelayThroughAHTest::new(test_args); @@ -894,8 +928,14 @@ fn transfer_native_asset_from_penpal_to_relay_through_asset_hub() { }); fn transfer_assets_dispatchable(t: PenpalToRelayThroughAHTest) -> DispatchResult { - let fee_idx = t.args.fee_asset_item as usize; - let fee: Asset = t.args.assets.inner().get(fee_idx).cloned().unwrap(); + let fee: Asset = t + .args + .assets + .inner() + .iter() + .find(|a| a.id == t.args.fee_asset_id) + .cloned() + .unwrap(); let asset_hub_location = PenpalA::sibling_location_of(AssetHubWestend::para_id()); let context = PenpalUniversalLocation::get(); @@ -972,7 +1012,8 @@ fn bidirectional_transfer_multiple_assets_between_penpal_and_asset_hub() { fn execute_xcm_penpal_to_asset_hub(t: ParaToSystemParaTest) -> DispatchResult { let all_assets = t.args.assets.clone().into_inner(); let mut assets = all_assets.clone(); - let mut fees = assets.remove(t.args.fee_asset_item as usize); + let fee_asset_index = assets.iter().position(|a| a.id == t.args.fee_asset_id).unwrap(); + let mut fees = assets.remove(fee_asset_index); // TODO(https://github.com/paritytech/polkadot-sdk/issues/6197): dry-run to get exact fees. // For now just use half the fees locally, half on dest if let Fungible(fees_amount) = fees.fun { @@ -1010,7 +1051,8 @@ fn bidirectional_transfer_multiple_assets_between_penpal_and_asset_hub() { fn execute_xcm_asset_hub_to_penpal(t: SystemParaToParaTest) -> DispatchResult { let all_assets = t.args.assets.clone().into_inner(); let mut assets = all_assets.clone(); - let mut fees = assets.remove(t.args.fee_asset_item as usize); + let fee_asset_index = assets.iter().position(|a| a.id == t.args.fee_asset_id).unwrap(); + let mut fees = assets.remove(fee_asset_index); // TODO(https://github.com/paritytech/polkadot-sdk/issues/6197): dry-run to get exact fees. // For now just use half the fees locally, half on dest if let Fungible(fees_amount) = fees.fun { diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs index 7738e36e5d728..01eeb28bdaff7 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs @@ -230,10 +230,10 @@ pub fn para_to_system_para_receiver_assertions(t: ParaToSystemParaTest) { 1, Parachain(PenpalA::para_id().into()), )); - for (idx, asset) in t.args.assets.into_inner().into_iter().enumerate() { + for asset in t.args.assets.into_inner().into_iter() { let expected_id = asset.id.0.clone().try_into().unwrap(); let asset_amount = if let Fungible(a) = asset.fun { Some(a) } else { None }.unwrap(); - if idx == t.args.fee_asset_item as usize { + if asset.id == t.args.fee_asset_id { assert_expected_events!( AssetHubWestend, vec![ @@ -478,7 +478,7 @@ fn para_to_para_asset_hub_hop_assertions(t: ParaToParaThroughAHTest) { AssetHubWestend::sibling_location_of(PenpalA::para_id()), ); - let (_, asset_amount) = fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let (_, asset_amount) = fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); assert_expected_events!( AssetHubWestend, @@ -526,24 +526,13 @@ fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult { unimplemented!("Destination is not a parachain?") }; - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - Dmp::make_parachain_reachable(para_id); ::XcmPallet::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::LocalReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::LocalReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -555,23 +544,12 @@ fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult { } fn para_to_relay_reserve_transfer_assets(t: ParaToRelayTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::DestinationReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::DestinationReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -583,23 +561,12 @@ fn para_to_relay_reserve_transfer_assets(t: ParaToRelayTest) -> DispatchResult { } fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::LocalReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::LocalReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -611,23 +578,12 @@ fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> Dispa } fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::DestinationReserve), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::DestinationReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -645,17 +601,6 @@ fn para_to_para_through_relay_limited_reserve_transfer_assets( unimplemented!("Destination is not a parachain?") }; - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - let relay_location = VersionedLocation::from(Location::parent()); Westend::ext_wrapper(|| { @@ -666,7 +611,7 @@ fn para_to_para_through_relay_limited_reserve_transfer_assets( bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::RemoteReserve(relay_location.clone())), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::RemoteReserve(relay_location)), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -685,7 +630,7 @@ fn para_to_para_through_asset_hub_limited_reserve_transfer_assets( bx!(t.args.dest.into()), bx!(t.args.beneficiary.into()), bx!(t.args.assets.into()), - t.args.fee_asset_item, + bx!(t.args.fee_asset_id.into()), t.args.weight_limit, ) } @@ -700,7 +645,7 @@ fn reserve_transfer_native_asset_from_relay_to_asset_hub_fails() { AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); let amount_to_send: Balance = WESTEND_ED * 1000; let assets: Assets = (Here, amount_to_send).into(); - let fee_asset_item = 0; + let fee_asset_id: AssetId = Here.into(); // this should fail Westend::execute_with(|| { @@ -709,7 +654,7 @@ fn reserve_transfer_native_asset_from_relay_to_asset_hub_fails() { bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - fee_asset_item, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); assert_err!( @@ -736,7 +681,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_relay_fails() { let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000; let assets: Assets = (Parent, amount_to_send).into(); - let fee_asset_item = 0; + let fee_asset_id: AssetId = Parent.into(); // this should fail AssetHubWestend::execute_with(|| { @@ -746,7 +691,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_relay_fails() { bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - fee_asset_item, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); assert_err!( @@ -817,6 +762,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() { let sender = PenpalASender::get(); let amount_to_send: Balance = WESTEND_ED * 1000; let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let asset_owner = PenpalAssetOwner::get(); let relay_native_asset_location = RelayLocation::get(); @@ -846,7 +792,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() { amount_to_send, assets.clone(), None, - 0, + fee_asset_id, ), }; let mut test = ParaToRelayTest::new(test_args); @@ -887,6 +833,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_para() { let sender = AssetHubWestendSender::get(); let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 2000; let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); // Init values for Parachain let system_para_native_asset_location = RelayLocation::get(); @@ -902,7 +849,7 @@ fn reserve_transfer_native_asset_from_asset_hub_to_para() { amount_to_send, assets.clone(), None, - 0, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(test_args); @@ -941,6 +888,7 @@ fn reserve_transfer_native_asset_from_para_to_asset_hub() { let sender = PenpalASender::get(); let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000; let assets: Assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let system_para_native_asset_location = RelayLocation::get(); let asset_owner = PenpalAssetOwner::get(); @@ -971,7 +919,7 @@ fn reserve_transfer_native_asset_from_para_to_asset_hub() { amount_to_send, assets.clone(), None, - 0, + fee_asset_id, ), }; let mut test = ParaToSystemParaTest::new(test_args); @@ -1026,11 +974,7 @@ fn reserve_transfer_multiple_assets_from_asset_hub_to_para() { .into(), ] .into(); - let fee_asset_index = assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); AssetHubWestend::mint_asset( asset_owner_signer, RESERVABLE_ASSET_ID, @@ -1056,7 +1000,7 @@ fn reserve_transfer_multiple_assets_from_asset_hub_to_para() { asset_amount_to_send, assets, None, - fee_asset_index, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(para_test_args); @@ -1129,11 +1073,7 @@ fn reserve_transfer_multiple_assets_from_para_to_asset_hub() { (asset_location_on_penpal.clone(), asset_amount_to_send).into(), ] .into(); - let fee_asset_index = assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); // Fund Parachain's sender account with some foreign assets PenpalA::mint_foreign_asset( penpal_asset_owner_signer.clone(), @@ -1182,7 +1122,7 @@ fn reserve_transfer_multiple_assets_from_para_to_asset_hub() { asset_amount_to_send, assets, None, - fee_asset_index, + fee_asset_id, ), }; let mut test = ParaToSystemParaTest::new(para_test_args); @@ -1242,6 +1182,7 @@ fn reserve_transfer_native_asset_from_para_to_para_through_relay() { let amount_to_send: Balance = WESTEND_ED * 10000; let asset_owner = PenpalAssetOwner::get(); let assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let relay_native_asset_location = RelayLocation::get(); let sender_as_seen_by_relay = Westend::child_location_of(PenpalA::para_id()); let sov_of_sender_on_relay = Westend::sovereign_account_id_of(sender_as_seen_by_relay); @@ -1264,7 +1205,14 @@ fn reserve_transfer_native_asset_from_para_to_para_through_relay() { let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), - args: TestArgs::new_para(destination, receiver.clone(), amount_to_send, assets, None, 0), + args: TestArgs::new_para( + destination, + receiver.clone(), + amount_to_send, + assets, + None, + fee_asset_id, + ), }; let mut test = ParaToParaThroughRelayTest::new(test_args); @@ -1334,6 +1282,9 @@ fn reserve_transfer_usdt_from_asset_hub_to_para() { .into()] .into(); + let fee_asset_id: AssetId = + [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(usdt_id.into())].into(); + let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), @@ -1343,7 +1294,7 @@ fn reserve_transfer_usdt_from_asset_hub_to_para() { asset_amount_to_send, assets, None, - 0, + fee_asset_id, ), }; let mut test = SystemParaToParaTest::new(test_args); @@ -1448,6 +1399,7 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() { (usdt_from_asset_hub.clone(), asset_amount_to_send + fee_amount_to_send).into(); // Just to be very specific we're not including anything other than USDT. assert_eq!(assets.len(), 1); + let fee_asset_id: AssetId = usdt_from_asset_hub.clone().into(); // Give the sender enough Relay tokens to pay for local delivery fees. // TODO(https://github.com/paritytech/polkadot-sdk/issues/5160): When we support local delivery fee payment in other assets, we don't need this. @@ -1462,7 +1414,6 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() { let receiver = PenpalBReceiver::get(); // Init Test - let fee_asset_index = 0; let test_args = TestContext { sender: sender.clone(), receiver: receiver.clone(), @@ -1472,7 +1423,7 @@ fn reserve_transfer_usdt_from_para_to_para_through_asset_hub() { asset_amount_to_send, assets, None, - fee_asset_index, + fee_asset_id, ), }; let mut test = ParaToParaThroughAHTest::new(test_args); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs index af0227ecb5fe3..ddc9b3dd3fc23 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs @@ -34,8 +34,7 @@ fn penpal_to_ah_foreign_assets_sender_assertions(t: ParaToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; let system_para_native_asset_location = RelayLocation::get(); let expected_asset_id = t.args.asset_id.unwrap(); - let (_, expected_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let (_, expected_asset_amount) = non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); PenpalA::assert_xcm_pallet_attempted_complete(None); assert_expected_events!( @@ -62,8 +61,8 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { AssetHubWestend::sibling_location_of(PenpalA::para_id()), ); let (_, expected_foreign_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); - let (_, fee_asset_amount) = fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); + let (_, fee_asset_amount) = fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); AssetHubWestend::assert_xcmp_queue_success(None); @@ -94,7 +93,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { type RuntimeEvent = ::RuntimeEvent; AssetHubWestend::assert_xcm_pallet_attempted_complete(None); let (expected_foreign_asset_id, expected_foreign_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -111,8 +110,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { fn ah_to_penpal_foreign_assets_receiver_assertions(t: SystemParaToParaTest) { type RuntimeEvent = ::RuntimeEvent; let expected_asset_id = t.args.asset_id.unwrap(); - let (_, expected_asset_amount) = - non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let (_, expected_asset_amount) = non_fee_asset(&t.args.assets, &t.args.fee_asset_id).unwrap(); let checking_account = ::PolkadotXcm::check_account(); let system_para_native_asset_location = RelayLocation::get(); @@ -150,29 +148,18 @@ fn relay_to_system_para_limited_teleport_assets(t: RelayToSystemParaTest) -> Dis bx!(t.args.dest.into()), bx!(t.args.beneficiary.into()), bx!(t.args.assets.into()), - t.args.fee_asset_item, + bx!(t.args.fee_asset_id.into()), t.args.weight_limit, ) } fn para_to_system_para_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::Teleport), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::DestinationReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -184,23 +171,12 @@ fn para_to_system_para_transfer_assets(t: ParaToSystemParaTest) -> DispatchResul } fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult { - type Runtime = ::Runtime; - let remote_fee_id: AssetId = t - .args - .assets - .clone() - .into_inner() - .get(t.args.fee_asset_item as usize) - .ok_or(pallet_xcm::Error::::Empty)? - .clone() - .id; - ::PolkadotXcm::transfer_assets_using_type_and_then( t.signed_origin, bx!(t.args.dest.into()), bx!(t.args.assets.into()), bx!(TransferType::Teleport), - bx!(remote_fee_id.into()), + bx!(t.args.fee_asset_id.into()), bx!(TransferType::LocalReserve), bx!(VersionedXcm::from( Xcm::<()>::builder_unsafe() @@ -215,11 +191,13 @@ fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResul fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { let amount = ASSET_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin vec![BridgeHubWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -228,11 +206,13 @@ fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { fn teleport_via_transfer_assets_to_other_system_parachains_works() { let amount = ASSET_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin vec![BridgeHubWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -240,12 +220,11 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = WESTEND_ED * 100; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, vec![AssetHubWestend], - (native_asset, amount), + amount, limited_teleport_assets ); @@ -260,14 +239,8 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = WESTEND_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Westend, - vec![AssetHubWestend], - (native_asset, amount), - transfer_assets - ); + test_relay_is_trusted_teleporter!(Westend, vec![AssetHubWestend], amount, transfer_assets); test_parachain_is_trusted_teleporter_for_relay!( AssetHubWestend, @@ -289,6 +262,7 @@ fn limited_teleport_native_assets_from_relay_to_asset_hub_checking_acc_fails() { let destination = Westend::child_location_of(AssetHubWestend::para_id()); let beneficiary_id = AssetHubWestendReceiver::get().into(); let assets = (Here, amount_to_send_larger_than_checking_acc).into(); + let fee_asset_id: AssetId = Here.into(); let test_args = TestContext { sender: WestendSender::get(), @@ -299,7 +273,7 @@ fn limited_teleport_native_assets_from_relay_to_asset_hub_checking_acc_fails() { amount_to_send_larger_than_checking_acc, assets, None, - 0, + fee_asset_id, ), }; @@ -332,7 +306,11 @@ fn limited_teleport_native_assets_from_relay_to_asset_hub_checking_acc_fails() { xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( - test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + test.args.assets.clone(), + test.args.fee_asset_id, + test.args.weight_limit, + test.args.beneficiary, + test.args.dest, ) }); @@ -353,11 +331,19 @@ fn limited_teleport_native_assets_from_relay_to_asset_hub_checking_acc_burn_work let destination = Westend::child_location_of(AssetHubWestend::para_id()); let beneficiary_id = AssetHubWestendReceiver::get().into(); let assets = (Here, amount_to_send).into(); + let fee_asset_id: AssetId = Here.into(); let test_args = TestContext { sender: WestendSender::get(), receiver: AssetHubWestendReceiver::get(), - args: TestArgs::new_para(destination, beneficiary_id, amount_to_send, assets, None, 0), + args: TestArgs::new_para( + destination, + beneficiary_id, + amount_to_send, + assets, + None, + fee_asset_id, + ), }; let mut test = RelayToSystemParaTest::new(test_args); @@ -397,7 +383,11 @@ fn limited_teleport_native_assets_from_relay_to_asset_hub_checking_acc_burn_work xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( - test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + test.args.assets.clone(), + test.args.fee_asset_id, + test.args.weight_limit, + test.args.beneficiary, + test.args.dest, ) }); @@ -419,11 +409,19 @@ fn limited_teleport_native_assets_from_asset_hub_to_relay_checking_acc_mint_work let destination = AssetHubWestend::parent_location().into(); let beneficiary_id = WestendReceiver::get().into(); let assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); let test_args = TestContext { sender: AssetHubWestendSender::get(), receiver: WestendReceiver::get(), - args: TestArgs::new_para(destination, beneficiary_id, amount_to_send, assets, None, 0), + args: TestArgs::new_para( + destination, + beneficiary_id, + amount_to_send, + assets, + None, + fee_asset_id, + ), }; let mut test = SystemParaToRelayTest::new(test_args); @@ -476,7 +474,7 @@ fn limited_teleport_native_assets_from_asset_hub_to_relay_checking_acc_mint_work bx!(t.args.dest.into()), bx!(t.args.beneficiary.into()), bx!(t.args.assets.into()), - t.args.fee_asset_item, + bx!(t.args.fee_asset_id.into()), t.args.weight_limit, ) } @@ -493,7 +491,11 @@ fn limited_teleport_native_assets_from_asset_hub_to_relay_checking_acc_mint_work xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( - test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + test.args.assets.clone(), + test.args.fee_asset_id, + test.args.weight_limit, + test.args.beneficiary, + test.args.dest, ) }); @@ -531,11 +533,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using (asset_location_on_penpal.clone(), asset_amount_to_send).into(), ] .into(); - let fee_asset_index = penpal_assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); // fund Parachain's sender account PenpalA::mint_foreign_asset( @@ -582,7 +580,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using asset_amount_to_send, penpal_assets, Some(asset_id_on_penpal), - fee_asset_index, + fee_asset_id, ), }; let mut penpal_to_ah = ParaToSystemParaTest::new(penpal_to_ah_test_args); @@ -667,11 +665,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using (foreign_asset_at_asset_hub.clone(), asset_amount_to_send).into(), ] .into(); - let fee_asset_index = ah_assets - .inner() - .iter() - .position(|r| r == &(Parent, fee_amount_to_send).into()) - .unwrap() as u32; + let fee_asset_id: AssetId = Parent.into(); // AH to Penpal test args let ah_to_penpal_test_args = TestContext { @@ -683,7 +677,7 @@ pub fn do_bidirectional_teleport_foreign_assets_between_para_and_asset_hub_using asset_amount_to_send, ah_assets, Some(asset_id_on_penpal), - fee_asset_index, + fee_asset_id, ), }; let mut ah_to_penpal = SystemParaToParaTest::new(ah_to_penpal_test_args); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transfer_assets_validation.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transfer_assets_validation.rs index 6db851daaeff8..78b3c625606a9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transfer_assets_validation.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/transfer_assets_validation.rs @@ -48,13 +48,14 @@ fn transfer_assets_wnd_reserve_transfer_para_to_relay_fails() { let sov_penpal_on_relay = Westend::sovereign_account_id_of(penpal_location_as_seen_by_relay); Westend::fund_accounts(vec![(sov_penpal_on_relay.into(), amount_to_send * 2)]); + let fee_asset_id: AssetId = Parent.into(); PenpalA::execute_with(|| { let result = ::PolkadotXcm::transfer_assets( ::RuntimeOrigin::signed(PenpalASender::get()), bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - 0, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); @@ -80,13 +81,14 @@ fn transfer_assets_wnd_reserve_transfer_relay_to_para_fails() { let amount_to_send: Balance = WESTEND_ED * 1000; let assets: Assets = (Here, amount_to_send).into(); + let fee_asset_id: AssetId = Here.into(); Westend::execute_with(|| { let result = ::XcmPallet::transfer_assets( ::RuntimeOrigin::signed(WestendSender::get()), bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - 0, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); @@ -123,13 +125,14 @@ fn transfer_assets_wnd_reserve_transfer_para_to_para_fails() { amount_to_send * 2, ); + let fee_asset_id: AssetId = Parent.into(); PenpalA::execute_with(|| { let result = ::PolkadotXcm::transfer_assets( ::RuntimeOrigin::signed(PenpalASender::get()), bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - 0, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); @@ -188,7 +191,7 @@ fn transfer_assets_wnd_as_fee_in_reserve_transfer_fails() { (Parent, fee_amount).into(), // WND as fee. ] .into(); - let fee_asset_item = 1; // WND is the fee asset. + let fee_asset_id: AssetId = Parent.into(); // WND is the fee asset. PenpalA::execute_with(|| { let result = ::PolkadotXcm::transfer_assets( @@ -196,7 +199,7 @@ fn transfer_assets_wnd_as_fee_in_reserve_transfer_fails() { bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - fee_asset_item, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); @@ -245,8 +248,8 @@ fn transfer_assets_non_native_assets_work() { ); // Transfer non-native assets. - let assets: Assets = (asset_location, amount).into(); - let fee_asset_item = 0; + let assets: Assets = (asset_location.clone(), amount).into(); + let fee_asset_id: AssetId = (asset_location).into(); PenpalA::execute_with(|| { let result = ::PolkadotXcm::transfer_assets( @@ -254,7 +257,7 @@ fn transfer_assets_non_native_assets_work() { bx!(destination.into()), bx!(beneficiary.into()), bx!(assets.into()), - fee_asset_item, + bx!(fee_asset_id.into()), WeightLimit::Unlimited, ); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/xcm_fee_estimation.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/xcm_fee_estimation.rs index 7deaaa9a984f9..f190bf185c7da 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/xcm_fee_estimation.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/xcm_fee_estimation.rs @@ -125,6 +125,7 @@ fn multi_hop_works() { // Init values for Parachain Destination let beneficiary_id = PenpalBReceiver::get(); + let fee_asset_id: AssetId = Parent.into(); let test_args = TestContext { sender: PenpalASender::get(), // Bob in PenpalB. receiver: PenpalBReceiver::get(), // Alice. @@ -134,7 +135,7 @@ fn multi_hop_works() { amount_to_send, assets, None, - 0, + fee_asset_id, ), }; let mut test = ParaToParaThroughAHTest::new(test_args); diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs index f6b759a36f476..7d89096eb2e9d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs @@ -20,10 +20,12 @@ fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { let amount = BRIDGE_HUB_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( BridgeHubRococo, // Origin vec![AssetHubRococo], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -33,10 +35,12 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { let amount = BRIDGE_HUB_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( BridgeHubRococo, // Origin vec![AssetHubRococo], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -44,12 +48,11 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = ROCOCO_ED * 100; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Rococo, vec![BridgeHubRococo], - (native_asset, amount), + amount, limited_teleport_assets ); @@ -64,14 +67,8 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = ROCOCO_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Rococo, - vec![BridgeHubRococo], - (native_asset, amount), - transfer_assets - ); + test_relay_is_trusted_teleporter!(Rococo, vec![BridgeHubRococo], amount, transfer_assets); test_parachain_is_trusted_teleporter_for_relay!( BridgeHubRococo, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge.rs index 82e1748cf3cb0..697cabfa4ab31 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge.rs @@ -364,12 +364,13 @@ fn send_eth_asset_from_asset_hub_to_ethereum_and_back() { AssetHubWestendReceiver::get(), ); // Send the Weth back to Ethereum + let fee_asset_id: AssetId = AssetId(origin_location.clone()); ::PolkadotXcm::limited_reserve_transfer_assets( RuntimeOrigin::signed(AssetHubWestendReceiver::get()), Box::new(destination), Box::new(beneficiary), Box::new(multi_assets), - 0, + Box::new(fee_asset_id.into()), Unlimited, ) .unwrap(); @@ -677,12 +678,19 @@ fn send_weth_asset_from_asset_hub_to_ethereum() { AssetHubWestendReceiver::get(), ); // Send the Weth back to Ethereum + let fee_asset_id: AssetId = AssetId(Location::new( + 2, + [ + GlobalConsensus(Ethereum { chain_id: SEPOLIA_ID }), + AccountKey20 { network: None, key: WETH }, + ], + )); ::PolkadotXcm::limited_reserve_transfer_assets( RuntimeOrigin::signed(AssetHubWestendReceiver::get()), Box::new(destination), Box::new(beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), Unlimited, ) .unwrap(); @@ -1032,12 +1040,13 @@ fn transfer_ah_token() { [AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }], )); + let fee_asset_id: AssetId = AssetId(asset_id.clone()); assert_ok!(::PolkadotXcm::transfer_assets( RuntimeOrigin::signed(AssetHubWestendSender::get()), Box::new(VersionedLocation::from(ethereum_destination)), Box::new(beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), Unlimited, )); @@ -1391,12 +1400,19 @@ fn send_weth_from_ethereum_to_ahw_to_ahr_back_to_ahw_and_ethereum() { AssetHubWestendReceiver::get(), ); // Send the Weth back to Ethereum + let fee_asset_id: AssetId = AssetId(Location::new( + 2, + [ + GlobalConsensus(Ethereum { chain_id: SEPOLIA_ID }), + AccountKey20 { network: None, key: WETH }, + ], + )); ::PolkadotXcm::limited_reserve_transfer_assets( RuntimeOrigin::signed(AssetHubWestendReceiver::get()), Box::new(destination), Box::new(beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), Unlimited, ) .unwrap(); @@ -1596,13 +1612,14 @@ fn transfer_penpal_native_asset() { let assets = vec![Asset { id: AssetId(pal_at_asset_hub.clone()), fun: Fungible(TOKEN_AMOUNT) }]; + let fee_asset_id: AssetId = AssetId(pal_at_asset_hub.clone()); assert_ok!( ::PolkadotXcm::limited_teleport_assets( RuntimeOrigin::signed(AssetHubWestendSender::get()), Box::new(VersionedLocation::from(destination)), Box::new(VersionedLocation::from(beneficiary)), Box::new(VersionedAssets::from(assets)), - 0, + Box::new(fee_asset_id.into()), Unlimited, ) ); @@ -2001,12 +2018,13 @@ fn transfer_roc_from_ah_with_legacy_api_will_fail() { [AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }], )); + let fee_asset_id: AssetId = AssetId(asset_id.clone()); let result = ::PolkadotXcm::transfer_assets( RuntimeOrigin::signed(AssetHubWestendSender::get()), Box::new(VersionedLocation::from(ethereum_destination)), Box::new(beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), Unlimited, ); diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs index 1cb208866336f..a26ebf72558f5 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs @@ -20,10 +20,12 @@ fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { let amount = BRIDGE_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( BridgeHubWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -33,10 +35,12 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { let amount = BRIDGE_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( BridgeHubWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -44,12 +48,11 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = WESTEND_ED * 100; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, vec![BridgeHubWestend], - (native_asset, amount), + amount, limited_teleport_assets ); @@ -64,14 +67,8 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = WESTEND_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Westend, - vec![BridgeHubWestend], - (native_asset, amount), - transfer_assets - ); + test_relay_is_trusted_teleporter!(Westend, vec![BridgeHubWestend], amount, transfer_assets); test_parachain_is_trusted_teleporter_for_relay!( BridgeHubWestend, diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs index aeab5a1ba5f2a..94e2d9a24b973 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs @@ -79,7 +79,7 @@ fn fellowship_treasury_spend() { id: native_asset.clone().into(), fun: treasury_balance.into() }))), - fee_asset_item: 0, + fee_asset_id: bx!(native_asset.into()), })), }); diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/teleport.rs index 2b6522bb3928b..5909272c6f498 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/teleport.rs @@ -21,12 +21,11 @@ use emulated_integration_tests_common::{ #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = WESTEND_ED * 10; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, // Origin vec![CollectivesWestend], // Destinations - (native_asset, amount), + amount, limited_teleport_assets ); @@ -41,12 +40,11 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = WESTEND_ED * 10; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, // Origin vec![CollectivesWestend], // Destinations - (native_asset, amount), + amount, transfer_assets ); @@ -63,10 +61,12 @@ fn teleport_via_limited_teleport_assets_from_collectives_to_asset_hub() { let amount = ASSET_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( CollectivesWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -76,10 +76,12 @@ fn teleport_via_transfer_assets_from_collectives_to_asset_hub() { let amount = ASSET_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( CollectivesWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -89,10 +91,12 @@ fn teleport_via_limited_teleport_assets_from_asset_hub_to_collectives() { let amount = COLLECTIVES_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin vec![CollectivesWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -102,10 +106,12 @@ fn teleport_via_transfer_assets_from_asset_hub_to_collectives() { let amount = COLLECTIVES_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin vec![CollectivesWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/teleport.rs index 3ca72b1e7a662..9ff4206125f9c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-rococo/src/tests/teleport.rs @@ -22,12 +22,11 @@ use emulated_integration_tests_common::{ #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = ROCOCO_ED * 10; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Rococo, // Origin vec![CoretimeRococo], // Destinations - (native_asset, amount), + amount, limited_teleport_assets ); @@ -42,12 +41,11 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = ROCOCO_ED * 10; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Rococo, // Origin vec![CoretimeRococo], // Destinations - (native_asset, amount), + amount, transfer_assets ); @@ -64,10 +62,12 @@ fn teleport_via_limited_teleport_assets_from_coretime_to_asset_hub() { let amount = ASSET_HUB_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( CoretimeRococo, // Origin vec![AssetHubRococo], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -77,10 +77,12 @@ fn teleport_via_transfer_assets_from_coretime_to_asset_hub() { let amount = ASSET_HUB_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( CoretimeRococo, // Origin vec![AssetHubRococo], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -90,10 +92,12 @@ fn teleport_via_limited_teleport_assets_from_asset_hub_to_coretime() { let amount = CORETIME_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin vec![CoretimeRococo], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -103,10 +107,12 @@ fn teleport_via_transfer_assets_from_asset_hub_to_coretime() { let amount = CORETIME_ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin vec![CoretimeRococo], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } diff --git a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/teleport.rs index 5e057e6ea18c3..7243f83942b94 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/coretime/coretime-westend/src/tests/teleport.rs @@ -22,12 +22,11 @@ use emulated_integration_tests_common::{ #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = WESTEND_ED * 10; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, // Origin vec![CoretimeWestend], // Destinations - (native_asset, amount), + amount, limited_teleport_assets ); @@ -42,12 +41,11 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = WESTEND_ED * 10; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, // Origin vec![CoretimeWestend], // Destinations - (native_asset, amount), + amount, transfer_assets ); @@ -64,10 +62,12 @@ fn teleport_via_limited_teleport_assets_from_coretime_to_asset_hub() { let amount = ASSET_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( CoretimeWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -77,10 +77,12 @@ fn teleport_via_transfer_assets_from_coretime_to_asset_hub() { let amount = ASSET_HUB_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( CoretimeWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -90,10 +92,12 @@ fn teleport_via_limited_teleport_assets_from_asset_hub_to_coretime() { let amount = CORETIME_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin vec![CoretimeWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -103,10 +107,12 @@ fn teleport_via_transfer_assets_from_asset_hub_to_coretime() { let amount = CORETIME_WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin vec![CoretimeWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/teleport.rs index 3f0a0f974f834..53fbf9733ed36 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/teleport.rs @@ -22,14 +22,8 @@ use emulated_integration_tests_common::{ #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = ROCOCO_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Rococo, - vec![PeopleRococo], - (native_asset, amount), - limited_teleport_assets - ); + test_relay_is_trusted_teleporter!(Rococo, vec![PeopleRococo], amount, limited_teleport_assets); test_parachain_is_trusted_teleporter_for_relay!( PeopleRococo, @@ -42,14 +36,8 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = ROCOCO_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Rococo, - vec![PeopleRococo], - (native_asset, amount), - transfer_assets - ); + test_relay_is_trusted_teleporter!(Rococo, vec![PeopleRococo], amount, transfer_assets); test_parachain_is_trusted_teleporter_for_relay!(PeopleRococo, Rococo, amount, transfer_assets); } @@ -59,10 +47,12 @@ fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { let amount = ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( PeopleRococo, // Origin vec![AssetHubRococo], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -72,10 +62,12 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { let amount = ROCOCO_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( PeopleRococo, // Origin vec![AssetHubRococo], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } @@ -109,7 +101,7 @@ fn system_para_limited_teleport_assets(t: SystemParaToRelayTest) -> DispatchResu bx!(t.args.dest.into()), bx!(t.args.beneficiary.into()), bx!(t.args.assets.into()), - t.args.fee_asset_item, + bx!(t.args.fee_asset_id.into()), t.args.weight_limit, ) } @@ -123,6 +115,7 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() { let destination = PeopleRococo::parent_location(); let beneficiary_id = RococoReceiver::get(); let assets = (Parent, amount_to_send).into(); + let fee_asset_id: AssetId = Parent.into(); // Fund a sender PeopleRococo::fund_accounts(vec![(PeopleRococoSender::get(), ROCOCO_ED * 2_000u128)]); @@ -130,7 +123,14 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() { let test_args = TestContext { sender: PeopleRococoSender::get(), receiver: RococoReceiver::get(), - args: TestArgs::new_para(destination, beneficiary_id, amount_to_send, assets, None, 0), + args: TestArgs::new_para( + destination, + beneficiary_id, + amount_to_send, + assets, + None, + fee_asset_id, + ), }; let mut test = SystemParaToRelayTest::new(test_args); @@ -150,7 +150,11 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() { xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( - test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + test.args.assets.clone(), + test.args.fee_asset_id, + test.args.weight_limit, + test.args.beneficiary, + test.args.dest, ) }); diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/teleport.rs index 94c096fb83dc7..c62c4527f8caf 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-westend/src/tests/teleport.rs @@ -22,12 +22,11 @@ use emulated_integration_tests_common::{ #[test] fn teleport_via_limited_teleport_assets_from_and_to_relay() { let amount = WESTEND_ED * 100; - let native_asset: Assets = (Here, amount).into(); test_relay_is_trusted_teleporter!( Westend, vec![PeopleWestend], - (native_asset, amount), + amount, limited_teleport_assets ); @@ -42,14 +41,8 @@ fn teleport_via_limited_teleport_assets_from_and_to_relay() { #[test] fn teleport_via_transfer_assets_from_and_to_relay() { let amount = WESTEND_ED * 100; - let native_asset: Assets = (Here, amount).into(); - test_relay_is_trusted_teleporter!( - Westend, - vec![PeopleWestend], - (native_asset, amount), - transfer_assets - ); + test_relay_is_trusted_teleporter!(Westend, vec![PeopleWestend], amount, transfer_assets); test_parachain_is_trusted_teleporter_for_relay!( PeopleWestend, @@ -64,10 +57,12 @@ fn teleport_via_limited_teleport_assets_to_other_system_parachains_works() { let amount = WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( PeopleWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, limited_teleport_assets ); } @@ -77,10 +72,12 @@ fn teleport_via_transfer_assets_to_other_system_parachains_works() { let amount = WESTEND_ED * 100; let native_asset: Assets = (Parent, amount).into(); + let fee_asset_id: AssetId = Parent.into(); test_parachain_is_trusted_teleporter!( PeopleWestend, // Origin vec![AssetHubWestend], // Destinations (native_asset, amount), + fee_asset_id, transfer_assets ); } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 302db52e4945f..7d4a7e438c33c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1770,7 +1770,7 @@ impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(XcmAssets, u32, Location, alloc::boxed::Box)> { + ) -> Option<(XcmAssets, AssetId, Location, alloc::boxed::Box)> { let dest = PeopleLocation::get(); let fee_amount = EXISTENTIAL_DEPOSIT; @@ -1799,7 +1799,7 @@ impl_runtime_apis! { let transfer_asset: Asset = (asset_location, asset_amount).into(); let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into(); - let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; + let fee_asset_id = fee_asset.id; // verify transferred successfully let verify = alloc::boxed::Box::new(move || { @@ -1812,7 +1812,7 @@ impl_runtime_apis! { initial_asset_amount - asset_amount, ); }); - Some((assets, fee_index as u32, dest, verify)) + Some((assets, fee_asset_id, dest, verify)) } fn get_asset() -> Asset { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index c39a2dab7fbab..972ec603bf42a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -2288,7 +2288,7 @@ pallet_revive::impl_runtime_apis_plus_revive_traits!( } fn set_up_complex_asset_transfer( - ) -> Option<(XcmAssets, u32, Location, alloc::boxed::Box)> { + ) -> Option<(XcmAssets, AssetId, Location, alloc::boxed::Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) @@ -2320,7 +2320,7 @@ pallet_revive::impl_runtime_apis_plus_revive_traits!( let transfer_asset: Asset = (asset_location, asset_amount).into(); let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into(); - let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; + let fee_asset_id = fee_asset.id; // verify transferred successfully let verify = alloc::boxed::Box::new(move || { @@ -2333,7 +2333,7 @@ pallet_revive::impl_runtime_apis_plus_revive_traits!( initial_asset_amount - asset_amount, ); }); - Some((assets, fee_index as u32, dest, verify)) + Some((assets, fee_asset_id, dest, verify)) } fn get_asset() -> Asset { diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index e6a0aea3605e3..ee78d40bcc647 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -215,7 +215,7 @@ pub fn teleports_for_native_asset_works< let delivery_fees = xcm_helpers::teleport_assets_delivery_fees::( (native_asset_id.clone(), native_asset_to_teleport_away.into()).into(), - 0, + native_asset_id.clone().into(), Unlimited, dest_beneficiary.clone(), dest.clone(), @@ -609,7 +609,7 @@ pub fn teleports_for_foreign_assets_works< let delivery_fees = xcm_helpers::teleport_assets_delivery_fees::( (foreign_asset_id_location.clone(), asset_to_teleport_away).into(), - 0, + foreign_asset_id_location.clone().into(), Unlimited, dest_beneficiary.clone(), dest.clone(), diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs index b81785fec6906..e41ef552f73b1 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs @@ -23,12 +23,12 @@ use xcm::latest::prelude::*; /// in one asset and that asset is known. pub fn teleport_assets_delivery_fees( assets: Assets, - fee_asset_item: u32, + fee_asset_id: AssetId, weight_limit: WeightLimit, beneficiary: Location, destination: Location, ) -> u128 { - let message = teleport_assets_dummy_message(assets, fee_asset_item, weight_limit, beneficiary); + let message = teleport_assets_dummy_message(assets, fee_asset_id, weight_limit, beneficiary); get_fungible_delivery_fees::(destination, message) } @@ -82,14 +82,17 @@ pub fn pay_over_xcm_delivery_fees( /// Also has same encoded size as the one created by the reserve transfer assets extrinsic. fn teleport_assets_dummy_message( assets: Assets, - fee_asset_item: u32, + fee_asset_id: AssetId, weight_limit: WeightLimit, beneficiary: Location, ) -> Xcm<()> { Xcm(vec![ ReceiveTeleportedAsset(assets.clone()), // Same encoded size as `ReserveAssetDeposited` ClearOrigin, - BuyExecution { fees: assets.get(fee_asset_item as usize).unwrap().clone(), weight_limit }, + BuyExecution { + fees: assets.inner().iter().find(|a| a.id == fee_asset_id).unwrap().clone(), + weight_limit, + }, DepositAsset { assets: Wild(AllCounted(assets.len() as u32)), beneficiary }, SetTopic([0u8; 32]), // Dummy topic ]) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 8b037a77a8445..8de74c2923c19 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1148,7 +1148,7 @@ impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(Assets, u32, Location, Box)> { + ) -> Option<(Assets, AssetId, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = TokenLocation::get(); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 23f0275ee32d6..6dac18f8886e6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -1088,7 +1088,7 @@ impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + ) -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = WestendLocation::get(); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 2dc06e50aade3..83e86df6b912b 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -1189,7 +1189,7 @@ impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + ) -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { // Collectives only supports teleports to system parachain. // Relay/native token can be teleported between Collectives and Relay. let native_location = WndLocation::get(); diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 736e6dd6ead14..062a422912afb 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -1026,7 +1026,7 @@ impl_runtime_apis! { )) } - fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { let native_location = Parent.into(); let dest = AssetHubLocation::get(); diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 4579b78ab4715..e3de2d76c2e6c 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -1041,7 +1041,7 @@ impl_runtime_apis! { )) } - fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { let native_location = Parent.into(); let dest = AssetHubLocation::get(); diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 1ed6cedffd806..a7ed73ac11087 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -948,7 +948,7 @@ impl_runtime_apis! { None } - fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { let native_location = Parent.into(); let dest = AssetHubLocation::get(); diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 4966b8783ea60..08d77ab279a7c 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -975,7 +975,7 @@ impl_runtime_apis! { None } - fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { let native_location = Parent.into(); let dest = AssetHubLocation::get(); diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 2c8b122576a58..2d0ecc3978703 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -445,8 +445,8 @@ impl< origin, Box::new(dest.into()), Box::new(beneficiary.into()), - Box::new((AssetId(asset), amount).into()), - 0, + Box::new((AssetId(asset.clone()), amount).into()), + Box::new(AssetId(asset).into()), Unlimited, ) } diff --git a/cumulus/xcm/xcm-emulator/src/lib.rs b/cumulus/xcm/xcm-emulator/src/lib.rs index de0f9dc6aae01..27118f3f0caf7 100644 --- a/cumulus/xcm/xcm-emulator/src/lib.rs +++ b/cumulus/xcm/xcm-emulator/src/lib.rs @@ -86,7 +86,7 @@ pub use polkadot_runtime_parachains::inclusion::{AggregateMessageOrigin, UmpQueu pub use polkadot_parachain_primitives::primitives::RelayChainBlockNumber; use sp_core::{crypto::AccountId32, H256}; pub use xcm::latest::prelude::{ - AccountId32 as AccountId32Junction, Ancestor, Assets, Here, Location, + AccountId32 as AccountId32Junction, Ancestor, AssetId, Assets, Here, Location, Parachain as ParachainJunction, Parent, WeightLimit, XcmHash, }; pub use xcm_executor::traits::ConvertLocation; @@ -302,7 +302,7 @@ pub trait Parachain: Chain { } fn parent_location() -> Location { - (Parent).into() + Parent.into() } fn sibling_location_of(para_id: ParaId) -> Location { @@ -1554,7 +1554,7 @@ pub struct TestArgs { pub amount: Balance, pub assets: Assets, pub asset_id: Option, - pub fee_asset_item: u32, + pub fee_asset_id: AssetId, pub weight_limit: WeightLimit, } @@ -1567,7 +1567,7 @@ impl TestArgs { amount, assets: (Here, amount).into(), asset_id: None, - fee_asset_item: 0, + fee_asset_id: Here.into(), weight_limit: WeightLimit::Unlimited, } } @@ -1579,7 +1579,7 @@ impl TestArgs { amount: Balance, assets: Assets, asset_id: Option, - fee_asset_item: u32, + fee_asset_id: AssetId, ) -> Self { Self { dest, @@ -1587,7 +1587,7 @@ impl TestArgs { amount, assets, asset_id, - fee_asset_item, + fee_asset_id, weight_limit: WeightLimit::Unlimited, } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 1c08a1c6b3e1d..54b91b4074cd0 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2564,7 +2564,7 @@ sp_api::impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(Assets, u32, Location, alloc::boxed::Box)> { + ) -> Option<(Assets, AssetId, Location, alloc::boxed::Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 99e02b1053320..4d21517429a3f 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2941,7 +2941,7 @@ sp_api::impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(Assets, u32, Location, Box)> { + ) -> Option<(Assets, AssetId, Location, Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index cdc4b6dea108b..c1b4bedd35e29 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -64,7 +64,7 @@ fn sanity_check_teleport_assets_weight() { dest: Box::new(Here.into()), beneficiary: Box::new(Here.into()), assets: Box::new((Here, 200_000).into()), - fee_asset_item: 0, + fee_asset_id: Box::new(Here.into()), weight_limit: Unlimited, } .get_dispatch_info() diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index 1a498123e1f05..6a7f77821419c 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -61,8 +61,8 @@ pub trait Config: crate::Config + pallet_balances::Config { /// Sets up a complex transfer (usually consisting of a teleport and reserve-based transfer), so /// that runtime can properly benchmark `transfer_assets()` extrinsic. Should return a tuple - /// `(Asset, u32, Location, dyn FnOnce())` representing the assets to transfer, the - /// `u32` index of the asset to be used for fees, the destination chain for the transfer, and a + /// `(Asset, AssetId, Location, dyn FnOnce())` representing the assets to transfer, the + /// `AssetId` of the asset to be used for fees, the destination chain for the transfer, and a /// `verify()` closure to verify the intended transfer side-effects. /// /// Implementation should make sure the provided assets can be transacted by the runtime, there @@ -71,7 +71,7 @@ pub trait Config: crate::Config + pallet_balances::Config { /// Used only in benchmarks. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, AssetId, Location, Box)> { None } @@ -142,7 +142,7 @@ mod benchmarks { Fungible(amount) => { // Add transferred_amount to origin ::AssetTransactor::deposit_asset( - &Asset { fun: Fungible(*amount), id: asset.id }, + &Asset { fun: Fungible(*amount), id: asset.id.clone() }, &origin_location, None, ) @@ -170,13 +170,14 @@ mod benchmarks { AccountId32 { network: None, id: recipient.into() }.into(); let versioned_assets: VersionedAssets = assets.into(); + let fee_asset_id: AssetId = asset.id; #[extrinsic_call] _( send_origin, Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), ); Ok(()) @@ -240,13 +241,14 @@ mod benchmarks { AccountId32 { network: None, id: recipient.into() }.into(); let versioned_assets: VersionedAssets = assets.into(); + let fee_asset_id: AssetId = asset.id.clone(); #[extrinsic_call] _( send_origin, Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), ); match &asset.fun { @@ -271,7 +273,7 @@ mod benchmarks { #[benchmark] fn transfer_assets() -> Result<(), BenchmarkError> { - let (assets, _fee_index, destination, verify_fn) = T::set_up_complex_asset_transfer() + let (assets, fee_asset_id, destination, verify_fn) = T::set_up_complex_asset_transfer() .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; let caller: T::AccountId = whitelisted_caller(); let send_origin = RawOrigin::Signed(caller.clone()); @@ -295,7 +297,7 @@ mod benchmarks { Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), - 0, + Box::new(fee_asset_id.into()), WeightLimit::Unlimited, ); @@ -745,7 +747,7 @@ pub mod helpers { pub fn native_teleport_as_asset_transfer( native_asset_location: Location, destination: Location, - ) -> Option<(Assets, u32, Location, Box)> + ) -> Option<(Assets, AssetId, Location, Box)> where T: Config + pallet_balances::Config, u128: From<::Balance>, @@ -753,8 +755,9 @@ pub mod helpers { // Relay/native token can be teleported to/from AH. let amount = T::ExistentialDeposit::get() * 100u32.into(); let assets: Assets = - Asset { fun: Fungible(amount.into()), id: AssetId(native_asset_location) }.into(); - let fee_index = 0u32; + Asset { fun: Fungible(amount.into()), id: AssetId(native_asset_location.clone()) } + .into(); + let fee_asset_id: AssetId = AssetId(native_asset_location); // Give some multiple of transferred amount let balance = amount * 10u32.into(); @@ -769,6 +772,6 @@ pub mod helpers { // verify balance after transfer, decreased by transferred amount (and delivery fees) assert!(pallet_balances::Pallet::::free_balance(&who) <= balance - amount); }); - Some((assets, fee_index, destination, verify)) + Some((assets, fee_asset_id, destination, verify)) } } diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index cec618e3603a2..63607a4a737e7 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -1132,7 +1132,7 @@ pub mod pallet { /// **This function is deprecated: Use `limited_teleport_assets` instead.** /// /// Fee payment on the destination side is made from the asset in the `assets` vector of - /// index `fee_asset_item`. The weight limit for fees is not provided and thus is unlimited, + /// id `fee_asset_id`. The weight limit for fees is not provided and thus is unlimited, /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. @@ -1143,8 +1143,7 @@ pub mod pallet { /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the /// fee on the `dest` chain. - /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay - /// fees. + /// - `fee_asset_id`: Id of the asset from `assets` which should be used to pay fees. #[pallet::call_index(1)] #[allow(deprecated)] #[deprecated( @@ -1155,9 +1154,9 @@ pub mod pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, ) -> DispatchResult { - Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, Unlimited) + Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_id, Unlimited) } /// Transfer some assets from the local chain to the destination chain through their local, @@ -1177,7 +1176,7 @@ pub mod pallet { /// **This function is deprecated: Use `limited_reserve_transfer_assets` instead.** /// /// Fee payment on the destination side is made from the asset in the `assets` vector of - /// index `fee_asset_item`. The weight limit for fees is not provided and thus is unlimited, + /// id `fee_asset_id`. The weight limit for fees is not provided and thus is unlimited, /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. @@ -1188,8 +1187,7 @@ pub mod pallet { /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the /// fee on the `dest` (and possibly reserve) chains. - /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay - /// fees. + /// - `fee_asset_id`: Id of the asset from `assets` which should be used to pay fees. #[pallet::call_index(2)] #[allow(deprecated)] #[deprecated( @@ -1200,14 +1198,14 @@ pub mod pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, ) -> DispatchResult { Self::do_reserve_transfer_assets( origin, dest, beneficiary, assets, - fee_asset_item, + fee_asset_id, Unlimited, ) } @@ -1343,7 +1341,7 @@ pub mod pallet { /// to mint and deposit reserve-based assets to `beneficiary`. /// /// Fee payment on the destination side is made from the asset in the `assets` vector of - /// index `fee_asset_item`, up to enough to pay for `weight_limit` of weight. If more weight + /// id `fee_asset_id`, up to enough to pay for `weight_limit` of weight. If more weight /// is needed than `weight_limit`, then the operation will fail and the sent assets may be /// at risk. /// @@ -1355,8 +1353,7 @@ pub mod pallet { /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the /// fee on the `dest` (and possibly reserve) chains. - /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay - /// fees. + /// - `fee_asset_id`: Id of the asset from `assets` which should be used to pay fees. /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(8)] #[pallet::weight(T::WeightInfo::reserve_transfer_assets())] @@ -1365,7 +1362,7 @@ pub mod pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, weight_limit: WeightLimit, ) -> DispatchResult { Self::do_reserve_transfer_assets( @@ -1373,7 +1370,7 @@ pub mod pallet { dest, beneficiary, assets, - fee_asset_item, + fee_asset_id, weight_limit, ) } @@ -1381,7 +1378,7 @@ pub mod pallet { /// Teleport some assets from the local chain to some destination chain. /// /// Fee payment on the destination side is made from the asset in the `assets` vector of - /// index `fee_asset_item`, up to enough to pay for `weight_limit` of weight. If more weight + /// id `fee_asset_id`, up to enough to pay for `weight_limit` of weight. If more weight /// is needed than `weight_limit`, then the operation will fail and the sent assets may be /// at risk. /// @@ -1393,8 +1390,7 @@ pub mod pallet { /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the /// fee on the `dest` chain. - /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay - /// fees. + /// - `fee_asset_id`: Id of the asset from `assets` which should be used to pay fees. /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(9)] #[pallet::weight(T::WeightInfo::teleport_assets())] @@ -1403,17 +1399,10 @@ pub mod pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, weight_limit: WeightLimit, ) -> DispatchResult { - Self::do_teleport_assets( - origin, - dest, - beneficiary, - assets, - fee_asset_item, - weight_limit, - ) + Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_id, weight_limit) } /// Set or unset the global suspension state of the XCM executor. @@ -1431,7 +1420,7 @@ pub mod pallet { /// destination or remote reserve, or through teleports. /// /// Fee payment on the destination side is made from the asset in the `assets` vector of - /// index `fee_asset_item` (hence referred to as `fees`), up to enough to pay for + /// id `fee_asset_id` (hence referred to as `fees`), up to enough to pay for /// `weight_limit` of weight. If more weight is needed than `weight_limit`, then the /// operation will fail and the sent assets may be at risk. /// @@ -1457,8 +1446,7 @@ pub mod pallet { /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the /// fee on the `dest` (and possibly reserve) chains. - /// - `fee_asset_item`: The index into `assets` of the item which should be used to pay - /// fees. + /// - `fee_asset_id`: Id of the asset from `assets` which should be used to pay fees. /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(11)] pub fn transfer_assets( @@ -1466,7 +1454,7 @@ pub mod pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, weight_limit: WeightLimit, ) -> DispatchResult { let origin = T::ExecuteXcmOrigin::ensure_origin(origin)?; @@ -1491,24 +1479,30 @@ pub mod pallet { ); Error::::BadVersion })?; + let fee_asset_id: AssetId = (*fee_asset_id).try_into().map_err(|()| { + tracing::debug!( + target: "xcm::pallet_xcm::do_teleport_assets", + "Failed to convert VersionedAssetId", + ); + Error::::BadVersion + })?; tracing::debug!( target: "xcm::pallet_xcm::transfer_assets", - ?origin, ?dest, ?beneficiary, ?assets, ?fee_asset_item, ?weight_limit, + ?origin, ?dest, ?beneficiary, ?assets, ?fee_asset_id, ?weight_limit, ); ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); let assets = assets.into_inner(); - let fee_asset_item = fee_asset_item as usize; // Find transfer types for fee and non-fee assets. let (fees_transfer_type, assets_transfer_type) = - Self::find_fee_and_assets_transfer_types(&assets, fee_asset_item, &dest)?; + Self::find_fee_and_assets_transfer_types(&assets, &fee_asset_id, &dest)?; // We check for network native asset reserve transfers in preparation for the Asset Hub // Migration. This check will be removed after the migration and the determined // reserve location adjusted accordingly. For more information, see https://github.com/paritytech/polkadot-sdk/issues/9054. Self::ensure_network_asset_reserve_transfer_allowed( &assets, - fee_asset_item, + &fee_asset_id, &assets_transfer_type, &fees_transfer_type, )?; @@ -1519,7 +1513,7 @@ pub mod pallet { Either::Left(beneficiary), assets, assets_transfer_type, - fee_asset_item, + fee_asset_id, fees_transfer_type, weight_limit, ) @@ -1678,15 +1672,13 @@ pub mod pallet { let assets = assets.into_inner(); ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); - let fee_asset_index = - assets.iter().position(|a| a.id == fees_id).ok_or(Error::::FeesNotMet)?; Self::do_transfer_assets( origin_location, dest, Either::Right(remote_xcm), assets, *assets_transfer_type, - fee_asset_index, + fees_id, *fees_transfer_type, weight_limit, ) @@ -1998,25 +1990,25 @@ impl Pallet { AssetTraps::::get(trap_id) } - /// Find `TransferType`s for `assets` and fee identified through `fee_asset_item`, when + /// Find `TransferType`s for `assets` and fee identified through `fee_asset_id`, when /// transferring to `dest`. /// /// Validate `assets` to all have same `TransferType`. fn find_fee_and_assets_transfer_types( assets: &[Asset], - fee_asset_item: usize, + fee_asset_id: &AssetId, dest: &Location, ) -> Result<(TransferType, TransferType), Error> { let mut fees_transfer_type = None; let mut assets_transfer_type = None; - for (idx, asset) in assets.iter().enumerate() { + for asset in assets.iter() { if let Fungible(x) = asset.fun { // If fungible asset, ensure non-zero amount. ensure!(!x.is_zero(), Error::::Empty); } let transfer_type = T::XcmExecutor::determine_for(&asset, dest).map_err(Error::::from)?; - if idx == fee_asset_item { + if asset.id == *fee_asset_id { fees_transfer_type = Some(transfer_type); } else { if let Some(existing) = assets_transfer_type.as_ref() { @@ -2044,7 +2036,7 @@ impl Pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; @@ -2069,9 +2061,16 @@ impl Pallet { ); Error::::BadVersion })?; + let fee_asset_id: AssetId = (*fee_asset_id).try_into().map_err(|()| { + tracing::debug!( + target: "xcm::pallet_xcm::do_teleport_assets", + "Failed to convert VersionedAssetId", + ); + Error::::BadVersion + })?; tracing::debug!( target: "xcm::pallet_xcm::do_reserve_transfer_assets", - ?origin_location, ?dest, ?beneficiary, ?assets, ?fee_asset_item, + ?origin_location, ?dest, ?beneficiary, ?assets, ?fee_asset_id, ); ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); @@ -2079,12 +2078,11 @@ impl Pallet { ensure!(T::XcmReserveTransferFilter::contains(&value), Error::::Filtered); let (origin, assets) = value; - let fee_asset_item = fee_asset_item as usize; - let fees = assets.get(fee_asset_item as usize).ok_or(Error::::Empty)?.clone(); + let fees = assets.iter().find(|a| a.id == fee_asset_id).ok_or(Error::::Empty)?.clone(); // Find transfer types for fee and non-fee assets. let (fees_transfer_type, assets_transfer_type) = - Self::find_fee_and_assets_transfer_types(&assets, fee_asset_item, &dest)?; + Self::find_fee_and_assets_transfer_types(&assets, &fee_asset_id, &dest)?; // Ensure assets (and fees according to check below) are not teleportable to `dest`. ensure!(assets_transfer_type != TransferType::Teleport, Error::::Filtered); // Ensure all assets (including fees) have same reserve location. @@ -2095,7 +2093,7 @@ impl Pallet { // reserve location adjusted accordingly. For more information, see https://github.com/paritytech/polkadot-sdk/issues/9054. Self::ensure_network_asset_reserve_transfer_allowed( &assets, - fee_asset_item, + &fee_asset_id, &assets_transfer_type, &fees_transfer_type, )?; @@ -2117,7 +2115,7 @@ impl Pallet { dest: Box, beneficiary: Box, assets: Box, - fee_asset_item: u32, + fee_asset_id: Box, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; @@ -2142,21 +2140,33 @@ impl Pallet { ); Error::::BadVersion })?; + let fee_asset_id: AssetId = (*fee_asset_id).try_into().map_err(|()| { + tracing::debug!( + target: "xcm::pallet_xcm::do_teleport_assets", + "Failed to convert VersionedAssetId", + ); + Error::::BadVersion + })?; + tracing::debug!( target: "xcm::pallet_xcm::do_teleport_assets", - ?origin_location, ?dest, ?beneficiary, ?assets, ?fee_asset_item, ?weight_limit, + ?origin_location, ?dest, ?beneficiary, ?assets, ?fee_asset_id, ?weight_limit, ); ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::::TooManyAssets); let value = (origin_location, assets.into_inner()); ensure!(T::XcmTeleportFilter::contains(&value), Error::::Filtered); let (origin_location, assets) = value; + let mut maybe_fee_asset = None; for asset in assets.iter() { let transfer_type = T::XcmExecutor::determine_for(asset, &dest).map_err(Error::::from)?; ensure!(transfer_type == TransferType::Teleport, Error::::Filtered); + if asset.id == fee_asset_id { + maybe_fee_asset = Some(asset) + } } - let fees = assets.get(fee_asset_item as usize).ok_or(Error::::Empty)?.clone(); + let fees = maybe_fee_asset.ok_or(Error::::Empty)?.clone(); let (local_xcm, remote_xcm) = Self::build_xcm_transfer_type( origin_location.clone(), @@ -2176,13 +2186,14 @@ impl Pallet { beneficiary: Either>, mut assets: Vec, assets_transfer_type: TransferType, - fee_asset_index: usize, + fee_asset_id: AssetId, fees_transfer_type: TransferType, weight_limit: WeightLimit, ) -> DispatchResult { // local and remote XCM programs to potentially handle fees separately let fees = if fees_transfer_type == assets_transfer_type { - let fees = assets.get(fee_asset_index).ok_or(Error::::Empty)?.clone(); + let fees = + assets.iter().find(|a| a.id == fee_asset_id).ok_or(Error::::Empty)?.clone(); // no need for custom fees instructions, fees are batched with assets FeesHandling::Batched { fees } } else { @@ -2198,6 +2209,8 @@ impl Pallet { let weight_limit = weight_limit.clone(); // remove `fees` from `assets` and build separate fees transfer instructions to be // added to assets transfers XCM programs + let fee_asset_index = + assets.iter().position(|a| a.id == fee_asset_id).ok_or(Error::::FeesNotMet)?; let fees = assets.remove(fee_asset_index); let (local_xcm, remote_xcm) = match fees_transfer_type { TransferType::LocalReserve => Self::local_reserve_fees_instructions( diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 71268530a2052..ccb211372a8a6 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -632,7 +632,7 @@ impl super::benchmarking::Config for Test { )) } - fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, AssetId, Location, Box)> { use crate::tests::assets_transfer::{into_assets_checked, set_up_foreign_asset}; // Transfer native asset (local reserve) to `USDT_PARA_ID`. Using teleport-trusted USDT for // fees. @@ -660,7 +660,7 @@ impl super::benchmarking::Config for Test { // native assets transfer destination is USDT chain (teleport trust only for USDT) let dest = usdt_chain; - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported (usdt_id_location.clone(), fee_amount).into(), // native asset to transfer (not used for fees) - local reserve @@ -682,7 +682,7 @@ impl super::benchmarking::Config for Test { usdt_initial_local_amount - fee_amount ); }); - Some((assets, fee_index as u32, dest, verify)) + Some((assets, fee_asset.id, dest, verify)) } fn get_asset() -> Asset { diff --git a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs index 5b2ac0f44492c..3ad94d8557619 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs @@ -57,7 +57,7 @@ fn limited_teleport_assets_works() { Box::new(RelayLocation::get().into()), Box::new(expected_beneficiary.clone().into()), Box::new((Here, SEND_AMOUNT).into()), - 0, + Box::new(RelayLocation::get().into()), weight_limit, )); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); @@ -110,7 +110,7 @@ fn limited_teleport_filtered_assets_disallowed() { Box::new(FilteredTeleportLocation::get().into()), Box::new(beneficiary.into()), Box::new(FilteredTeleportAsset::get().into()), - 0, + Box::new(FilteredTeleportAsset::get().id.into()), Unlimited, ); let expected_result = Err(crate::Error::::Filtered.into()); @@ -144,7 +144,7 @@ fn reserve_transfer_assets_with_paid_router_works() { Box::new(Parachain(paid_para_id).into()), Box::new(dest.clone().into()), Box::new((Here, SEND_AMOUNT).into()), - 0, + Box::new(Here.into()), Unlimited, )); @@ -239,15 +239,13 @@ pub(crate) fn set_up_foreign_asset( (reserve_location, reserve_sovereign_account, foreign_asset_id_location) } -// Helper function that provides correct `fee_index` after `sort()` done by -// `vec![Asset, Asset].into()`. +// Helper function that provides assets list with fee and transfer assets pub(crate) fn into_assets_checked( fee_asset: Asset, transfer_asset: Asset, -) -> (Assets, usize, Asset, Asset) { +) -> (Assets, Asset, Asset) { let assets: Assets = vec![fee_asset.clone(), transfer_asset.clone()].into(); - let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; - (assets, fee_index, fee_asset, transfer_asset) + (assets, fee_asset, transfer_asset) } /// Test `tested_call` with local asset reserve and local fee reserve. @@ -265,7 +263,7 @@ fn local_asset_reserve_and_local_fee_reserve_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -291,7 +289,7 @@ fn local_asset_reserve_and_local_fee_reserve_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new((Here, SEND_AMOUNT).into()), - 0, + Box::new(Here.into()), weight_limit, ); assert_eq!(result, expected_result); @@ -386,7 +384,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -410,7 +408,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( // transfer destination is reserve location (no teleport trust) let dest = reserve_location; - let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( + let (assets, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - destination reserve @@ -419,7 +417,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_fee = fee_asset.clone().reanchored(&dest, &context).unwrap(); let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before @@ -435,7 +433,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -549,7 +547,7 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -570,7 +568,7 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( // chain) let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // native asset for fee - local reserve (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - remote reserve @@ -590,7 +588,7 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -662,7 +660,7 @@ fn local_asset_reserve_and_destination_fee_reserve_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -685,7 +683,7 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // native assets transfer to fee reserve location (no teleport trust) let dest = usdc_reserve_location; - let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( + let (assets, fee_asset, xfer_asset) = into_assets_checked( // usdc for fees (is sufficient on local chain too) - destination reserve (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve @@ -694,7 +692,7 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_fee = fee_asset.clone().reanchored(&dest, &context).unwrap(); let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before @@ -710,7 +708,7 @@ fn local_asset_reserve_and_destination_fee_reserve_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -821,7 +819,7 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -845,7 +843,7 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // transfer destination is reserve location let dest = reserve_location; let assets: Assets = vec![(foreign_asset_id_location.clone(), SEND_AMOUNT).into()].into(); - let fee_index = 0; + let fee_asset_id = foreign_asset_id_location.clone(); // reanchor according to test-case let mut expected_assets = assets.clone(); @@ -864,7 +862,7 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index, + Box::new(fee_asset_id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -976,7 +974,7 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1007,7 +1005,7 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // reserve chain) let dest = usdc_chain; - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - destination reserve (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve @@ -1031,7 +1029,7 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1103,7 +1101,7 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1124,7 +1122,7 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); let dest_sovereign_account = SovereignAccountOf::convert_location(&dest).unwrap(); - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve @@ -1144,7 +1142,7 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1210,7 +1208,7 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1242,7 +1240,7 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve @@ -1262,7 +1260,7 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1356,7 +1354,7 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1377,13 +1375,13 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); - let fee_index = 0; + let fee_asset_id: AssetId = usdc_id_location.clone().into(); // reanchor according to test-case let context = UniversalLocation::get(); let expected_dest_on_reserve = dest.clone().reanchored(&usdc_chain, &context).unwrap(); - let fees = assets.get(fee_index as usize).unwrap().clone(); - let (fees_half_1, fees_half_2) = XcmPallet::halve_fees(fees).unwrap(); + let fees = assets.inner().iter().find(|a| a.id == fee_asset_id).unwrap(); + let (fees_half_1, fees_half_2) = XcmPallet::halve_fees(fees.clone()).unwrap(); let mut expected_assets_on_reserve = assets.clone(); expected_assets_on_reserve.reanchor(&usdc_chain, &context).unwrap(); let expected_fee_on_reserve = fees_half_1.reanchored(&usdc_chain, &context).unwrap(); @@ -1402,7 +1400,7 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index, + Box::new(fee_asset_id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1506,7 +1504,7 @@ fn local_asset_reserve_and_teleported_fee_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1523,7 +1521,7 @@ fn local_asset_reserve_and_teleported_fee_call( // native assets transfer destination is USDT chain (teleport trust only for USDT) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( + let (assets, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported (usdt_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve @@ -1532,7 +1530,7 @@ fn local_asset_reserve_and_teleported_fee_call( // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_fee = fee_asset.clone().reanchored(&dest, &context).unwrap(); let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before @@ -1548,7 +1546,7 @@ fn local_asset_reserve_and_teleported_fee_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1656,7 +1654,7 @@ fn destination_asset_reserve_and_teleported_fee_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1685,7 +1683,7 @@ fn destination_asset_reserve_and_teleported_fee_call( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( + let (assets, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve @@ -1694,7 +1692,7 @@ fn destination_asset_reserve_and_teleported_fee_call( // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_fee = fee_asset.clone().reanchored(&dest, &context).unwrap(); let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before @@ -1710,7 +1708,7 @@ fn destination_asset_reserve_and_teleported_fee_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1835,7 +1833,7 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -1860,7 +1858,7 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve @@ -1880,7 +1878,7 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -1964,7 +1962,7 @@ fn reserve_transfer_assets_with_teleportable_asset_disallowed() { // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; let assets: Assets = vec![(usdt_id_location.clone(), FEE_AMOUNT).into()].into(); - let fee_index = 0; + let fee_asset_id = usdt_id_location.clone(); // balances checks before assert_eq!( @@ -1979,7 +1977,7 @@ fn reserve_transfer_assets_with_teleportable_asset_disallowed() { Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset_id.into()), Unlimited, ); assert_err!(res, crate::Error::::Filtered); @@ -2009,7 +2007,7 @@ fn reserve_transfer_assets_with_teleportable_asset_disallowed() { fn transfer_assets_with_filtered_teleported_fee_disallowed() { let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); new_test_ext_with_balances(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { - let (assets, fee_index, _, _) = into_assets_checked( + let (assets, fee_asset, _) = into_assets_checked( // FilteredTeleportAsset for fees - teleportable but filtered FilteredTeleportAsset::get().into(), // native asset to transfer (not used for fees) - local reserve @@ -2020,7 +2018,7 @@ fn transfer_assets_with_filtered_teleported_fee_disallowed() { Box::new(FilteredTeleportLocation::get().into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_err!(result, crate::Error::::Filtered); @@ -2056,7 +2054,7 @@ fn intermediary_error_reverts_side_effects() { let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); - let fee_index = 0; + let fee_asset_id = usdc_id_location.clone(); // balances checks before assert_eq!( @@ -2076,7 +2074,7 @@ fn intermediary_error_reverts_side_effects() { Box::new(dest.into()), Box::new(beneficiary.into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset_id.into()), Unlimited, ); assert!(result.is_err()); @@ -2134,7 +2132,7 @@ fn teleport_asset_using_local_fee_reserve_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -2151,7 +2149,7 @@ fn teleport_asset_using_local_fee_reserve_call( // transfer destination is reserve location (no teleport trust) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( + let (assets, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve (Location::here(), FEE_AMOUNT).into(), // USDT to transfer - destination reserve @@ -2160,7 +2158,7 @@ fn teleport_asset_using_local_fee_reserve_call( // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_fee = fee_asset.clone().reanchored(&dest, &context).unwrap(); let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before @@ -2176,7 +2174,7 @@ fn teleport_asset_using_local_fee_reserve_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -2284,7 +2282,7 @@ fn teleported_asset_using_destination_reserve_fee_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -2312,7 +2310,7 @@ fn teleported_asset_using_destination_reserve_fee_call( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( + let (assets, fee_asset, xfer_asset) = into_assets_checked( // foreign asset BLA used for fees - destination reserve (foreign_asset_id_location.clone(), FEE_AMOUNT).into(), // USDT to transfer - teleported @@ -2321,7 +2319,7 @@ fn teleported_asset_using_destination_reserve_fee_call( // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_fee = fee_asset.clone().reanchored(&dest, &context).unwrap(); let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before @@ -2337,7 +2335,7 @@ fn teleported_asset_using_destination_reserve_fee_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(assets.into()), - fee_index as u32, + Box::new(fee_asset.id.into()), Unlimited, ); assert_eq!(result, expected_result); @@ -2473,7 +2471,7 @@ fn remote_asset_reserve_and_remote_fee_reserve_paid_call( Box, Box, Box, - u32, + Box, WeightLimit, ) -> DispatchResult, { @@ -2517,7 +2515,7 @@ fn remote_asset_reserve_and_remote_fee_reserve_paid_call( Box::new(dest.clone().into()), Box::new(beneficiary.clone().into()), Box::new(transferred_asset.into()), - 0 as u32, + Box::new(foreign_asset_id_location.clone().into()), Unlimited, ); assert_eq!(result, expected_result); diff --git a/polkadot/xcm/pallet-xcm/src/transfer_assets_validation.rs b/polkadot/xcm/pallet-xcm/src/transfer_assets_validation.rs index 2be7fffc5965d..04bac47748f0c 100644 --- a/polkadot/xcm/pallet-xcm/src/transfer_assets_validation.rs +++ b/polkadot/xcm/pallet-xcm/src/transfer_assets_validation.rs @@ -46,15 +46,14 @@ impl Pallet { /// `execute` instead, which allows explicit reserve specification. pub(crate) fn ensure_network_asset_reserve_transfer_allowed( assets: &Vec, - fee_asset_index: usize, + fee_asset_id: &AssetId, assets_transfer_type: &TransferType, fees_transfer_type: &TransferType, ) -> Result<(), Error> { // Extract fee asset and check both assets and fees separately. let mut remaining_assets = assets.clone(); - if fee_asset_index >= remaining_assets.len() { - return Err(Error::::Empty); - } + let fee_asset_index = + assets.iter().position(|a| a.id == *fee_asset_id).ok_or(Error::::Empty)?; let fee_asset = remaining_assets.remove(fee_asset_index); // Check remaining assets with their transfer type. diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs index 43d7d2fb92197..3c4f0683fc3ff 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -336,9 +336,9 @@ fn deposit_reserve_asset_works_for_any_xcm_sender() { // Init values for the simulated origin Parachain let amount_to_send: u128 = 1_000_000_000_000; let assets: Assets = (Parent, amount_to_send).into(); - let fee_asset_item = 0; + let fee_asset_id: AssetId = Parent.into(); let max_assets = assets.len() as u32; - let fees = assets.get(fee_asset_item as usize).unwrap().clone(); + let fees = assets.inner().iter().find(|a| a.id == fee_asset_id).unwrap().clone(); let weight_limit = Unlimited; let reserve = Location::parent(); let dest = Location::new(1, [Parachain(2000)]); diff --git a/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs b/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs index 1307c7adaa9cb..eb31fdaaece8a 100644 --- a/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs +++ b/polkadot/xcm/xcm-runtime-apis/tests/fee_estimation.rs @@ -61,7 +61,7 @@ fn fee_estimation_for_teleport() { (Here, 100u128).into(), (Parent, 20u128).into(), ])), - fee_asset_item: 1, // Fees are paid with the RelayToken + fee_asset_id: Box::new(Parent.into()), // Fees are paid with the RelayToken weight_limit: Unlimited, }); let origin = OriginCaller::system(RawOrigin::Signed(who)); @@ -226,7 +226,7 @@ fn dry_run_reserve_asset_transfer_common( .into_version(input_xcm_version) .unwrap(), ), - fee_asset_item: 0, + fee_asset_id: Box::new(Parent.into()), weight_limit: Unlimited, }); let origin = OriginCaller::system(RawOrigin::Signed(who)); diff --git a/polkadot/xcm/xcm-simulator/example/src/tests.rs b/polkadot/xcm/xcm-simulator/example/src/tests.rs index 7e1595ef6c27f..222f15cfa01b5 100644 --- a/polkadot/xcm/xcm-simulator/example/src/tests.rs +++ b/polkadot/xcm/xcm-simulator/example/src/tests.rs @@ -132,7 +132,7 @@ fn reserve_transfer() { Box::new(Parachain(1).into()), Box::new(AccountId32 { network: None, id: ALICE.into() }.into()), Box::new((Here, withdraw_amount).into()), - 0, + Box::new(Here.into()), Unlimited, )); assert_eq!( @@ -179,7 +179,7 @@ fn reserve_transfer_with_error() { invalid_dest, Box::new(AccountId32 { network: None, id: ALICE.into() }.into()), Box::new((Here, withdraw_amount).into()), - 0, + Box::new(Here.into()), Unlimited, ); diff --git a/polkadot/zombienet-sdk-tests/tests/smoke/coretime_revenue.rs b/polkadot/zombienet-sdk-tests/tests/smoke/coretime_revenue.rs index 501b1b20a51eb..466b8998ba544 100644 --- a/polkadot/zombienet-sdk-tests/tests/smoke/coretime_revenue.rs +++ b/polkadot/zombienet-sdk-tests/tests/smoke/coretime_revenue.rs @@ -25,7 +25,7 @@ use rococo::runtime_types::{ junctions::Junctions, location::Location, }, - xcm::{VersionedAssets, VersionedLocation}, + xcm::{VersionedAssetId, VersionedAssets, VersionedLocation}, }; use serde_json::json; @@ -318,7 +318,7 @@ async fn coretime_revenue_test() -> Result<(), anyhow::Error> { id: AssetId(Location { parents: 0, interior: Junctions::Here }), fun: Fungibility::Fungible(1_500_000_000), }])), - 0, + VersionedAssetId::V4(AssetId(Location { parents: 0, interior: Junctions::Here })), ), &alice, ) diff --git a/prdoc/pr_10243.prdoc b/prdoc/pr_10243.prdoc new file mode 100644 index 0000000000000..5ed76a5f737bd --- /dev/null +++ b/prdoc/pr_10243.prdoc @@ -0,0 +1,53 @@ +title: 'pallet-xcm: API changes to use `VersionedAssetId` instead of `u32` to specify + asset for fees' +doc: +- audience: Runtime User + description: |- + Multiple pallet-xcm calls use `u32` index as a way to specify which asset from the `assets` (also an arg of the call) is to be used for fees purposes. This PR brings **major API change (breaking change)** that proposes usage of `VersionedAssetId` instead + + Affected pallet-xcm calls: `teleport_assets`, `reserve_transfer_assets`, `limited_reserve_transfer_assets`, `limited_teleport_assets`, `transfer_assets` + + This is follow-up change to the: https://github.com/paritytech/polkadot-sdk/pull/9842, that aims to remove the requirement of the client to provide sorted list of Assets to the APIs (often a point failures). With the mentioned change sorting happens on the runtime side and `u32` index (provided by the client) can become invalid after sorting (this PR aims that problem) + + Relevant [dicussion](https://matrix.to/#/!nYxxyvMNMUaniRIokh:parity.io/$gAcAEznmQL6LhUlvGPHSaePUV4cZtxoco2I6ap8Cn3Q?via=parity.io&via=matrix.org&via=web3.foundation) on XCM public element channel +crates: +- name: parachains-common + bump: major +- name: emulated-integration-tests-common + bump: major +- name: asset-test-utils + bump: major +- name: parachains-runtimes-test-utils + bump: major +- name: xcm-emulator + bump: major +- name: westend-runtime + bump: major +- name: pallet-xcm + bump: major +- name: xcm-runtime-apis + bump: major +- name: xcm-simulator-example + bump: major +- name: pallet-staking-async + bump: major +- name: asset-hub-rococo-runtime + bump: major +- name: asset-hub-westend-runtime + bump: major +- name: bridge-hub-rococo-runtime + bump: major +- name: bridge-hub-westend-runtime + bump: major +- name: collectives-westend-runtime + bump: major +- name: coretime-rococo-runtime + bump: major +- name: coretime-westend-runtime + bump: major +- name: people-rococo-runtime + bump: major +- name: people-westend-runtime + bump: major +- name: rococo-runtime + bump: major diff --git a/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts b/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts index 5184baa966b02..085d8ab73015e 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/tests/vmp-spamming.test.ts @@ -51,7 +51,7 @@ async function sendUp(api: TypedApi, count: number) { value: [ { id: { - parents: 0, + parents: 1, interior: { type: "Here", value: undefined @@ -64,7 +64,16 @@ async function sendUp(api: TypedApi, count: number) { } ] }, - fee_asset_item: 0, + fee_asset_id: { + type: "V5", + value: { + parents: 1, + interior: { + type: "Here", + value: undefined + } + }, + }, }) const dispatchAs = api.tx.Utility.dispatch_as({ as_origin: { type: "system", value: { type: "Signed", value: ss58(account.publicKey) } }, @@ -153,7 +162,16 @@ async function sendDown(api: TypedApi, count: number) { } ] }, - fee_asset_item: 0, + fee_asset_id: { + type: "V5", + value: { + parents: 0, + interior: { + type: "Here", + value: undefined + } + }, + }, }) const dispatchAs = api.tx.Utility.dispatch_as({ as_origin: { type: "system", value: { type: "Signed", value: ss58(account.publicKey) } }, diff --git a/substrate/frame/staking-async/runtimes/parachain/src/lib.rs b/substrate/frame/staking-async/runtimes/parachain/src/lib.rs index 38f70633d6a8d..5ef8ea9f0c458 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/lib.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/lib.rs @@ -1920,7 +1920,7 @@ impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(XcmAssets, u32, Location, alloc::boxed::Box)> { + ) -> Option<(XcmAssets, AssetId, Location, alloc::boxed::Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) @@ -1952,7 +1952,6 @@ impl_runtime_apis! { let transfer_asset: Asset = (asset_location, asset_amount).into(); let assets: XcmAssets = vec![fee_asset.clone(), transfer_asset].into(); - let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully let verify = alloc::boxed::Box::new(move || { @@ -1965,7 +1964,7 @@ impl_runtime_apis! { initial_asset_amount - asset_amount, ); }); - Some((assets, fee_index as u32, dest, verify)) + Some((assets, fee_asset.id, dest, verify)) } fn get_asset() -> Asset { diff --git a/substrate/frame/staking-async/runtimes/rc/src/lib.rs b/substrate/frame/staking-async/runtimes/rc/src/lib.rs index 8f0f6b4f33096..ad95ea6725cde 100644 --- a/substrate/frame/staking-async/runtimes/rc/src/lib.rs +++ b/substrate/frame/staking-async/runtimes/rc/src/lib.rs @@ -2827,7 +2827,7 @@ sp_api::impl_runtime_apis! { } fn set_up_complex_asset_transfer( - ) -> Option<(Assets, u32, Location, Box)> { + ) -> Option<(Assets, AssetId, Location, Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. diff --git a/substrate/frame/staking-async/runtimes/rc/src/tests.rs b/substrate/frame/staking-async/runtimes/rc/src/tests.rs index 657370a9b6f95..0433c2c0fab19 100644 --- a/substrate/frame/staking-async/runtimes/rc/src/tests.rs +++ b/substrate/frame/staking-async/runtimes/rc/src/tests.rs @@ -60,7 +60,7 @@ fn sanity_check_teleport_assets_weight() { dest: Box::new(Here.into()), beneficiary: Box::new(Here.into()), assets: Box::new((Here, 200_000).into()), - fee_asset_item: 0, + fee_asset_id: Box::new(Here.into()), weight_limit: Unlimited, } .get_dispatch_info()