diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index e7e7891461b2..0c7a9ad1a83d 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -38,7 +38,7 @@ use frame_support::weights::Weight; use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams}; use sp_runtime::traits::{Header, Zero}; use sp_std::prelude::*; -use xcm::v3::prelude::*; +use xcm::latest::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. fn prepare_inbound_message( @@ -266,19 +266,19 @@ where /// Returns callback which generates `BridgeMessage` from Polkadot XCM builder based on /// `expected_message_size` for benchmark. pub fn generate_xcm_builder_bridge_message_sample( - destination: InteriorMultiLocation, + destination: InteriorLocation, ) -> impl Fn(usize) -> MessagePayload { move |expected_message_size| -> MessagePayload { // For XCM bridge hubs, it is the message that // will be pushed further to some XCM queue (XCMP/UMP) - let location = xcm::VersionedInteriorMultiLocation::V3(destination); + let location = xcm::VersionedInteriorLocation::V4(destination.clone()); let location_encoded_size = location.encoded_size(); // we don't need to be super-precise with `expected_size` here let xcm_size = expected_message_size.saturating_sub(location_encoded_size); let xcm_data_size = xcm_size.saturating_sub( // minus empty instruction size - xcm::v3::Instruction::<()>::ExpectPallet { + Instruction::<()>::ExpectPallet { index: 0, name: vec![], module_name: vec![], @@ -294,8 +294,8 @@ pub fn generate_xcm_builder_bridge_message_sample( expected_message_size, location_encoded_size, xcm_size, xcm_data_size, ); - let xcm = xcm::VersionedXcm::<()>::V3( - vec![xcm::v3::Instruction::<()>::ExpectPallet { + let xcm = xcm::VersionedXcm::<()>::V4( + vec![Instruction::<()>::ExpectPallet { index: 0, name: vec![42; xcm_data_size], module_name: vec![], diff --git a/bridges/bin/runtime-common/src/messages_xcm_extension.rs b/bridges/bin/runtime-common/src/messages_xcm_extension.rs index 53c0579c4cd0..fd2c20af72ad 100644 --- a/bridges/bin/runtime-common/src/messages_xcm_extension.rs +++ b/bridges/bin/runtime-common/src/messages_xcm_extension.rs @@ -123,14 +123,14 @@ impl< #[cfg_attr(feature = "std", derive(Debug, Eq, PartialEq))] pub struct SenderAndLane { /// Sending chain relative location. - pub location: MultiLocation, + pub location: Location, /// Message lane, used by the sending chain. pub lane: LaneId, } impl SenderAndLane { /// Create new object using provided location and lane. - pub fn new(location: MultiLocation, lane: LaneId) -> Self { + pub fn new(location: Location, lane: LaneId) -> Self { SenderAndLane { location, lane } } } @@ -168,7 +168,7 @@ pub struct XcmBlobHaulerAdapter( impl< H: XcmBlobHauler, - Lanes: Get>, + Lanes: Get>, > OnMessagesDelivered for XcmBlobHaulerAdapter { fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce) { @@ -288,7 +288,7 @@ impl LocalXcmQueueManager { /// Send congested signal to the `sending_chain_location`. fn send_congested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> { if let Some(msg) = H::CongestedMessage::get() { - send_xcm::(sender_and_lane.location, msg)?; + send_xcm::(sender_and_lane.location.clone(), msg)?; OutboundLanesCongestedSignals::::insert( sender_and_lane.lane, true, @@ -300,7 +300,7 @@ impl LocalXcmQueueManager { /// Send `uncongested` signal to the `sending_chain_location`. fn send_uncongested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> { if let Some(msg) = H::UncongestedMessage::get() { - send_xcm::(sender_and_lane.location, msg)?; + send_xcm::(sender_and_lane.location.clone(), msg)?; OutboundLanesCongestedSignals::::remove( sender_and_lane.lane, ); @@ -315,10 +315,10 @@ impl LocalXcmQueueManager { pub struct XcmVersionOfDestAndRemoteBridge( sp_std::marker::PhantomData<(Version, RemoteBridge)>, ); -impl> GetVersion +impl> GetVersion for XcmVersionOfDestAndRemoteBridge { - fn get_version_for(dest: &MultiLocation) -> Option { + fn get_version_for(dest: &Location) -> Option { let dest_version = Version::get_version_for(dest); let bridge_hub_version = Version::get_version_for(&RemoteBridge::get()); @@ -342,11 +342,11 @@ mod tests { parameter_types! { pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: MultiLocation::new(1, X1(Parachain(1000))), + location: Location::new(1, [Parachain(1000)]), lane: TEST_LANE_ID, }; - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ - (TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorMultiLocation::Here)) + pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ + (TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorLocation::Here)) ]; pub DummyXcmMessage: Xcm<()> = Xcm::new(); } @@ -363,7 +363,7 @@ mod tests { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { Ok(((), Default::default())) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 922e4bf94ba8..c4f9f534c1a4 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -37,10 +37,10 @@ pub trait Config: crate::Config { /// Returns destination which is valid for this router instance. /// (Needs to pass `T::Bridges`) /// Make sure that `SendXcm` will pass. - fn ensure_bridged_target_destination() -> Result { - Ok(MultiLocation::new( + fn ensure_bridged_target_destination() -> Result { + Ok(Location::new( Self::UniversalLocation::get().len() as u8, - X1(GlobalConsensus(Self::BridgedNetworkId::get().unwrap())), + [GlobalConsensus(Self::BridgedNetworkId::get().unwrap())], )) } } diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 229628aedcb8..f219be78f9e1 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -80,7 +80,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// Universal location of this runtime. - type UniversalLocation: Get; + type UniversalLocation: Get; /// The bridged network that this config is for if specified. /// Also used for filtering `Bridges` by `BridgedNetworkId`. /// If not specified, allows all networks pass through. @@ -235,9 +235,9 @@ type ViaBridgeHubExporter = SovereignPaidRemoteExporter< impl, I: 'static> ExporterFor for Pallet { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { // ensure that the message is sent to the expected bridged network (if specified). if let Some(bridged_network) = T::BridgedNetworkId::get() { if *network != bridged_network { @@ -268,7 +268,7 @@ impl, I: 'static> ExporterFor for Pallet { // take `base_fee` from `T::Brides`, but it has to be the same `T::FeeAsset` let base_fee = match maybe_payment { Some(payment) => match payment { - MultiAsset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, + Asset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, invalid_asset => { log::error!( target: LOG_TARGET, @@ -318,7 +318,7 @@ impl, I: 'static> SendXcm for Pallet { type Ticket = (u32, ::Ticket); fn validate( - dest: &mut Option, + dest: &mut Option, xcm: &mut Option>, ) -> SendResult { // `dest` and `xcm` are required here @@ -446,7 +446,7 @@ mod tests { run_test(|| { assert_eq!( send_xcm::( - MultiLocation::new(2, X2(GlobalConsensus(Rococo), Parachain(1000))), + Location::new(2, [GlobalConsensus(Rococo), Parachain(1000)]), vec![].into(), ), Err(SendError::NotApplicable), @@ -459,7 +459,7 @@ mod tests { run_test(|| { assert_eq!( send_xcm::( - MultiLocation::new(2, X2(GlobalConsensus(Rococo), Parachain(1000))), + Location::new(2, [GlobalConsensus(Rococo), Parachain(1000)]), vec![ClearOrigin; HARD_MESSAGE_SIZE_LIMIT as usize].into(), ), Err(SendError::ExceedsMaxMessageSize), @@ -483,14 +483,14 @@ mod tests { #[test] fn returns_proper_delivery_price() { run_test(|| { - let dest = MultiLocation::new(2, X1(GlobalConsensus(BridgedNetworkId::get()))); + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); let xcm: Xcm<()> = vec![ClearOrigin].into(); let msg_size = xcm.encoded_size(); // initially the base fee is used: `BASE_FEE + BYTE_FEE * msg_size + HRMP_FEE` let expected_fee = BASE_FEE + BYTE_FEE * (msg_size as u128) + HRMP_FEE; assert_eq!( - XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm.clone())) + XcmBridgeHubRouter::validate(&mut Some(dest.clone()), &mut Some(xcm.clone())) .unwrap() .1 .get(0), @@ -518,10 +518,7 @@ mod tests { run_test(|| { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); @@ -538,10 +535,7 @@ mod tests { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); @@ -560,10 +554,7 @@ mod tests { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 9079f4b9c4c6..6dbfba5f6fdc 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -49,9 +49,9 @@ construct_runtime! { parameter_types! { pub ThisNetworkId: NetworkId = Polkadot; pub BridgedNetworkId: NetworkId = Kusama; - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ThisNetworkId::get()), Parachain(1000)); - pub SiblingBridgeHubLocation: MultiLocation = ParentThen(X1(Parachain(1002))).into(); - pub BridgeFeeAsset: AssetId = MultiLocation::parent().into(); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetworkId::get()), Parachain(1000)].into(); + pub SiblingBridgeHubLocation: Location = ParentThen([Parachain(1002)].into()).into(); + pub BridgeFeeAsset: AssetId = Location::parent().into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( @@ -61,7 +61,7 @@ parameter_types! { Some((BridgeFeeAsset::get(), BASE_FEE).into()) ) ]; - pub UnknownXcmVersionLocation: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(9999))); + pub UnknownXcmVersionLocation: Location = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(9999)]); } #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] @@ -87,11 +87,11 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { } pub struct LatestOrNoneForLocationVersionChecker(sp_std::marker::PhantomData); -impl> GetVersion - for LatestOrNoneForLocationVersionChecker +impl> GetVersion + for LatestOrNoneForLocationVersionChecker { - fn get_version_for(dest: &MultiLocation) -> Option { - if Location::contains(dest) { + fn get_version_for(dest: &Location) -> Option { + if LocationValue::contains(dest) { return None } Some(XCM_VERSION) @@ -110,7 +110,7 @@ impl SendXcm for TestToBridgeHubSender { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { Ok(((), (BridgeFeeAsset::get(), HRMP_FEE).into())) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 5318b222c545..3dd7459d30fe 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -52,10 +52,10 @@ where fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, - ) -> Result<(Self::Ticket, MultiAssets), SendError> { + ) -> Result<(Self::Ticket, Assets), SendError> { // Find supported lane_id. let sender_and_lane = Self::lane_for( universal_source.as_ref().ok_or(SendError::MissingArgument)?, @@ -137,11 +137,11 @@ mod tests { use frame_support::assert_ok; use xcm_executor::traits::export_xcm; - fn universal_source() -> InteriorMultiLocation { - X2(GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)) + fn universal_source() -> InteriorLocation { + [GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)].into() } - fn universal_destination() -> InteriorMultiLocation { + fn universal_destination() -> InteriorLocation { BridgedDestination::get() } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 44f6903b018b..60b988497fc5 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -45,25 +45,25 @@ pub mod pallet { BridgeMessagesConfig { /// Runtime's universal location. - type UniversalLocation: Get; + type UniversalLocation: Get; // TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 remove `ChainId` and // replace it with the `NetworkId` - then we'll be able to use // `T as pallet_bridge_messages::Config::BridgedChain::NetworkId` /// Bridged network as relative location of bridged `GlobalConsensus`. #[pallet::constant] - type BridgedNetwork: Get; + type BridgedNetwork: Get; /// Associated messages pallet instance that bridges us with the /// `BridgedNetworkId` consensus. type BridgeMessagesPalletInstance: 'static; /// Price of single message export to the bridged consensus (`Self::BridgedNetworkId`). - type MessageExportPrice: Get; + type MessageExportPrice: Get; /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; /// Get point-to-point links with bridged consensus (`Self::BridgedNetworkId`). /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) - type Lanes: Get>; + type Lanes: Get>; /// Support for point-to-point links /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) type LanesSupport: XcmBlobHauler; @@ -86,10 +86,10 @@ pub mod pallet { impl, I: 'static> Pallet { /// Returns dedicated/configured lane identifier. pub(crate) fn lane_for( - source: &InteriorMultiLocation, - dest: (&NetworkId, &InteriorMultiLocation), + source: &InteriorLocation, + dest: (&NetworkId, &InteriorLocation), ) -> Option { - let source = source.relative_to(&T::UniversalLocation::get()); + let source = source.clone().relative_to(&T::UniversalLocation::get()); // Check that we have configured a point-to-point lane for 'source' and `dest`. T::Lanes::get() diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 8edd4b1f7aa9..6708d4b789a9 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -170,16 +170,13 @@ impl pallet_bridge_messages::WeightInfoExt for TestMessagesWeights { parameter_types! { pub const RelayNetwork: NetworkId = NetworkId::Kusama; pub const BridgedRelayNetwork: NetworkId = NetworkId::Polkadot; - pub const BridgedRelayNetworkLocation: MultiLocation = MultiLocation { - parents: 1, - interior: X1(GlobalConsensus(BridgedRelayNetwork::get())) - }; + pub BridgedRelayNetworkLocation: Location = (Parent, GlobalConsensus(BridgedRelayNetwork::get())).into(); pub const NonBridgedRelayNetwork: NetworkId = NetworkId::Rococo; pub const BridgeReserve: Balance = 100_000; - pub UniversalLocation: InteriorMultiLocation = X2( + pub UniversalLocation: InteriorLocation = [ GlobalConsensus(RelayNetwork::get()), Parachain(THIS_BRIDGE_HUB_ID), - ); + ].into(); pub const Penalty: Balance = 1_000; } @@ -197,13 +194,13 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { parameter_types! { pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: MultiLocation::new(1, X1(Parachain(SIBLING_ASSET_HUB_ID))), + location: Location::new(1, [Parachain(SIBLING_ASSET_HUB_ID)]), lane: TEST_LANE_ID, }; - pub const BridgedDestination: InteriorMultiLocation = X1( + pub BridgedDestination: InteriorLocation = [ Parachain(BRIDGED_ASSET_HUB_ID) - ); - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + ].into(); + pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ (TestSenderAndLane::get(), (BridgedRelayNetwork::get(), BridgedDestination::get())) ]; } diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs index f7eea0aadfa0..bdc21fcf0370 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs @@ -54,8 +54,8 @@ use scale_info::TypeInfo; use sp_core::{H160, H256}; use sp_std::{convert::TryFrom, vec}; use xcm::prelude::{ - send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, - SendError as XcmpSendError, SendXcm, Xcm, XcmContext, XcmHash, + send_xcm, Instruction::SetTopic, Junction::*, Location, SendError as XcmpSendError, SendXcm, + Xcm, XcmContext, XcmHash, }; use xcm_executor::traits::TransactAsset; @@ -324,7 +324,7 @@ pub mod pallet { } pub fn send_xcm(xcm: Xcm<()>, dest: ParaId) -> Result> { - let dest = MultiLocation { parents: 1, interior: X1(Parachain(dest.into())) }; + let dest = Location::new(1, [Parachain(dest.into())]); let (xcm_hash, _) = send_xcm::(dest, xcm).map_err(Error::::from)?; Ok(xcm_hash) } @@ -341,8 +341,8 @@ pub mod pallet { pub fn burn_fees(para_id: ParaId, fee: BalanceOf) -> DispatchResult { let dummy_context = XcmContext { origin: None, message_id: Default::default(), topic: None }; - let dest = MultiLocation { parents: 1, interior: X1(Parachain(para_id.into())) }; - let fees = (MultiLocation::parent(), fee.saturated_into::()).into(); + let dest = Location::new(1, [Parachain(para_id.into())]); + let fees = (Location::parent(), fee.saturated_into::()).into(); T::AssetTransactor::can_check_out(&dest, &fees, &dummy_context).map_err(|error| { log::error!( target: LOG_TARGET, diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs index b031a46e219a..39374aa3d71a 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs @@ -21,8 +21,8 @@ use sp_runtime::{ BuildStorage, FixedU128, MultiSignature, }; use sp_std::convert::From; -use xcm::v3::{prelude::*, MultiAssets, SendXcm}; -use xcm_executor::Assets; +use xcm::v4::{prelude::*, SendXcm}; +use xcm_executor::AssetsInHolding; use crate::{self as inbound_queue}; @@ -155,17 +155,16 @@ impl SendXcm for MockXcmSender { type Ticket = Xcm<()>; fn validate( - dest: &mut Option, - xcm: &mut Option>, + dest: &mut Option, + xcm: &mut Option>, ) -> SendResult { - match dest { - Some(MultiLocation { interior, .. }) => { - if let X1(Parachain(1001)) = interior { - return Err(XcmpSendError::NotApplicable) - } - Ok((xcm.clone().unwrap(), MultiAssets::default())) - }, - _ => Ok((xcm.clone().unwrap(), MultiAssets::default())), + if let Some(location) = dest { + match location.unpack() { + (_, [Parachain(1001)]) => return Err(XcmpSendError::NotApplicable), + _ => Ok((xcm.clone().unwrap(), Assets::default())), + } + } else { + Ok((xcm.clone().unwrap(), Assets::default())) } } @@ -203,45 +202,33 @@ impl StaticLookup for MockChannelLookup { pub struct SuccessfulTransactor; impl TransactAsset for SuccessfulTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs index 17ebeb394460..9a47e475b8c9 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs @@ -41,8 +41,8 @@ fn test_submit_happy_path() { .into(), nonce: 1, message_id: [ - 27, 217, 88, 127, 46, 143, 199, 70, 236, 66, 212, 244, 85, 221, 153, 104, 175, 37, - 224, 20, 140, 95, 140, 7, 27, 74, 182, 199, 77, 12, 194, 236, + 57, 61, 232, 3, 66, 61, 25, 190, 234, 188, 193, 174, 13, 186, 1, 64, 237, 94, 73, + 83, 14, 18, 209, 213, 78, 121, 43, 108, 251, 245, 107, 67, ], fee_burned: 110000000000, } diff --git a/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs index d99b456c8488..7f119809546e 100644 --- a/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs @@ -3,11 +3,11 @@ #![cfg_attr(not(feature = "std"), no_std)] use snowbridge_core::AgentId; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; sp_api::decl_runtime_apis! { pub trait ControlApi { - fn agent_id(location: VersionedMultiLocation) -> Option; + fn agent_id(location: VersionedLocation) -> Option; } } diff --git a/bridges/snowbridge/parachain/pallets/system/src/api.rs b/bridges/snowbridge/parachain/pallets/system/src/api.rs index 245e6eea1c14..ef12b03e1d75 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/api.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/api.rs @@ -3,14 +3,14 @@ //! Helpers for implementing runtime api use snowbridge_core::AgentId; -use xcm::{prelude::*, VersionedMultiLocation}; +use xcm::{prelude::*, VersionedLocation}; use crate::{agent_id_of, Config}; -pub fn agent_id(location: VersionedMultiLocation) -> Option +pub fn agent_id(location: VersionedLocation) -> Option where Runtime: Config, { - let location: MultiLocation = location.try_into().ok()?; + let location: Location = location.try_into().ok()?; agent_id_of::(&location).ok() } diff --git a/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs b/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs index 8d26408b38e5..ef908ad6a3f9 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs @@ -63,7 +63,7 @@ mod benchmarks { #[benchmark] fn create_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; @@ -76,7 +76,7 @@ mod benchmarks { #[benchmark] fn create_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; @@ -91,7 +91,7 @@ mod benchmarks { #[benchmark] fn update_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; @@ -106,7 +106,7 @@ mod benchmarks { #[benchmark] fn force_update_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); let channel_id: ChannelId = ParaId::from(origin_para_id).into(); @@ -123,7 +123,7 @@ mod benchmarks { #[benchmark] fn transfer_native_from_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; @@ -138,12 +138,12 @@ mod benchmarks { #[benchmark] fn force_transfer_native_from_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; - let origin = T::Helper::make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(origin_para_id)]); + let origin = T::Helper::make_xcm_origin(origin_location.clone()); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; - let versioned_location: VersionedMultiLocation = origin_location.into(); + let versioned_location: VersionedLocation = origin_location.into(); #[extrinsic_call] _(RawOrigin::Root, Box::new(versioned_location), H160::default(), 1); diff --git a/bridges/snowbridge/parachain/pallets/system/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/src/lib.rs index 0042093ee662..e742bd8e1102 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/lib.rs @@ -87,12 +87,12 @@ pub type AccountIdOf = ::AccountId; pub type PricingParametersOf = PricingParametersRecord>; /// Ensure origin location is a sibling -fn ensure_sibling(location: &MultiLocation) -> Result<(ParaId, H256), DispatchError> +fn ensure_sibling(location: &Location) -> Result<(ParaId, H256), DispatchError> where T: Config, { - match location { - MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } => { + match location.unpack() { + (1, [Parachain(para_id)]) => { let agent_id = agent_id_of::(location)?; Ok(((*para_id).into(), agent_id)) }, @@ -101,7 +101,7 @@ where } /// Hash the location to produce an agent id -fn agent_id_of(location: &MultiLocation) -> Result { +fn agent_id_of(location: &Location) -> Result { T::AgentIdOf::convert_location(location).ok_or(Error::::LocationConversionFailed.into()) } @@ -110,7 +110,7 @@ pub trait BenchmarkHelper where O: OriginTrait, { - fn make_xcm_origin(location: MultiLocation) -> O; + fn make_xcm_origin(location: Location) -> O; } /// Whether a fee should be withdrawn to an account for sending an outbound message @@ -145,9 +145,9 @@ pub mod pallet { type OutboundQueue: SendMessage>; /// Origin check for XCM locations that can create agents - type SiblingOrigin: EnsureOrigin; + type SiblingOrigin: EnsureOrigin; - /// Converts MultiLocation to AgentId + /// Converts Location to AgentId type AgentIdOf: ConvertLocation; /// Token reserved for control operations @@ -180,7 +180,7 @@ pub mod pallet { }, /// An CreateAgent message was sent to the Gateway CreateAgent { - location: Box, + location: Box, agent_id: AgentId, }, /// An CreateChannel message was sent to the Gateway @@ -299,7 +299,7 @@ pub mod pallet { /// /// Fee required: No /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` #[pallet::call_index(1)] #[pallet::weight((T::WeightInfo::set_operating_mode(), DispatchClass::Operational))] pub fn set_operating_mode(origin: OriginFor, mode: OperatingMode) -> DispatchResult { @@ -342,11 +342,11 @@ pub mod pallet { /// /// Fee required: Yes /// - /// - `origin`: Must be `MultiLocation` of a sibling parachain + /// - `origin`: Must be `Location` of a sibling parachain #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::create_agent())] pub fn create_agent(origin: OriginFor) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is some consensus system on a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -375,12 +375,12 @@ pub mod pallet { /// /// The message is sent over the bridge on BridgeHub's own channel to the Gateway. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` /// - `mode`: Initial operating mode of the channel #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::create_channel())] pub fn create_channel(origin: OriginFor, mode: OperatingMode) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -407,12 +407,12 @@ pub mod pallet { /// /// A partial fee will be charged for local processing only. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` /// - `mode`: Initial operating mode of the channel #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::update_channel())] pub fn update_channel(origin: OriginFor, mode: OperatingMode) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is a sibling parachain let (para_id, _) = ensure_sibling::(&origin_location)?; @@ -461,7 +461,7 @@ pub mod pallet { /// /// A partial fee will be charged for local processing only. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` #[pallet::call_index(7)] #[pallet::weight(T::WeightInfo::transfer_native_from_agent())] pub fn transfer_native_from_agent( @@ -469,7 +469,7 @@ pub mod pallet { recipient: H160, amount: u128, ) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is some consensus system on a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -501,14 +501,14 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_transfer_native_from_agent())] pub fn force_transfer_native_from_agent( origin: OriginFor, - location: Box, + location: Box, recipient: H160, amount: u128, ) -> DispatchResult { ensure_root(origin)?; // Ensure that location is some consensus system on a sibling parachain - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|_| Error::::UnsupportedLocationVersion)?; let (_, agent_id) = ensure_sibling::(&location).map_err(|_| Error::::InvalidLocation)?; @@ -621,8 +621,8 @@ pub mod pallet { /// Initializes agents and channels. pub fn initialize(para_id: ParaId, asset_hub_para_id: ParaId) -> Result<(), DispatchError> { // Asset Hub - let asset_hub_location: MultiLocation = - ParentThen(X1(Parachain(asset_hub_para_id.into()))).into(); + let asset_hub_location: Location = + ParentThen(Parachain(asset_hub_para_id.into()).into()).into(); let asset_hub_agent_id = agent_id_of::(&asset_hub_location)?; let asset_hub_channel_id: ChannelId = asset_hub_para_id.into(); Agents::::insert(asset_hub_agent_id, ()); @@ -632,7 +632,7 @@ pub mod pallet { ); // Governance channels - let bridge_hub_agent_id = agent_id_of::(&MultiLocation::here())?; + let bridge_hub_agent_id = agent_id_of::(&Location::here())?; // Agent for BridgeHub Agents::::insert(bridge_hub_agent_id, ()); diff --git a/bridges/snowbridge/parachain/pallets/system/src/mock.rs b/bridges/snowbridge/parachain/pallets/system/src/mock.rs index bb9bae6b56dc..bc2295781327 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/mock.rs @@ -49,22 +49,22 @@ mod pallet_xcm_origin { // Insert this custom Origin into the aggregate RuntimeOrigin #[pallet::origin] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct Origin(pub MultiLocation); + pub struct Origin(pub Location); - impl From for Origin { - fn from(location: MultiLocation) -> Origin { + impl From for Origin { + fn from(location: Location) -> Origin { Origin(location) } } - /// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and + /// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and /// filter the contained location pub struct EnsureXcm(PhantomData); - impl, F: Contains> EnsureOrigin for EnsureXcm + impl, F: Contains> EnsureOrigin for EnsureXcm where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = Location; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { @@ -77,7 +77,7 @@ mod pallet_xcm_origin { #[cfg(feature = "runtime-benchmarks")] fn try_successful_origin() -> Result { - Ok(O::from(Origin(MultiLocation { parents: 1, interior: X1(Parachain(2000)) }))) + Ok(O::from(Origin(Location::new(1, [Parachain(2000)])))) } } } @@ -186,9 +186,9 @@ parameter_types! { pub const SS58Prefix: u8 = 42; pub const AnyNetwork: Option = None; pub const RelayNetwork: Option = Some(NetworkId::Kusama); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)); + pub const RelayLocation: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)].into(); } pub const DOT: u128 = 10_000_000_000; @@ -211,7 +211,7 @@ parameter_types! { #[cfg(feature = "runtime-benchmarks")] impl BenchmarkHelper for () { - fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { RuntimeOrigin::from(pallet_xcm_origin::Origin(location)) } } @@ -260,11 +260,11 @@ pub fn new_test_ext(genesis_build: bool) -> sp_io::TestExternalities { // Test helpers -pub fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { +pub fn make_xcm_origin(location: Location) -> RuntimeOrigin { pallet_xcm_origin::Origin(location).into() } -pub fn make_agent_id(location: MultiLocation) -> AgentId { +pub fn make_agent_id(location: Location) -> AgentId { ::AgentIdOf::convert_location(&location) .expect("convert location") } diff --git a/bridges/snowbridge/parachain/pallets/system/src/tests.rs b/bridges/snowbridge/parachain/pallets/system/src/tests.rs index e07481c1e33e..8b417c258ea1 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/tests.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/tests.rs @@ -11,8 +11,8 @@ use sp_runtime::{AccountId32, DispatchError::BadOrigin, TokenError}; fn create_agent() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; - let agent_id = make_agent_id(origin_location); + let origin_location = Location::new(1, [Parachain(origin_para_id)]); + let agent_id = make_agent_id(origin_location.clone()); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); // fund sovereign account of origin @@ -30,7 +30,7 @@ fn create_agent() { #[test] fn test_agent_for_here() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation::here(); + let origin_location = Location::here(); let agent_id = make_agent_id(origin_location); assert_eq!( agent_id, @@ -42,7 +42,7 @@ fn test_agent_for_here() { #[test] fn create_agent_fails_on_funds_unavailable() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; + let origin_location = Location::new(1, [Parachain(2000)]); let origin = make_xcm_origin(origin_location); // Reset balance of sovereign_account to zero so to trigger the FundsUnavailable error let sovereign_account = sibling_sovereign_account::(2000.into()); @@ -56,19 +56,16 @@ fn create_agent_bad_origin() { new_test_ext(true).execute_with(|| { // relay chain location not allowed assert_noop!( - EthereumSystem::create_agent(make_xcm_origin(MultiLocation { - parents: 1, - interior: Here, - })), + EthereumSystem::create_agent(make_xcm_origin(Location::new(1, [],))), BadOrigin, ); // local account location not allowed assert_noop!( - EthereumSystem::create_agent(make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - })), + EthereumSystem::create_agent(make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + ))), BadOrigin, ); @@ -243,7 +240,7 @@ fn set_token_transfer_fees_invalid() { fn create_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -259,7 +256,7 @@ fn create_channel() { fn create_channel_fail_already_exists() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -282,7 +279,7 @@ fn create_channel_bad_origin() { // relay chain location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { parents: 1, interior: Here }), + make_xcm_origin(Location::new(1, [])), OperatingMode::Normal, ), BadOrigin, @@ -291,13 +288,10 @@ fn create_channel_bad_origin() { // child of sibling location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - }), + make_xcm_origin(Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), OperatingMode::Normal, ), BadOrigin, @@ -306,10 +300,10 @@ fn create_channel_bad_origin() { // local account location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - }), + make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), OperatingMode::Normal, ), BadOrigin, @@ -333,7 +327,7 @@ fn create_channel_bad_origin() { fn update_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -359,23 +353,17 @@ fn update_channel_bad_origin() { // relay chain location not allowed assert_noop!( - EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { parents: 1, interior: Here }), - mode, - ), + EthereumSystem::update_channel(make_xcm_origin(Location::new(1, [])), mode,), BadOrigin, ); // child of sibling location not allowed assert_noop!( EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - }), + make_xcm_origin(Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), mode, ), BadOrigin, @@ -384,10 +372,10 @@ fn update_channel_bad_origin() { // local account location not allowed assert_noop!( EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - }), + make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), mode, ), BadOrigin, @@ -407,7 +395,7 @@ fn update_channel_bad_origin() { #[test] fn update_channel_fails_not_exist() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; + let origin_location = Location::new(1, [Parachain(2000)]); let origin = make_xcm_origin(origin_location); // Now try to update it @@ -422,7 +410,7 @@ fn update_channel_fails_not_exist() { fn force_update_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -468,8 +456,8 @@ fn force_update_channel_bad_origin() { #[test] fn transfer_native_from_agent() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; - let origin = make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(2000)]); + let origin = make_xcm_origin(origin_location.clone()); let recipient: H160 = [27u8; 20].into(); let amount = 103435; @@ -477,7 +465,7 @@ fn transfer_native_from_agent() { assert_ok!(EthereumSystem::create_agent(origin.clone())); assert_ok!(EthereumSystem::create_channel(origin, OperatingMode::Normal)); - let origin = make_xcm_origin(origin_location); + let origin = make_xcm_origin(origin_location.clone()); assert_ok!(EthereumSystem::transfer_native_from_agent(origin, recipient, amount),); System::assert_last_event(RuntimeEvent::EthereumSystem( @@ -494,13 +482,13 @@ fn transfer_native_from_agent() { fn force_transfer_native_from_agent() { new_test_ext(true).execute_with(|| { let origin = RuntimeOrigin::root(); - let location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; - let versioned_location: Box = Box::new(location.into()); + let location = Location::new(1, [Parachain(2000)]); + let versioned_location: Box = Box::new(location.clone().into()); let recipient: H160 = [27u8; 20].into(); let amount = 103435; // First create the agent - Agents::::insert(make_agent_id(location), ()); + Agents::::insert(make_agent_id(location.clone()), ()); assert_ok!(EthereumSystem::force_transfer_native_from_agent( origin, @@ -530,13 +518,10 @@ fn force_transfer_native_from_agent_bad_origin() { EthereumSystem::force_transfer_native_from_agent( RuntimeOrigin::signed([14; 32].into()), Box::new( - MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - } + Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + ) .into() ), recipient, @@ -571,8 +556,8 @@ fn check_sibling_sovereign_account() { fn charge_fee_for_create_agent() { new_test_ext(true).execute_with(|| { let para_id: u32 = TestParaId::get(); - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(para_id)) }; - let origin = make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(para_id)]); + let origin = make_xcm_origin(origin_location.clone()); let sovereign_account = sibling_sovereign_account::(para_id.into()); let (_, agent_id) = ensure_sibling::(&origin_location).unwrap(); @@ -605,10 +590,10 @@ fn charge_fee_for_create_agent() { fn charge_fee_for_transfer_native_from_agent() { new_test_ext(true).execute_with(|| { let para_id: u32 = TestParaId::get(); - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(para_id)) }; + let origin_location = Location::new(1, [Parachain(para_id)]); let recipient: H160 = [27u8; 20].into(); let amount = 103435; - let origin = make_xcm_origin(origin_location); + let origin = make_xcm_origin(origin_location.clone()); let (_, agent_id) = ensure_sibling::(&origin_location).unwrap(); let sovereign_account = sibling_sovereign_account::(para_id.into()); diff --git a/bridges/snowbridge/parachain/primitives/core/src/lib.rs b/bridges/snowbridge/parachain/primitives/core/src/lib.rs index ecbc3bb365fc..a464557a72b4 100644 --- a/bridges/snowbridge/parachain/primitives/core/src/lib.rs +++ b/bridges/snowbridge/parachain/primitives/core/src/lib.rs @@ -28,11 +28,7 @@ use sp_core::H256; use sp_io::hashing::keccak_256; use sp_runtime::{traits::AccountIdConversion, RuntimeDebug}; use sp_std::prelude::*; -use xcm::prelude::{ - Junction::Parachain, - Junctions::{Here, X1}, - MultiLocation, -}; +use xcm::prelude::{Junction::Parachain, Location}; use xcm_builder::{DescribeAllTerminal, DescribeFamily, DescribeLocation, HashedDescription}; /// The ID of an agent contract @@ -53,9 +49,9 @@ pub fn sibling_sovereign_account_raw(para_id: ParaId) -> [u8; 32] { } pub struct AllowSiblingsOnly; -impl Contains for AllowSiblingsOnly { - fn contains(location: &MultiLocation) -> bool { - matches!(location, MultiLocation { parents: 1, interior: X1(Parachain(_)) }) +impl Contains for AllowSiblingsOnly { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(_)])) } } @@ -161,14 +157,14 @@ pub const SECONDARY_GOVERNANCE_CHANNEL: ChannelId = pub struct DescribeHere; impl DescribeLocation for DescribeHere { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, l.interior) { - (0, Here) => Some(Vec::::new().encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, []) => Some(Vec::::new().encode()), _ => None, } } } -/// Creates an AgentId from a MultiLocation. An AgentId is a unique mapping to a Agent contract on -/// Ethereum which acts as the sovereign account for the MultiLocation. +/// Creates an AgentId from a Location. An AgentId is a unique mapping to a Agent contract on +/// Ethereum which acts as the sovereign account for the Location. pub type AgentIdOf = HashedDescription)>; diff --git a/bridges/snowbridge/parachain/primitives/core/tests/mod.rs b/bridges/snowbridge/parachain/primitives/core/tests/mod.rs index 2da5d2df182e..c91063a81480 100644 --- a/bridges/snowbridge/parachain/primitives/core/tests/mod.rs +++ b/bridges/snowbridge/parachain/primitives/core/tests/mod.rs @@ -2,12 +2,12 @@ mod tests { use frame_support::traits::Contains; use snowbridge_core::AllowSiblingsOnly; - use xcm::prelude::{Junction::Parachain, Junctions::X1, MultiLocation}; + use xcm::prelude::{Junction::Parachain, Location}; #[test] fn allow_siblings_predicate_only_allows_siblings() { - let sibling = MultiLocation::new(1, X1(Parachain(1000))); - let child = MultiLocation::new(0, X1(Parachain(1000))); + let sibling = Location::new(1, [Parachain(1000)]); + let child = Location::new(0, [Parachain(1000)]); assert!(AllowSiblingsOnly::contains(&sibling), "Sibling returns true."); assert!(!AllowSiblingsOnly::contains(&child), "Child returns false."); } diff --git a/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs b/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs index a07e0eae5d73..c20554c6d184 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs @@ -161,13 +161,13 @@ where { fn convert_register_token(chain_id: u64, token: H160, fee: u128) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; - let xcm_fee: MultiAsset = (MultiLocation::parent(), fee).into(); - let deposit: MultiAsset = (MultiLocation::parent(), CreateAssetDeposit::get()).into(); + let xcm_fee: Asset = (Location::parent(), fee).into(); + let deposit: Asset = (Location::parent(), CreateAssetDeposit::get()).into(); let total_amount = fee + CreateAssetDeposit::get(); - let total: MultiAsset = (MultiLocation::parent(), total_amount).into(); + let total: Asset = (Location::parent(), total_amount).into(); - let bridge_location: MultiLocation = (Parent, Parent, GlobalConsensus(network)).into(); + let bridge_location: Location = (Parent, Parent, GlobalConsensus(network)).into(); let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); let asset_id = Self::convert_token_address(network, token); @@ -182,7 +182,7 @@ where // Fund the snowbridge sovereign with the required deposit for creation. DepositAsset { assets: Definite(deposit.into()), beneficiary: bridge_location }, // Only our inbound-queue pallet is allowed to invoke `UniversalOrigin` - DescendOrigin(X1(PalletInstance(inbound_queue_pallet_index))), + DescendOrigin(PalletInstance(inbound_queue_pallet_index).into()), // Change origin to the bridge. UniversalOrigin(GlobalConsensus(network)), // Call create_asset on foreign assets pallet. @@ -216,40 +216,37 @@ where asset_hub_fee: u128, ) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; - let asset_hub_fee_asset: MultiAsset = (MultiLocation::parent(), asset_hub_fee).into(); - let asset: MultiAsset = (Self::convert_token_address(network, token), amount).into(); + let asset_hub_fee_asset: Asset = (Location::parent(), asset_hub_fee).into(); + let asset: Asset = (Self::convert_token_address(network, token), amount).into(); let (dest_para_id, beneficiary, dest_para_fee) = match destination { // Final destination is a 32-byte account on AssetHub - Destination::AccountId32 { id } => ( - None, - MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id }) }, - 0, - ), + Destination::AccountId32 { id } => + (None, Location::new(0, [AccountId32 { network: None, id }]), 0), // Final destination is a 32-byte account on a sibling of AssetHub Destination::ForeignAccountId32 { para_id, id, fee } => ( Some(para_id), - MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id }) }, + Location::new(0, [AccountId32 { network: None, id }]), // Total fee needs to cover execution on AssetHub and Sibling fee, ), // Final destination is a 20-byte account on a sibling of AssetHub Destination::ForeignAccountId20 { para_id, id, fee } => ( Some(para_id), - MultiLocation { parents: 0, interior: X1(AccountKey20 { network: None, key: id }) }, + Location::new(0, [AccountKey20 { network: None, key: id }]), // Total fee needs to cover execution on AssetHub and Sibling fee, ), }; let total_fees = asset_hub_fee.saturating_add(dest_para_fee); - let total_fee_asset: MultiAsset = (MultiLocation::parent(), total_fees).into(); + let total_fee_asset: Asset = (Location::parent(), total_fees).into(); let inbound_queue_pallet_index = InboundQueuePalletInstance::get(); let mut instructions = vec![ ReceiveTeleportedAsset(total_fee_asset.into()), BuyExecution { fees: asset_hub_fee_asset, weight_limit: Unlimited }, - DescendOrigin(X1(PalletInstance(inbound_queue_pallet_index))), + DescendOrigin(PalletInstance(inbound_queue_pallet_index).into()), UniversalOrigin(GlobalConsensus(network)), ReserveAssetDeposited(asset.clone().into()), ClearOrigin, @@ -257,14 +254,13 @@ where match dest_para_id { Some(dest_para_id) => { - let dest_para_fee_asset: MultiAsset = - (MultiLocation::parent(), dest_para_fee).into(); + let dest_para_fee_asset: Asset = (Location::parent(), dest_para_fee).into(); instructions.extend(vec![ // Perform a deposit reserve to send to destination chain. DepositReserveAsset { assets: Definite(vec![dest_para_fee_asset.clone(), asset.clone()].into()), - dest: MultiLocation { parents: 1, interior: X1(Parachain(dest_para_id)) }, + dest: Location::new(1, [Parachain(dest_para_id)]), xcm: vec![ // Buy execution on target. BuyExecution { fees: dest_para_fee_asset, weight_limit: Unlimited }, @@ -286,15 +282,12 @@ where (instructions.into(), total_fees.into()) } - // Convert ERC20 token address to a Multilocation that can be understood by Assets Hub. - fn convert_token_address(network: NetworkId, token: H160) -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(network), - AccountKey20 { network: None, key: token.into() }, - ), - } + // Convert ERC20 token address to a location that can be understood by Assets Hub. + fn convert_token_address(network: NetworkId, token: H160) -> Location { + Location::new( + 2, + [GlobalConsensus(network), AccountKey20 { network: None, key: token.into() }], + ) } } @@ -303,12 +296,11 @@ impl ConvertLocation for GlobalConsensusEthereumConvertsFo where AccountId: From<[u8; 32]> + Clone, { - fn convert_location(location: &MultiLocation) -> Option { - if let MultiLocation { interior: X1(GlobalConsensus(Ethereum { chain_id })), .. } = location - { - Some(Self::from_chain_id(chain_id).into()) - } else { - None + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (_, [GlobalConsensus(Ethereum { chain_id })]) => + Some(Self::from_chain_id(chain_id).into()), + _ => None, } } } diff --git a/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs b/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs index 8c96c13cf223..c46b88a84a4b 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs @@ -2,7 +2,7 @@ use super::GlobalConsensusEthereumConvertsFor; use crate::inbound::CallIndex; use frame_support::parameter_types; use hex_literal::hex; -use xcm::v3::prelude::*; +use xcm::v4::prelude::*; use xcm_executor::traits::ConvertLocation; const NETWORK: NetworkId = Ethereum { chain_id: 11155111 }; @@ -20,7 +20,7 @@ parameter_types! { fn test_contract_location_with_network_converts_successfully() { let expected_account: [u8; 32] = hex!("ce796ae65569a670d0c1cc1ac12515a3ce21b5fbf729d63d7b289baad070139d"); - let contract_location = MultiLocation { parents: 2, interior: X1(GlobalConsensus(NETWORK)) }; + let contract_location = Location::new(2, [GlobalConsensus(NETWORK)]); let account = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::convert_location(&contract_location) @@ -31,8 +31,7 @@ fn test_contract_location_with_network_converts_successfully() { #[test] fn test_contract_location_with_incorrect_location_fails_convert() { - let contract_location = - MultiLocation { parents: 2, interior: X2(GlobalConsensus(Polkadot), Parachain(1000)) }; + let contract_location = Location::new(2, [GlobalConsensus(Polkadot), Parachain(1000)]); assert_eq!( GlobalConsensusEthereumConvertsFor::<[u8; 32]>::convert_location(&contract_location), diff --git a/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs b/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs index c7f2f440834c..21823992db7c 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs @@ -16,7 +16,7 @@ use snowbridge_core::{ }; use sp_core::{H160, H256}; use sp_std::{iter::Peekable, marker::PhantomData, prelude::*}; -use xcm::v3::prelude::*; +use xcm::v4::prelude::*; use xcm_executor::traits::{ConvertLocation, ExportXcm}; pub struct EthereumBlobExporter< @@ -29,7 +29,7 @@ pub struct EthereumBlobExporter< impl ExportXcm for EthereumBlobExporter where - UniversalLocation: Get, + UniversalLocation: Get, EthereumNetwork: Get, OutboundQueue: SendMessage, AgentHashedDescription: ConvertLocation, @@ -39,8 +39,8 @@ where fn validate( network: NetworkId, _channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let expected_network = EthereumNetwork::get(); @@ -74,8 +74,8 @@ where return Err(SendError::NotApplicable) } - let para_id = match local_sub { - X1(Parachain(para_id)) => para_id, + let para_id = match local_sub.as_slice() { + [Parachain(para_id)] => *para_id, _ => { log::error!(target: "xcm::ethereum_blob_exporter", "could not get parachain id from universal source '{local_sub:?}'."); return Err(SendError::MissingArgument) @@ -93,7 +93,7 @@ where SendError::Unroutable })?; - let source_location: MultiLocation = MultiLocation { parents: 1, interior: local_sub }; + let source_location = Location::new(1, local_sub.clone()); let agent_id = match AgentHashedDescription::convert_location(&source_location) { Some(id) => id, None => { @@ -116,8 +116,8 @@ where SendError::Unroutable })?; - // convert fee to MultiAsset - let fee = MultiAsset::from((MultiLocation::parent(), fee.total())).into(); + // convert fee to Asset + let fee = Asset::from((Location::parent(), fee.total())).into(); Ok(((ticket.encode(), message_id), fee)) } @@ -216,8 +216,8 @@ impl<'a, Call> XcmConverter<'a, Call> { // assert that the beneficiary is AccountKey20. let recipient = match_expression!( - beneficiary, - MultiLocation { parents: 0, interior: X1(AccountKey20 { network, key }) } + beneficiary.unpack(), + (0, [AccountKey20 { network, key }]) if self.network_matches(network), H160(*key) ) @@ -245,14 +245,15 @@ impl<'a, Call> XcmConverter<'a, Call> { } } - let (token, amount) = match_expression!( - reserve_asset, - MultiAsset { - id: Concrete(MultiLocation { parents: 0, interior: X1(AccountKey20 { network , key })}), - fun: Fungible(amount) - } if self.network_matches(network), - (H160(*key), *amount) - ) + let (token, amount) = match reserve_asset { + Asset { id: AssetId(inner_location), fun: Fungible(amount) } => + match inner_location.unpack() { + (0, [AccountKey20 { network, key }]) if self.network_matches(network) => + Some((H160(*key), *amount)), + _ => None, + }, + _ => None, + } .ok_or(AssetResolutionFailed)?; // transfer amount must be greater than 0. diff --git a/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs b/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs index 153d934c3909..111243bb45a7 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs @@ -11,7 +11,7 @@ use super::*; parameter_types! { const MaxMessageSize: u32 = u32::MAX; const RelayNetwork: NetworkId = Polkadot; - const UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(1013)); + UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(1013)].into(); const BridgedNetwork: NetworkId = Ethereum{ chain_id: 1 }; const NonBridgedNetwork: NetworkId = Ethereum{ chain_id: 2 }; } @@ -61,8 +61,8 @@ impl SendMessageFeeProvider for MockErrOutboundQueue { fn exporter_validate_with_unknown_network_yields_not_applicable() { let network = Ethereum { chain_id: 1337 }; let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = None; + let mut universal_source: Option = None; + let mut destination: Option = None; let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -80,8 +80,8 @@ fn exporter_validate_with_unknown_network_yields_not_applicable() { fn exporter_validate_with_invalid_destination_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = None; + let mut universal_source: Option = None; + let mut destination: Option = None; let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -99,10 +99,11 @@ fn exporter_validate_with_invalid_destination_yields_missing_argument() { fn exporter_validate_with_x8_destination_yields_not_applicable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = Some(X8( - OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, - )); + let mut universal_source: Option = None; + let mut destination: Option = Some( + [OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild] + .into(), + ); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -120,8 +121,8 @@ fn exporter_validate_with_x8_destination_yields_not_applicable() { fn exporter_validate_without_universal_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = Here.into(); + let mut universal_source: Option = None; + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -139,8 +140,8 @@ fn exporter_validate_without_universal_source_yields_missing_argument() { fn exporter_validate_without_global_universal_location_yields_unroutable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Here.into(); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Here.into(); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -158,8 +159,8 @@ fn exporter_validate_without_global_universal_location_yields_unroutable() { fn exporter_validate_without_global_bridge_location_yields_not_applicable() { let network = NonBridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Here.into(); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Here.into(); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -177,9 +178,9 @@ fn exporter_validate_without_global_bridge_location_yields_not_applicable() { fn exporter_validate_with_remote_universal_source_yields_not_applicable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X2(GlobalConsensus(Kusama), Parachain(1000))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Kusama), Parachain(1000)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -197,8 +198,8 @@ fn exporter_validate_with_remote_universal_source_yields_not_applicable() { fn exporter_validate_without_para_id_in_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Some(X1(GlobalConsensus(Polkadot))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Some(GlobalConsensus(Polkadot).into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -216,9 +217,9 @@ fn exporter_validate_without_para_id_in_source_yields_missing_argument() { fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X3(GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(12))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(12)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -236,9 +237,9 @@ fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { fn exporter_validate_without_xcm_message_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -255,23 +256,23 @@ fn exporter_validate_without_xcm_message_yields_missing_argument() { #[test] fn exporter_validate_with_max_target_fee_yields_unroutable() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); let channel: u32 = 0; - let fee = MultiAsset { id: Concrete(Here.into()), fun: Fungible(1000) }; - let fees: MultiAssets = vec![fee.clone()].into(); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let fee = Asset { id: AssetId(Here.into()), fun: Fungible(1000) }; + let fees: Assets = vec![fee.clone()].into(); + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let mut message: Option> = Some( vec![ @@ -280,7 +281,7 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { WithdrawAsset(assets), DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: Some(network), key: beneficiary_address }) + beneficiary: AccountKey20 { network: Some(network), key: beneficiary_address } .into(), }, SetTopic([0; 32]), @@ -303,14 +304,14 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { #[test] fn exporter_validate_with_unparsable_xcm_yields_unroutable() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let channel: u32 = 0; - let fee = MultiAsset { id: Concrete(Here.into()), fun: Fungible(1000) }; - let fees: MultiAssets = vec![fee.clone()].into(); + let fee = Asset { id: AssetId(Here.into()), fun: Fungible(1000) }; + let fees: Assets = vec![fee.clone()].into(); let mut message: Option> = Some(vec![WithdrawAsset(fees), BuyExecution { fees: fee, weight_limit: Unlimited }].into()); @@ -330,22 +331,22 @@ fn exporter_validate_with_unparsable_xcm_yields_unroutable() { #[test] fn exporter_validate_xcm_success_case_1() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); let channel: u32 = 0; - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); let fee = assets.clone().get(0).unwrap().clone(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let mut message: Option> = Some( vec![ @@ -354,7 +355,7 @@ fn exporter_validate_xcm_success_case_1() { BuyExecution { fees: fee, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -391,12 +392,12 @@ fn xcm_converter_convert_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -404,7 +405,7 @@ fn xcm_converter_convert_success() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -426,18 +427,18 @@ fn xcm_converter_convert_without_buy_execution_yields_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -459,12 +460,12 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(All); + let filter: AssetFilter = Wild(All); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -472,7 +473,7 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -494,13 +495,12 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(500) }; + let asset_location: Location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = Asset { id: AssetId(asset_location.clone()), fun: Fungible(500) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -508,7 +508,7 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -530,19 +530,19 @@ fn xcm_converter_convert_without_set_topic_yields_set_topic_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, ClearTopic, ] @@ -557,8 +557,8 @@ fn xcm_converter_convert_with_partial_message_yields_unexpected_end_of_xcm() { let network = BridgedNetwork::get(); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); @@ -576,16 +576,13 @@ fn xcm_converter_with_different_fee_asset_fails() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { - id: Concrete(MultiLocation { parents: 0, interior: Here }), - fun: Fungible(1000), - }; + let asset_location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = + Asset { id: AssetId(Location { parents: 0, interior: Here }), fun: Fungible(1000) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -593,7 +590,7 @@ fn xcm_converter_with_different_fee_asset_fails() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -610,13 +607,12 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(1001) }; + let asset_location: Location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = Asset { id: AssetId(asset_location.clone()), fun: Fungible(1001) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -624,7 +620,7 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -653,12 +649,12 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -666,7 +662,7 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ClearError, @@ -685,19 +681,19 @@ fn xcm_converter_convert_without_withdraw_asset_yields_withdraw_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ ClearOrigin, BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -714,8 +710,8 @@ fn xcm_converter_convert_without_withdraw_asset_yields_deposit_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); @@ -741,11 +737,11 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let assets: Assets = vec![].into(); + let filter: AssetFilter = assets.clone().into(); - let fee = MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let fee = Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }; @@ -755,7 +751,7 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { BuyExecution { fees: fee, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -774,18 +770,18 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { let token_address_2: [u8; 20] = hex!("1100000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![ - MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address_1 }).into()), + let assets: Assets = vec![ + Asset { + id: AssetId(AccountKey20 { network: None, key: token_address_1 }.into()), fun: Fungible(1000), }, - MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address_2 }).into()), + Asset { + id: AssetId(AccountKey20 { network: None, key: token_address_2 }.into()), fun: Fungible(500), }, ] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -793,7 +789,7 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -811,12 +807,12 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(0)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(0)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -824,7 +820,7 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -842,12 +838,12 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(0), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -855,7 +851,7 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -872,12 +868,12 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X3(GlobalConsensus(Polkadot), Parachain(1000), GeneralIndex(0)).into()), + let assets: Assets = vec![Asset { + id: AssetId([GlobalConsensus(Polkadot), Parachain(1000), GeneralIndex(0)].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -885,7 +881,7 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -903,14 +899,14 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete( - X1(AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: token_address }).into(), + let assets: Assets = vec![Asset { + id: AssetId( + AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: token_address }.into(), ), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -918,7 +914,7 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -936,14 +932,14 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete( - X1(AccountKey20 { network: Some(NonBridgedNetwork::get()), key: token_address }).into(), + let assets: Assets = vec![Asset { + id: AssetId( + [AccountKey20 { network: Some(NonBridgedNetwork::get()), key: token_address }].into(), ), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -951,7 +947,7 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -971,23 +967,23 @@ fn xcm_converter_convert_with_non_ethereum_beneficiary_yields_beneficiary_resolu let beneficiary_address: [u8; 32] = hex!("2000000000000000000000000000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), ClearOrigin, BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X3( + beneficiary: [ GlobalConsensus(Polkadot), Parachain(1000), AccountId32 { network: Some(Polkadot), id: beneficiary_address }, - ) + ] .into(), }, SetTopic([0; 32]), @@ -1007,12 +1003,12 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -1020,10 +1016,10 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { + beneficiary: AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: beneficiary_address, - }) + } .into(), }, SetTopic([0; 32]), @@ -1037,14 +1033,13 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ #[test] fn test_describe_asset_hub() { - let legacy_location: MultiLocation = - MultiLocation { parents: 0, interior: X1(Parachain(1000)) }; + let legacy_location: Location = Location::new(0, [Parachain(1000)]); let legacy_agent_id = AgentIdOf::convert_location(&legacy_location).unwrap(); assert_eq!( legacy_agent_id, hex!("72456f48efed08af20e5b317abf8648ac66e86bb90a411d9b0b713f7364b75b4").into() ); - let location: MultiLocation = MultiLocation { parents: 1, interior: X1(Parachain(1000)) }; + let location: Location = Location::new(1, [Parachain(1000)]); let agent_id = AgentIdOf::convert_location(&location).unwrap(); assert_eq!( agent_id, @@ -1054,7 +1049,7 @@ fn test_describe_asset_hub() { #[test] fn test_describe_here() { - let location: MultiLocation = MultiLocation { parents: 0, interior: Here }; + let location: Location = Location::new(0, []); let agent_id = AgentIdOf::convert_location(&location).unwrap(); assert_eq!( agent_id, diff --git a/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs b/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs index b7f54d262bbb..1a9b704f356c 100644 --- a/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs +++ b/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs @@ -46,43 +46,38 @@ impl where Balance: BaseArithmetic + Unsigned + Copy + From + Into, AccountId: Clone + Into<[u8; 32]> + From<[u8; 32]>, - FeeAssetLocation: Get, + FeeAssetLocation: Get, EthereumNetwork: Get, AssetTransactor: TransactAsset, FeeProvider: SendMessageFeeProvider, { - fn handle_fee( - fees: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fees: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets { let token_location = FeeAssetLocation::get(); // Check the reason to see if this export is for snowbridge. if !matches!( reason, - FeeReason::Export { network: bridged_network, destination } - if bridged_network == EthereumNetwork::get() && destination == Here + FeeReason::Export { network: bridged_network, ref destination } + if bridged_network == EthereumNetwork::get() && destination == &Here ) { return fees } // Get the parachain sovereign from the `context`. - let para_sovereign = if let Some(XcmContext { - origin: Some(MultiLocation { parents: 1, interior }), - .. - }) = context - { - if let Some(Parachain(sibling_para_id)) = interior.first() { - let account: AccountId = - sibling_sovereign_account_raw((*sibling_para_id).into()).into(); - account + let para_sovereign = + if let Some(XcmContext { origin: Some(Location { parents: 1, interior }), .. }) = + context + { + if let Some(Parachain(sibling_para_id)) = interior.first() { + let account: AccountId = + sibling_sovereign_account_raw((*sibling_para_id).into()).into(); + account + } else { + return fees + } } else { return fees - } - } else { - return fees - }; + }; // Get the total fee offered by export message. let maybe_total_supplied_fee: Option<(usize, Balance)> = fees @@ -90,8 +85,8 @@ impl (0u128).into() { // Refund remote component of fee to physical origin deposit_or_burn_fee::( - MultiAsset { id: Concrete(token_location), fun: Fungible(remote_fee.into()) } + Asset { id: AssetId(token_location.clone()), fun: Fungible(remote_fee.into()) } .into(), context, para_sovereign, @@ -112,8 +107,8 @@ impl::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + XcmExecutor::::prepare_and_execute( assethub_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ) } @@ -176,7 +175,7 @@ pub fn send_unpaid_transfer_token_message( XcmConfig: xcm_executor::Config, ValidatorIdOf: From>, { - let assethub_parachain_location = MultiLocation::new(1, Parachain(assethub_parachain_id)); + let assethub_parachain_location = Location::new(1, Parachain(assethub_parachain_id)); ExtBuilder::::default() .with_collators(collator_session_key.collators()) @@ -194,28 +193,25 @@ pub fn send_unpaid_transfer_token_message( ) .unwrap(); - let asset = MultiAsset { - id: Concrete(MultiLocation { - parents: 0, - interior: X1(AccountKey20 { network: None, key: weth_contract_address.into() }), - }), + let asset = Asset { + id: AssetId(Location::new( + 0, + [AccountKey20 { network: None, key: weth_contract_address.into() }], + )), fun: Fungible(1000000000), }; let assets = vec![asset.clone()]; let inner_xcm = Xcm(vec![ - WithdrawAsset(MultiAssets::from(assets.clone())), + WithdrawAsset(Assets::from(assets.clone())), ClearOrigin, BuyExecution { fees: asset, weight_limit: Unlimited }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { - parents: 0, - interior: X1(AccountKey20 { - network: None, - key: destination_contract.into(), - }), - }, + beneficiary: Location::new( + 0, + [AccountKey20 { network: None, key: destination_contract.into() }], + ), }, SetTopic([0; 32]), ]); @@ -231,12 +227,13 @@ pub fn send_unpaid_transfer_token_message( ]); // execute XCM - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let outcome = XcmExecutor::::prepare_and_execute( assethub_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); // check error is barrier assert_err!(outcome.ensure_complete(), Barrier); diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs index 71cd21d45f77..5b900769622a 100644 --- a/cumulus/pallets/xcmp-queue/src/lib.rs +++ b/cumulus/pallets/xcmp-queue/src/lib.rs @@ -135,7 +135,7 @@ pub mod pallet { /// The origin that is allowed to resume or suspend the XCMP queue. type ControllerOrigin: EnsureOrigin; - /// The conversion function used to attempt to convert an XCM `MultiLocation` origin to a + /// The conversion function used to attempt to convert an XCM `Location` origin to a /// superuser origin. type ControllerOriginConverter: ConvertOrigin; @@ -903,14 +903,14 @@ impl SendXcm for Pallet { type Ticket = (ParaId, VersionedXcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult<(ParaId, VersionedXcm<()>)> { let d = dest.take().ok_or(SendError::MissingArgument)?; - match &d { + match d.unpack() { // An HRMP message for a sibling parachain. - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => { + (1, [Parachain(id)]) => { let xcm = msg.take().ok_or(SendError::MissingArgument)?; let id = ParaId::from(*id); let price = T::PriceForSiblingDelivery::price_for_delivery(id, &xcm); diff --git a/cumulus/pallets/xcmp-queue/src/mock.rs b/cumulus/pallets/xcmp-queue/src/mock.rs index a41be6fa9ca3..031c07217537 100644 --- a/cumulus/pallets/xcmp-queue/src/mock.rs +++ b/cumulus/pallets/xcmp-queue/src/mock.rs @@ -124,8 +124,8 @@ impl cumulus_pallet_parachain_system::Config for Test { } parameter_types! { - pub const RelayChain: MultiLocation = MultiLocation::parent(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(1u32)); + pub const RelayChain: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = [Parachain(1u32)].into(); pub UnitWeightCost: Weight = Weight::from_parts(1_000_000, 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; @@ -138,7 +138,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -187,17 +187,14 @@ impl ConvertOrigin for SystemParachainAsSuperuser { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); if kind == OriginKind::Superuser && matches!( - origin, - MultiLocation { - parents: 1, - interior: X1(Parachain(id)), - } if ParaId::from(id).is_system(), + origin.unpack(), + (1, [Parachain(id)]) if ParaId::from(*id).is_system(), ) { Ok(RuntimeOrigin::root()) } else { @@ -256,7 +253,7 @@ impl> EnqueueMessage for EnqueueToLocalStorage parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RelayChain::get()); + pub FeeAssetId: AssetId = AssetId(RelayChain::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: Balance = 300_000_000; /// The fee per byte diff --git a/cumulus/pallets/xcmp-queue/src/tests.rs b/cumulus/pallets/xcmp-queue/src/tests.rs index 8e8f6e852e1e..0b41095828f2 100644 --- a/cumulus/pallets/xcmp-queue/src/tests.rs +++ b/cumulus/pallets/xcmp-queue/src/tests.rs @@ -333,11 +333,11 @@ struct OkFixedXcmHashWithAssertingRequiredInputsSender; impl OkFixedXcmHashWithAssertingRequiredInputsSender { const FIXED_XCM_HASH: [u8; 32] = [9; 32]; - fn fixed_delivery_asset() -> MultiAssets { - MultiAssets::new() + fn fixed_delivery_asset() -> Assets { + Assets::new() } - fn expected_delivery_result() -> Result<(XcmHash, MultiAssets), SendError> { + fn expected_delivery_result() -> Result<(XcmHash, Assets), SendError> { Ok((Self::FIXED_XCM_HASH, Self::fixed_delivery_asset())) } } @@ -345,7 +345,7 @@ impl SendXcm for OkFixedXcmHashWithAssertingRequiredInputsSender { type Ticket = (); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { assert!(destination.is_some()); @@ -392,8 +392,8 @@ fn xcmp_queue_consumes_dest_and_msg_on_ok_validate() { let message = Xcm(vec![Trap(5)]); // XcmpQueue - check dest/msg is valid - let dest = (Parent, X1(Parachain(5555))); - let mut dest_wrapper = Some(dest.into()); + let dest: Location = (Parent, Parachain(5555)).into(); + let mut dest_wrapper = Some(dest.clone()); let mut msg_wrapper = Some(message.clone()); new_test_ext().execute_with(|| { @@ -416,7 +416,7 @@ fn xcmp_queue_consumes_dest_and_msg_on_ok_validate() { #[test] fn xcmp_queue_validate_nested_xcm_works() { - let dest = (Parent, X1(Parachain(5555))); + let dest = (Parent, Parachain(5555)); // Message that is not too deeply nested: let mut good = Xcm(vec![ClearOrigin]); for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { @@ -441,7 +441,7 @@ fn xcmp_queue_validate_nested_xcm_works() { #[test] fn send_xcm_nested_works() { - let dest = (Parent, X1(Parachain(HRMP_PARA_ID))); + let dest = (Parent, Parachain(HRMP_PARA_ID)); // Message that is not too deeply nested: let mut good = Xcm(vec![ClearOrigin]); for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { @@ -455,7 +455,7 @@ fn send_xcm_nested_works() { XcmpQueue::take_outbound_messages(usize::MAX), vec![( HRMP_PARA_ID.into(), - (XcmpMessageFormat::ConcatenatedVersionedXcm, VersionedXcm::V3(good.clone())) + (XcmpMessageFormat::ConcatenatedVersionedXcm, VersionedXcm::V4(good.clone())) .encode(), )] ); @@ -474,7 +474,7 @@ fn hrmp_signals_are_prioritized() { let message = Xcm(vec![Trap(5)]); let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))); + let dest = (Parent, Parachain(sibling_para_id.into())); let mut dest_wrapper = Some(dest.into()); let mut msg_wrapper = Some(message.clone()); @@ -511,7 +511,7 @@ fn hrmp_signals_are_prioritized() { // Without a signal we get the messages in order: let mut expected_msg = XcmpMessageFormat::ConcatenatedVersionedXcm.encode(); for _ in 0..31 { - expected_msg.extend(VersionedXcm::V3(message.clone()).encode()); + expected_msg.extend(VersionedXcm::V4(message.clone()).encode()); } hypothetically!({ @@ -590,7 +590,7 @@ fn take_first_concatenated_xcm_good_recursion_depth_works() { for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { good = Xcm(vec![SetAppendix(good)]); } - let good = VersionedXcm::V3(good); + let good = VersionedXcm::V4(good); let page = good.encode(); assert_ok!(XcmpQueue::take_first_concatenated_xcm(&mut &page[..], &mut WeightMeter::new())); @@ -603,7 +603,7 @@ fn take_first_concatenated_xcm_good_bad_depth_errors() { for _ in 0..MAX_XCM_DECODE_DEPTH { bad = Xcm(vec![SetAppendix(bad)]); } - let bad = VersionedXcm::V3(bad); + let bad = VersionedXcm::V4(bad); let page = bad.encode(); assert_err!( @@ -699,12 +699,12 @@ fn lazy_migration_noop_when_out_of_weight() { fn xcmp_queue_send_xcm_works() { new_test_ext().execute_with(|| { let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))).into(); + let dest: Location = (Parent, Parachain(sibling_para_id.into())).into(); let msg = Xcm(vec![ClearOrigin]); // try to send without opened HRMP channel to the sibling_para_id assert_eq!( - send_xcm::(dest, msg.clone()), + send_xcm::(dest.clone(), msg.clone()), Err(SendError::Transport("NoChannel")), ); @@ -728,7 +728,7 @@ fn xcmp_queue_send_xcm_works() { fn xcmp_queue_send_too_big_xcm_fails() { new_test_ext().execute_with(|| { let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))).into(); + let dest = (Parent, Parachain(sibling_para_id.into())).into(); let max_message_size = 100_u32; @@ -774,7 +774,7 @@ fn verify_fee_factor_increase_and_decrease() { use sp_runtime::FixedU128; let sibling_para_id = ParaId::from(12345); - let destination = (Parent, Parachain(sibling_para_id.into())).into(); + let destination: Location = (Parent, Parachain(sibling_para_id.into())).into(); let xcm = Xcm(vec![ClearOrigin; 100]); let versioned_xcm = VersionedXcm::from(xcm.clone()); let mut xcmp_message = XcmpMessageFormat::ConcatenatedVersionedXcm.encode(); @@ -799,15 +799,15 @@ fn verify_fee_factor_increase_and_decrease() { // Fee factor is only increased in `send_fragment`, which is called by `send_xcm`. // When queue is not congested, fee factor doesn't change. - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 104 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 208 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 312 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 416 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 104 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 208 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 312 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 416 assert_eq!(DeliveryFeeFactor::::get(sibling_para_id), initial); // Sending the message right now is cheap - let (_, delivery_fees) = - validate_send::(destination, xcm.clone()).expect("message can be sent; qed"); + let (_, delivery_fees) = validate_send::(destination.clone(), xcm.clone()) + .expect("message can be sent; qed"); let Fungible(delivery_fee_amount) = delivery_fees.inner()[0].fun else { unreachable!("asset is fungible; qed"); }; @@ -817,18 +817,18 @@ fn verify_fee_factor_increase_and_decrease() { // When we get to half of `max_total_size`, because `THRESHOLD_FACTOR` is 2, // then the fee factor starts to increase. - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 520 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 520 assert_eq!(DeliveryFeeFactor::::get(sibling_para_id), FixedU128::from_float(1.05)); for _ in 0..12 { // We finish at size 929 - assert_ok!(send_xcm::(destination, smaller_xcm.clone())); + assert_ok!(send_xcm::(destination.clone(), smaller_xcm.clone())); } assert!(DeliveryFeeFactor::::get(sibling_para_id) > FixedU128::from_float(1.88)); // Sending the message right now is expensive - let (_, delivery_fees) = - validate_send::(destination, xcm.clone()).expect("message can be sent; qed"); + let (_, delivery_fees) = validate_send::(destination.clone(), xcm.clone()) + .expect("message can be sent; qed"); let Fungible(delivery_fee_amount) = delivery_fees.inner()[0].fun else { unreachable!("asset is fungible; qed"); }; diff --git a/cumulus/parachain-template/runtime/src/xcm_config.rs b/cumulus/parachain-template/runtime/src/xcm_config.rs index 7d1a748819ce..d407292d0bd6 100644 --- a/cumulus/parachain-template/runtime/src/xcm_config.rs +++ b/cumulus/parachain-template/runtime/src/xcm_config.rs @@ -3,8 +3,8 @@ use super::{ Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, Everything, Nothing}, + parameter_types, + traits::{ConstU32, Contains, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -25,13 +25,13 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -50,7 +50,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -86,11 +86,11 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; +pub struct ParentOrParentsExecutivePlurality; +impl Contains for ParentOrParentsExecutivePlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }])) + } } pub type Barrier = TrailingSetTopicAsId< diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs index beb655134ad4..69da325dd4fc 100644 --- a/cumulus/parachains/common/src/impls.rs +++ b/cumulus/parachains/common/src/impls.rs @@ -24,8 +24,8 @@ use pallet_asset_tx_payment::HandleCredit; use sp_runtime::traits::Zero; use sp_std::{marker::PhantomData, prelude::*}; use xcm::latest::{ - AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, MultiAsset, - MultiLocation, Parent, WeightLimit, + Asset, AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, Location, + Parent, WeightLimit, }; use xcm_executor::traits::ConvertLocation; @@ -113,11 +113,11 @@ where /// Asset filter that allows all assets from a certain location. pub struct AssetsFrom(PhantomData); -impl> ContainsPair for AssetsFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for AssetsFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if asset_loc.match_and_split(&loc).is_some()) } } @@ -148,7 +148,7 @@ where Err(amount) => amount, }; let imbalance = amount.peek(); - let root_location: MultiLocation = Here.into(); + let root_location: Location = Here.into(); let root_account: AccountIdOf = match AccountIdConverter::convert_location(&root_location) { Some(a) => a, @@ -329,13 +329,13 @@ mod tests { #[test] fn assets_from_filters_correctly() { parameter_types! { - pub SomeSiblingParachain: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); + pub SomeSiblingParachain: Location = (Parent, Parachain(1234)).into(); } let asset_location = SomeSiblingParachain::get() .pushed_with_interior(GeneralIndex(42)) - .expect("multilocation will only have 2 junctions; qed"); - let asset = MultiAsset { id: Concrete(asset_location), fun: 1_000_000u128.into() }; + .expect("location will only have 2 junctions; qed"); + let asset = Asset { id: AssetId(asset_location), fun: 1_000_000u128.into() }; assert!( AssetsFrom::::contains(&asset, &SomeSiblingParachain::get()), "AssetsFrom should allow assets from any of its interior locations" diff --git a/cumulus/parachains/common/src/xcm_config.rs b/cumulus/parachains/common/src/xcm_config.rs index 7a63e720b079..15b090923d50 100644 --- a/cumulus/parachains/common/src/xcm_config.rs +++ b/cumulus/parachains/common/src/xcm_config.rs @@ -66,37 +66,36 @@ where } } -/// Accepts an asset if it is a native asset from a particular `MultiLocation`. -pub struct ConcreteNativeAssetFrom(PhantomData); -impl> ContainsPair - for ConcreteNativeAssetFrom +/// Accepts an asset if it is a native asset from a particular `Location`. +pub struct ConcreteNativeAssetFrom(PhantomData); +impl> ContainsPair + for ConcreteNativeAssetFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::filter_asset_location", "ConcreteNativeAsset asset: {:?}, origin: {:?}, location: {:?}", - asset, origin, Location::get()); - matches!(asset.id, Concrete(ref id) if id == origin && origin == &Location::get()) + asset, origin, LocationValue::get()); + asset.id.0 == *origin && origin == &LocationValue::get() } } pub struct RelayOrOtherSystemParachains< - SystemParachainMatcher: Contains, + SystemParachainMatcher: Contains, Runtime: parachain_info::Config, > { _runtime: PhantomData<(SystemParachainMatcher, Runtime)>, } -impl, Runtime: parachain_info::Config> - Contains for RelayOrOtherSystemParachains +impl, Runtime: parachain_info::Config> Contains + for RelayOrOtherSystemParachains { - fn contains(l: &MultiLocation) -> bool { + fn contains(l: &Location) -> bool { let self_para_id: u32 = parachain_info::Pallet::::get().into(); - if let MultiLocation { parents: 0, interior: X1(Parachain(para_id)) } = l { + if let (0, [Parachain(para_id)]) = l.unpack() { if *para_id == self_para_id { return false } } - matches!(l, MultiLocation { parents: 1, interior: Here }) || - SystemParachainMatcher::contains(l) + matches!(l.unpack(), (1, [])) || SystemParachainMatcher::contains(l) } } @@ -105,14 +104,12 @@ impl, Runtime: parachain_info::C /// This structure can only be used at a parachain level. In the Relay Chain, please use /// the `xcm_builder::IsChildSystemParachain` matcher. pub struct AllSiblingSystemParachains; - -impl Contains for AllSiblingSystemParachains { - fn contains(l: &MultiLocation) -> bool { +impl Contains for AllSiblingSystemParachains { + fn contains(l: &Location) -> bool { log::trace!(target: "xcm::contains", "AllSiblingSystemParachains location: {:?}", l); - match *l { + match l.unpack() { // System parachain - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - ParaId::from(id).is_system(), + (1, [Parachain(id)]) => ParaId::from(*id).is_system(), // Everything else _ => false, } @@ -121,21 +118,20 @@ impl Contains for AllSiblingSystemParachains { /// Accepts an asset if it is a concrete asset from the system (Relay Chain or system parachain). pub struct ConcreteAssetFromSystem(PhantomData); -impl> ContainsPair +impl> ContainsPair for ConcreteAssetFromSystem { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "ConcreteAssetFromSystem asset: {:?}, origin: {:?}", asset, origin); - let is_system = match origin { + let is_system = match origin.unpack() { // The Relay Chain - MultiLocation { parents: 1, interior: Here } => true, + (1, []) => true, // System parachain - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - ParaId::from(*id).is_system(), + (1, [Parachain(id)]) => ParaId::from(*id).is_system(), // Others _ => false, }; - matches!(asset.id, Concrete(id) if id == AssetLocation::get()) && is_system + asset.id.0 == AssetLocation::get() && is_system } } @@ -144,13 +140,9 @@ impl> ContainsPair /// This type should only be used within the context of a parachain, since it does not verify that /// the parent is indeed a Relay Chain. pub struct ParentRelayOrSiblingParachains; -impl Contains for ParentRelayOrSiblingParachains { - fn contains(location: &MultiLocation) -> bool { - matches!( - location, - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - ) +impl Contains for ParentRelayOrSiblingParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) } } @@ -159,20 +151,20 @@ mod tests { use frame_support::{parameter_types, traits::Contains}; use super::{ - AllSiblingSystemParachains, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, Here, - MultiAsset, MultiLocation, PalletInstance, Parachain, Parent, + AllSiblingSystemParachains, Asset, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, + Here, Location, PalletInstance, Parachain, Parent, }; use polkadot_primitives::LOWEST_PUBLIC_ID; use xcm::latest::prelude::*; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); } #[test] fn concrete_asset_from_relay_works() { - let expected_asset: MultiAsset = (Parent, 1000000).into(); - let expected_origin: MultiLocation = (Parent, Here).into(); + let expected_asset: Asset = (Parent, 1000000).into(); + let expected_origin: Location = (Parent, Here).into(); assert!(>::contains( &expected_asset, @@ -182,12 +174,12 @@ mod tests { #[test] fn concrete_asset_from_sibling_system_para_fails_for_wrong_asset() { - let unexpected_assets: Vec = vec![ + let unexpected_assets: Vec = vec![ (Here, 1000000).into(), ((PalletInstance(50), GeneralIndex(1)), 1000000).into(), ((Parent, Parachain(1000), PalletInstance(50), GeneralIndex(1)), 1000000).into(), ]; - let expected_origin: MultiLocation = (Parent, Parachain(1000)).into(); + let expected_origin: Location = (Parent, Parachain(1000)).into(); unexpected_assets.iter().for_each(|asset| { assert!(!>::contains(asset, &expected_origin)); @@ -206,10 +198,10 @@ mod tests { (2001, false), // Not a System Parachain ]; - let expected_asset: MultiAsset = (Parent, 1000000).into(); + let expected_asset: Asset = (Parent, 1000000).into(); for (para_id, expected_result) in test_data { - let origin: MultiLocation = (Parent, Parachain(para_id)).into(); + let origin: Location = (Parent, Parachain(para_id)).into(); assert_eq!( expected_result, >::contains(&expected_asset, &origin) @@ -220,15 +212,15 @@ mod tests { #[test] fn all_sibling_system_parachains_works() { // system parachain - assert!(AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(Parachain(1))))); + assert!(AllSiblingSystemParachains::contains(&Location::new(1, [Parachain(1)]))); // non-system parachain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new( + assert!(!AllSiblingSystemParachains::contains(&Location::new( 1, - X1(Parachain(LOWEST_PUBLIC_ID.into())) + [Parachain(LOWEST_PUBLIC_ID.into())] ))); // when used at relay chain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(0, X1(Parachain(1))))); + assert!(!AllSiblingSystemParachains::contains(&Location::new(0, [Parachain(1)]))); // when used with non-parachain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(OnlyChild)))); + assert!(!AllSiblingSystemParachains::contains(&Location::new(1, [OnlyChild]))); } } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs index 244a846bbc2f..8f586a46a75c 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs @@ -15,7 +15,9 @@ mod genesis; pub use genesis::{genesis, ED, PARA_ID_A, PARA_ID_B}; -pub use penpal_runtime::xcm_config::{LocalTeleportableToAssetHub, XcmConfig}; +pub use penpal_runtime::xcm_config::{ + LocalTeleportableToAssetHub, LocalTeleportableToAssetHubV3, XcmConfig, +}; // Substrate use frame_support::traits::OnInitialize; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index aa3ec214f8c6..4bbb4701e439 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -38,8 +38,9 @@ pub use polkadot_runtime_parachains::{ inclusion::{AggregateMessageOrigin, UmpQueueId}, }; pub use xcm::{ - prelude::{MultiLocation, OriginKind, Outcome, VersionedXcm, XcmVersion}, - v3::Error, + prelude::{Location, OriginKind, Outcome, VersionedXcm, XcmVersion}, + v3, + v4::Error as XcmError, DoubleEncoded, }; @@ -209,7 +210,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { Self, vec![ [<$chain RuntimeEvent>]::::XcmPallet( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete { used: weight } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), @@ -224,21 +225,21 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { /// Asserts a dispatchable is incompletely executed and XCM sent pub fn assert_xcm_pallet_attempted_incomplete( expected_weight: Option<$crate::impls::Weight>, - expected_error: Option<$crate::impls::Error>, + expected_error: Option<$crate::impls::XcmError>, ) { $crate::impls::assert_expected_events!( Self, vec![ // Dispatchable is properly executed and XCM message sent [<$chain RuntimeEvent>]::::XcmPallet( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete { used: weight, error } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), expected_weight.unwrap_or(*weight), *weight ), - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); @@ -365,7 +366,7 @@ macro_rules! impl_send_transact_helpers_for_relay_chain { ::execute_with(|| { let root_origin = ::RuntimeOrigin::root(); - let destination: $crate::impls::MultiLocation = ::child_location_of(recipient); + let destination: $crate::impls::Location = ::child_location_of(recipient); let xcm = $crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Superuser); // Send XCM `Transact` @@ -416,13 +417,13 @@ macro_rules! impl_accounts_helpers_for_parachain { network_id: $crate::impls::NetworkId, para_id: $crate::impls::ParaId, ) -> $crate::impls::AccountId { - let remote_location = $crate::impls::MultiLocation { - parents: 2, - interior: $crate::impls::Junctions::X2( + let remote_location = $crate::impls::Location::new( + 2, + [ $crate::impls::Junction::GlobalConsensus(network_id), $crate::impls::Junction::Parachain(para_id.into()), - ), - }; + ], + ); ::execute_with(|| { Self::sovereign_account_id_of(remote_location) }) @@ -445,7 +446,7 @@ macro_rules! impl_assert_events_helpers_for_parachain { Self, vec![ [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete { used: weight } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), @@ -460,36 +461,36 @@ macro_rules! impl_assert_events_helpers_for_parachain { /// Asserts a dispatchable is incompletely executed and XCM sent pub fn assert_xcm_pallet_attempted_incomplete( expected_weight: Option<$crate::impls::Weight>, - expected_error: Option<$crate::impls::Error>, + expected_error: Option<$crate::impls::XcmError>, ) { $crate::impls::assert_expected_events!( Self, vec![ // Dispatchable is properly executed and XCM message sent [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete { used: weight, error } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), expected_weight.unwrap_or(*weight), *weight ), - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); } /// Asserts a dispatchable throws and error when trying to be sent - pub fn assert_xcm_pallet_attempted_error(expected_error: Option<$crate::impls::Error>) { + pub fn assert_xcm_pallet_attempted_error(expected_error: Option<$crate::impls::XcmError>) { $crate::impls::assert_expected_events!( Self, vec![ // Execution fails in the origin with `Barrier` [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error(error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error { error } } ) => { - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); @@ -639,7 +640,7 @@ macro_rules! impl_assets_helpers_for_parachain { ::execute_with(|| { $crate::impls::assert_ok!(]>::Assets::mint( signed_origin, - id.into(), + id.clone().into(), beneficiary.clone().into(), amount_to_mint )); @@ -717,7 +718,7 @@ macro_rules! impl_assets_helpers_for_parachain { ] ); - assert!(]>::Assets::asset_exists(id.into())); + assert!(]>::Assets::asset_exists(id.clone().into())); }); } } @@ -732,7 +733,7 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { impl $chain { /// Create foreign assets using sudo `ForeignAssets::force_create()` pub fn force_create_foreign_asset( - id: $crate::impls::MultiLocation, + id: $crate::impls::v3::Location, owner: $crate::impls::AccountId, is_sufficient: bool, min_balance: u128, @@ -744,13 +745,13 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { $crate::impls::assert_ok!( ]>::ForeignAssets::force_create( sudo_origin, - id, + id.clone(), owner.clone().into(), is_sufficient, min_balance, ) ); - assert!(]>::ForeignAssets::asset_exists(id)); + assert!(]>::ForeignAssets::asset_exists(id.clone())); type RuntimeEvent = <$chain as $crate::impls::Chain>::RuntimeEvent; $crate::impls::assert_expected_events!( Self, @@ -767,21 +768,21 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { for (beneficiary, amount) in prefund_accounts.into_iter() { let signed_origin = <$chain as $crate::impls::Chain>::RuntimeOrigin::signed(owner.clone()); - Self::mint_foreign_asset(signed_origin, id, beneficiary, amount); + Self::mint_foreign_asset(signed_origin, id.clone(), beneficiary, amount); } } /// Mint assets making use of the ForeignAssets pallet-assets instance pub fn mint_foreign_asset( signed_origin: ::RuntimeOrigin, - id: $crate::impls::MultiLocation, + id: $crate::impls::v3::Location, beneficiary: $crate::impls::AccountId, amount_to_mint: u128, ) { ::execute_with(|| { $crate::impls::assert_ok!(]>::ForeignAssets::mint( signed_origin, - id.into(), + id.clone().into(), beneficiary.clone().into(), amount_to_mint )); @@ -813,7 +814,7 @@ macro_rules! impl_xcm_helpers_for_parachain { $crate::impls::paste::paste! { impl $chain { /// Set XCM version for destination. - pub fn force_xcm_version(dest: $crate::impls::MultiLocation, version: $crate::impls::XcmVersion) { + pub fn force_xcm_version(dest: $crate::impls::Location, version: $crate::impls::XcmVersion) { ::execute_with(|| { $crate::impls::assert_ok!(]>::PolkadotXcm::force_xcm_version( ::RuntimeOrigin::root(), diff --git a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs index 48ee1a3b7808..ad69d5576aae 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs @@ -40,6 +40,7 @@ use polkadot_service::chain_spec::get_authority_keys_from_seed_no_beefy; pub const XCM_V2: u32 = 2; pub const XCM_V3: u32 = 3; +pub const XCM_V4: u32 = 4; pub const REF_TIME_THRESHOLD: u64 = 33; pub const PROOF_SIZE_THRESHOLD: u64 = 33; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs index 8718f1e83a00..01a376e4dbf8 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs @@ -48,7 +48,7 @@ macro_rules! test_parachain_is_trusted_teleporter { <$receiver_para as $crate::macros::Chain>::account_data_of(receiver.clone()).free; let para_destination = <$sender_para>::sibling_location_of(<$receiver_para>::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = $crate::macros::AccountId32 { network: None, id: receiver.clone().into() }.into(); // Send XCM message from Origin Parachain @@ -57,8 +57,8 @@ macro_rules! test_parachain_is_trusted_teleporter { <$sender_para>::execute_with(|| { assert_ok!(<$sender_para as [<$sender_para Pallet>]>::PolkadotXcm::limited_teleport_assets( origin.clone(), - bx!(para_destination.into()), - bx!(beneficiary.into()), + bx!(para_destination.clone().into()), + bx!(beneficiary.clone().into()), bx!($assets.clone().into()), fee_asset_item, weight_limit.clone(), @@ -127,8 +127,8 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { $crate::impls::paste::paste! { pub fn penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal: u32, - foreign_asset_at_asset_hub: MultiLocation, - ah_as_seen_by_penpal: MultiLocation, + foreign_asset_at_asset_hub: v3::Location, + ah_as_seen_by_penpal: Location, is_sufficient: bool, asset_owner: AccountId, prefund_amount: u128, @@ -144,14 +144,14 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { // prefund SA of Penpal on AssetHub with enough native tokens to pay for creating // new foreign asset, also prefund CheckingAccount with ED, because teleported asset // itself might not be sufficient and CheckingAccount cannot be created otherwise - let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah); + let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah.clone()); $asset_hub::fund_accounts(vec![ (sov_penpal_on_ah.clone().into(), $relay_ed * 100_000_000_000), (ah_check_account.clone().into(), $relay_ed * 1000), ]); // prefund SA of AssetHub on Penpal with native asset - let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal); + let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal.clone()); $penpal::fund_accounts(vec![ (sov_ah_on_penpal.into(), $relay_ed * 1_000_000_000), (penpal_check_account.clone().into(), $relay_ed * 1000), @@ -183,8 +183,8 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { let buy_execution_fee_amount = $weight_to_fee::weight_to_fee( &Weight::from_parts(10_100_000_000_000, 300_000), ); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + let buy_execution_fee = Asset { + id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(buy_execution_fee_amount), }; let xcm = VersionedXcm::from(Xcm(vec![ 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 70a9408c3097..25e1cffad543 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs @@ -23,12 +23,12 @@ use xcm::{prelude::*, DoubleEncoded}; pub fn xcm_transact_paid_execution( call: DoubleEncoded<()>, origin_kind: OriginKind, - native_asset: MultiAsset, + native_asset: Asset, beneficiary: AccountId, ) -> VersionedXcm<()> { let weight_limit = WeightLimit::Unlimited; let require_weight_at_most = Weight::from_parts(1000000000, 200000); - let native_assets: MultiAssets = native_asset.clone().into(); + let native_assets: Assets = native_asset.clone().into(); VersionedXcm::from(Xcm(vec![ WithdrawAsset(native_assets), @@ -37,9 +37,9 @@ pub fn xcm_transact_paid_execution( RefundSurplus, DepositAsset { assets: All.into(), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { network: None, id: beneficiary.into() }), + interior: [AccountId32 { network: None, id: beneficiary.into() }].into(), }, }, ])) @@ -61,15 +61,11 @@ 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: &MultiAssets, fee_idx: usize) -> Option<(MultiLocation, u128)> { +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(); - let asset_id = match asset.id { - Concrete(id) => id, - _ => return None, - }; let asset_amount = match asset.fun { Fungible(amount) => amount, _ => return None, }; - Some((asset_id, asset_amount)) + Some((asset.id.0, asset_amount)) } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs index 721f8b511ea6..155c952327aa 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs @@ -26,7 +26,7 @@ pub use frame_support::{ // Polkadot pub use xcm::{ prelude::{AccountId32 as AccountId32Junction, *}, - v3::{Error, NetworkId::Rococo as RococoId}, + v3::{self, Error, NetworkId::Rococo as RococoId}, }; // Cumulus 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 24a71d3fb45a..dfc0bc6ff392 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 @@ -30,7 +30,7 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == Rococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -53,7 +53,7 @@ fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -130,7 +130,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { asset_id: *asset_id == ASSET_ID, from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -190,10 +190,10 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn reserve_transfer_native_asset_from_relay_to_system_para_fails() { let signed_origin = ::RuntimeOrigin::signed(RococoSender::get().into()); let destination = Rococo::child_location_of(AssetHubRococo::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); let amount_to_send: Balance = ROCOCO_ED * 1000; - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -225,11 +225,11 @@ fn reserve_transfer_native_asset_from_system_para_to_relay_fails() { ::RuntimeOrigin::signed(AssetHubRococoSender::get().into()); let destination = AssetHubRococo::parent_location(); let beneficiary_id = RococoReceiver::get(); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: beneficiary_id.into() }.into(); let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000; - let assets: MultiAssets = (Parent, amount_to_send).into(); + let assets: Assets = (Parent, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -418,9 +418,9 @@ fn reserve_transfer_assets_from_system_para_to_para() { let beneficiary_id = PenpalAReceiver::get(); let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let assets: MultiAssets = vec![ + let assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send) + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], asset_amount_to_send) .into(), ] .into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs index 8faba50fc888..7d630d368051 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs @@ -19,14 +19,13 @@ use crate::*; fn relay_sets_system_para_xcm_supported_version() { // Init tests variables let sudo_origin = ::RuntimeOrigin::root(); - let system_para_destination: MultiLocation = - Rococo::child_location_of(AssetHubRococo::para_id()); + let system_para_destination: Location = Rococo::child_location_of(AssetHubRococo::para_id()); // Relay Chain sets supported version for Asset Parachain Rococo::execute_with(|| { assert_ok!(::XcmPallet::force_xcm_version( sudo_origin, - bx!(system_para_destination), + bx!(system_para_destination.clone()), XCM_V3 )); @@ -52,7 +51,7 @@ fn system_para_sets_relay_xcm_supported_version() { ::RuntimeCall::PolkadotXcm(pallet_xcm::Call::< ::Runtime, >::force_xcm_version { - location: bx!(parent_location), + location: bx!(parent_location.clone()), version: XCM_V3, }) .encode() diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs index b1af69a1cd10..d6aade68086d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs @@ -15,16 +15,19 @@ use crate::*; use parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT; -use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; use sp_runtime::ModuleError; #[test] fn swap_locally_on_chain_using_local_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let asset_one = MultiLocation { - parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), - }; + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); + let asset_one = Box::new(v3::Location::new( + 0, + [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ], + )); AssetHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -46,8 +49,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), )); assert_expected_events!( @@ -59,8 +62,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -75,7 +78,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![Box::new(asset_native), Box::new(asset_one)]; + let path = vec![asset_native.clone(), asset_one.clone()]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -100,8 +103,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native, + asset_one, 1414213562273 - EXISTENTIAL_DEPOSIT * 2, // all but the 2 EDs can't be retrieved. 0, 0, @@ -112,16 +115,16 @@ fn swap_locally_on_chain_using_local_assets() { #[test] fn swap_locally_on_chain_using_foreign_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalASender::get(); let foreign_asset_at_asset_hub_rococo = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalA::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); @@ -167,7 +170,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 4. Create pool: assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), )); @@ -181,7 +184,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 5. Add liquidity: assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), 1_000_000_000_000, 2_000_000_000_000, @@ -200,7 +203,7 @@ fn swap_locally_on_chain_using_foreign_assets() { ); // 6. Swap! - let path = vec![Box::new(asset_native), Box::new(foreign_asset_at_asset_hub_rococo)]; + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo)]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -226,7 +229,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 7. Remove liquidity assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, @@ -238,9 +241,11 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let mut asset_one = asset_hub_rococo_runtime::xcm_config::PoolAssetsPalletLocation::get(); - asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets"); + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); + let mut asset_one = asset_hub_rococo_runtime::xcm_config::PoolAssetsPalletLocationV3::get(); + asset_one + .append_with(v3::Junction::GeneralIndex(ASSET_ID.into())) + .expect("pool assets"); AssetHubRococo::execute_with(|| { let pool_owner_account_id = asset_hub_rococo_runtime::AssetConversionOrigin::get(); @@ -263,7 +268,7 @@ fn cannot_create_pool_from_pool_assets() { assert_matches::assert_matches!( ::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), + asset_native, Box::new(asset_one), ), Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) @@ -273,10 +278,14 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let asset_one = MultiLocation { + let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get(); + let asset_one = xcm::v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), }; let penpal = AssetHubRococo::sovereign_account_id_of(AssetHubRococo::sibling_location_of( PenpalA::para_id(), @@ -365,8 +374,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { let penpal_root = ::RuntimeOrigin::root(); let fee_amount = 4_000_000_000_000u128; let asset_one = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) - .into(); + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); let asset_hub_location = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); let xcm = xcm_transact_paid_execution( call, 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 a07463cec50e..218234cc78ea 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 @@ -17,7 +17,7 @@ use crate::*; use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig; use emulated_integration_tests_common::xcm_helpers::non_fee_asset; use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig; -use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; fn relay_origin_assertions(t: RelayToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -143,6 +143,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { ); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -157,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { who: *who == t.receiver.account_id, }, RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.receiver.account_id, amount: *amount == expected_foreign_asset_amount, }, @@ -174,6 +175,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { 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 expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -183,13 +185,13 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, // foreign asset is burned locally as part of teleportation RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.sender.account_id, balance: *balance == expected_foreign_asset_amount, }, @@ -542,7 +544,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() { #[test] fn teleport_to_other_system_parachains_works() { let amount = ASSET_HUB_ROCOCO_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin @@ -557,20 +559,20 @@ fn teleport_to_other_system_parachains_works() { #[test] fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalASender::get(); let foreign_asset_at_asset_hub_rococo = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalA::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); super::penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal, foreign_asset_at_asset_hub_rococo, - ah_as_seen_by_penpal, + ah_as_seen_by_penpal.clone(), false, asset_owner_on_penpal, ASSET_MIN_BALANCE * 1_000_000, @@ -580,9 +582,10 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 10_000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let penpal_assets: MultiAssets = vec![ + let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap(); + let penpal_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (asset_location_on_penpal, asset_amount_to_send).into(), + (asset_location_on_penpal_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = penpal_assets @@ -670,11 +673,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { )); }); + let foreign_asset_at_asset_hub_rococo_latest: Location = + foreign_asset_at_asset_hub_rococo.try_into().unwrap(); let ah_to_penpal_beneficiary_id = PenpalAReceiver::get(); let penpal_as_seen_by_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id()); - let ah_assets: MultiAssets = vec![ + let ah_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (foreign_asset_at_asset_hub_rococo, asset_amount_to_send).into(), + (foreign_asset_at_asset_hub_rococo_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = ah_assets diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs index fbeb08649e78..018e948e5d76 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs @@ -28,7 +28,7 @@ pub use frame_support::{ // Polkadot pub use xcm::{ prelude::{AccountId32 as AccountId32Junction, *}, - v3::{Error, NetworkId::Westend as WestendId}, + v3::{self, Error, NetworkId::Westend as WestendId}, }; // Cumulus diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs index d7de0a451f20..11e1e1762dbb 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs @@ -24,22 +24,20 @@ fn create_and_claim_treasury_spend() { const ASSET_ID: u32 = 1984; const SPEND_AMOUNT: u128 = 1_000_000; // treasury location from a sibling parachain. - let treasury_location: MultiLocation = MultiLocation::new( - 1, - X2(Parachain(CollectivesWestend::para_id().into()), PalletInstance(65)), - ); + let treasury_location: Location = + Location::new(1, [Parachain(CollectivesWestend::para_id().into()), PalletInstance(65)]); // treasury account on a sibling parachain. let treasury_account = asset_hub_westend_runtime::xcm_config::LocationToAccountId::convert_location( &treasury_location, ) .unwrap(); - let asset_hub_location = MultiLocation::new(1, Parachain(AssetHubWestend::para_id().into())); + let asset_hub_location = Location::new(1, [Parachain(AssetHubWestend::para_id().into())]); let root = ::RuntimeOrigin::root(); // asset kind to be spent from the treasury. - let asset_kind = VersionedLocatableAsset::V3 { + let asset_kind = VersionedLocatableAsset::V4 { location: asset_hub_location, - asset_id: AssetId::Concrete((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), + asset_id: AssetId((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), }; // treasury spend beneficiary. let alice: AccountId = Westend::account_id_of(ALICE); @@ -75,7 +73,7 @@ fn create_and_claim_treasury_spend() { root, Box::new(asset_kind), SPEND_AMOUNT, - Box::new(MultiLocation::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), None, )); // claim the spend. 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 3cce6c4417ea..a2934be97580 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 @@ -32,7 +32,7 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == Westend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -57,7 +57,7 @@ fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -140,7 +140,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { asset_id: *asset_id == ASSET_ID, from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -200,10 +200,10 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn reserve_transfer_native_asset_from_relay_to_system_para_fails() { let signed_origin = ::RuntimeOrigin::signed(WestendSender::get().into()); let destination = Westend::child_location_of(AssetHubWestend::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); let amount_to_send: Balance = WESTEND_ED * 1000; - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -235,10 +235,10 @@ fn reserve_transfer_native_asset_from_system_para_to_relay_fails() { ::RuntimeOrigin::signed(AssetHubWestendSender::get().into()); let destination = AssetHubWestend::parent_location(); let beneficiary_id = WestendReceiver::get(); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: beneficiary_id.into() }.into(); let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000; - let assets: MultiAssets = (Parent, amount_to_send).into(); + let assets: Assets = (Parent, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -428,9 +428,9 @@ fn reserve_transfer_assets_from_system_para_to_para() { let beneficiary_id = PenpalBReceiver::get(); let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let assets: MultiAssets = vec![ + let assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send) + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], asset_amount_to_send) .into(), ] .into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs index 2133d5e5fb7c..130454551d2c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs @@ -19,14 +19,13 @@ use crate::*; fn relay_sets_system_para_xcm_supported_version() { // Init tests variables let sudo_origin = ::RuntimeOrigin::root(); - let system_para_destination: MultiLocation = - Westend::child_location_of(AssetHubWestend::para_id()); + let system_para_destination: Location = Westend::child_location_of(AssetHubWestend::para_id()); // Relay Chain sets supported version for Asset Parachain Westend::execute_with(|| { assert_ok!(::XcmPallet::force_xcm_version( sudo_origin, - bx!(system_para_destination), + bx!(system_para_destination.clone()), XCM_V3 )); @@ -52,7 +51,7 @@ fn system_para_sets_relay_xcm_supported_version() { ::RuntimeCall::PolkadotXcm(pallet_xcm::Call::< ::Runtime, >::force_xcm_version { - location: bx!(parent_location), + location: bx!(parent_location.clone()), version: XCM_V3, }) .encode() diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs index c768a1366faf..b39cc2159de8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs @@ -14,15 +14,19 @@ // limitations under the License. use crate::*; -use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; #[test] fn swap_locally_on_chain_using_local_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let asset_one = MultiLocation { + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); + let asset_one = Box::new(v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), - }; + interior: [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), + }); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -44,8 +48,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), )); assert_expected_events!( @@ -57,8 +61,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -73,7 +77,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![Box::new(asset_native), Box::new(asset_one)]; + let path = vec![asset_native.clone(), asset_one.clone()]; assert_ok!(::AssetConversion::swap_exact_tokens_for_tokens( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), @@ -96,8 +100,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, 0, @@ -108,16 +112,16 @@ fn swap_locally_on_chain_using_local_assets() { #[test] fn swap_locally_on_chain_using_foreign_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalBSender::get(); let foreign_asset_at_asset_hub_westend = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalB::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); @@ -163,7 +167,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 4. Create pool: assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), )); @@ -177,7 +181,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 5. Add liquidity: assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), 1_000_000_000_000, 2_000_000_000_000, @@ -196,7 +200,7 @@ fn swap_locally_on_chain_using_foreign_assets() { ); // 6. Swap! - let path = vec![Box::new(asset_native), Box::new(foreign_asset_at_asset_hub_westend)]; + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend)]; assert_ok!(::AssetConversion::swap_exact_tokens_for_tokens( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), @@ -220,7 +224,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 7. Remove liquidity assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, @@ -232,9 +236,11 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let mut asset_one = asset_hub_westend_runtime::xcm_config::PoolAssetsPalletLocation::get(); - asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets"); + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); + let mut asset_one = asset_hub_westend_runtime::xcm_config::PoolAssetsPalletLocationV3::get(); + asset_one + .append_with(v3::Junction::GeneralIndex(ASSET_ID.into())) + .expect("pool assets"); AssetHubWestend::execute_with(|| { let pool_owner_account_id = asset_hub_westend_runtime::AssetConversionOrigin::get(); @@ -257,7 +263,7 @@ fn cannot_create_pool_from_pool_assets() { assert_matches::assert_matches!( ::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), + asset_native, Box::new(asset_one), ), Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) @@ -267,10 +273,14 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let asset_one = MultiLocation { + let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocationV3::get(); + let asset_one = xcm::v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), }; let penpal = AssetHubWestend::sovereign_account_id_of(AssetHubWestend::sibling_location_of( PenpalB::para_id(), @@ -359,8 +369,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { let penpal_root = ::RuntimeOrigin::root(); let fee_amount = 4_000_000_000_000u128; let asset_one = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) - .into(); + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); let asset_hub_location = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); let xcm = xcm_transact_paid_execution( call, 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 27a6e7aaaf43..01498f7bb4e3 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 @@ -17,7 +17,7 @@ use crate::*; use asset_hub_westend_runtime::xcm_config::XcmConfig as AssetHubWestendXcmConfig; use emulated_integration_tests_common::xcm_helpers::non_fee_asset; use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig; -use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; fn relay_origin_assertions(t: RelayToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -143,6 +143,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { ); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -157,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { who: *who == t.receiver.account_id, }, RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.receiver.account_id, amount: *amount == expected_foreign_asset_amount, }, @@ -174,6 +175,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { 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(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -183,13 +185,13 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, // foreign asset is burned locally as part of teleportation RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.sender.account_id, balance: *balance == expected_foreign_asset_amount, }, @@ -542,7 +544,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() { #[test] fn teleport_to_other_system_parachains_works() { let amount = ASSET_HUB_WESTEND_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin @@ -557,20 +559,20 @@ fn teleport_to_other_system_parachains_works() { #[test] fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalBSender::get(); let foreign_asset_at_asset_hub_westend = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalB::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); super::penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal, foreign_asset_at_asset_hub_westend, - ah_as_seen_by_penpal, + ah_as_seen_by_penpal.clone(), false, asset_owner_on_penpal, ASSET_MIN_BALANCE * 1_000_000, @@ -580,9 +582,10 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let penpal_assets: MultiAssets = vec![ + let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap(); + let penpal_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (asset_location_on_penpal, asset_amount_to_send).into(), + (asset_location_on_penpal_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = penpal_assets @@ -670,11 +673,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { )); }); + let foreign_asset_at_asset_hub_westend_latest: Location = + foreign_asset_at_asset_hub_westend.try_into().unwrap(); let ah_to_penpal_beneficiary_id = PenpalBReceiver::get(); let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalB::para_id()); - let ah_assets: MultiAssets = vec![ + let ah_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (foreign_asset_at_asset_hub_westend, asset_amount_to_send).into(), + (foreign_asset_at_asset_hub_westend_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = ah_assets diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs index 32089f7ecec0..8e82059a32d1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs @@ -24,19 +24,19 @@ fn create_and_claim_treasury_spend() { const ASSET_ID: u32 = 1984; const SPEND_AMOUNT: u128 = 1_000_000; // treasury location from a sibling parachain. - let treasury_location: MultiLocation = MultiLocation::new(1, PalletInstance(37)); + let treasury_location: Location = Location::new(1, PalletInstance(37)); // treasury account on a sibling parachain. let treasury_account = asset_hub_westend_runtime::xcm_config::LocationToAccountId::convert_location( &treasury_location, ) .unwrap(); - let asset_hub_location = MultiLocation::new(0, Parachain(AssetHubWestend::para_id().into())); + let asset_hub_location = Location::new(0, Parachain(AssetHubWestend::para_id().into())); let root = ::RuntimeOrigin::root(); // asset kind to be spend from the treasury. - let asset_kind = VersionedLocatableAsset::V3 { + let asset_kind = VersionedLocatableAsset::V4 { location: asset_hub_location, - asset_id: AssetId::Concrete((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), + asset_id: AssetId([PalletInstance(50), GeneralIndex(ASSET_ID.into())].into()), }; // treasury spend beneficiary. let alice: AccountId = Westend::account_id_of(ALICE); @@ -71,7 +71,7 @@ fn create_and_claim_treasury_spend() { root, Box::new(asset_kind), SPEND_AMOUNT, - Box::new(MultiLocation::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), None, )); // claim the spend. diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index 608aa388ce81..0039eb087fe0 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -22,7 +22,7 @@ pub use xcm::{ latest::ParentThen, prelude::{AccountId32 as AccountId32Junction, *}, v3::{ - Error, + self, Error, NetworkId::{Rococo as RococoId, Westend as WestendId}, }, }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs index 8b5a72a8e62c..a203de0f8c93 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs @@ -15,14 +15,14 @@ use crate::tests::*; -fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amount: u128) { +fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: Location, amount: u128) { let destination = asset_hub_westend_location(); // fund the AHR's SA on BHR for paying bridge transport fees BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128); // set XCM versions - AssetHubRococo::force_xcm_version(destination, XCM_VERSION); + AssetHubRococo::force_xcm_version(destination.clone(), XCM_VERSION); BridgeHubRococo::force_xcm_version(bridge_hub_westend_location(), XCM_VERSION); // send message over bridge @@ -33,9 +33,9 @@ fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amou #[test] fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { - let roc_at_asset_hub_rococo: MultiLocation = Parent.into(); + let roc_at_asset_hub_rococo: v3::Location = v3::Parent.into(); let roc_at_asset_hub_westend = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubWestend::force_create_foreign_asset( roc_at_asset_hub_westend, @@ -62,7 +62,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(roc_at_asset_hub_westend), )); @@ -75,7 +75,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(roc_at_asset_hub_westend), 1_000_000_000_000, 2_000_000_000_000, @@ -101,8 +101,9 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { >::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get()) }); + let roc_at_asset_hub_rococo_latest: Location = roc_at_asset_hub_rococo.try_into().unwrap(); let amount = ASSET_HUB_ROCOCO_ED * 1_000_000; - send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount); + send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo_latest, amount); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( @@ -142,7 +143,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() { let prefund_amount = 10_000_000_000_000u128; let wnd_at_asset_hub_rococo = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubRococo::force_create_foreign_asset( wnd_at_asset_hub_rococo, @@ -170,8 +171,12 @@ fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() { let receiver_wnds_before = ::account_data_of(AssetHubWestendReceiver::get()).free; + let wnd_at_asset_hub_rococo_latest: Location = wnd_at_asset_hub_rococo.try_into().unwrap(); let amount_to_send = ASSET_HUB_WESTEND_ED * 1_000; - send_asset_from_asset_hub_rococo_to_asset_hub_westend(wnd_at_asset_hub_rococo, amount_to_send); + send_asset_from_asset_hub_rococo_to_asset_hub_westend( + wnd_at_asset_hub_rococo_latest.clone(), + amount_to_send, + ); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs index e71a022af4cf..a33d2fab7536 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs @@ -20,37 +20,31 @@ mod send_xcm; mod snowbridge; mod teleport; -pub(crate) fn asset_hub_westend_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Westend), - Parachain(AssetHubWestend::para_id().into()), - ), - } +pub(crate) fn asset_hub_westend_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Westend), Parachain(AssetHubWestend::para_id().into())], + ) } -pub(crate) fn bridge_hub_westend_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Westend), - Parachain(BridgeHubWestend::para_id().into()), - ), - } +pub(crate) fn bridge_hub_westend_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Westend), Parachain(BridgeHubWestend::para_id().into())], + ) } pub(crate) fn send_asset_from_asset_hub_rococo( - destination: MultiLocation, - (id, amount): (MultiLocation, u128), + destination: Location, + (id, amount): (Location, u128), ) -> DispatchResult { let signed_origin = ::RuntimeOrigin::signed(AssetHubRococoSender::get().into()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); - let assets: MultiAssets = (id, amount).into(); + let assets: Assets = (id, amount).into(); let fee_asset_item = 0; AssetHubRococo::execute_with(|| { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs index a3a7d96a14ae..a1d871cdb618 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs @@ -29,8 +29,8 @@ fn send_xcm_from_rococo_relay_to_westend_asset_hub_should_fail_on_not_applicable let xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit, check_origin }, ExportMessage { - network: WestendId, - destination: X1(Parachain(AssetHubWestend::para_id().into())), + network: WestendId.into(), + destination: [Parachain(AssetHubWestend::para_id().into())].into(), xcm: remote_xcm, }, ])); @@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // prepare data let destination = asset_hub_westend_location(); - let native_token = MultiLocation::parent(); + let native_token = Location::parent(); let amount = ASSET_HUB_ROCOCO_ED * 1_000; // fund the AHR's SA on BHR for paying bridge transport fees @@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // send XCM from AssetHubRococo - fails - destination version not known assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // set destination version - AssetHubRococo::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION); + AssetHubRococo::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION); // TODO: remove this block, when removing `xcm:v2` { @@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // version, which does not have the `ExportMessage` instruction. If the default `2` is // changed to `3`, then this assert can go away" assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubRococo - fails - `ExportMessage` is not in `2` assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { xcm::v3::prelude::XCM_VERSION, ); // send XCM from AssetHubRococo - ok - assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_rococo( + destination.clone(), + (native_token.clone(), amount) + )); // `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known assert_bridge_hub_rococo_message_accepted(false); @@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubRococo - ok - assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_rococo( + destination.clone(), + (native_token.clone(), amount) + )); assert_bridge_hub_rococo_message_accepted(true); assert_bridge_hub_westend_message_received(); // message delivered and processed at destination diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 85547f210a7c..fe0e479d8e5c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -61,7 +61,7 @@ fn create_agent() { let remote_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -109,14 +109,14 @@ fn create_channel() { BridgeHubRococo::fund_para_sovereign(origin_para.into(), INITIAL_FUND); let sudo_origin = ::RuntimeOrigin::root(); - let destination: VersionedMultiLocation = + let destination: VersionedLocation = Rococo::child_location_of(BridgeHubRococo::para_id()).into(); let create_agent_call = SnowbridgeControl::Control(ControlCall::CreateAgent {}); let create_agent_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -129,7 +129,7 @@ fn create_channel() { let create_channel_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -218,10 +218,10 @@ fn register_weth_token_from_ethereum_to_asset_hub() { #[test] fn send_token_from_ethereum_to_penpal() { - let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation { - parents: 1, - interior: X1(Parachain(AssetHubRococo::para_id().into())), - }); + let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new( + 1, + [Parachain(AssetHubRococo::para_id().into())], + )); BridgeHubRococo::fund_accounts(vec![(asset_hub_sovereign.clone(), INITIAL_FUND)]); PenpalA::fund_accounts(vec![ @@ -229,9 +229,9 @@ fn send_token_from_ethereum_to_penpal() { (PenpalASender::get(), INITIAL_FUND), ]); - let weth_asset_location: MultiLocation = + let weth_asset_location: Location = (Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into(); - let weth_asset_id = weth_asset_location.into(); + let weth_asset_id: v3::Location = weth_asset_location.try_into().unwrap(); let origin_location = (Parent, Parent, EthereumNetwork::get()).into(); @@ -375,18 +375,15 @@ fn send_token_from_ethereum_to_asset_hub() { #[test] fn send_weth_asset_from_asset_hub_to_ethereum() { use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee; - let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation { - parents: 1, - interior: X1(Parachain(AssetHubRococo::para_id().into())), - }); + let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new( + 1, + [Parachain(AssetHubRococo::para_id().into())], + )); AssetHubRococo::force_default_xcm_version(Some(XCM_VERSION)); BridgeHubRococo::force_default_xcm_version(Some(XCM_VERSION)); AssetHubRococo::force_xcm_version( - MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })), - }, + Location::new(2, [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })]), XCM_VERSION, ); @@ -437,27 +434,27 @@ fn send_weth_asset_from_asset_hub_to_ethereum() { RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, ] ); - let assets = vec![MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X2( + let assets = vec![Asset { + id: AssetId(Location::new( + 2, + [ GlobalConsensus(Ethereum { chain_id: CHAIN_ID }), AccountKey20 { network: None, key: WETH }, - ), - }), + ], + )), fun: Fungible(WETH_AMOUNT), }]; - let multi_assets = VersionedMultiAssets::V3(MultiAssets::from(assets)); + let multi_assets = VersionedAssets::V4(Assets::from(assets)); - let destination = VersionedMultiLocation::V3(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })), - }); + let destination = VersionedLocation::V4(Location::new( + 2, + [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })], + )); - let beneficiary = VersionedMultiLocation::V3(MultiLocation { - parents: 0, - interior: X1(AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }), - }); + let beneficiary = VersionedLocation::V4(Location::new( + 0, + [AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }], + )); let free_balance_before = ::Balances::free_balance( AssetHubRococoReceiver::get(), 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 f00288a4d8c7..43f8af9244f5 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 @@ -19,7 +19,7 @@ use bridge_hub_rococo_runtime::xcm_config::XcmConfig; #[test] fn teleport_to_other_system_parachains_works() { let amount = BRIDGE_HUB_ROCOCO_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( BridgeHubRococo, // Origin diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs index 17255320f1de..223979cc9c9d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs @@ -21,7 +21,8 @@ pub use sp_runtime::DispatchError; pub use xcm::{ latest::ParentThen, prelude::{AccountId32 as AccountId32Junction, *}, - v3::{ + v3, + v4::{ Error, NetworkId::{Rococo as RococoId, Westend as WestendId}, }, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs index a4b2719e9fdd..c2a9c0089022 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs @@ -14,14 +14,14 @@ // limitations under the License. use crate::tests::*; -fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amount: u128) { +fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: Location, amount: u128) { let destination = asset_hub_rococo_location(); // fund the AHW's SA on BHW for paying bridge transport fees BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128); // set XCM versions - AssetHubWestend::force_xcm_version(destination, XCM_VERSION); + AssetHubWestend::force_xcm_version(destination.clone(), XCM_VERSION); BridgeHubWestend::force_xcm_version(bridge_hub_rococo_location(), XCM_VERSION); // send message over bridge @@ -32,9 +32,9 @@ fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amou #[test] fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { - let wnd_at_asset_hub_westend: MultiLocation = Parent.into(); + let wnd_at_asset_hub_westend: Location = Parent.into(); let wnd_at_asset_hub_rococo = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]); let owner: AccountId = AssetHubRococo::account_id_of(ALICE); AssetHubRococo::force_create_foreign_asset( wnd_at_asset_hub_rococo, @@ -61,7 +61,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(wnd_at_asset_hub_rococo), )); @@ -74,7 +74,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(wnd_at_asset_hub_rococo), 1_000_000_000_000, 2_000_000_000_000, @@ -141,7 +141,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() { let prefund_amount = 10_000_000_000_000u128; let roc_at_asset_hub_westend = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubWestend::force_create_foreign_asset( roc_at_asset_hub_westend, @@ -169,8 +169,12 @@ fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() { let receiver_rocs_before = ::account_data_of(AssetHubRococoReceiver::get()).free; + let roc_at_asset_hub_westend_latest: Location = roc_at_asset_hub_westend.try_into().unwrap(); let amount_to_send = ASSET_HUB_ROCOCO_ED * 1_000; - send_asset_from_asset_hub_westend_to_asset_hub_rococo(roc_at_asset_hub_westend, amount_to_send); + send_asset_from_asset_hub_westend_to_asset_hub_rococo( + roc_at_asset_hub_westend_latest.clone(), + amount_to_send, + ); AssetHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs index ec2e68fc8894..186b96b39769 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs @@ -19,37 +19,31 @@ mod asset_transfers; mod send_xcm; mod teleport; -pub(crate) fn asset_hub_rococo_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Rococo), - Parachain(AssetHubRococo::para_id().into()), - ), - } +pub(crate) fn asset_hub_rococo_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Rococo), Parachain(AssetHubRococo::para_id().into())], + ) } -pub(crate) fn bridge_hub_rococo_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Rococo), - Parachain(BridgeHubRococo::para_id().into()), - ), - } +pub(crate) fn bridge_hub_rococo_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Rococo), Parachain(BridgeHubRococo::para_id().into())], + ) } pub(crate) fn send_asset_from_asset_hub_westend( - destination: MultiLocation, - (id, amount): (MultiLocation, u128), + destination: Location, + (id, amount): (Location, u128), ) -> DispatchResult { let signed_origin = ::RuntimeOrigin::signed(AssetHubWestendSender::get().into()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); - let assets: MultiAssets = (id, amount).into(); + let assets: Assets = (id, amount).into(); let fee_asset_item = 0; AssetHubWestend::execute_with(|| { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs index 0773cbb05992..b01be5e8dc84 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs @@ -30,7 +30,7 @@ fn send_xcm_from_westend_relay_to_rococo_asset_hub_should_fail_on_not_applicable UnpaidExecution { weight_limit, check_origin }, ExportMessage { network: RococoId, - destination: X1(Parachain(AssetHubRococo::para_id().into())), + destination: [Parachain(AssetHubRococo::para_id().into())].into(), xcm: remote_xcm, }, ])); @@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // prepare data let destination = asset_hub_rococo_location(); - let native_token = MultiLocation::parent(); + let native_token = Location::parent(); let amount = ASSET_HUB_WESTEND_ED * 1_000; // fund the AHR's SA on BHR for paying bridge transport fees @@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // send XCM from AssetHubWestend - fails - destination version not known assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // set destination version - AssetHubWestend::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION); + AssetHubWestend::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION); // TODO: remove this block, when removing `xcm:v2` { @@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // version, which does not have the `ExportMessage` instruction. If the default `2` is // changed to `3`, then this assert can go away" assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubWestend - fails - `ExportMessage` is not in `2` assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { xcm::v3::prelude::XCM_VERSION, ); // send XCM from AssetHubWestend - ok - assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_westend( + destination.clone(), + (native_token.clone(), amount) + )); // `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known assert_bridge_hub_westend_message_accepted(false); @@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubWestend - ok - assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_westend( + destination.clone(), + (native_token.clone(), amount) + )); assert_bridge_hub_westend_message_accepted(true); assert_bridge_hub_rococo_message_received(); // message delivered and processed at destination 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 8dff6c292955..edffaf165960 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 @@ -19,7 +19,7 @@ use bridge_hub_westend_runtime::xcm_config::XcmConfig; #[test] fn teleport_to_other_system_parachains_works() { let amount = BRIDGE_HUB_WESTEND_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( BridgeHubWestend, // Origin diff --git a/cumulus/parachains/pallets/ping/src/lib.rs b/cumulus/parachains/pallets/ping/src/lib.rs index feda3d0b6f9f..a738c05e0366 100644 --- a/cumulus/parachains/pallets/ping/src/lib.rs +++ b/cumulus/parachains/pallets/ping/src/lib.rs @@ -77,9 +77,9 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - PingSent(ParaId, u32, Vec, XcmHash, MultiAssets), + PingSent(ParaId, u32, Vec, XcmHash, Assets), Pinged(ParaId, u32, Vec), - PongSent(ParaId, u32, Vec, XcmHash, MultiAssets), + PongSent(ParaId, u32, Vec, XcmHash, Assets), Ponged(ParaId, u32, Vec, BlockNumberFor), ErrorSendingPing(SendError, ParaId, u32, Vec), ErrorSendingPong(SendError, ParaId, u32, Vec), 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 8cfa4565187b..53b41892685c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -31,7 +31,7 @@ use assets_common::{ foreign_creators::ForeignCreators, local_and_foreign_assets::{LocalFromLeft, TargetFromLeft}, matching::{FromNetwork, FromSiblingParachain}, - AssetIdForTrustBackedAssetsConvert, MultiLocationForAssetId, + AssetIdForTrustBackedAssetsConvert, }; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; @@ -80,13 +80,11 @@ use parachains_common::{ Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; - use sp_runtime::{Perbill, RuntimeDebug}; -use xcm::opaque::v3::MultiLocation; use xcm_config::{ ForeignAssetsConvertedConcreteId, ForeignCreatorsSovereignAccountOf, GovernanceLocation, - PoolAssetsConvertedConcreteId, TokenLocation, TrustBackedAssetsConvertedConcreteId, - TrustBackedAssetsPalletLocation, + PoolAssetsConvertedConcreteId, TokenLocation, TokenLocationV3, + TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3, }; #[cfg(any(feature = "std", test))] @@ -95,7 +93,13 @@ pub use sp_runtime::BuildStorage; // Polkadot imports use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; -use xcm::latest::prelude::*; +// We exclude `Assets` since it's the name of a pallet +#[cfg(feature = "runtime-benchmarks")] +use xcm::latest::prelude::{ + Asset, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, + NonFungible, Parent, ParentThen, Response, XCM_VERSION, +}; +use xcm::latest::prelude::{AssetId, BodyId}; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; @@ -317,10 +321,11 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, + xcm::v3::Location, >, - MultiLocation, + xcm::v3::Location, AccountId, >; @@ -328,8 +333,8 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< pub type NativeAndAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, - TargetFromLeft, - MultiLocation, + TargetFromLeft, + xcm::v3::Location, AccountId, >; @@ -337,15 +342,15 @@ impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; - type AssetKind = MultiLocation; + type AssetKind = xcm::v3::Location; type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = - pallet_asset_conversion::WithFirstAsset; + pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam - type PoolSetupFeeAsset = TokenLocation; + type PoolSetupFeeAsset = TokenLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; @@ -355,9 +360,10 @@ impl pallet_asset_conversion::Config for Runtime { type WeightInfo = weights::pallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< - TokenLocation, + TokenLocationV3, parachain_info::Pallet, - xcm_config::AssetsPalletIndex, + xcm_config::TrustBackedAssetsPalletIndex, + xcm::v3::Location, >; } @@ -379,16 +385,17 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::MultiLocation; + type AssetIdParameter = xcm::v3::MultiLocation; type Currency = Balances; type CreateOrigin = ForeignCreators< ( - FromSiblingParachain>, - FromNetwork, + FromSiblingParachain, xcm::v3::Location>, + FromNetwork, ), ForeignCreatorsSovereignAccountOf, AccountId, + xcm::v3::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; @@ -664,7 +671,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -753,7 +760,7 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = - AssetConversionAdapter; + AssetConversionAdapter; } parameter_types! { @@ -1157,18 +1164,16 @@ impl_runtime_apis! { impl pallet_asset_conversion::AssetConversionApi< Block, Balance, - MultiLocation, + xcm::v3::Location, > for Runtime { - fn quote_price_exact_tokens_for_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_exact_tokens_for_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } - - fn quote_price_tokens_for_exact_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_tokens_for_exact_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } - - fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> { + fn get_reserves(asset1: xcm::v3::Location, asset2: xcm::v3::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } @@ -1222,7 +1227,7 @@ impl_runtime_apis! { AccountId, > for Runtime { - fn query_account_balances(account: AccountId) -> Result { + fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pallet_balance @@ -1346,45 +1351,45 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // AH can reserve transfer native token to some random parachain. let random_para_id = 43211234; ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( random_para_id.into() ); Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, ParentThen(Parachain(random_para_id).into()).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(xcm::v4::Assets, u32, Location, 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) let dest = Parent.into(); let fee_amount = EXISTENTIAL_DEPOSIT; - let fee_asset: MultiAsset = (MultiLocation::parent(), fee_amount).into(); + let fee_asset: Asset = (Location::parent(), fee_amount).into(); let who = frame_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit @@ -1402,13 +1407,13 @@ impl_runtime_apis! { Runtime, pallet_assets::Instance1 >(true, initial_asset_amount); - let asset_location = MultiLocation::new( + let asset_location = Location::new( 0, - X2(PalletInstance(50), GeneralIndex(u32::from(asset_id).into())) + [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); - let transfer_asset: MultiAsset = (asset_location, asset_amount).into(); + let transfer_asset: Asset = (asset_location, asset_amount).into(); - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset].into(); + let assets: xcm::v4::Assets = vec![fee_asset.clone(), transfer_asset].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully @@ -1432,14 +1437,14 @@ impl_runtime_apis! { xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } - fn ensure_bridged_target_destination() -> Result { + fn ensure_bridged_target_destination() -> Result { ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_westend::AssetHubWestend::get(); let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), - Box::new(bridged_asset_hub), + Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { log::error!( @@ -1455,12 +1460,11 @@ impl_runtime_apis! { } } - use xcm::latest::prelude::*; use xcm_config::{TokenLocation, MaxAssetsIntoHolding}; use pallet_xcm_benchmarks::asset_instance_from; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -1471,33 +1475,33 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(TokenLocation::get()) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> xcm::v4::Assets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles.saturating_sub(1); let fungibles_amount: u128 = 100; let mut assets = (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: GeneralIndex(i as u128).into(), fun: Fungible(fungibles_amount * i as u128), } }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: Here.into(), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: GeneralIndex(i as u128).into(), fun: NonFungible(asset_instance_from(i)), })) .collect::>(); - assets.push(MultiAsset { - id: Concrete(TokenLocation::get()), + assets.push(Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }); assets.into() @@ -1505,16 +1509,16 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( TokenLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; // AssetHubRococo trusts AssetHubWestend as reserve for WNDs - pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + pub TrustedReserve: Option<(Location, Asset)> = Some( ( xcm_config::bridging::to_westend::AssetHubWestend::get(), - MultiAsset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128)) + Asset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128)) ) ); } @@ -1526,9 +1530,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(UNITS), } } @@ -1542,42 +1546,42 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(xcm::v4::Assets, xcm::v4::Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() { Some(alias) => Ok(alias), None => Err(BenchmarkError::Skip) } } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(TokenLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, xcm::v4::Assets), BenchmarkError> { let origin = TokenLocation::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: xcm::v4::Assets = (TokenLocation::get(), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs index 2fbbd61654be..8e675ad0cf8e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct AssetHubRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for AssetHubRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,43 +107,35 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index f88d10664888..98b23efc06ec 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -20,12 +20,12 @@ use super::{ ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ - local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, + local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, matching::{FromNetwork, FromSiblingParachain, IsForeignConcreteAsset}, - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess, @@ -64,26 +64,32 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const TokenLocation: MultiLocation = MultiLocation::parent(); + pub const TokenLocation: Location = Location::parent(); + pub const TokenLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Rococo; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); - pub AssetsPalletIndex: u32 = ::index() as u32; - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(AssetsPalletIndex::get() as u8).into(); - pub ForeignAssetsPalletLocation: MultiLocation = + pub TrustBackedAssetsPalletLocation: Location = + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); + pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); - pub PoolAssetsPalletLocation: MultiLocation = + pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub PoolAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub const GovernanceLocation: Location = Location::parent(); pub StakingPot: AccountId = CollatorSelection::account_id(); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -110,7 +116,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -128,7 +134,7 @@ pub type FungiblesTransactor = FungiblesAdapter< Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -145,8 +151,8 @@ pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConverte // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore assets that start explicitly with our `GlobalConsensus(NetworkId)`, means: - // - foreign assets from our consensus should be: `MultiLocation {parents: 1, - // X*(Parachain(xyz), ..)}` + // - foreign assets from our consensus should be: `Location {parents: 1, X*(Parachain(xyz), + // ..)}` // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` won't // be accepted here StartsWithExplicitGlobalConsensus, @@ -160,7 +166,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -180,7 +186,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -195,20 +201,32 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); -/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`. -pub struct LocalAndForeignAssetsMultiLocationMatcher; -impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher { - fn is_local(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - TrustBackedAssetsConvertedConcreteId::contains(location) +/// Simple `Location` matcher for Local and Foreign asset `Location`. +pub struct LocalAndForeignAssetsLocationMatcher; +impl MatchesLocalAndForeignAssetsLocation + for LocalAndForeignAssetsLocationMatcher +{ + fn is_local(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + TrustBackedAssetsConvertedConcreteId::contains(&latest_location) } - fn is_foreign(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - ForeignAssetsConvertedConcreteId::contains(location) + fn is_foreign(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + ForeignAssetsConvertedConcreteId::contains(&latest_location) } } -impl Contains for LocalAndForeignAssetsMultiLocationMatcher { - fn contains(location: &MultiLocation) -> bool { +impl Contains for LocalAndForeignAssetsLocationMatcher { + fn contains(location: &xcm::v3::Location) -> bool { Self::is_local(location) || Self::is_foreign(location) } } @@ -243,11 +261,11 @@ parameter_types! { pub XcmAssetFeesReceiver: Option = Authorship::author(); } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -556,12 +574,12 @@ impl xcm_executor::Config for XcmConfig { type Trader = ( UsingComponents>, cumulus_primitives_utility::SwapFirstAssetTrader< - TokenLocation, + TokenLocationV3, crate::AssetConversion, WeightToFee, crate::NativeAndAssets, ( - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, @@ -588,7 +606,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -664,9 +682,9 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } @@ -698,7 +716,7 @@ pub mod bridging { pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID; - pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + pub SiblingBridgeHub: Location = Location::new(1, [Parachain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = TokenLocation::get().into(); @@ -722,25 +740,25 @@ pub mod bridging { use super::*; parameter_types! { - pub SiblingBridgeHubWithBridgeHubWestendInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithBridgeHubWestendInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX) - ) + ] ); pub const WestendNetwork: NetworkId = NetworkId::Westend; - pub AssetHubWestend: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(WestendNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID))); - pub WndLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(WestendNetwork::get()))); + pub AssetHubWestend: Location = Location::new(2, [GlobalConsensus(WestendNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID)]); + pub WndLocation: Location = Location::new(2, [GlobalConsensus(WestendNetwork::get())]); - pub WndFromAssetHubWestend: (MultiAssetFilter, MultiLocation) = ( - Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), + pub WndFromAssetHubWestend: (AssetFilter, Location) = ( + Wild(AllOf { fun: WildFungible, id: AssetId(WndLocation::get()) }), AssetHubWestend::get() ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( WestendNetwork::get(), @@ -757,15 +775,15 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithBridgeHubWestendInstance::get(), GlobalConsensus(WestendNetwork::get())) ] ); } - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -804,16 +822,16 @@ pub mod bridging { /// Polkadot uses 10 decimals, Kusama and Rococo 12 decimals. pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000; pub storage BridgeHubEthereumBaseFee: Balance = DefaultBridgeHubEthereumBaseFee::get(); - pub SiblingBridgeHubWithEthereumInboundQueueInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithEthereumInboundQueueInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(parachains_common::rococo::snowbridge::INBOUND_QUEUE_PALLET_INDEX) - ) + ] ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( EthereumNetwork::get(), @@ -827,7 +845,7 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithEthereumInboundQueueInstance::get(), GlobalConsensus(EthereumNetwork::get())), ] @@ -837,8 +855,8 @@ pub mod bridging { pub type IsTrustedBridgedReserveLocationForForeignAsset = matching::IsForeignConcreteAsset>; - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -850,7 +868,7 @@ pub mod bridging { #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { - pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_westend::UniversalAliases::get() .into_iter() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index c67374126d38..3da1a1e66bd8 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -19,12 +19,18 @@ use asset_hub_rococo_runtime::{ xcm_config, - xcm_config::{bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation}, + xcm_config::{ + bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation, + TokenLocationV3, + }, AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, }; pub use asset_hub_rococo_runtime::{ - xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + xcm_config::{ + CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + XcmConfig, + }, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, TrustBackedAssetsInstance, @@ -49,14 +55,18 @@ use parachains_common::{ }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; -use xcm::latest::prelude::*; -use xcm_executor::traits::{Identity, JustTry, WeightTrader}; +use xcm::latest::prelude::{Assets as XcmAssets, *}; +use xcm_builder::V4V3LocationConverter; +use xcm_executor::traits::{JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = - assets_common::AssetIdForTrustBackedAssetsConvert; + assets_common::AssetIdForTrustBackedAssetsConvert; + +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; type RuntimeHelper = asset_test_utils::RuntimeHelper; @@ -99,7 +109,7 @@ fn test_buy_and_refund_weight_in_native() { let fee = WeightToFee::weight_to_fee(&weight); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (native_location, fee + extra_amount).into(); + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -108,7 +118,7 @@ fn test_buy_and_refund_weight_in_native() { // assert. let unused_amount = - unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Balances::total_issuance(), total_issuance); @@ -144,7 +154,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); let asset_1: u32 = 1; - let native_location = TokenLocation::get(); + let native_location = TokenLocationV3::get(); let asset_1_location = AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); // bob's initial balance for native and `asset1` assets. @@ -180,6 +190,8 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let asset_total_issuance = Assets::total_issuance(asset_1); let native_total_issuance = Balances::total_issuance(); + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -187,7 +199,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -195,8 +207,10 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); @@ -210,7 +224,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -239,9 +253,15 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { .execute_with(|| { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); - let native_location = TokenLocation::get(); - let foreign_location = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let native_location = TokenLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; // bob's initial balance for native and `asset1` assets. let initial_balance = 200 * UNITS; // liquidity for both arms of (native, asset1) pool. @@ -280,6 +300,8 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); let native_total_issuance = Balances::total_issuance(); + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -287,7 +309,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -295,8 +317,10 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!( ForeignAssets::total_issuance(foreign_location), @@ -313,7 +337,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -343,19 +367,21 @@ fn test_assets_balances_api_works() { .build() .execute_with(|| { let local_asset_id = 1; - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let foreign_asset_id_location = xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(1234), xcm::v3::Junction::GeneralIndex(12345)], + ); // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 0 ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() - .try_as::() + .try_as::() .unwrap() .is_none()); @@ -386,7 +412,7 @@ fn test_assets_balances_api_works() { let foreign_asset_minimum_asset_balance = 3333333_u128; assert_ok!(ForeignAssets::force_create( RuntimeHelper::root_origin(), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(SOME_ASSET_ADMIN).into(), false, foreign_asset_minimum_asset_balance @@ -395,7 +421,7 @@ fn test_assets_balances_api_works() { // We first mint enough asset for the account to exist for assets assert_ok!(ForeignAssets::mint( RuntimeHelper::origin_of(AccountId::from(SOME_ASSET_ADMIN)), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(ALICE).into(), 6 * foreign_asset_minimum_asset_balance )); @@ -406,12 +432,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 6 * minimum_asset_balance ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency); - let result: MultiAssets = Runtime::query_account_balances(AccountId::from(ALICE)) + let result: XcmAssets = Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() .try_into() .unwrap(); @@ -426,13 +452,13 @@ fn test_assets_balances_api_works() { ))); // check trusted asset assert!(result.inner().iter().any(|asset| asset.eq(&( - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(), + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(), minimum_asset_balance ) .into()))); // check foreign asset assert!(result.inner().iter().any(|asset| asset.eq(&( - Identity::convert_back(&foreign_asset_id_multilocation).unwrap(), + V4V3LocationConverter::convert_back(&foreign_asset_id_location).unwrap(), 6 * foreign_asset_minimum_asset_balance ) .into()))); @@ -503,7 +529,7 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ XcmConfig, TrustBackedAssetsInstance, AssetIdForTrustBackedAssets, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, collator_session_keys(), ExistentialDeposit::get(), 12345, @@ -520,11 +546,14 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ Runtime, XcmConfig, ForeignAssetsInstance, - MultiLocation, + xcm::v3::Location, JustTry, collator_session_keys(), ExistentialDeposit::get(), - MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(1313), xcm::v3::Junction::GeneralIndex(12345)] + ), Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); }), @@ -539,8 +568,8 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p WeightToFee, ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, - MultiLocation, - JustTry, + xcm::v3::Location, + V4V3LocationConverter, collator_session_keys(), ExistentialDeposit::get(), AssetDeposit::get(), @@ -637,12 +666,12 @@ mod asset_hub_rococo_tests { AccountId::from([73; 32]), AccountId::from(BLOCK_AUTHOR_ACCOUNT), // receiving WNDs - (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Westend)) }, 1000000000000, 1_000_000_000), + (xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Westend)]), 1000000000000, 1_000_000_000), bridging_to_asset_hub_westend, ( - X1(PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX)), + [PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX)].into(), GlobalConsensus(Westend), - X1(Parachain(1000)) + [Parachain(1000)].into() ) ) } 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 8543500fa23f..cf10c0ac0528 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -76,21 +76,25 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::opaque::v3::MultiLocation; use xcm_config::{ ForeignAssetsConvertedConcreteId, PoolAssetsConvertedConcreteId, - TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation, WestendLocation, - XcmOriginToTransactDispatchOrigin, + TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3, WestendLocation, + WestendLocationV3, XcmOriginToTransactDispatchOrigin, }; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -use assets_common::{ - foreign_creators::ForeignCreators, matching::FromSiblingParachain, MultiLocationForAssetId, -}; +use assets_common::{foreign_creators::ForeignCreators, matching::FromSiblingParachain}; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; -use xcm::latest::prelude::*; +// We exclude `Assets` since it's the name of a pallet +use xcm::latest::prelude::AssetId; + +#[cfg(feature = "runtime-benchmarks")] +use xcm::latest::prelude::{ + Asset, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, + NonFungible, Parent, ParentThen, Response, XCM_VERSION, +}; use crate::xcm_config::ForeignCreatorsSovereignAccountOf; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; @@ -300,10 +304,11 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, + xcm::v3::Location, >, - MultiLocation, + xcm::v3::Location, AccountId, >; @@ -311,8 +316,8 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< pub type NativeAndAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, - TargetFromLeft, - MultiLocation, + TargetFromLeft, + xcm::v3::Location, AccountId, >; @@ -320,15 +325,15 @@ impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; - type AssetKind = MultiLocation; + type AssetKind = xcm::v3::Location; type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = - pallet_asset_conversion::WithFirstAsset; + pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam - type PoolSetupFeeAsset = WestendLocation; + type PoolSetupFeeAsset = WestendLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; @@ -338,9 +343,10 @@ impl pallet_asset_conversion::Config for Runtime { type WeightInfo = weights::pallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< - WestendLocation, + WestendLocationV3, parachain_info::Pallet, - xcm_config::AssetsPalletIndex, + xcm_config::TrustBackedAssetsPalletIndex, + xcm::v3::Location, >; } @@ -362,13 +368,14 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::Location; + type AssetIdParameter = xcm::v3::Location; type Currency = Balances; type CreateOrigin = ForeignCreators< - (FromSiblingParachain>,), + FromSiblingParachain, xcm::v3::Location>, ForeignCreatorsSovereignAccountOf, AccountId, + xcm::v3::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; @@ -644,7 +651,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WestendLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -728,7 +735,7 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = - AssetConversionAdapter; + AssetConversionAdapter; } parameter_types! { @@ -1229,18 +1236,18 @@ impl_runtime_apis! { impl pallet_asset_conversion::AssetConversionApi< Block, Balance, - MultiLocation, + xcm::v3::Location, > for Runtime { - fn quote_price_exact_tokens_for_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_exact_tokens_for_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } - fn quote_price_tokens_for_exact_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_tokens_for_exact_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } - fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> { + fn get_reserves(asset1: xcm::v3::Location, asset2: xcm::v3::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } @@ -1294,7 +1301,7 @@ impl_runtime_apis! { AccountId, > for Runtime { - fn query_account_balances(account: AccountId) -> Result { + fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pallet_balance @@ -1413,45 +1420,45 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // AH can reserve transfer native token to some random parachain. let random_para_id = 43211234; ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( random_para_id.into() ); Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, ParentThen(Parachain(random_para_id).into()).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(xcm::v4::Assets, u32, Location, 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) let dest = Parent.into(); let fee_amount = EXISTENTIAL_DEPOSIT; - let fee_asset: MultiAsset = (MultiLocation::parent(), fee_amount).into(); + let fee_asset: Asset = (Location::parent(), fee_amount).into(); let who = frame_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit @@ -1469,13 +1476,13 @@ impl_runtime_apis! { Runtime, pallet_assets::Instance1 >(true, initial_asset_amount); - let asset_location = MultiLocation::new( + let asset_location = Location::new( 0, - X2(PalletInstance(50), GeneralIndex(u32::from(asset_id).into())) + [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); - let transfer_asset: MultiAsset = (asset_location, asset_amount).into(); + let transfer_asset: Asset = (asset_location, asset_amount).into(); - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset].into(); + let assets: xcm::v4::Assets = vec![fee_asset.clone(), transfer_asset].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully @@ -1504,14 +1511,14 @@ impl_runtime_apis! { xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } - fn ensure_bridged_target_destination() -> Result { + fn ensure_bridged_target_destination() -> Result { ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_rococo::AssetHubRococo::get(); let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), - Box::new(bridged_asset_hub), + Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { log::error!( @@ -1527,12 +1534,11 @@ impl_runtime_apis! { } } - use xcm::latest::prelude::*; use xcm_config::{MaxAssetsIntoHolding, WestendLocation}; use pallet_xcm_benchmarks::asset_instance_from; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WestendLocation::get(), ExistentialDeposit::get() ).into()); @@ -1543,33 +1549,33 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WestendLocation::get()) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> xcm::v4::Assets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles - 1; let fungibles_amount: u128 = 100; let mut assets = (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * i as u128), } }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>(); - assets.push(MultiAsset { - id: Concrete(WestendLocation::get()), + assets.push(Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS), }); assets.into() @@ -1577,16 +1583,16 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WestendLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; // AssetHubWestend trusts AssetHubRococo as reserve for ROCs - pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + pub TrustedReserve: Option<(Location, Asset)> = Some( ( xcm_config::bridging::to_rococo::AssetHubRococo::get(), - MultiAsset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128)) + Asset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128)) ) ); } @@ -1598,9 +1604,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WestendLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(UNITS), } } @@ -1614,42 +1620,42 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(xcm::v4::Assets, xcm::v4::Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() { Some(alias) => Ok(alias), None => Err(BenchmarkError::Skip) } } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WestendLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WestendLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, xcm::v4::Assets), BenchmarkError> { let origin = WestendLocation::get(); - let assets: MultiAssets = (Concrete(WestendLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: xcm::v4::Assets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs index bcd51167f97e..8c77774da2dd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,40 +49,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct AssetHubWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for AssetHubWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -110,44 +106,36 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 28876d1d4542..b2498418cc73 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -20,12 +20,12 @@ use super::{ ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ - local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, + local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, matching::{FromSiblingParachain, IsForeignConcreteAsset}, - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess, @@ -61,25 +61,31 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); + pub const WestendLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); - pub AssetsPalletIndex: u32 = ::index() as u32; - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(AssetsPalletIndex::get() as u8).into(); - pub ForeignAssetsPalletLocation: MultiLocation = + pub TrustBackedAssetsPalletLocation: Location = + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); + pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); - pub PoolAssetsPalletLocation: MultiLocation = + pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub PoolAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); pub StakingPot: AccountId = CollatorSelection::account_id(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -104,7 +110,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -122,7 +128,7 @@ pub type FungiblesTransactor = FungiblesAdapter< Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -139,8 +145,8 @@ pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConverte // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore asset which starts explicitly with our `GlobalConsensus(NetworkId)`, means: - // - foreign assets from our consensus should be: `MultiLocation {parents: 1, - // X*(Parachain(xyz), ..)} + // - foreign assets from our consensus should be: `Location {parents: 1, X*(Parachain(xyz), + // ..)} // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont // be accepted here StartsWithExplicitGlobalConsensus, @@ -154,7 +160,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -174,7 +180,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -189,21 +195,33 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); -/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`. -pub struct LocalAndForeignAssetsMultiLocationMatcher; -impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher { - fn is_local(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - TrustBackedAssetsConvertedConcreteId::contains(location) +/// Simple `Location` matcher for Local and Foreign asset `Location`. +pub struct LocalAndForeignAssetsLocationMatcher; +impl MatchesLocalAndForeignAssetsLocation + for LocalAndForeignAssetsLocationMatcher +{ + fn is_local(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + TrustBackedAssetsConvertedConcreteId::contains(&latest_location) } - fn is_foreign(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - ForeignAssetsConvertedConcreteId::contains(location) + fn is_foreign(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + ForeignAssetsConvertedConcreteId::contains(&latest_location) } } -impl Contains for LocalAndForeignAssetsMultiLocationMatcher { - fn contains(location: &MultiLocation) -> bool { +impl Contains for LocalAndForeignAssetsLocationMatcher { + fn contains(location: &xcm::v3::Location) -> bool { Self::is_local(location) || Self::is_foreign(location) } } @@ -238,23 +256,30 @@ parameter_types! { pub XcmAssetFeesReceiver: Option = Authorship::author(); } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type FellowshipEntities: impl Contains = { - // Fellowship Plurality - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } | - // Fellowship Salary Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(64)) } | - // Fellowship Treasury Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(65)) } - }; - pub type AmbassadorEntities: impl Contains = { - // Ambassador Salary Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(74)) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct FellowshipEntities; +impl Contains for FellowshipEntities { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }]) | + (1, [Parachain(1001), PalletInstance(64)]) | + (1, [Parachain(1001), PalletInstance(65)]) + ) + } +} + +pub struct AmbassadorEntities; +impl Contains for AmbassadorEntities { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), PalletInstance(74)])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -573,12 +598,12 @@ impl xcm_executor::Config for XcmConfig { type Trader = ( UsingComponents>, cumulus_primitives_utility::SwapFirstAssetTrader< - WestendLocation, + WestendLocationV3, crate::AssetConversion, WeightToFee, crate::NativeAndAssets, ( - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, @@ -671,9 +696,9 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } @@ -704,7 +729,7 @@ pub mod bridging { pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID; - pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + pub SiblingBridgeHub: Location = Location::new(1, [Parachain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = WestendLocation::get().into(); @@ -721,25 +746,25 @@ pub mod bridging { use super::*; parameter_types! { - pub SiblingBridgeHubWithBridgeHubRococoInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithBridgeHubRococoInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX) - ) + ] ); pub const RococoNetwork: NetworkId = NetworkId::Rococo; - pub AssetHubRococo: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID))); - pub RocLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(RococoNetwork::get()))); + pub AssetHubRococo: Location = Location::new(2, [GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID)]); + pub RocLocation: Location = Location::new(2, [GlobalConsensus(RococoNetwork::get())]); - pub RocFromAssetHubRococo: (MultiAssetFilter, MultiLocation) = ( - Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) }), + pub RocFromAssetHubRococo: (AssetFilter, Location) = ( + Wild(AllOf { fun: WildFungible, id: AssetId(RocLocation::get()) }), AssetHubRococo::get() ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( RococoNetwork::get(), @@ -756,15 +781,15 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithBridgeHubRococoInstance::get(), GlobalConsensus(RococoNetwork::get())) ] ); } - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -799,7 +824,7 @@ pub mod bridging { #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { - pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_rococo::UniversalAliases::get().into_iter().find_map(|(location, junction)| { match to_rococo::SiblingBridgeHubWithBridgeHubRococoInstance::get() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index c50a8f3661d2..28fc7ba705a4 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -21,12 +21,16 @@ use asset_hub_westend_runtime::{ xcm_config, xcm_config::{ bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, + WestendLocationV3, }, AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, }; pub use asset_hub_westend_runtime::{ - xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + xcm_config::{ + CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + XcmConfig, + }, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, TrustBackedAssetsInstance, @@ -51,14 +55,18 @@ use parachains_common::{ }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; -use xcm::latest::prelude::*; -use xcm_executor::traits::{Identity, JustTry, WeightTrader}; +use xcm::latest::prelude::{Assets as XcmAssets, *}; +use xcm_builder::V4V3LocationConverter; +use xcm_executor::traits::{JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = - assets_common::AssetIdForTrustBackedAssetsConvert; + assets_common::AssetIdForTrustBackedAssetsConvert; + +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; type RuntimeHelper = asset_test_utils::RuntimeHelper; @@ -101,7 +109,7 @@ fn test_buy_and_refund_weight_in_native() { let fee = WeightToFee::weight_to_fee(&weight); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (native_location, fee + extra_amount).into(); + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -110,7 +118,7 @@ fn test_buy_and_refund_weight_in_native() { // assert. let unused_amount = - unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Balances::total_issuance(), total_issuance); @@ -146,7 +154,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); let asset_1: u32 = 1; - let native_location = WestendLocation::get(); + let native_location = WestendLocationV3::get(); let asset_1_location = AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); // bob's initial balance for native and `asset1` assets. @@ -182,6 +190,8 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let asset_total_issuance = Assets::total_issuance(asset_1); let native_total_issuance = Balances::total_issuance(); + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -189,7 +199,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -197,8 +207,10 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); @@ -212,7 +224,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -241,9 +253,15 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { .execute_with(|| { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); - let native_location = WestendLocation::get(); - let foreign_location = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let native_location = WestendLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; // bob's initial balance for native and `asset1` assets. let initial_balance = 200 * UNITS; // liquidity for both arms of (native, asset1) pool. @@ -282,6 +300,8 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); let native_total_issuance = Balances::total_issuance(); + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -289,7 +309,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -297,8 +317,10 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!( ForeignAssets::total_issuance(foreign_location), @@ -315,7 +337,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -345,19 +367,25 @@ fn test_assets_balances_api_works() { .build() .execute_with(|| { let local_asset_id = 1; - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let foreign_asset_id_location = xcm::v3::Location { + parents: 1, + interior: [ + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ] + .into(), + }; // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 0 ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() - .try_as::() + .try_as::() .unwrap() .is_none()); @@ -388,7 +416,7 @@ fn test_assets_balances_api_works() { let foreign_asset_minimum_asset_balance = 3333333_u128; assert_ok!(ForeignAssets::force_create( RuntimeHelper::root_origin(), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(SOME_ASSET_ADMIN).into(), false, foreign_asset_minimum_asset_balance @@ -397,7 +425,7 @@ fn test_assets_balances_api_works() { // We first mint enough asset for the account to exist for assets assert_ok!(ForeignAssets::mint( RuntimeHelper::origin_of(AccountId::from(SOME_ASSET_ADMIN)), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(ALICE).into(), 6 * foreign_asset_minimum_asset_balance )); @@ -408,12 +436,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 6 * minimum_asset_balance ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency); - let result: MultiAssets = Runtime::query_account_balances(AccountId::from(ALICE)) + let result: XcmAssets = Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() .try_into() .unwrap(); @@ -428,13 +456,13 @@ fn test_assets_balances_api_works() { ))); // check trusted asset assert!(result.inner().iter().any(|asset| asset.eq(&( - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(), + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(), minimum_asset_balance ) .into()))); // check foreign asset assert!(result.inner().iter().any(|asset| asset.eq(&( - Identity::convert_back(&foreign_asset_id_multilocation).unwrap(), + V4V3LocationConverter::convert_back(&foreign_asset_id_location).unwrap(), 6 * foreign_asset_minimum_asset_balance ) .into()))); @@ -505,7 +533,7 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ XcmConfig, TrustBackedAssetsInstance, AssetIdForTrustBackedAssets, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, collator_session_keys(), ExistentialDeposit::get(), 12345, @@ -522,11 +550,15 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ Runtime, XcmConfig, ForeignAssetsInstance, - MultiLocation, + xcm::v3::Location, JustTry, collator_session_keys(), ExistentialDeposit::get(), - MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + xcm::v3::Location { + parents: 1, + interior: [xcm::v3::Junction::Parachain(1313), xcm::v3::Junction::GeneralIndex(12345)] + .into() + }, Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); }), @@ -541,8 +573,8 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p WeightToFee, ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, - MultiLocation, - JustTry, + xcm::v3::Location, + V4V3LocationConverter, collator_session_keys(), ExistentialDeposit::get(), AssetDeposit::get(), @@ -626,12 +658,12 @@ fn receive_reserve_asset_deposited_roc_from_asset_hub_rococo_works() { AccountId::from([73; 32]), AccountId::from(BLOCK_AUTHOR_ACCOUNT), // receiving ROCs - (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Rococo)) }, 1000000000000, 1_000_000_000), + (xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Rococo)]), 1000000000000, 1_000_000_000), bridging_to_asset_hub_rococo, ( - X1(PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)), + [PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)].into(), GlobalConsensus(Rococo), - X1(Parachain(1000)) + [Parachain(1000)].into() ) ) } diff --git a/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs b/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs index 344cb5ca3368..44bda1eb3709 100644 --- a/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs +++ b/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs @@ -19,26 +19,25 @@ use sp_std::marker::PhantomData; use xcm::latest::prelude::*; /// Creates asset pairs for liquidity pools with `Target` always being the first asset. -pub struct AssetPairFactory( - PhantomData<(Target, SelfParaId, PalletId)>, +pub struct AssetPairFactory( + PhantomData<(Target, SelfParaId, PalletId, L)>, ); -impl, SelfParaId: Get, PalletId: Get> - pallet_asset_conversion::BenchmarkHelper - for AssetPairFactory +impl, SelfParaId: Get, PalletId: Get, L: TryFrom> + pallet_asset_conversion::BenchmarkHelper for AssetPairFactory { - fn create_pair(seed1: u32, seed2: u32) -> (MultiLocation, MultiLocation) { - let with_id = MultiLocation::new( + fn create_pair(seed1: u32, seed2: u32) -> (L, L) { + let with_id = Location::new( 1, - X3( + [ Parachain(SelfParaId::get().into()), PalletInstance(PalletId::get() as u8), GeneralIndex(seed2.into()), - ), + ], ); if seed1 % 2 == 0 { - (with_id, Target::get()) + (with_id.try_into().map_err(|_| "Something went wrong").unwrap(), Target::get()) } else { - (Target::get(), with_id) + (Target::get(), with_id.try_into().map_err(|_| "Something went wrong").unwrap()) } } } diff --git a/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs b/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs index 1ed7bd0538c2..a9fd79bf939f 100644 --- a/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs +++ b/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs @@ -17,21 +17,21 @@ use frame_support::traits::{ ContainsPair, EnsureOrigin, EnsureOriginWithArg, Everything, OriginTrait, }; use pallet_xcm::{EnsureXcm, Origin as XcmOrigin}; -use xcm::latest::MultiLocation; +use xcm::latest::Location; use xcm_executor::traits::ConvertLocation; /// `EnsureOriginWithArg` impl for `CreateOrigin` that allows only XCM origins that are locations /// containing the class location. -pub struct ForeignCreators( - sp_std::marker::PhantomData<(IsForeign, AccountOf, AccountId)>, +pub struct ForeignCreators( + sp_std::marker::PhantomData<(IsForeign, AccountOf, AccountId, L)>, ); impl< - IsForeign: ContainsPair, + IsForeign: ContainsPair, AccountOf: ConvertLocation, AccountId: Clone, RuntimeOrigin: From + OriginTrait + Clone, - > EnsureOriginWithArg - for ForeignCreators + L: TryFrom + TryInto + Clone, + > EnsureOriginWithArg for ForeignCreators where RuntimeOrigin::PalletsOrigin: From + TryInto, @@ -40,17 +40,20 @@ where fn try_origin( origin: RuntimeOrigin, - asset_location: &MultiLocation, + asset_location: &L, ) -> sp_std::result::Result { - let origin_location = EnsureXcm::::try_origin(origin.clone())?; + let origin_location = EnsureXcm::::try_origin(origin.clone())?; if !IsForeign::contains(asset_location, &origin_location) { return Err(origin) } - AccountOf::convert_location(&origin_location).ok_or(origin) + let latest_location: Location = + origin_location.clone().try_into().map_err(|_| origin.clone())?; + AccountOf::convert_location(&latest_location).ok_or(origin) } #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(a: &MultiLocation) -> Result { - Ok(pallet_xcm::Origin::Xcm(*a).into()) + fn try_successful_origin(a: &L) -> Result { + let latest_location: Location = (*a).clone().try_into().map_err(|_| ())?; + Ok(pallet_xcm::Origin::Xcm(latest_location).into()) } } diff --git a/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs b/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs index 80f8a971d217..e21203485a76 100644 --- a/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs +++ b/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs @@ -19,52 +19,48 @@ use crate::runtime_api::FungiblesAccessError; use frame_support::traits::Contains; use sp_runtime::traits::MaybeEquivalence; use sp_std::{borrow::Borrow, vec::Vec}; -use xcm::latest::{MultiAsset, MultiLocation}; +use xcm::latest::{Asset, Location}; use xcm_builder::{ConvertedConcreteId, MatchedConvertedConcreteId}; use xcm_executor::traits::MatchesFungibles; -/// Converting any [`(AssetId, Balance)`] to [`MultiAsset`] -pub trait MultiAssetConverter: +/// Converting any [`(AssetId, Balance)`] to [`Asset`] +pub trait AssetConverter: MatchesFungibles where AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result; + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result; } -/// Checks for `MultiLocation`. -pub trait MatchesMultiLocation: +/// Checks for `Location`. +pub trait MatchesLocation: MatchesFungibles where AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, { - fn contains(location: &MultiLocation) -> bool; + fn contains(location: &Location) -> bool; } impl< AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MultiAssetConverter + > AssetConverter for ConvertedConcreteId { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result { + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result { let (asset_id, balance) = value.borrow(); match ConvertAssetId::convert_back(asset_id) { - Some(asset_id_as_multilocation) => match ConvertBalance::convert_back(balance) { - Some(amount) => Ok((asset_id_as_multilocation, amount).into()), + Some(asset_id_as_location) => match ConvertBalance::convert_back(balance) { + Some(amount) => Ok((asset_id_as_location, amount).into()), None => Err(FungiblesAccessError::AmountToBalanceConversionFailed), }, None => Err(FungiblesAccessError::AssetIdConversionFailed), @@ -75,19 +71,17 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MultiAssetConverter + > AssetConverter for MatchedConvertedConcreteId { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result { + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result { let (asset_id, balance) = value.borrow(); match ConvertAssetId::convert_back(asset_id) { - Some(asset_id_as_multilocation) => match ConvertBalance::convert_back(balance) { - Some(amount) => Ok((asset_id_as_multilocation, amount).into()), + Some(asset_id_as_location) => match ConvertBalance::convert_back(balance) { + Some(amount) => Ok((asset_id_as_location, amount).into()), None => Err(FungiblesAccessError::AmountToBalanceConversionFailed), }, None => Err(FungiblesAccessError::AssetIdConversionFailed), @@ -98,13 +92,13 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MatchesMultiLocation + > MatchesLocation for MatchedConvertedConcreteId { - fn contains(location: &MultiLocation) -> bool { + fn contains(location: &Location) -> bool { MatchAssetId::contains(location) } } @@ -113,12 +107,12 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MatchesMultiLocation for Tuple + > MatchesLocation for Tuple { - fn contains(location: &MultiLocation) -> bool { + fn contains(location: &Location) -> bool { for_tuples!( #( match Tuple::contains(location) { o @ true => return o, _ => () } )* ); @@ -127,27 +121,24 @@ impl< } } -/// Helper function to convert collections with [`(AssetId, Balance)`] to [`MultiAsset`] +/// Helper function to convert collections with [`(AssetId, Balance)`] to [`Asset`] pub fn convert<'a, AssetId, Balance, ConvertAssetId, ConvertBalance, Converter>( items: impl Iterator, -) -> Result, FungiblesAccessError> +) -> Result, FungiblesAccessError> where AssetId: Clone + 'a, Balance: Clone + 'a, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - Converter: MultiAssetConverter, + Converter: AssetConverter, { items.map(Converter::convert_ref).collect() } -/// Helper function to convert `Balance` with MultiLocation` to `MultiAsset` -pub fn convert_balance< - T: frame_support::pallet_prelude::Get, - Balance: TryInto, ->( +/// Helper function to convert `Balance` with Location` to `Asset` +pub fn convert_balance, Balance: TryInto>( balance: Balance, -) -> Result { +) -> Result { match balance.try_into() { Ok(balance) => Ok((T::get(), balance).into()), Err(_) => Err(FungiblesAccessError::AmountToBalanceConversionFailed), @@ -162,20 +153,20 @@ mod tests { use xcm::latest::prelude::*; use xcm_executor::traits::{Identity, JustTry}; - type Converter = MatchedConvertedConcreteId; + type Converter = MatchedConvertedConcreteId; #[test] fn converted_concrete_id_fungible_multi_asset_conversion_roundtrip_works() { - let location = MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))); + let location = Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))]); let amount = 123456_u64; - let expected_multi_asset = MultiAsset { - id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))), + let expected_multi_asset = Asset { + id: AssetId(Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))])), fun: Fungible(123456_u128), }; assert_eq!( Converter::matches_fungibles(&expected_multi_asset).map_err(|_| ()), - Ok((location, amount)) + Ok((location.clone(), amount)) ); assert_eq!(Converter::convert_ref((location, amount)), Ok(expected_multi_asset)); @@ -184,17 +175,17 @@ mod tests { #[test] fn converted_concrete_id_fungible_multi_asset_conversion_collection_works() { let data = vec![ - (MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))), 123456_u64), - (MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32])))), 654321_u64), + (Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))]), 123456_u64), + (Location::new(1, [GlobalConsensus(ByGenesis([1; 32]))]), 654321_u64), ]; let expected_data = vec![ - MultiAsset { - id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))), + Asset { + id: AssetId(Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))])), fun: Fungible(123456_u128), }, - MultiAsset { - id: Concrete(MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32]))))), + Asset { + id: AssetId(Location::new(1, [GlobalConsensus(ByGenesis([1; 32]))])), fun: Fungible(654321_u128), }, ]; diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index b0e471439297..f21e1766436a 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -23,15 +23,24 @@ pub mod local_and_foreign_assets; pub mod matching; pub mod runtime_api; -use crate::matching::{LocalMultiLocationPattern, ParentLocation}; +use crate::matching::{LocalLocationPattern, ParentLocation}; use frame_support::traits::{Equals, EverythingBut}; use parachains_common::AssetIdForTrustBackedAssets; -use xcm::prelude::MultiLocation; -use xcm_builder::{AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith}; -use xcm_executor::traits::{Identity, JustTry}; +use xcm_builder::{ + AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith, V4V3LocationConverter, +}; +use xcm_executor::traits::JustTry; -/// `MultiLocation` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets` +/// `Location` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets` pub type AssetIdForTrustBackedAssetsConvert = + AsPrefixedGeneralIndex< + TrustBackedAssetsPalletLocation, + AssetIdForTrustBackedAssets, + JustTry, + xcm::v3::Location, + >; + +pub type AssetIdForTrustBackedAssetsConvertLatest = AsPrefixedGeneralIndex; /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` @@ -40,59 +49,55 @@ pub type TrustBackedAssetsConvertedConcreteId, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, JustTry, >; -/// AssetId used for identifying assets by MultiLocation. -pub type MultiLocationForAssetId = MultiLocation; +/// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `Location`. +pub type LocationConvertedConcreteId = MatchedConvertedConcreteId< + xcm::v3::Location, + Balance, + LocationFilter, + V4V3LocationConverter, + JustTry, +>; /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` -pub type TrustBackedAssetsAsMultiLocation = +pub type TrustBackedAssetsAsLocation = MatchedConvertedConcreteId< - MultiLocationForAssetId, + xcm::v3::Location, Balance, StartsWith, - Identity, - JustTry, - >; - -/// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `MultiLocation`. -pub type MultiLocationConvertedConcreteId = - MatchedConvertedConcreteId< - MultiLocationForAssetId, - Balance, - MultiLocationFilter, - Identity, + V4V3LocationConverter, JustTry, >; /// [`MatchedConvertedConcreteId`] converter dedicated for storing `ForeignAssets` with `AssetId` as -/// `MultiLocation`. +/// `Location`. /// /// Excludes by default: /// - parent as relay chain -/// - all local MultiLocations +/// - all local Locations /// -/// `AdditionalMultiLocationExclusionFilter` can customize additional excluded MultiLocations -pub type ForeignAssetsConvertedConcreteId = - MultiLocationConvertedConcreteId< +/// `AdditionalLocationExclusionFilter` can customize additional excluded Locations +pub type ForeignAssetsConvertedConcreteId = + LocationConvertedConcreteId< EverythingBut<( // Excludes relay/parent chain currency Equals, // Here we rely on fact that something like this works: - // assert!(MultiLocation::new(1, - // X1(Parachain(100))).starts_with(&MultiLocation::parent())); - // assert!(X1(Parachain(100)).starts_with(&Here)); - StartsWith, + // assert!(Location::new(1, + // [Parachain(100)]).starts_with(&Location::parent())); + // assert!([Parachain(100)].into().starts_with(&Here)); + StartsWith, // Here we can exclude more stuff or leave it as `()` - AdditionalMultiLocationExclusionFilter, + AdditionalLocationExclusionFilter, )>, Balance, >; type AssetIdForPoolAssets = u32; -/// `MultiLocation` vs `AssetIdForPoolAssets` converter for `PoolAssets`. +/// `Location` vs `AssetIdForPoolAssets` converter for `PoolAssets`. pub type AssetIdForPoolAssetsConvert = AsPrefixedGeneralIndex; /// [`MatchedConvertedConcreteId`] converter dedicated for `PoolAssets` @@ -109,28 +114,28 @@ pub type PoolAssetsConvertedConcreteId = mod tests { use super::*; use sp_runtime::traits::MaybeEquivalence; - use xcm::latest::prelude::*; + use xcm::prelude::*; use xcm_builder::StartsWithExplicitGlobalConsensus; use xcm_executor::traits::{Error as MatchError, MatchesFungibles}; #[test] fn asset_id_for_trust_backed_assets_convert_works() { frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(5, X1(PalletInstance(13))); + pub TrustBackedAssetsPalletLocation: Location = Location::new(5, [PalletInstance(13)]); } let local_asset_id = 123456789 as AssetIdForTrustBackedAssets; let expected_reverse_ref = - MultiLocation::new(5, X2(PalletInstance(13), GeneralIndex(local_asset_id.into()))); + Location::new(5, [PalletInstance(13), GeneralIndex(local_asset_id.into())]); assert_eq!( - AssetIdForTrustBackedAssetsConvert::::convert_back( + AssetIdForTrustBackedAssetsConvertLatest::::convert_back( &local_asset_id ) .unwrap(), expected_reverse_ref ); assert_eq!( - AssetIdForTrustBackedAssetsConvert::::convert( + AssetIdForTrustBackedAssetsConvertLatest::::convert( &expected_reverse_ref ) .unwrap(), @@ -141,7 +146,7 @@ mod tests { #[test] fn trust_backed_assets_match_fungibles_works() { frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(0, X1(PalletInstance(13))); + pub TrustBackedAssetsPalletLocation: Location = Location::new(0, [PalletInstance(13)]); } // setup convert type TrustBackedAssetsConvert = @@ -149,85 +154,86 @@ mod tests { let test_data = vec![ // missing GeneralIndex - (ma_1000(0, X1(PalletInstance(13))), Err(MatchError::AssetIdConversionFailed)), + (ma_1000(0, [PalletInstance(13)].into()), Err(MatchError::AssetIdConversionFailed)), ( - ma_1000(0, X2(PalletInstance(13), GeneralKey { data: [0; 32], length: 32 })), + ma_1000(0, [PalletInstance(13), GeneralKey { data: [0; 32], length: 32 }].into()), Err(MatchError::AssetIdConversionFailed), ), ( - ma_1000(0, X2(PalletInstance(13), Parachain(1000))), + ma_1000(0, [PalletInstance(13), Parachain(1000)].into()), Err(MatchError::AssetIdConversionFailed), ), // OK - (ma_1000(0, X2(PalletInstance(13), GeneralIndex(1234))), Ok((1234, 1000))), + (ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Ok((1234, 1000))), ( - ma_1000(0, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(0, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Ok((1234, 1000)), ), ( ma_1000( 0, - X4( + [ PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222), GeneralKey { data: [0; 32], length: 32 }, - ), + ] + .into(), ), Ok((1234, 1000)), ), // wrong pallet instance ( - ma_1000(0, X2(PalletInstance(77), GeneralIndex(1234))), + ma_1000(0, [PalletInstance(77), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(0, X3(PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(0, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // wrong parent ( - ma_1000(1, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(1, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(1, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X2(PalletInstance(77), GeneralIndex(1234))), + ma_1000(1, [PalletInstance(77), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X3(PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(1, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // wrong parent ( - ma_1000(2, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(2, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(2, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(2, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // missing GeneralIndex - (ma_1000(0, X1(PalletInstance(77))), Err(MatchError::AssetNotHandled)), - (ma_1000(1, X1(PalletInstance(13))), Err(MatchError::AssetNotHandled)), - (ma_1000(2, X1(PalletInstance(13))), Err(MatchError::AssetNotHandled)), + (ma_1000(0, [PalletInstance(77)].into()), Err(MatchError::AssetNotHandled)), + (ma_1000(1, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)), + (ma_1000(2, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)), ]; - for (multi_asset, expected_result) in test_data { + for (asset, expected_result) in test_data { assert_eq!( - >::matches_fungibles(&multi_asset), - expected_result, "multi_asset: {:?}", multi_asset); + >::matches_fungibles(&asset.clone().try_into().unwrap()), + expected_result, "asset: {:?}", asset); } } #[test] - fn multi_location_converted_concrete_id_converter_works() { + fn location_converted_concrete_id_converter_works() { frame_support::parameter_types! { - pub Parachain100Pattern: MultiLocation = MultiLocation::new(1, X1(Parachain(100))); + pub Parachain100Pattern: Location = Location::new(1, [Parachain(100)]); pub UniversalLocationNetworkId: NetworkId = NetworkId::ByGenesis([9; 32]); } @@ -243,95 +249,125 @@ mod tests { let test_data = vec![ // excluded as local (ma_1000(0, Here), Err(MatchError::AssetNotHandled)), - (ma_1000(0, X1(Parachain(100))), Err(MatchError::AssetNotHandled)), + (ma_1000(0, [Parachain(100)].into()), Err(MatchError::AssetNotHandled)), ( - ma_1000(0, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), // excluded as parent (ma_1000(1, Here), Err(MatchError::AssetNotHandled)), // excluded as additional filter - Parachain100Pattern - (ma_1000(1, X1(Parachain(100))), Err(MatchError::AssetNotHandled)), - (ma_1000(1, X2(Parachain(100), GeneralIndex(1234))), Err(MatchError::AssetNotHandled)), + (ma_1000(1, [Parachain(100)].into()), Err(MatchError::AssetNotHandled)), ( - ma_1000(1, X3(Parachain(100), PalletInstance(13), GeneralIndex(1234))), + ma_1000(1, [Parachain(100), GeneralIndex(1234)].into()), + Err(MatchError::AssetNotHandled), + ), + ( + ma_1000(1, [Parachain(100), PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), // excluded as additional filter - StartsWithExplicitGlobalConsensus ( - ma_1000(1, X1(GlobalConsensus(NetworkId::ByGenesis([9; 32])))), + ma_1000(1, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(2, X1(GlobalConsensus(NetworkId::ByGenesis([9; 32])))), + ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()), Err(MatchError::AssetNotHandled), ), ( ma_1000( 2, - X3( + [ GlobalConsensus(NetworkId::ByGenesis([9; 32])), Parachain(200), GeneralIndex(1234), - ), + ] + .into(), ), Err(MatchError::AssetNotHandled), ), // ok - (ma_1000(1, X1(Parachain(200))), Ok((MultiLocation::new(1, X1(Parachain(200))), 1000))), - (ma_1000(2, X1(Parachain(200))), Ok((MultiLocation::new(2, X1(Parachain(200))), 1000))), ( - ma_1000(1, X2(Parachain(200), GeneralIndex(1234))), - Ok((MultiLocation::new(1, X2(Parachain(200), GeneralIndex(1234))), 1000)), + ma_1000(1, [Parachain(200)].into()), + Ok((xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(200)]), 1000)), + ), + ( + ma_1000(2, [Parachain(200)].into()), + Ok((xcm::v3::Location::new(2, [xcm::v3::Junction::Parachain(200)]), 1000)), ), ( - ma_1000(2, X2(Parachain(200), GeneralIndex(1234))), - Ok((MultiLocation::new(2, X2(Parachain(200), GeneralIndex(1234))), 1000)), + ma_1000(1, [Parachain(200), GeneralIndex(1234)].into()), + Ok(( + xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(200), xcm::v3::Junction::GeneralIndex(1234)], + ), + 1000, + )), ), ( - ma_1000(2, X1(GlobalConsensus(NetworkId::ByGenesis([7; 32])))), + ma_1000(2, [Parachain(200), GeneralIndex(1234)].into()), Ok(( - MultiLocation::new(2, X1(GlobalConsensus(NetworkId::ByGenesis([7; 32])))), + xcm::v3::Location::new( + 2, + [xcm::v3::Junction::Parachain(200), xcm::v3::Junction::GeneralIndex(1234)], + ), + 1000, + )), + ), + ( + ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([7; 32]))].into()), + Ok(( + xcm::v3::Location::new( + 2, + [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::ByGenesis( + [7; 32], + ))], + ), 1000, )), ), ( ma_1000( 2, - X3( + [ GlobalConsensus(NetworkId::ByGenesis([7; 32])), Parachain(200), GeneralIndex(1234), - ), + ] + .into(), ), Ok(( - MultiLocation::new( + xcm::v3::Location::new( 2, - X3( - GlobalConsensus(NetworkId::ByGenesis([7; 32])), - Parachain(200), - GeneralIndex(1234), - ), + [ + xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::ByGenesis( + [7; 32], + )), + xcm::v3::Junction::Parachain(200), + xcm::v3::Junction::GeneralIndex(1234), + ], ), 1000, )), ), ]; - for (multi_asset, expected_result) in test_data { + for (asset, expected_result) in test_data { assert_eq!( - >::matches_fungibles( - &multi_asset + >::matches_fungibles( + &asset.clone().try_into().unwrap() ), expected_result, - "multi_asset: {:?}", - multi_asset + "asset: {:?}", + asset ); } } - // Create MultiAsset - fn ma_1000(parents: u8, interior: Junctions) -> MultiAsset { - (MultiLocation::new(parents, interior), 1000).into() + // Create Asset + fn ma_1000(parents: u8, interior: Junctions) -> Asset { + (Location::new(parents, interior), 1000).into() } } diff --git a/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs b/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs index 7dd497797eaa..7c237660610f 100644 --- a/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs +++ b/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs @@ -20,32 +20,32 @@ use sp_runtime::{ Either::{Left, Right}, }; use sp_std::marker::PhantomData; -use xcm::latest::MultiLocation; +use xcm::latest::Location; -/// Converts a given [`MultiLocation`] to [`Either::Left`] when equal to `Target`, or +/// Converts a given [`Location`] to [`Either::Left`] when equal to `Target`, or /// [`Either::Right`] otherwise. /// /// Suitable for use as a `Criterion` with [`frame_support::traits::tokens::fungible::UnionOf`]. -pub struct TargetFromLeft(PhantomData); -impl> Convert> - for TargetFromLeft -{ - fn convert(l: MultiLocation) -> Either<(), MultiLocation> { +pub struct TargetFromLeft(PhantomData<(Target, L)>); +impl, L: PartialEq + Eq> Convert> for TargetFromLeft { + fn convert(l: L) -> Either<(), L> { Target::get().eq(&l).then(|| Left(())).map_or(Right(l), |n| n) } } -/// Converts a given [`MultiLocation`] to [`Either::Left`] based on the `Equivalence` criteria. +/// Converts a given [`Location`] to [`Either::Left`] based on the `Equivalence` criteria. /// Returns [`Either::Right`] if not equivalent. /// /// Suitable for use as a `Criterion` with [`frame_support::traits::tokens::fungibles::UnionOf`]. -pub struct LocalFromLeft(PhantomData<(Equivalence, AssetId)>); -impl Convert> - for LocalFromLeft +pub struct LocalFromLeft( + PhantomData<(Equivalence, AssetId, L)>, +); +impl Convert> + for LocalFromLeft where - Equivalence: MaybeEquivalence, + Equivalence: MaybeEquivalence, { - fn convert(l: MultiLocation) -> Either { + fn convert(l: L) -> Either { match Equivalence::convert(&l) { Some(id) => Left(id), None => Right(l), @@ -53,7 +53,7 @@ where } } -pub trait MatchesLocalAndForeignAssetsMultiLocation { - fn is_local(location: &MultiLocation) -> bool; - fn is_foreign(location: &MultiLocation) -> bool; +pub trait MatchesLocalAndForeignAssetsLocation { + fn is_local(location: &L) -> bool; + fn is_foreign(location: &L) -> bool; } diff --git a/cumulus/parachains/runtimes/assets/common/src/matching.rs b/cumulus/parachains/runtimes/assets/common/src/matching.rs index d6ecc3ec99f0..478bba4565dc 100644 --- a/cumulus/parachains/runtimes/assets/common/src/matching.rs +++ b/cumulus/parachains/runtimes/assets/common/src/matching.rs @@ -15,67 +15,72 @@ use cumulus_primitives_core::ParaId; use frame_support::{pallet_prelude::Get, traits::ContainsPair}; -use xcm::{ - latest::prelude::{MultiAsset, MultiLocation}, - prelude::*, -}; +use xcm::prelude::*; + use xcm_builder::ensure_is_remote; frame_support::parameter_types! { - pub LocalMultiLocationPattern: MultiLocation = MultiLocation::new(0, Here); - pub ParentLocation: MultiLocation = MultiLocation::parent(); + pub LocalLocationPattern: Location = Location::new(0, Here); + pub ParentLocation: Location = Location::parent(); } /// Accepts an asset if it is from the origin. pub struct IsForeignConcreteAsset(sp_std::marker::PhantomData); -impl> ContainsPair +impl> ContainsPair for IsForeignConcreteAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "IsForeignConcreteAsset asset: {:?}, origin: {:?}", asset, origin); - matches!(asset.id, Concrete(ref id) if IsForeign::contains(id, origin)) + matches!(asset.id, AssetId(ref id) if IsForeign::contains(id, origin)) } } -/// Checks if `a` is from sibling location `b`. Checks that `MultiLocation-a` starts with -/// `MultiLocation-b`, and that the `ParaId` of `b` is not equal to `a`. -pub struct FromSiblingParachain(sp_std::marker::PhantomData); -impl> ContainsPair - for FromSiblingParachain +/// Checks if `a` is from sibling location `b`. Checks that `Location-a` starts with +/// `Location-b`, and that the `ParaId` of `b` is not equal to `a`. +pub struct FromSiblingParachain( + sp_std::marker::PhantomData<(SelfParaId, L)>, +); +impl, L: TryFrom + TryInto + Clone> ContainsPair + for FromSiblingParachain { - fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { - // `a` needs to be from `b` at least - if !a.starts_with(b) { - return false - } + fn contains(a: &L, b: &L) -> bool { + // We convert locations to latest + let a = match ((*a).clone().try_into(), (*b).clone().try_into()) { + (Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least + _ => return false, + }; // here we check if sibling - match a { - MultiLocation { parents: 1, interior } => + match a.unpack() { + (1, interior) => matches!(interior.first(), Some(Parachain(sibling_para_id)) if sibling_para_id.ne(&u32::from(SelfParaId::get()))), _ => false, } } } -/// Checks if `a` is from the expected global consensus network. Checks that `MultiLocation-a` -/// starts with `MultiLocation-b`, and that network is a foreign consensus system. -pub struct FromNetwork( - sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId)>, +/// Checks if `a` is from the expected global consensus network. Checks that `Location-a` +/// starts with `Location-b`, and that network is a foreign consensus system. +pub struct FromNetwork( + sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId, L)>, ); -impl, ExpectedNetworkId: Get> - ContainsPair for FromNetwork +impl< + UniversalLocation: Get, + ExpectedNetworkId: Get, + L: TryFrom + TryInto + Clone, + > ContainsPair for FromNetwork { - fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { - // `a` needs to be from `b` at least - if !a.starts_with(b) { - return false - } + fn contains(a: &L, b: &L) -> bool { + // We convert locations to latest + let a = match ((*a).clone().try_into(), (*b).clone().try_into()) { + (Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least + _ => return false, + }; let universal_source = UniversalLocation::get(); - // ensure that `a`` is remote and from the expected network - match ensure_is_remote(universal_source, a) { + // ensure that `a` is remote and from the expected network + match ensure_is_remote(universal_source.clone(), a.clone()) { Ok((network_id, _)) => network_id == ExpectedNetworkId::get(), Err(e) => { log::trace!( @@ -89,19 +94,17 @@ impl, ExpectedNetworkId: Get( sp_std::marker::PhantomData<(UniversalLocation, Reserves)>, ); -impl< - UniversalLocation: Get, - Reserves: ContainsPair, - > ContainsPair +impl, Reserves: ContainsPair> + ContainsPair for IsTrustedBridgedReserveLocationForConcreteAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::contains", @@ -110,7 +113,7 @@ impl< ); // check remote origin - let _ = match ensure_is_remote(universal_source, *origin) { + let _ = match ensure_is_remote(universal_source.clone(), origin.clone()) { Ok(devolved) => devolved, Err(_) => { log::trace!( @@ -133,14 +136,14 @@ mod tests { use frame_support::parameter_types; parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Rococo), Parachain(1000)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(Rococo), Parachain(1000)].into(); pub ExpectedNetworkId: NetworkId = Wococo; } #[test] fn from_network_contains_works() { // asset and origin from foreign consensus works - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Wococo), @@ -149,12 +152,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); assert!(FromNetwork::::contains(&asset, &origin)); // asset and origin from local consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Rococo), @@ -163,17 +165,16 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Rococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Rococo), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset and origin from here fails - let asset: MultiLocation = (PalletInstance(1), GeneralIndex(1)).into(); - let origin: MultiLocation = Here.into(); + let asset: Location = (PalletInstance(1), GeneralIndex(1)).into(); + let origin: Location = Here.into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset from different consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Polkadot), @@ -182,12 +183,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // origin from different consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Wococo), @@ -196,12 +196,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset and origin from unexpected consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Polkadot), @@ -210,8 +209,7 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); } } diff --git a/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs b/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs index 0a166a048193..19977cbedab0 100644 --- a/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs +++ b/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs @@ -18,12 +18,12 @@ use codec::{Codec, Decode, Encode}; use sp_runtime::RuntimeDebug; #[cfg(feature = "std")] -use {sp_std::vec::Vec, xcm::latest::MultiAsset}; +use {sp_std::vec::Vec, xcm::latest::Asset}; /// The possible errors that can happen querying the storage of assets. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug, scale_info::TypeInfo)] pub enum FungiblesAccessError { - /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + /// `Location` to `AssetId`/`ClassId` conversion failed. AssetIdConversionFailed, /// `u128` amount to currency `Balance` conversion failed. AmountToBalanceConversionFailed, @@ -36,11 +36,11 @@ sp_api::decl_runtime_apis! { where AccountId: Codec, { - /// Returns the list of all [`MultiAsset`] that an `AccountId` has. + /// Returns the list of all [`Asset`] that an `AccountId` has. #[changed_in(2)] - fn query_account_balances(account: AccountId) -> Result, FungiblesAccessError>; + fn query_account_balances(account: AccountId) -> Result, FungiblesAccessError>; - /// Returns the list of all [`MultiAsset`] that an `AccountId` has. - fn query_account_balances(account: AccountId) -> Result; + /// Returns the list of all [`Asset`] that an `AccountId` has. + fn query_account_balances(account: AccountId) -> Result; } } diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs b/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs index 872ad06ddd5b..877d61780ce7 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs @@ -28,7 +28,7 @@ use xcm::latest::prelude::*; use xcm_builder::{CreateMatcher, MatchXcm}; /// Given a message, a sender, and a destination, it returns the delivery fees -fn get_fungible_delivery_fees(destination: MultiLocation, message: Xcm<()>) -> u128 { +fn get_fungible_delivery_fees(destination: Location, message: Xcm<()>) -> u128 { let Ok((_, delivery_fees)) = validate_send::(destination, message) else { unreachable!("message can be sent; qed") }; @@ -46,8 +46,8 @@ fn get_fungible_delivery_fees(destination: MultiLocation, message: X /// chain as part of a reserve-asset-transfer. pub(crate) fn assert_matches_reserve_asset_deposited_instructions( xcm: &mut Xcm, - expected_reserve_assets_deposited: &MultiAssets, - expected_beneficiary: &MultiLocation, + expected_reserve_assets_deposited: &Assets, + expected_beneficiary: &Location, ) { let _ = xcm .0 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 915d99470c36..e981fae80154 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -37,7 +37,7 @@ use sp_runtime::{ traits::{MaybeEquivalence, StaticLookup, Zero}, DispatchError, Saturating, }; -use xcm::{latest::prelude::*, VersionedMultiAssets}; +use xcm::{latest::prelude::*, VersionedAssets}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; type RuntimeHelper = @@ -110,7 +110,7 @@ pub fn teleports_for_native_asset_works< 0.into() ); - let native_asset_id = MultiLocation::parent(); + let native_asset_id = Location::parent(); let buy_execution_fee_amount_eta = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 1024)); let native_asset_amount_unit = existential_deposit; @@ -119,38 +119,40 @@ pub fn teleports_for_native_asset_works< // 1. process received teleported assets from relaychain let xcm = Xcm(vec![ - ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(native_asset_id), + ReceiveTeleportedAsset(Assets::from(vec![Asset { + id: AssetId(native_asset_id.clone()), fun: Fungible(native_asset_amount_received.into()), }])), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(native_asset_id), + fees: Asset { + id: AssetId(native_asset_id.clone()), fun: Fungible(buy_execution_fee_amount_eta), }, weight_limit: Limited(Weight::from_parts(3035310000, 65536)), }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: target_account.clone().into(), - }), + }] + .into(), }, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( Parent, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Parent), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -163,14 +165,14 @@ pub fn teleports_for_native_asset_works< // 2. try to teleport asset back to the relaychain { - let dest = MultiLocation::parent(); - let mut dest_beneficiary = MultiLocation::parent() + let dest = Location::parent(); + let mut dest_beneficiary = Location::parent() .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::free_balance(&target_account); @@ -183,11 +185,11 @@ pub fn teleports_for_native_asset_works< // Mint funds into account to ensure it has enough balance to pay delivery fees let delivery_fees = xcm_helpers::transfer_assets_delivery_fees::( - (native_asset_id, native_asset_to_teleport_away.into()).into(), + (native_asset_id.clone(), native_asset_to_teleport_away.into()).into(), 0, Unlimited, - dest_beneficiary, - dest, + dest_beneficiary.clone(), + dest.clone(), ); >::mint_into( &target_account, @@ -199,7 +201,7 @@ pub fn teleports_for_native_asset_works< RuntimeHelper::::origin_of(target_account.clone()), dest, dest_beneficiary, - (native_asset_id, native_asset_to_teleport_away.into()), + (native_asset_id.clone(), native_asset_to_teleport_away.into()), None, included_head.clone(), &alice, @@ -228,14 +230,14 @@ pub fn teleports_for_native_asset_works< // trust `IsTeleporter` for `(relay-native-asset, para(2345))` pair { let other_para_id = 2345; - let dest = MultiLocation::new(1, X1(Parachain(other_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id))) + let dest = Location::new(1, [Parachain(other_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(other_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::free_balance(&target_account); @@ -245,6 +247,7 @@ pub fn teleports_for_native_asset_works< native_asset_to_teleport_away < target_account_balance_before_teleport - existential_deposit ); + assert_eq!( RuntimeHelper::::do_teleport_assets::( RuntimeHelper::::origin_of(target_account.clone()), @@ -356,9 +359,9 @@ pub fn teleports_for_foreign_assets_works< ::Balance: From + Into, SovereignAccountOf: ConvertLocation>, >::AssetId: - From + Into, + From + Into, >::AssetIdParameter: - From + Into, + From + Into, >::Balance: From + Into, ::AccountId: @@ -370,23 +373,25 @@ pub fn teleports_for_foreign_assets_works< { // foreign parachain with the same consensus currency as asset let foreign_para_id = 2222; - let foreign_asset_id_multilocation = MultiLocation { + let foreign_asset_id_location = xcm::v3::Location { parents: 1, - interior: X2(Parachain(foreign_para_id), GeneralIndex(1234567)), + interior: [ + xcm::v3::Junction::Parachain(foreign_para_id), + xcm::v3::Junction::GeneralIndex(1234567), + ] + .into(), }; // foreign creator, which can be sibling parachain to match ForeignCreators - let foreign_creator = MultiLocation { parents: 1, interior: X1(Parachain(foreign_para_id)) }; + let foreign_creator = Location { parents: 1, interior: [Parachain(foreign_para_id)].into() }; let foreign_creator_as_account_id = SovereignAccountOf::convert_location(&foreign_creator).expect(""); // we want to buy execution with local relay chain currency let buy_execution_fee_amount = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 0)); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation::parent()), - fun: Fungible(buy_execution_fee_amount), - }; + let buy_execution_fee = + Asset { id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount) }; let teleported_foreign_asset_amount = 10_000_000_000_000; let runtime_para_id = 1000; @@ -425,14 +430,14 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -441,14 +446,14 @@ pub fn teleports_for_foreign_assets_works< assert_total::< pallet_assets::Pallet, AccountIdOf, - >(foreign_asset_id_multilocation, 0, 0); + >(foreign_asset_id_location, 0, 0); // create foreign asset (0 total issuance) let asset_minimum_asset_balance = 3333333_u128; assert_ok!( >::force_create( RuntimeHelper::::root_origin(), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), asset_owner.into(), false, asset_minimum_asset_balance.into() @@ -457,47 +462,52 @@ pub fn teleports_for_foreign_assets_works< assert_total::< pallet_assets::Pallet, AccountIdOf, - >(foreign_asset_id_multilocation, 0, 0); + >(foreign_asset_id_location, 0, 0); assert!(teleported_foreign_asset_amount > asset_minimum_asset_balance); + let foreign_asset_id_location_latest: Location = + foreign_asset_id_location.try_into().unwrap(); + // 1. process received teleported assets from sibling parachain (foreign_para_id) let xcm = Xcm(vec![ // BuyExecution with relaychain native token WithdrawAsset(buy_execution_fee.clone().into()), BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation::parent()), + fees: Asset { + id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount), }, weight_limit: Limited(Weight::from_parts(403531000, 65536)), }, // Process teleported asset - ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + ReceiveTeleportedAsset(Assets::from(vec![Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(teleported_foreign_asset_amount), }])), DepositAsset { assets: Wild(AllOf { - id: Concrete(foreign_asset_id_multilocation), + id: AssetId(foreign_asset_id_location_latest.clone()), fun: WildFungibility::Fungible, }), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: target_account.clone().into(), - }), + }] + .into(), }, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( foreign_creator, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -508,7 +518,7 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), teleported_foreign_asset_amount.into() @@ -520,7 +530,7 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -530,25 +540,25 @@ pub fn teleports_for_foreign_assets_works< pallet_assets::Pallet, AccountIdOf, >( - foreign_asset_id_multilocation, + foreign_asset_id_location, teleported_foreign_asset_amount, teleported_foreign_asset_amount, ); // 2. try to teleport asset back to source parachain (foreign_para_id) { - let dest = MultiLocation::new(1, X1(Parachain(foreign_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(foreign_para_id))) + let dest = Location::new(1, [Parachain(foreign_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(foreign_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account, ); let asset_to_teleport_away = asset_minimum_asset_balance * 3; @@ -562,11 +572,11 @@ pub fn teleports_for_foreign_assets_works< // Make sure the target account has enough native asset to pay for delivery fees let delivery_fees = xcm_helpers::transfer_assets_delivery_fees::( - (foreign_asset_id_multilocation, asset_to_teleport_away).into(), + (foreign_asset_id_location_latest.clone(), asset_to_teleport_away).into(), 0, Unlimited, - dest_beneficiary, - dest, + dest_beneficiary.clone(), + dest.clone(), ); >::mint_into( &target_account, @@ -578,7 +588,7 @@ pub fn teleports_for_foreign_assets_works< RuntimeHelper::::origin_of(target_account.clone()), dest, dest_beneficiary, - (foreign_asset_id_multilocation, asset_to_teleport_away), + (foreign_asset_id_location_latest.clone(), asset_to_teleport_away), Some((runtime_para_id, foreign_para_id)), included_head, &alice, @@ -587,14 +597,14 @@ pub fn teleports_for_foreign_assets_works< // check balances assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), (target_account_balance_before_teleport - asset_to_teleport_away.into()) ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -604,7 +614,7 @@ pub fn teleports_for_foreign_assets_works< pallet_assets::Pallet, AccountIdOf, >( - foreign_asset_id_multilocation, + foreign_asset_id_location, teleported_foreign_asset_amount - asset_to_teleport_away, teleported_foreign_asset_amount - asset_to_teleport_away, ); @@ -717,17 +727,19 @@ pub fn asset_transactor_transfer_with_local_consensus_currency_works BOB let _ = RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: source_account.clone().into() }), + interior: [AccountId32 { network: None, id: source_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: target_account.clone().into() }), + interior: [AccountId32 { network: None, id: target_account.clone().into() }] + .into(), }, // local_consensus_currency_asset, e.g.: relaychain token (KSM, DOT, ...) ( - MultiLocation { parents: 1, interior: Here }, + Location { parents: 1, interior: Here }, (BalanceOf::::from(1_u128) * unit).into(), ), ) @@ -779,7 +791,7 @@ macro_rules! include_asset_transactor_transfer_with_local_consensus_currency_wor } ); -///Test-case makes sure that `Runtime`'s `xcm::AssetTransactor` can handle native relay chain +/// Test-case makes sure that `Runtime`'s `xcm::AssetTransactor` can handle native relay chain /// currency pub fn asset_transactor_transfer_with_pallet_assets_instance_works< Runtime, @@ -820,8 +832,8 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< <::Lookup as StaticLookup>::Source: From<::AccountId>, AssetsPalletInstance: 'static, - AssetId: Clone + Copy, - AssetIdConverter: MaybeEquivalence, + AssetId: Clone, + AssetIdConverter: MaybeEquivalence, { ExtBuilder::::default() .with_collators(collator_session_keys.collators()) @@ -836,10 +848,10 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< .execute_with(|| { // create some asset class let asset_minimum_asset_balance = 3333333_u128; - let asset_id_as_multilocation = AssetIdConverter::convert_back(&asset_id).unwrap(); + let asset_id_as_location = AssetIdConverter::convert_back(&asset_id).unwrap(); assert_ok!(>::force_create( RuntimeHelper::::root_origin(), - asset_id.into(), + asset_id.clone().into(), asset_owner.clone().into(), false, asset_minimum_asset_balance.into() @@ -848,7 +860,7 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // We first mint enough asset for the account to exist for assets assert_ok!(>::mint( RuntimeHelper::::origin_of(asset_owner.clone()), - asset_id.into(), + asset_id.clone().into(), alice_account.clone().into(), (6 * asset_minimum_asset_balance).into() )); @@ -856,28 +868,28 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // check Assets before assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &alice_account ), (6 * asset_minimum_asset_balance).into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &bob_account ), 0.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &charlie_account ), 0.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &asset_owner ), 0.into() @@ -904,21 +916,20 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // ExistentialDeposit) assert_noop!( RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { - network: None, - id: alice_account.clone().into() - }), + interior: [AccountId32 { network: None, id: alice_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: charlie_account.clone().into() - }), + }] + .into(), }, - (asset_id_as_multilocation, asset_minimum_asset_balance), + (asset_id_as_location.clone(), asset_minimum_asset_balance), ), XcmError::FailedToTransactAsset(Into::<&str>::into( sp_runtime::TokenError::CannotCreate @@ -928,18 +939,17 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // transfer_asset (deposit/withdraw) ALICE -> BOB (ok - has ExistentialDeposit) assert!(matches!( RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { - network: None, - id: alice_account.clone().into() - }), + interior: [AccountId32 { network: None, id: alice_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: bob_account.clone().into() }), + interior: [AccountId32 { network: None, id: bob_account.clone().into() }] + .into(), }, - (asset_id_as_multilocation, asset_minimum_asset_balance), + (asset_id_as_location, asset_minimum_asset_balance), ), Ok(_) )); @@ -947,21 +957,21 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // check Assets after assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &alice_account ), (5 * asset_minimum_asset_balance).into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &bob_account ), asset_minimum_asset_balance.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &charlie_account ), 0.into() @@ -1093,26 +1103,23 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor <::Lookup as StaticLookup>::Source: From<::AccountId>, ForeignAssetsPalletInstance: 'static, - AssetId: Clone + Copy, - AssetIdConverter: MaybeEquivalence, + AssetId: Clone, + AssetIdConverter: MaybeEquivalence, { - // foreign parachain with the same consensus currency as asset - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(2222), GeneralIndex(1234567)) }; - let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap(); + // foreign parachain with the same consenus currency as asset + let foreign_asset_id_location = Location::new(1, [Parachain(2222), GeneralIndex(1234567)]); + let asset_id = AssetIdConverter::convert(&foreign_asset_id_location).unwrap(); // foreign creator, which can be sibling parachain to match ForeignCreators - let foreign_creator = MultiLocation { parents: 1, interior: X1(Parachain(2222)) }; + let foreign_creator = Location { parents: 1, interior: [Parachain(2222)].into() }; let foreign_creator_as_account_id = SovereignAccountOf::convert_location(&foreign_creator).expect(""); // we want to buy execution with local relay chain currency let buy_execution_fee_amount = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 0)); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation::parent()), - fun: Fungible(buy_execution_fee_amount), - }; + let buy_execution_fee = + Asset { id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount) }; const ASSET_NAME: &str = "My super coin"; const ASSET_SYMBOL: &str = "MY_S_COIN"; @@ -1152,7 +1159,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::create { - id: asset_id.into(), + id: asset_id.clone().into(), // admin as sovereign_account admin: foreign_creator_as_account_id.clone().into(), min_balance: 1.into(), @@ -1162,7 +1169,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::set_metadata { - id: asset_id.into(), + id: asset_id.clone().into(), name: Vec::from(ASSET_NAME), symbol: Vec::from(ASSET_SYMBOL), decimals: 12, @@ -1172,7 +1179,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::set_team { - id: asset_id.into(), + id: asset_id.clone().into(), issuer: foreign_creator_as_account_id.clone().into(), admin: foreign_creator_as_account_id.clone().into(), freezer: bob_account.clone().into(), @@ -1202,14 +1209,15 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor ]); // messages with different consensus should go through the local bridge-hub - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( - foreign_creator, + let outcome = XcmExecutor::::prepare_and_execute( + foreign_creator.clone(), xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -1230,25 +1238,25 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor use frame_support::traits::fungibles::roles::Inspect as InspectRoles; assert_eq!( >::owner( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::admin( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::issuer( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::freezer( - asset_id.into() + asset_id.clone().into() ), Some(bob_account.clone()) ); @@ -1262,13 +1270,13 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor assert_metadata::< pallet_assets::Pallet, AccountIdOf, - >(asset_id, ASSET_NAME, ASSET_SYMBOL, 12); + >(asset_id.clone(), ASSET_NAME, ASSET_SYMBOL, 12); // check if changed freezer, can freeze assert_noop!( >::freeze( RuntimeHelper::::origin_of(bob_account), - asset_id.into(), + asset_id.clone().into(), alice_account.clone().into() ), pallet_assets::Error::::NoAccount @@ -1284,9 +1292,9 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor // lets try create asset for different parachain(3333) (foreign_creator(2222) can create // just his assets) - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(3333), GeneralIndex(1234567)) }; - let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap(); + let foreign_asset_id_location = + Location { parents: 1, interior: [Parachain(3333), GeneralIndex(1234567)].into() }; + let asset_id = AssetIdConverter::convert(&foreign_asset_id_location).unwrap(); // prepare data for xcm::Transact(create) let foreign_asset_create = runtime_call_encode(pallet_assets::Call::< @@ -1310,14 +1318,15 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor ]); // messages with different consensus should go through the local bridge-hub - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( foreign_creator, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -1441,15 +1450,15 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< // reserve-transfer native asset with local reserve to remote parachain (2345) let other_para_id = 2345; - let native_asset = MultiLocation::parent(); - let dest = MultiLocation::new(1, X1(Parachain(other_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id))) + let native_asset = Location::parent(); + let dest = Location::new(1, [Parachain(other_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(other_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let reserve_account = LocationToAccountId::convert_location(&dest) .expect("Sovereign account for reserves"); @@ -1495,17 +1504,15 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< ); // local native asset (pallet_balances) - let asset_to_transfer = MultiAsset { - fun: Fungible(balance_to_transfer.into()), - id: Concrete(native_asset), - }; + let asset_to_transfer = + Asset { fun: Fungible(balance_to_transfer.into()), id: AssetId(native_asset) }; // pallet_xcm call reserve transfer assert_ok!(>::limited_reserve_transfer_assets( RuntimeHelper::::origin_of(alice_account.clone()), - Box::new(dest.into_versioned()), - Box::new(dest_beneficiary.into_versioned()), - Box::new(VersionedMultiAssets::from(MultiAssets::from(asset_to_transfer))), + Box::new(dest.clone().into_versioned()), + Box::new(dest_beneficiary.clone().into_versioned()), + Box::new(VersionedAssets::from(Assets::from(asset_to_transfer))), 0, weight_limit, )); @@ -1535,9 +1542,12 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< ) .unwrap(); + let v4_xcm: Xcm<()> = xcm_sent.clone().try_into().unwrap(); + dbg!(&v4_xcm); + let delivery_fees = get_fungible_delivery_fees::< ::XcmSender, - >(dest, Xcm::try_from(xcm_sent.clone()).unwrap()); + >(dest.clone(), Xcm::try_from(xcm_sent.clone()).unwrap()); assert_eq!( xcm_sent_message_hash, @@ -1547,8 +1557,8 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< // check sent XCM Program to other parachain println!("reserve_transfer_native_asset_works sent xcm: {:?}", xcm_sent); - let reserve_assets_deposited = MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + let reserve_assets_deposited = Assets::from(vec![Asset { + id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(1000000000000), }]); diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index d7441880426d..878dddc91372 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -31,15 +31,15 @@ use parachains_runtimes_test_utils::{ }; use sp_runtime::{traits::StaticLookup, Saturating}; use sp_std::ops::Mul; -use xcm::{latest::prelude::*, VersionedMultiAssets}; +use xcm::{latest::prelude::*, VersionedAssets}; use xcm_builder::{CreateMatcher, MatchXcm}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; pub struct TestBridgingConfig { pub bridged_network: NetworkId, pub local_bridge_hub_para_id: u32, - pub local_bridge_hub_location: MultiLocation, - pub bridged_target_location: MultiLocation, + pub local_bridge_hub_location: Location, + pub bridged_target_location: Location, } /// Test-case makes sure that `Runtime` can initiate **reserve transfer assets** over bridge. @@ -117,7 +117,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< LocationToAccountId::convert_location(&target_location_from_different_consensus) .expect("Sovereign account for reserves"); let balance_to_transfer = 1_000_000_000_000_u128; - let native_asset = MultiLocation::parent(); + let native_asset = Location::parent(); // open HRMP to bridge hub mock_open_hrmp_channel::( @@ -163,35 +163,33 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< .unwrap_or(0.into()); // local native asset (pallet_balances) - let asset_to_transfer = MultiAsset { - fun: Fungible(balance_to_transfer.into()), - id: Concrete(native_asset), - }; + let asset_to_transfer = + Asset { fun: Fungible(balance_to_transfer.into()), id: native_asset.into() }; // destination is (some) account relative to the destination different consensus - let target_destination_account = MultiLocation { - parents: 0, - interior: X1(AccountId32 { + let target_destination_account = Location::new( + 0, + [AccountId32 { network: Some(bridged_network), id: sp_runtime::AccountId32::new([3; 32]).into(), - }), - }; + }], + ); - let assets_to_transfer = MultiAssets::from(asset_to_transfer); + let assets_to_transfer = Assets::from(asset_to_transfer); let mut expected_assets = assets_to_transfer.clone(); let context = XcmConfig::UniversalLocation::get(); expected_assets - .reanchor(&target_location_from_different_consensus, context) + .reanchor(&target_location_from_different_consensus, &context) .unwrap(); - let expected_beneficiary = target_destination_account; + let expected_beneficiary = target_destination_account.clone(); // do pallet_xcm call reserve transfer assert_ok!(>::limited_reserve_transfer_assets( RuntimeHelper::::origin_of(alice_account.clone()), - Box::new(target_location_from_different_consensus.into_versioned()), + Box::new(target_location_from_different_consensus.clone().into_versioned()), Box::new(target_destination_account.into_versioned()), - Box::new(VersionedMultiAssets::from(assets_to_transfer)), + Box::new(VersionedAssets::from(assets_to_transfer)), 0, weight_limit, )); @@ -266,13 +264,17 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< let (_, target_location_junctions_without_global_consensus) = target_location_from_different_consensus .interior + .clone() .split_global() .expect("split works"); assert_eq!(destination, &target_location_junctions_without_global_consensus); // Call `SendXcm::validate` to get delivery fees. delivery_fees = get_fungible_delivery_fees::< ::XcmSender, - >(target_location_from_different_consensus, inner_xcm.clone()); + >( + target_location_from_different_consensus.clone(), + inner_xcm.clone(), + ); assert_matches_reserve_asset_deposited_instructions( inner_xcm, &expected_assets, @@ -322,10 +324,10 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< target_account: AccountIdOf, block_author_account: AccountIdOf, ( - foreign_asset_id_multilocation, + foreign_asset_id_location, transfered_foreign_asset_id_amount, foreign_asset_id_minimum_balance, - ): (MultiLocation, u128, u128), + ): (xcm::v3::Location, u128, u128), prepare_configuration: fn() -> TestBridgingConfig, (bridge_instance, universal_origin, descend_origin): (Junctions, Junction, Junctions), /* bridge adds origin manipulation on the way */ ) where @@ -347,9 +349,9 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< XcmConfig: xcm_executor::Config, LocationToAccountId: ConvertLocation>, >::AssetId: - From + Into, + From + Into, >::AssetIdParameter: - From + Into, + From + Into, >::Balance: From + Into + From, ::AccountId: Into<<::RuntimeOrigin as OriginTrait>::AccountId> @@ -357,7 +359,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< <::Lookup as StaticLookup>::Source: From<::AccountId>, ::AssetKind: - From + Into, + From + Into, ::Balance: From, ForeignAssetsPalletInstance: 'static, { @@ -385,7 +387,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // sovereign account as foreign asset owner (can be whoever for this scenario, doesnt // matter) let sovereign_account_as_owner_of_foreign_asset = - LocationToAccountId::convert_location(&MultiLocation::parent()).unwrap(); + LocationToAccountId::convert_location(&Location::parent()).unwrap(); // staking pot account for collecting local native fees from `BuyExecution` let staking_pot = >::account_id(); @@ -398,16 +400,16 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< assert_ok!( >::force_create( RuntimeHelper::::root_origin(), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), sovereign_account_as_owner_of_foreign_asset.clone().into(), true, // is_sufficient=true foreign_asset_id_minimum_balance.into() ) ); - // setup a pool to pay fees with `foreign_asset_id_multilocation` tokens + // setup a pool to pay fees with `foreign_asset_id_location` tokens let pool_owner: AccountIdOf = [1u8; 32].into(); - let native_asset = MultiLocation::parent(); + let native_asset = xcm::v3::Location::parent(); let pool_liquidity: u128 = existential_deposit.into().max(foreign_asset_id_minimum_balance).mul(100_000); @@ -420,7 +422,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< RuntimeHelper::::origin_of( sovereign_account_as_owner_of_foreign_asset ), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), pool_owner.clone().into(), (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), )); @@ -428,13 +430,13 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< assert_ok!(>::create_pool( RuntimeHelper::::origin_of(pool_owner.clone()), Box::new(native_asset.into()), - Box::new(foreign_asset_id_multilocation.into()) + Box::new(foreign_asset_id_location.into()) )); assert_ok!(>::add_liquidity( RuntimeHelper::::origin_of(pool_owner.clone()), Box::new(native_asset.into()), - Box::new(foreign_asset_id_multilocation.into()), + Box::new(foreign_asset_id_location.into()), pool_liquidity.into(), pool_liquidity.into(), 1.into(), @@ -459,34 +461,37 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // ForeignAssets balances before assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &block_author_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &staking_pot ), 0.into() ); - let expected_assets = MultiAssets::from(vec![MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + let foreign_asset_id_location_latest: Location = + foreign_asset_id_location.try_into().unwrap(); + + let expected_assets = Assets::from(vec![Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(transfered_foreign_asset_id_amount), }]); - let expected_beneficiary = MultiLocation { - parents: 0, - interior: X1(AccountId32 { network: None, id: target_account.clone().into() }), - }; + let expected_beneficiary = Location::new( + 0, + [AccountId32 { network: None, id: target_account.clone().into() }], + ); // Call received XCM execution let xcm = Xcm(vec![ @@ -496,13 +501,16 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ReserveAssetDeposited(expected_assets.clone()), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + fees: Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(transfered_foreign_asset_id_amount), }, weight_limit: Unlimited, }, - DepositAsset { assets: Wild(AllCounted(1)), beneficiary: expected_beneficiary }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: expected_beneficiary.clone(), + }, SetTopic([ 220, 188, 144, 32, 213, 83, 111, 175, 44, 210, 111, 19, 90, 165, 191, 112, 140, 247, 192, 124, 42, 17, 153, 141, 114, 34, 189, 20, 83, 69, 237, 173, @@ -514,16 +522,17 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< &expected_beneficiary, ); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( local_bridge_hub_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight( XcmReceivedFrom::Sibling, ), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -545,20 +554,20 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // ForeignAssets balances after assert!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ) > 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &staking_pot ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &block_author_account ), 0.into() @@ -614,14 +623,15 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< // Call received XCM execution let xcm = if is_congested { congested_message() } else { uncongested_message() }; - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( local_bridge_hub_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); assert_eq!(is_congested, pallet_xcm_bridge_hub_router::Pallet::::bridge().is_congested); 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 0aebe38fef53..f509a3a8acaa 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs @@ -23,11 +23,11 @@ use xcm::latest::prelude::*; /// Because it returns only a `u128`, it assumes delivery fees are only paid /// in one asset and that asset is known. pub fn transfer_assets_delivery_fees( - assets: MultiAssets, + assets: Assets, fee_asset_item: u32, weight_limit: WeightLimit, - beneficiary: MultiLocation, - destination: MultiLocation, + beneficiary: Location, + destination: Location, ) -> u128 { let message = teleport_assets_dummy_message(assets, fee_asset_item, weight_limit, beneficiary); get_fungible_delivery_fees::(destination, message) @@ -35,7 +35,7 @@ pub fn transfer_assets_delivery_fees( /// Returns the delivery fees amount for a query response as a result of the execution /// of a `ExpectError` instruction with no error. -pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 { +pub fn query_response_delivery_fees(querier: Location) -> u128 { // Message to calculate delivery fees, it's encoded size is what's important. // This message reports that there was no error, if an error is reported, the encoded size would // be different. @@ -45,7 +45,7 @@ pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 query_id: 0, // Dummy query id response: Response::ExecutionResult(None), max_weight: Weight::zero(), - querier: Some(querier), + querier: Some(querier.clone()), }, SetTopic([0u8; 32]), // Dummy topic ]); @@ -55,9 +55,9 @@ pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 /// Returns the delivery fees amount for the execution of `PayOverXcm` pub fn pay_over_xcm_delivery_fees( interior: Junctions, - destination: MultiLocation, - beneficiary: MultiLocation, - asset: MultiAsset, + destination: Location, + beneficiary: Location, + asset: Asset, ) -> u128 { // This is a dummy message. // The encoded size is all that matters for delivery fees. @@ -66,7 +66,11 @@ pub fn pay_over_xcm_delivery_fees( UnpaidExecution { weight_limit: Unlimited, check_origin: None }, SetAppendix(Xcm(vec![ SetFeesMode { jit_withdraw: true }, - ReportError(QueryResponseInfo { destination, query_id: 0, max_weight: Weight::zero() }), + ReportError(QueryResponseInfo { + destination: destination.clone(), + query_id: 0, + max_weight: Weight::zero(), + }), ])), TransferAsset { beneficiary, assets: vec![asset].into() }, ]); @@ -78,10 +82,10 @@ pub fn pay_over_xcm_delivery_fees( /// However, it should have the same encoded size, which is what matters for delivery fees. /// Also has same encoded size as the one created by the reserve transfer assets extrinsic. fn teleport_assets_dummy_message( - assets: MultiAssets, + assets: Assets, fee_asset_item: u32, weight_limit: WeightLimit, - beneficiary: MultiLocation, + beneficiary: Location, ) -> Xcm<()> { Xcm(vec![ ReceiveTeleportedAsset(assets.clone()), // Same encoded size as `ReserveAssetDeposited` @@ -93,7 +97,7 @@ fn teleport_assets_dummy_message( } /// Given a message, a sender, and a destination, it returns the delivery fees -fn get_fungible_delivery_fees(destination: MultiLocation, message: Xcm<()>) -> u128 { +fn get_fungible_delivery_fees(destination: Location, message: Xcm<()>) -> u128 { let Ok((_, delivery_fees)) = validate_send::(destination, message) else { unreachable!("message can be sent; qed") }; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index c9d7f60e71a5..1c7bdd4cbff3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -48,7 +48,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess}; use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -65,16 +65,16 @@ parameter_types! { /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. pub const RococoBulletinChainId: bp_runtime::ChainId = bp_runtime::POLKADOT_BULLETIN_CHAIN_ID; /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. - pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorMultiLocation = X1( + pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [ PalletInstance(::index() as u8) - ); + ].into(); /// Rococo Bulletin Network identifier. pub RococoBulletinGlobalConsensusNetwork: NetworkId = NetworkId::PolkadotBulletin; /// Relative location of the Rococo Bulletin chain. - pub RococoBulletinGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())) - }; + pub RococoBulletinGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())] + ); /// All active lanes that the current bridge supports. pub ActiveOutboundLanesToRococoBulletin: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN]; @@ -94,11 +94,11 @@ parameter_types! { /// A route (XCM location and bridge lane) that the Rococo People Chain -> Rococo Bulletin Chain /// message is following. pub FromRococoPeopleToRococoBulletinRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(RococoPeopleParaId::get().into()))).into(), + ParentThen(Parachain(RococoPeopleParaId::get().into()).into()).into(), XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN, ); /// All active routes and their destinations. - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromRococoPeopleToRococoBulletinRoute::get(), (RococoBulletinGlobalConsensusNetwork::get(), Here) @@ -282,11 +282,11 @@ mod tests { PriorityBoostPerMessage, >(FEE_BOOST_PER_MESSAGE); - assert_eq!( - BridgeRococoToRococoBulletinMessagesPalletInstance::get(), - X1(PalletInstance( - bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX - )) - ); + let expected: InteriorLocation = PalletInstance( + bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX, + ) + .into(); + + assert_eq!(BridgeRococoToRococoBulletinMessagesPalletInstance::get(), expected,); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 961b47e1e13b..4e8fe6454cc6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -48,7 +48,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess}; use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -58,12 +58,12 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; - pub BridgeRococoToWestendMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(::index() as u8)); + pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; - pub WestendGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(WestendGlobalConsensusNetwork::get())) - }; + pub WestendGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(WestendGlobalConsensusNetwork::get())] + ); // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; @@ -74,26 +74,26 @@ parameter_types! { pub ActiveOutboundLanesToBridgeHubWestend: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND]; pub const AssetHubRococoToAssetHubWestendMessagesLane: bp_messages::LaneId = XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND; pub FromAssetHubRococoToAssetHubWestendRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(AssetHubRococoParaId::get().into()))).into(), + ParentThen([Parachain(AssetHubRococoParaId::get().into())].into()).into(), XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, ); - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromAssetHubRococoToAssetHubWestendRoute::get(), - (WestendGlobalConsensusNetwork::get(), X1(Parachain(AssetHubWestendParaId::get().into()))) + (WestendGlobalConsensusNetwork::get(), [Parachain(AssetHubWestendParaId::get().into())].into()) ) ]; pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); - pub BridgeHubWestendLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X2( + pub BridgeHubWestendLocation: Location = Location::new( + 2, + [ GlobalConsensus(WestendGlobalConsensusNetwork::get()), Parachain(::PARACHAIN_ID) - ) - }; + ] + ); } pub const XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND: LaneId = LaneId([0, 0, 0, 2]); @@ -327,11 +327,11 @@ mod tests { PriorityBoostPerMessage, >(FEE_BOOST_PER_MESSAGE); - assert_eq!( - BridgeRococoToWestendMessagesPalletInstance::get(), - X1(PalletInstance( - bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX - )) - ); + let expected: InteriorLocation = [PalletInstance( + bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX, + )] + .into(); + + assert_eq!(BridgeRococoToWestendMessagesPalletInstance::get(), expected,); } } 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 0052e9dcb38a..7e99b0393095 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 @@ -78,7 +78,7 @@ use bridge_hub_common::{ use pallet_xcm::EnsureXcm; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::{MultiAddress, Perbill, Permill}; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; use xcm_config::{TreasuryAccount, XcmOriginToTransactDispatchOrigin, XcmRouter}; #[cfg(any(feature = "std", test))] @@ -385,7 +385,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -517,7 +517,7 @@ pub mod benchmark_helpers { use snowbridge_beacon_primitives::CompactExecutionHeader; use snowbridge_pallet_inbound_queue::BenchmarkHelper; use sp_core::H256; - use xcm::latest::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; + use xcm::latest::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; impl BenchmarkHelper for Runtime { fn initialize_storage(block_hash: H256, header: CompactExecutionHeader) { @@ -530,10 +530,10 @@ pub mod benchmark_helpers { type Ticket = Xcm<()>; fn validate( - _dest: &mut Option, + _dest: &mut Option, xcm: &mut Option>, ) -> SendResult { - Ok((xcm.clone().unwrap(), MultiAssets::new())) + Ok((xcm.clone().unwrap(), Assets::new())) } fn deliver(xcm: Xcm<()>) -> Result { let hash = xcm.using_encoded(sp_io::hashing::blake2_256); @@ -542,7 +542,7 @@ pub mod benchmark_helpers { } impl snowbridge_pallet_system::BenchmarkHelper for () { - fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { RuntimeOrigin::from(pallet_xcm::Origin::Xcm(location)) } } @@ -1016,7 +1016,7 @@ impl_runtime_apis! { } impl snowbridge_system_runtime_api::ControlApi for Runtime { - fn agent_id(location: VersionedMultiLocation) -> Option { + fn agent_id(location: VersionedLocation) -> Option { snowbridge_pallet_system::api::agent_id::(location) } } @@ -1095,28 +1095,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between BH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on BH. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = Parent.into(); @@ -1132,7 +1132,7 @@ impl_runtime_apis! { use xcm_config::TokenLocation; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -1143,17 +1143,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(TokenLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(TokenLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -1162,12 +1162,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( TokenLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -1177,9 +1177,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(UNITS), } } @@ -1193,35 +1193,35 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(TokenLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = TokenLocation::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // save XCM version for remote bridge hub let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), @@ -1241,12 +1241,12 @@ impl_runtime_apis! { ( bridge_to_westend_config::FromAssetHubRococoToAssetHubWestendRoute::get().location, NetworkId::Westend, - X1(Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())) + [Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())].into() ) ) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } @@ -1296,7 +1296,7 @@ impl_runtime_apis! { Runtime, bridge_common_config::BridgeGrandpaWestendInstance, bridge_to_westend_config::WithBridgeHubWestendMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Rococo), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } fn prepare_message_delivery_proof( @@ -1331,7 +1331,7 @@ impl_runtime_apis! { Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, bridge_to_bulletin_config::WithRococoBulletinMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Rococo), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } fn prepare_message_delivery_proof( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs index 1c2334a89e25..4f5bae0fe597 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct BridgeHubRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for BridgeHubRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,44 +107,36 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -163,7 +151,7 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -175,13 +163,13 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -215,16 +203,16 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { let inner_encoded_len = inner.encode().len() as u32; XcmGeneric::::export_message(inner_encoded_len) } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -236,11 +224,11 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index dc98622cafca..f641b428d4c6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -32,7 +32,7 @@ use bp_messages::LaneId; use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::ChainId; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -69,19 +69,19 @@ use xcm_executor::{ }; parameter_types! { - pub const TokenLocation: MultiLocation = MultiLocation::parent(); + pub const TokenLocation: Location = Location::parent(); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub RelayNetwork: NetworkId = NetworkId::Rococo; - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); - pub SiblingPeople: MultiLocation = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub SiblingPeople: Location = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -100,7 +100,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -132,11 +132,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -331,7 +331,7 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -407,14 +407,10 @@ impl< BridgeLaneId, > { - fn handle_fee( - fee: MultiAssets, - maybe_context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, maybe_context: Option<&XcmContext>, reason: FeeReason) -> Assets { if matches!(reason, FeeReason::Export { network: bridged_network, destination } if bridged_network == DestNetwork::get() && - destination == X1(Parachain(DestParaId::get().into()))) + destination == [Parachain(DestParaId::get().into())]) { // We have 2 relayer rewards accounts: // - the SA of the source parachain on this BH: this pays the relayers for delivering @@ -445,14 +441,14 @@ impl< Fungible(total_fee) => { let source_fee = total_fee / 2; deposit_or_burn_fee::( - MultiAsset { id: asset.id, fun: Fungible(source_fee) }.into(), + Asset { id: asset.id.clone(), fun: Fungible(source_fee) }.into(), maybe_context, source_para_account.clone(), ); let dest_fee = total_fee - source_fee; deposit_or_burn_fee::( - MultiAsset { id: asset.id, fun: Fungible(dest_fee) }.into(), + Asset { id: asset.id, fun: Fungible(dest_fee) }.into(), maybe_context, dest_para_account.clone(), ); @@ -467,7 +463,7 @@ impl< } } - return MultiAssets::new() + return Assets::new() } fee @@ -477,10 +473,10 @@ impl< pub struct XcmFeeManagerFromComponentsBridgeHub( PhantomData<(WaivedLocations, HandleFee)>, ); -impl, FeeHandler: HandleFee> FeeManager +impl, FeeHandler: HandleFee> FeeManager for XcmFeeManagerFromComponentsBridgeHub { - fn is_waived(origin: Option<&MultiLocation>, fee_reason: FeeReason) -> bool { + fn is_waived(origin: Option<&Location>, fee_reason: FeeReason) -> bool { let Some(loc) = origin else { return false }; if let Export { network, destination: Here } = fee_reason { return !(network == EthereumNetwork::get()) @@ -488,7 +484,7 @@ impl, FeeHandler: HandleFee> FeeManager WaivedLocations::contains(loc) } - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) { FeeHandler::handle_fee(fee, context, reason); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 0fba28c47b43..63e64506ec75 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -241,7 +241,7 @@ mod bridge_hub_westend_tests { _ => None, } }), - || ExportMessage { network: Westend, destination: X1(Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())), xcm: Xcm(vec![]) }, + || ExportMessage { network: Westend, destination: [Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())].into(), xcm: Xcm(vec![]) }, XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, Some((TokenLocation::get(), ExistentialDeposit::get()).into()), // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index eb5493872b40..716e01b85b42 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -47,7 +47,7 @@ use frame_support::{ use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -63,12 +63,12 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; - pub BridgeWestendToRococoMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(::index() as u8)); + pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; - pub RococoGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(RococoGlobalConsensusNetwork::get())) - }; + pub RococoGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(RococoGlobalConsensusNetwork::get())] + ); // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; @@ -79,26 +79,26 @@ parameter_types! { pub ActiveOutboundLanesToBridgeHubRococo: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO]; pub const AssetHubWestendToAssetHubRococoMessagesLane: bp_messages::LaneId = XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO; pub FromAssetHubWestendToAssetHubRococoRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(AssetHubWestendParaId::get().into()))).into(), + ParentThen([Parachain(AssetHubWestendParaId::get().into())].into()).into(), XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, ); - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromAssetHubWestendToAssetHubRococoRoute::get(), - (RococoGlobalConsensusNetwork::get(), X1(Parachain(AssetHubRococoParaId::get().into()))) + (RococoGlobalConsensusNetwork::get(), [Parachain(AssetHubRococoParaId::get().into())].into()) ) ]; pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); - pub BridgeHubRococoLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X2( + pub BridgeHubRococoLocation: Location = Location::new( + 2, + [ GlobalConsensus(RococoGlobalConsensusNetwork::get()), Parachain(::PARACHAIN_ID) - ) - }; + ] + ); } pub const XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO: LaneId = LaneId([0, 0, 0, 2]); @@ -363,9 +363,9 @@ mod tests { assert_eq!( BridgeWestendToRococoMessagesPalletInstance::get(), - X1(PalletInstance( + [PalletInstance( bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX - )) + )] ); } } 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 717cde6280db..d920f5a98cf6 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 @@ -352,7 +352,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WestendLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -797,28 +797,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between BH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on BH. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = Parent.into(); @@ -834,7 +834,7 @@ impl_runtime_apis! { use xcm_config::WestendLocation; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WestendLocation::get(), ExistentialDeposit::get() ).into()); @@ -845,17 +845,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WestendLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { - // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(WestendLocation::get()), + fn worst_case_holding(_depositable_count: u32) -> Assets { + // just assets according to relay chain. + let assets: Vec = vec![ + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -864,12 +864,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WestendLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -879,9 +879,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WestendLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(UNITS), } } @@ -895,35 +895,35 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WestendLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WestendLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = WestendLocation::get(); - let assets: MultiAssets = (Concrete(WestendLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // save XCM version for remote bridge hub let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), @@ -943,12 +943,12 @@ impl_runtime_apis! { ( bridge_to_rococo_config::FromAssetHubWestendToAssetHubRococoRoute::get().location, NetworkId::Rococo, - X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())) + [Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())].into() ) ) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } @@ -995,7 +995,7 @@ impl_runtime_apis! { Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, bridge_to_rococo_config::WithBridgeHubRococoMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Westend), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Westend), Parachain(42)].into())) } fn prepare_message_delivery_proof( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs index 7269fa84f84a..e8950678b40f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs @@ -25,14 +25,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -51,40 +51,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct BridgeHubWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for BridgeHubWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,44 +108,36 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -164,7 +152,7 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -176,13 +164,13 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -216,16 +204,16 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { let inner_encoded_len = inner.encode().len() as u32; XcmGeneric::::export_message(inner_encoded_len) } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -237,11 +225,11 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs index 397019190f3f..085608acf5d8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs @@ -21,7 +21,7 @@ use super::{ }; use crate::bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -52,18 +52,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Westend; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -82,7 +82,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -114,11 +114,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -270,7 +270,7 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 0e58b7b408eb..1237a2313901 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -207,7 +207,7 @@ fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { _ => None, } }), - || ExportMessage { network: Rococo, destination: X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())), xcm: Xcm(vec![]) }, + || ExportMessage { network: Rococo, destination: [Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())].into(), xcm: Xcm(vec![]) }, XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, Some((WestendLocation::get(), ExistentialDeposit::get()).into()), // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs index 3e821d455694..c1bba65b0abc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs @@ -23,7 +23,7 @@ use pallet_message_queue::OnQueueChanged; use scale_info::TypeInfo; use snowbridge_core::ChannelId; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::v3::{Junction, MultiLocation}; +use xcm::v4::{Junction, Location}; /// The aggregate origin of an inbound message. /// This is specialized for BridgeHub, as the snowbridge-outbound-queue-pallet is also using @@ -46,16 +46,16 @@ pub enum AggregateMessageOrigin { Snowbridge(ChannelId), } -impl From for MultiLocation { +impl From for Location { fn from(origin: AggregateMessageOrigin) -> Self { use AggregateMessageOrigin::*; match origin { - Here => MultiLocation::here(), - Parent => MultiLocation::parent(), - Sibling(id) => MultiLocation::new(1, Junction::Parachain(id.into())), + Here => Location::here(), + Parent => Location::parent(), + Sibling(id) => Location::new(1, Junction::Parachain(id.into())), // NOTE: We don't need this conversion for Snowbridge. However we have to // implement it anyway as xcm_builder::ProcessXcmMessage requires it. - Snowbridge(_) => MultiLocation::default(), + Snowbridge(_) => Location::default(), } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index e0e75f093cfc..5eca85d3112e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -336,9 +336,9 @@ where (), >( LaneId::default(), - vec![xcm::v3::Instruction::<()>::ClearOrigin; 1_024].into(), + vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, - X2(GlobalConsensus(Polkadot), Parachain(1_000)), + [GlobalConsensus(Polkadot), Parachain(1_000)].into(), 1u32.into(), ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 91bebb36b187..6e638b7b3503 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -418,9 +418,9 @@ where (), >( LaneId::default(), - vec![xcm::v3::Instruction::<()>::ClearOrigin; 1_024].into(), + vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, - X2(GlobalConsensus(Polkadot), Parachain(1_000)), + [GlobalConsensus(Polkadot), Parachain(1_000)].into(), 1, 5, 1_000, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index 69aa61db3cc6..ba58aeb046e0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -230,7 +230,7 @@ pub fn relayed_incoming_message_works( prepare_message_proof_import: impl FnOnce( Runtime::AccountId, Runtime::InboundRelayer, - InteriorMultiLocation, + InteriorLocation, MessageNonce, Xcm<()>, ) -> CallsAndVerifiers, @@ -276,21 +276,21 @@ pub fn relayed_incoming_message_works( // set up relayer details and proofs - let message_destination = - X2(GlobalConsensus(local_relay_chain_id), Parachain(sibling_parachain_id)); + let message_destination: InteriorLocation = + [GlobalConsensus(local_relay_chain_id), Parachain(sibling_parachain_id)].into(); // some random numbers (checked by test) let message_nonce = 1; - let xcm = vec![xcm::v3::Instruction::<()>::ClearOrigin; 42]; + let xcm = vec![Instruction::<()>::ClearOrigin; 42]; let expected_dispatch = xcm::latest::Xcm::<()>({ let mut expected_instructions = xcm.clone(); // dispatch prepends bridge pallet instance expected_instructions.insert( 0, - DescendOrigin(X1(PalletInstance( + DescendOrigin([PalletInstance( as PalletInfoAccess>::index() as u8, - ))), + )].into()), ); expected_instructions }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index 64ec87265992..eb7ba132168d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -319,8 +319,8 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< >, export_message_instruction: fn() -> Instruction, expected_lane_id: LaneId, - existential_deposit: Option, - maybe_paid_export_message: Option, + existential_deposit: Option, + maybe_paid_export_message: Option, prepare_configuration: impl Fn(), ) where Runtime: BasicParachainRuntime + BridgeMessagesConfig, @@ -328,7 +328,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< MessagesPalletInstance: 'static, { assert_ne!(runtime_para_id, sibling_parachain_id); - let sibling_parachain_location = MultiLocation::new(1, Parachain(sibling_parachain_id)); + let sibling_parachain_location = Location::new(1, [Parachain(sibling_parachain_id)]); run_test::(collator_session_key, runtime_para_id, vec![], || { prepare_configuration(); @@ -361,7 +361,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< .expect("deposited fee"); Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![fee.clone()])), + WithdrawAsset(Assets::from(vec![fee.clone()])), BuyExecution { fees: fee, weight_limit: Unlimited }, export_message_instruction(), ]) @@ -373,12 +373,13 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< }; // execute XCM - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - assert_ok!(XcmExecutor::::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + assert_ok!(XcmExecutor::::prepare_and_execute( sibling_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ) .ensure_complete()); @@ -446,9 +447,9 @@ pub fn message_dispatch_routing_works< NetworkDistanceAsParentCount: Get, { struct NetworkWithParentCount(core::marker::PhantomData<(N, C)>); - impl, C: Get> Get for NetworkWithParentCount { - fn get() -> MultiLocation { - MultiLocation { parents: C::get(), interior: X1(GlobalConsensus(N::get())) } + impl, C: Get> Get for NetworkWithParentCount { + fn get() -> Location { + Location::new(C::get(), [GlobalConsensus(N::get())]) } } @@ -495,7 +496,7 @@ pub fn message_dispatch_routing_works< BridgedNetwork, NetworkWithParentCount, AlwaysLatest, - >((RuntimeNetwork::get(), X1(Parachain(sibling_parachain_id)))); + >((RuntimeNetwork::get(), [Parachain(sibling_parachain_id)].into())); // 2.1. WITHOUT opened hrmp channel -> RoutingError let result = @@ -565,52 +566,43 @@ where { // data here are not relevant for weighing let mut xcm = Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + WithdrawAsset(Assets::from(vec![Asset { + id: AssetId(Location::new(1, [])), fun: Fungible(34333299), }])), BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), - fun: Fungible(34333299), - }, + fees: Asset { id: AssetId(Location::new(1, [])), fun: Fungible(34333299) }, weight_limit: Unlimited, }, ExportMessage { network: Polkadot, - destination: X1(Parachain(1000)), + destination: [Parachain(1000)].into(), xcm: Xcm(vec![ - ReserveAssetDeposited(MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Kusama)), - }), + ReserveAssetDeposited(Assets::from(vec![Asset { + id: AssetId(Location::new(2, [GlobalConsensus(Kusama)])), fun: Fungible(1000000000000), }])), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Kusama)), - }), + fees: Asset { + id: AssetId(Location::new(2, [GlobalConsensus(Kusama)])), fun: Fungible(1000000000000), }, weight_limit: Unlimited, }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { - parents: 0, - interior: X1(xcm::latest::prelude::AccountId32 { + beneficiary: Location::new( + 0, + [xcm::latest::prelude::AccountId32 { network: None, 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, ], - }), - }, + }], + ), }, SetTopic([ 116, 82, 194, 132, 171, 114, 217, 165, 23, 37, 161, 177, 165, 179, 247, 114, @@ -618,10 +610,7 @@ where ]), ]), }, - DepositAsset { - assets: Wild(All), - beneficiary: MultiLocation { parents: 1, interior: X1(Parachain(1000)) }, - }, + DepositAsset { assets: Wild(All), beneficiary: Location::new(1, [Parachain(1000)]) }, SetTopic([ 36, 224, 250, 165, 82, 195, 67, 110, 160, 170, 140, 87, 217, 62, 201, 164, 42, 98, 219, 157, 124, 105, 248, 25, 131, 218, 199, 36, 109, 173, 100, 122, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs index f905d21b1871..9285a1e7ad45 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs @@ -37,10 +37,10 @@ use xcm_executor::traits::{validate_export, ExportXcm}; pub fn prepare_inbound_xcm( xcm_message: Xcm, - destination: InteriorMultiLocation, + destination: InteriorLocation, ) -> Vec { - let location = xcm::VersionedInteriorMultiLocation::V3(destination); - let xcm = xcm::VersionedXcm::::V3(xcm_message); + let location = xcm::VersionedInteriorLocation::V4(destination); + let xcm = xcm::VersionedXcm::::V4(xcm_message); // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor // or public fields, so just tuple // (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed @@ -101,7 +101,7 @@ macro_rules! grab_haul_blob ( /// which are transferred over bridge. pub(crate) fn simulate_message_exporter_on_bridged_chain< SourceNetwork: Get, - DestinationNetwork: Get, + DestinationNetwork: Get, DestinationVersion: GetVersion, >( (destination_network, destination_junctions): (NetworkId, Junctions), @@ -109,8 +109,8 @@ pub(crate) fn simulate_message_exporter_on_bridged_chain< grab_haul_blob!(GrabbingHaulBlob, GRABBED_HAUL_BLOB_PAYLOAD); // lets pretend that some parachain on bridged chain exported the message - let universal_source_on_bridged_chain = - X2(GlobalConsensus(SourceNetwork::get()), Parachain(5678)); + let universal_source_on_bridged_chain: Junctions = + [GlobalConsensus(SourceNetwork::get()), Parachain(5678)].into(); let channel = 1_u32; // simulate XCM message export diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs index 9f6378de53a0..05b3427ef431 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs @@ -215,7 +215,7 @@ pub type AmbassadorSalaryInstance = pallet_salary::Instance2; parameter_types! { // The interior location on AssetHub for the paying account. This is the Ambassador Salary // pallet instance (which sits at index 74). This sovereign account will need funding. - pub AmbassadorSalaryLocation: InteriorMultiLocation = PalletInstance(74).into(); + pub AmbassadorSalaryLocation: InteriorLocation = PalletInstance(74).into(); } /// [`PayOverXcm`] setup to pay the Ambassador salary on the AssetHub in WND. diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs index f49306bf8e3a..273fa6a34150 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs @@ -43,7 +43,7 @@ use parachains_common::{ westend::{account, currency::GRAND}, }; use polkadot_runtime_common::impls::{ - LocatableAssetConverter, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; use sp_arithmetic::Permill; use sp_core::{ConstU128, ConstU32}; @@ -202,7 +202,7 @@ pub type FellowshipSalaryInstance = pallet_salary::Instance1; parameter_types! { // The interior location on AssetHub for the paying account. This is the Fellowship Salary // pallet instance (which sits at index 64). This sovereign account will need funding. - pub Interior: InteriorMultiLocation = PalletInstance(64).into(); + pub Interior: InteriorLocation = PalletInstance(64).into(); } const USDT_UNITS: u128 = 1_000_000; @@ -250,7 +250,7 @@ parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); // The asset's interior location for the paying account. This is the Fellowship Treasury // pallet instance (which sits at index 65). - pub FellowshipTreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(65).into(); + pub FellowshipTreasuryInteriorLocation: InteriorLocation = PalletInstance(65).into(); } #[cfg(feature = "runtime-benchmarks")] @@ -269,10 +269,10 @@ pub type FellowshipTreasuryPaymaster = PayOverXcm< crate::xcm_config::XcmRouter, crate::PolkadotXcm, ConstU32<{ 6 * HOURS }>, - VersionedMultiLocation, + VersionedLocation, VersionedLocatableAsset, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; pub type FellowshipTreasuryInstance = pallet_treasury::Instance1; @@ -327,7 +327,7 @@ impl pallet_treasury::Config for Runtime { >, >; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; #[cfg(not(feature = "runtime-benchmarks"))] type Paymaster = FellowshipTreasuryPaymaster; diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 6cb8e096e4b3..a527f620137a 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -427,7 +427,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WndLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WndLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -974,28 +974,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between Collectives and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }.into(), Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on Collectives. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Collectives only supports teleports to system parachain. // Relay/native token can be teleported between Collectives and Relay. let native_location = Parent.into(); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs index 2e64127d6a1d..aa7dbe991e4b 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ TransactionByteFee, WeightToFee, WestendTreasuryAccount, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, weights::Weight, }; @@ -51,17 +51,17 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WndLocation: MultiLocation = MultiLocation::parent(); + pub const WndLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); pub const FellowshipAdminBodyId: BodyId = BodyId::Index(xcm_constants::body::FELLOWSHIP_ADMIN_INDEX); + pub AssetHub: Location = (Parent, Parachain(1000)).into(); pub const TreasurerBodyId: BodyId = BodyId::Index(xcm_constants::body::TREASURER_INDEX); - pub AssetHub: MultiLocation = (Parent, Parachain(1000)).into(); pub AssetHubUsdtId: AssetId = (PalletInstance(50), GeneralIndex(1984)).into(); pub UsdtAssetHub: LocatableAssetId = LocatableAssetId { location: AssetHub::get(), @@ -73,7 +73,7 @@ parameter_types! { }; } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -92,7 +92,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -136,11 +136,11 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -292,7 +292,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -310,10 +310,10 @@ pub type XcmRouter = WithUniqueTopic<( #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = Some(Parent.into()); + pub ReachableDest: Option = Some(Parent.into()); } -/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +/// Type to convert the Fellows origin to a Plurality `Location` value. pub type FellowsToPlurality = OriginToPluralityVoice; impl pallet_xcm::Config for Runtime { diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 79b6b6be299b..bc7d94889a19 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -704,28 +704,28 @@ impl_runtime_apis! { use xcm::latest::prelude::*; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between Contracts-System-Para and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on Contracts-System-Para. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Contracts-System-Para only supports teleports to system parachain. // Relay/native token can be teleported between Contracts-System-Para and Relay. let native_location = Parent.into(); diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs index 569ca6e587c5..e2cf2c8e51a0 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs @@ -20,8 +20,8 @@ use super::{ use crate::common::rococo::currency::CENTS; use cumulus_primitives_core::AggregateMessageOrigin; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, EitherOfDiverse, Equals, Everything, Nothing}, + parameter_types, + traits::{ConstU32, Contains, EitherOfDiverse, Equals, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -51,13 +51,13 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); pub const ExecutiveBody: BodyId = BodyId::Executive; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } /// We allow root and the Relay Chain council to execute privileged collator selection operations. @@ -66,7 +66,7 @@ pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< EnsureXcm>, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -85,7 +85,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -123,11 +123,11 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } pub type Barrier = TrailingSetTopicAsId< @@ -200,7 +200,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -254,7 +254,7 @@ impl cumulus_pallet_xcm::Config for Runtime { parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs index f8a5dc6398ae..a46051212dee 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs @@ -98,7 +98,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Request to update schedulable cores sent successfully." @@ -128,7 +128,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Request for revenue information sent successfully." @@ -157,7 +157,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Instruction to credit account sent successfully." @@ -192,7 +192,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Core assignment sent successfully." diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index c381d78b57f5..c5843c1ef293 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -315,7 +315,7 @@ pub type RootOrFellows = EitherOfDiverse< parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RocRelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RocRelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -698,29 +698,29 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled None } } parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RocRelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -730,18 +730,18 @@ impl_runtime_apis! { type XcmConfig = xcm_config::XcmConfig; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; type AccountIdConverter = xcm_config::LocationToAccountId; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RocRelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RocRelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RocRelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -750,12 +750,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RocRelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RocRelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RocRelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -765,9 +765,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RocRelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RocRelayLocation::get()), fun: Fungible(UNITS), } } @@ -781,39 +781,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RocRelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RocRelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RocRelayLocation::get(); - let assets: MultiAssets = (Concrete(RocRelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RocRelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs index 2319c2e3a5b2..8815312f3042 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct CoretimeRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for CoretimeRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,43 +107,35 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs index 00bbe5b5037f..927d8f0a78e6 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ TransactionByteFee, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -51,18 +51,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RocRelayLocation: MultiLocation = MultiLocation::parent(); + pub const RocRelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); - pub const FellowshipLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); + pub const FellowshipLocation: Location = Location::parent(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -81,7 +81,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -114,11 +114,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -191,7 +191,7 @@ pub type Barrier = TrailingSetTopicAsId< parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Locations that will not be charged fees in the executor, neither for execution nor delivery. @@ -240,7 +240,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 742b3a29275c..59ed8d7c6032 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -306,7 +306,7 @@ pub type RootOrFellows = EitherOfDiverse< parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(WndRelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(WndRelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -689,29 +689,29 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled None } } parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WndRelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -721,18 +721,18 @@ impl_runtime_apis! { type XcmConfig = xcm_config::XcmConfig; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; type AccountIdConverter = xcm_config::LocationToAccountId; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WndRelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(WndRelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(WndRelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -741,12 +741,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WndRelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WndRelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WndRelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -756,9 +756,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WndRelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WndRelayLocation::get()), fun: Fungible(UNITS), } } @@ -772,39 +772,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WndRelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WndRelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = WndRelayLocation::get(); - let assets: MultiAssets = (Concrete(WndRelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(WndRelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs index 3dc7b82efc2d..a14da7c7a38a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,40 +49,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct CoretimeWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for CoretimeWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -110,44 +106,36 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs index 59d76d10d902..f468f29540aa 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ TransactionByteFee, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -51,18 +51,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WndRelayLocation: MultiLocation = MultiLocation::parent(); + pub const WndRelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub FellowshipLocation: Location = Location::new(1, Parachain(1001)); + pub const GovernanceLocation: Location = Location::parent(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -81,7 +81,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -114,14 +114,18 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type FellowsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct FellowsPlurality; +impl Contains for FellowsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -192,7 +196,7 @@ pub type Barrier = TrailingSetTopicAsId< parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Locations that will not be charged fees in the executor, neither for execution nor delivery. @@ -241,7 +245,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs index 5ebb0ade1231..1c37241563ec 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ RuntimeOrigin, }; use frame_support::{ - match_types, parameter_types, - traits::{Everything, Nothing}, + parameter_types, + traits::{Contains, Everything, Nothing}, weights::Weight, }; use xcm::latest::prelude::*; @@ -29,9 +29,9 @@ use xcm_builder::{ }; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); pub const WestendNetwork: Option = Some(NetworkId::Westend); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -47,8 +47,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, ); -match_types! { - pub type JustTheParent: impl Contains = { MultiLocation { parents:1, interior: Here } }; +pub struct JustTheParent; +impl Contains for JustTheParent { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [])) + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 7805e0ad9829..f5398829c737 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -682,22 +682,22 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between People and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } } @@ -706,7 +706,7 @@ impl_runtime_apis! { use xcm_config::{PriceForParentDelivery, RelayLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -717,17 +717,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -736,12 +736,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -751,9 +751,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(UNITS), } } @@ -767,39 +767,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location::new(0, []); Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs index c90a96c7f822..4afd65bdcfea 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,42 +49,38 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct PeopleRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for PeopleRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } // Currently there is no trusted reserve - fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + fn reserve_asset_deposited(_assets: &Assets) -> Weight { // TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974 Weight::from_parts(1_000_000_000_u64, 0) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,47 +108,39 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()); + let weight = assets.weigh_assets(XcmFungibleWeight::::deposit_asset()); hardcoded_weight.min(weight) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmGeneric::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -167,7 +155,7 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -179,13 +167,13 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -218,16 +206,16 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -239,11 +227,11 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs index 7a2f28aa813e..7ef6cb2fac9d 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::{TransactionByteFee, CENTS}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -49,22 +49,22 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RootLocation: Location = Location::here(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); - pub const FellowshipLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); + pub const FellowshipLocation: Location = Location::parent(); /// The asset ID for the asset that we use to pay for message delivery fees. Just ROC. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -82,7 +82,7 @@ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender: XcmpQueue, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -103,7 +103,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -136,18 +136,25 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type ParentOrSiblings: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Plurality { .. }])) + } +} + +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct ParentOrSiblings; +impl Contains for ParentOrSiblings { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -268,7 +275,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 8ea29c8aa218..33f0d511705f 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -682,22 +682,22 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between People and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } } @@ -706,7 +706,7 @@ impl_runtime_apis! { use xcm_config::{PriceForParentDelivery, RelayLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -717,17 +717,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -736,12 +736,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -751,9 +751,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(UNITS), } } @@ -767,39 +767,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs index 5d6f90e9f1bc..b2579230c9ed 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,42 +49,38 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct PeopleWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for PeopleWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } // Currently there is no trusted reserve - fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + fn reserve_asset_deposited(_assets: &Assets) -> Weight { // TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974 Weight::from_parts(1_000_000_000_u64, 0) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,50 +108,42 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()); + let weight = assets.weigh_assets(XcmFungibleWeight::::deposit_asset()); hardcoded_weight.min(weight) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmGeneric::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(200_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()); + let weight = assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()); hardcoded_weight.min(weight) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -170,7 +158,7 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -182,13 +170,13 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -221,16 +209,16 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -242,11 +230,11 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 0a51cf72d5b4..59c00dc5ff64 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::{TransactionByteFee, CENTS}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -49,22 +49,22 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RootLocation: Location = Location::here(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub FellowshipLocation: Location = Location::new(1, Parachain(1001)); + pub const GovernanceLocation: Location = Location::parent(); /// The asset ID for the asset that we use to pay for message delivery fees. Just WND. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -82,7 +82,7 @@ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender: XcmpQueue, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -103,7 +103,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): @@ -136,21 +136,32 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type ParentOrSiblings: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; - pub type FellowsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } - }; +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Plurality { .. }])) + } +} + +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct ParentOrSiblings; +impl Contains for ParentOrSiblings { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) + } +} + +pub struct FellowsPlurality; +impl Contains for FellowsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -272,7 +283,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs b/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs index ff773ca78161..f5ceabb1eb47 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ RuntimeOrigin, }; use frame_support::{ - match_types, parameter_types, - traits::{Everything, Nothing}, + parameter_types, + traits::{Contains, Everything, Nothing}, weights::Weight, }; use xcm::latest::prelude::*; @@ -29,9 +29,9 @@ use xcm_builder::{ }; parameter_types! { - pub const RococoLocation: MultiLocation = MultiLocation::parent(); + pub const RococoLocation: Location = Location::parent(); pub const RococoNetwork: Option = Some(NetworkId::Rococo); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -47,8 +47,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, ); -match_types! { - pub type JustTheParent: impl Contains = { MultiLocation { parents:1, interior: Here } }; +pub struct JustTheParent; +impl Contains for JustTheParent { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [])) + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 6d43875a8868..88e878c73a35 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -37,11 +37,11 @@ use sp_consensus_aura::{SlotDuration, AURA_ENGINE_ID}; use sp_core::Encode; use sp_runtime::{traits::Header, BuildStorage, Digest, DigestItem}; use xcm::{ - latest::{MultiAsset, MultiLocation, XcmContext, XcmHash}, + latest::{Asset, Location, XcmContext, XcmHash}, prelude::*, VersionedXcm, MAX_XCM_DECODE_DEPTH, }; -use xcm_executor::{traits::TransactAsset, Assets}; +use xcm_executor::{traits::TransactAsset, AssetsInHolding}; pub mod test_cases; @@ -307,12 +307,12 @@ impl RuntimeHelper { pub fn do_transfer( - from: MultiLocation, - to: MultiLocation, - (asset, amount): (MultiLocation, u128), - ) -> Result { + from: Location, + to: Location, + (asset, amount): (Location, u128), + ) -> Result { ::transfer_asset( - &MultiAsset { id: Concrete(asset), fun: Fungible(amount) }, + &Asset { id: AssetId(asset), fun: Fungible(amount) }, &from, &to, // We aren't able to track the XCM that initiated the fee deposit, so we create a @@ -329,9 +329,9 @@ impl< { pub fn do_teleport_assets( origin: ::RuntimeOrigin, - dest: MultiLocation, - beneficiary: MultiLocation, - (asset, amount): (MultiLocation, u128), + dest: Location, + beneficiary: Location, + (asset, amount): (Location, u128), open_hrmp_channel: Option<(u32, u32)>, included_head: HeaderFor, slot_digest: &[u8], @@ -356,7 +356,7 @@ impl< origin, Box::new(dest.into()), Box::new(beneficiary.into()), - Box::new((Concrete(asset), amount).into()), + Box::new((AssetId(asset), amount).into()), 0, ) } @@ -379,12 +379,13 @@ impl< ]); // execute xcm as parent origin - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - <::XcmExecutor>::execute_xcm( - MultiLocation::parent(), + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + <::XcmExecutor>::prepare_and_execute( + Location::parent(), xcm, - hash, + &mut hash, Self::xcm_max_weight(XcmReceivedFrom::Parent), + Weight::zero(), ) } } @@ -451,7 +452,7 @@ impl< } pub fn assert_metadata( - asset_id: impl Into + Copy, + asset_id: impl Into + Clone, expected_name: &str, expected_symbol: &str, expected_decimals: u8, @@ -459,20 +460,20 @@ pub fn assert_metadata( Fungibles: frame_support::traits::fungibles::metadata::Inspect + frame_support::traits::fungibles::Inspect, { - assert_eq!(Fungibles::name(asset_id.into()), Vec::from(expected_name),); - assert_eq!(Fungibles::symbol(asset_id.into()), Vec::from(expected_symbol),); + assert_eq!(Fungibles::name(asset_id.clone().into()), Vec::from(expected_name),); + assert_eq!(Fungibles::symbol(asset_id.clone().into()), Vec::from(expected_symbol),); assert_eq!(Fungibles::decimals(asset_id.into()), expected_decimals); } pub fn assert_total( - asset_id: impl Into + Copy, + asset_id: impl Into + Clone, expected_total_issuance: impl Into, expected_active_issuance: impl Into, ) where Fungibles: frame_support::traits::fungibles::metadata::Inspect + frame_support::traits::fungibles::Inspect, { - assert_eq!(Fungibles::total_issuance(asset_id.into()), expected_total_issuance.into()); + assert_eq!(Fungibles::total_issuance(asset_id.clone().into()), expected_total_issuance.into()); assert_eq!(Fungibles::active_issuance(asset_id.into()), expected_active_issuance.into()); } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 541bcd05644f..37a8454d62a5 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -32,7 +32,6 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod weights; pub mod xcm_config; -use assets_common::MultiLocationForAssetId; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ @@ -474,8 +473,8 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::Location; + type AssetIdParameter = xcm::v3::Location; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 9287ac30514c..b3f84a4bb9cb 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -29,7 +29,7 @@ use super::{ }; use core::marker::PhantomData; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ fungibles::{self, Balanced, Credit}, ConstU32, Contains, ContainsPair, Everything, Get, Nothing, @@ -59,13 +59,13 @@ use xcm_builder::{ use xcm_executor::{traits::JustTry, XcmExecutor}; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -84,7 +84,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -115,7 +115,7 @@ pub type FungiblesTransactor = FungiblesAdapter< JustTry, >, ), - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -180,14 +180,18 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; - pub type CommonGoodAssetsParachain: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(1000)) } - }; +pub struct ParentOrParentsExecutivePlurality; +impl Contains for ParentOrParentsExecutivePlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }])) + } +} + +pub struct CommonGoodAssetsParachain; +impl Contains for CommonGoodAssetsParachain { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1000)])) + } } pub type Barrier = TrailingSetTopicAsId< @@ -224,15 +228,15 @@ pub type AccountIdOf = ::AccountId; /// Asset filter that allows all assets from a certain location matching asset id. pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); -impl ContainsPair for AssetPrefixFrom +impl ContainsPair for AssetPrefixFrom where - Prefix: Get, - Origin: Get, + Prefix: Get, + Origin: Get, { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = Origin::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if asset_loc.starts_with(&Prefix::get())) } } @@ -241,12 +245,12 @@ type AssetsFrom = AssetPrefixFrom; /// Asset filter that allows native/relay asset if coming from a certain location. pub struct NativeAssetFrom(PhantomData); -impl> ContainsPair for NativeAssetFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for NativeAssetFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } - if *asset_loc == MultiLocation::from(Parent)) + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + if *asset_loc == Location::from(Parent)) } } @@ -282,29 +286,34 @@ where pub const TELEPORTABLE_ASSET_ID: u32 = 2; parameter_types! { /// The location that this chain recognizes as the Relay network's Asset Hub. - pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]); // ALWAYS ensure that the index in PalletInstance stays up-to-date with // the Relay Chain's Asset Hub's Assets pallet index - pub SystemAssetHubAssetsPalletLocation: MultiLocation = - MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); - pub AssetsPalletLocation: MultiLocation = - MultiLocation::new(0, X1(PalletInstance(50))); + pub SystemAssetHubAssetsPalletLocation: Location = + Location::new(1, [Parachain(1000), PalletInstance(50)]); + pub AssetsPalletLocation: Location = + Location::new(0, [PalletInstance(50)]); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub LocalTeleportableToAssetHub: MultiLocation = MultiLocation::new( + pub LocalTeleportableToAssetHub: Location = Location::new( + 0, + [PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())] + ); + pub LocalTeleportableToAssetHubV3: xcm::v3::Location = xcm::v3::Location::new( 0, - X2(PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())) + [xcm::v3::Junction::PalletInstance(50), xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into())] ); - pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(EthereumNetwork::get()))); + pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(EthereumNetwork::get())]); } /// Accepts asset with ID `AssetLocation` and is coming from `Origin` chain. pub struct AssetFromChain(PhantomData<(AssetLocation, Origin)>); -impl, Origin: Get> - ContainsPair for AssetFromChain +impl, Origin: Get> ContainsPair + for AssetFromChain { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "AssetFromChain asset: {:?}, origin: {:?}", asset, origin); - *origin == Origin::get() && matches!(asset.id, Concrete(id) if id == AssetLocation::get()) + *origin == Origin::get() && + matches!(asset.id.clone(), AssetId(id) if id == AssetLocation::get()) } } @@ -398,8 +407,8 @@ impl cumulus_pallet_xcm::Config for Runtime { /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 7faee4258f65..102127479d2c 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -42,10 +42,10 @@ pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, genesis_builder_helper::{build_config, create_default_config}, - match_types, parameter_types, + parameter_types, traits::{ - AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, - IsInVec, Nothing, Randomness, + AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, + Everything, IsInVec, Nothing, Randomness, }, weights::{ constants::{ @@ -330,14 +330,14 @@ impl pallet_message_queue::Config for Runtime { impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { - pub const RocLocation: MultiLocation = MultiLocation::parent(); + pub const RocLocation: Location = Location::parent(); pub const RococoNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -356,7 +356,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -379,7 +379,7 @@ pub type FungiblesTransactor = FungiblesAdapter< >, JustTry, >, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -420,20 +420,22 @@ parameter_types! { // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); // One ROC buys 1 second of weight. - pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), ROC); + pub const WeightPrice: (Location, u128) = (Location::parent(), ROC); pub const MaxInstructions: u32 = 100; } -match_types! { - // The parent or the parent's unit plurality. - pub type ParentOrParentsUnitPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } - }; - // The location recognized as the Relay network's Asset Hub. - pub type AssetHub: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(1000)) } - }; +pub struct ParentOrParentsUnitPlurality; +impl Contains for ParentOrParentsUnitPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Unit, .. }])) + } +} + +pub struct AssetHub; +impl Contains for AssetHub { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1000)])) + } } pub type Barrier = TrailingSetTopicAsId<( @@ -451,11 +453,11 @@ pub type Barrier = TrailingSetTopicAsId<( parameter_types! { pub MaxAssetsIntoHolding: u32 = 64; - pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]); // ALWAYS ensure that the index in PalletInstance stays up-to-date with // the Relay Chain's Asset Hub's Assets pallet index - pub SystemAssetHubAssetsPalletLocation: MultiLocation = - MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); + pub SystemAssetHubAssetsPalletLocation: Location = + Location::new(1, [Parachain(1000), PalletInstance(50)]); } pub type Reserves = (NativeAsset, AssetsFrom); diff --git a/cumulus/primitives/core/src/lib.rs b/cumulus/primitives/core/src/lib.rs index 835c9de649ea..7f7353685657 100644 --- a/cumulus/primitives/core/src/lib.rs +++ b/cumulus/primitives/core/src/lib.rs @@ -93,13 +93,12 @@ pub enum AggregateMessageOrigin { Sibling(ParaId), } -impl From for xcm::v3::MultiLocation { +impl From for Location { fn from(origin: AggregateMessageOrigin) -> Self { match origin { - AggregateMessageOrigin::Here => MultiLocation::here(), - AggregateMessageOrigin::Parent => MultiLocation::parent(), - AggregateMessageOrigin::Sibling(id) => - MultiLocation::new(1, Junction::Parachain(id.into())), + AggregateMessageOrigin::Here => Location::here(), + AggregateMessageOrigin::Parent => Location::parent(), + AggregateMessageOrigin::Sibling(id) => Location::new(1, Junction::Parachain(id.into())), } } } diff --git a/cumulus/primitives/utility/src/lib.rs b/cumulus/primitives/utility/src/lib.rs index 7216000cb45f..bd13ee1119b8 100644 --- a/cumulus/primitives/utility/src/lib.rs +++ b/cumulus/primitives/utility/src/lib.rs @@ -35,7 +35,10 @@ use sp_runtime::{ use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, WrapVersion}; use xcm_builder::TakeRevenue; -use xcm_executor::traits::{MatchesFungibles, TransactAsset, WeightTrader}; +use xcm_executor::{ + traits::{MatchesFungibles, TransactAsset, WeightTrader}, + AssetsInHolding, +}; #[cfg(test)] mod tests; @@ -56,10 +59,7 @@ where { type Ticket = Vec; - fn validate( - dest: &mut Option, - msg: &mut Option>, - ) -> SendResult> { + fn validate(dest: &mut Option, msg: &mut Option>) -> SendResult> { let d = dest.take().ok_or(SendError::MissingArgument)?; if d.contains_parents_only(1) { @@ -95,14 +95,14 @@ struct AssetTraderRefunder { // The amount of weight bought minus the weigh already refunded weight_outstanding: Weight, // The concrete asset containing the asset location and outstanding balance - outstanding_concrete_asset: MultiAsset, + outstanding_concrete_asset: Asset, } -/// Charges for execution in the first multiasset of those selected for fee payment +/// Charges for execution in the first asset of those selected for fee payment /// Only succeeds for Concrete Fungible Assets -/// First tries to convert the this MultiAsset into a local assetId +/// First tries to convert the this Asset into a local assetId /// Then charges for this assetId as described by FeeCharger -/// Weight, paid balance, local asset Id and the multilocation is stored for +/// Weight, paid balance, local asset Id and the location is stored for /// later refund purposes /// Important: Errors if the Trader is being called twice by 2 BuyExecution instructions /// Alternatively we could just return payment in the aforementioned case @@ -128,15 +128,15 @@ impl< fn new() -> Self { Self(None, PhantomData) } - // We take first multiasset + // We take first asset // Check whether we can convert fee to asset_fee (is_sufficient, min_deposit) // If everything goes well, we charge. fn buy_weight( &mut self, weight: Weight, - payment: xcm_executor::Assets, + payment: xcm_executor::AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!(target: "xcm::weight", "TakeFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); // Make sure we dont enter twice @@ -144,12 +144,12 @@ impl< return Err(XcmError::NotWithdrawable) } - // We take the very first multiasset from payment + // We take the very first asset from payment // (assets are sorted by fungibility/amount after this conversion) - let multiassets: MultiAssets = payment.clone().into(); + let assets: Assets = payment.clone().into(); - // Take the first multiasset from the selected MultiAssets - let first = multiassets.get(0).ok_or(XcmError::AssetNotFound)?; + // Take the first asset from the selected Assets + let first = assets.get(0).ok_or(XcmError::AssetNotFound)?; // Get the local asset id in which we can pay for fees let (local_asset_id, _) = @@ -171,13 +171,13 @@ impl< .try_into() .map_err(|_| XcmError::Overflow)?; - // Convert to the same kind of multiasset, with the required fungible balance - let required = first.id.into_multiasset(asset_balance.into()); + // Convert to the same kind of asset, with the required fungible balance + let required = first.id.clone().into_asset(asset_balance.into()); // Substract payment let unused = payment.checked_sub(required.clone()).map_err(|_| XcmError::TooExpensive)?; - // record weight and multiasset + // record weight and asset self.0 = Some(AssetTraderRefunder { weight_outstanding: weight, outstanding_concrete_asset: required, @@ -186,16 +186,16 @@ impl< Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "TakeFirstAssetTrader::refund_weight weight: {:?}, context: {:?}", weight, context); if let Some(AssetTraderRefunder { mut weight_outstanding, - outstanding_concrete_asset: MultiAsset { id, fun }, + outstanding_concrete_asset: Asset { id, fun }, }) = self.0.clone() { // Get the local asset id in which we can refund fees let (local_asset_id, outstanding_balance) = - Matcher::matches_fungibles(&(id, fun).into()).ok()?; + Matcher::matches_fungibles(&(id.clone(), fun).into()).ok()?; let minimum_balance = ConcreteAssets::minimum_balance(local_asset_id.clone()); @@ -225,7 +225,8 @@ impl< // Construct outstanding_concrete_asset with the same location id and substracted // balance - let outstanding_concrete_asset: MultiAsset = (id, outstanding_minus_substracted).into(); + let outstanding_concrete_asset: Asset = + (id.clone(), outstanding_minus_substracted).into(); // Substract from existing weight and balance weight_outstanding = weight_outstanding.saturating_sub(weight); @@ -272,11 +273,11 @@ impl< ReceiverAccount: Get>, > TakeRevenue for XcmFeesTo32ByteAccount { - fn take_revenue(revenue: MultiAsset) { + fn take_revenue(revenue: Asset) { if let Some(receiver) = ReceiverAccount::get() { let ok = FungiblesMutateAdapter::deposit_asset( &revenue, - &(X1(AccountId32 { network: None, id: receiver.into() }).into()), + &([AccountId32 { network: None, id: receiver.into() }].into()), None, ) .is_ok(); @@ -307,7 +308,7 @@ pub trait ChargeWeightInFungibles Result { + ) -> Result { log::trace!( target: "xcm::weight", "SwapFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}", weight, payment, ); - let first_asset: MultiAsset = + let first_asset: Asset = payment.fungible.pop_first().ok_or(XcmError::AssetNotFound)?.into(); let (fungibles_asset, balance) = FungiblesAssetMatcher::matches_fungibles(&first_asset) .map_err(|_| XcmError::AssetNotFound)?; @@ -424,14 +425,14 @@ impl< }, _ => (), }; - self.last_fee_asset = Some(first_asset.id); + self.last_fee_asset = Some(first_asset.id.clone()); payment.fungible.insert(first_asset.id, credit_change.peek().into()); drop(credit_change); Ok(payment) } - fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { log::trace!( target: "xcm::weight", "SwapFirstAssetTrader::refund_weight weight: {:?}, self.total_fee: {:?}", @@ -444,7 +445,7 @@ impl< } let mut refund_asset = if let Some(asset) = &self.last_fee_asset { // create an initial zero refund in the asset used in the last `buy_weight`. - (*asset, Fungible(0)).into() + (asset.clone(), Fungible(0)).into() } else { return None }; @@ -529,11 +530,11 @@ mod test_xcm_router { impl OkFixedXcmHashWithAssertingRequiredInputsSender { const FIXED_XCM_HASH: [u8; 32] = [9; 32]; - fn fixed_delivery_asset() -> MultiAssets { - MultiAssets::new() + fn fixed_delivery_asset() -> Assets { + Assets::new() } - fn expected_delivery_result() -> Result<(XcmHash, MultiAssets), SendError> { + fn expected_delivery_result() -> Result<(XcmHash, Assets), SendError> { Ok((Self::FIXED_XCM_HASH, Self::fixed_delivery_asset())) } } @@ -541,7 +542,7 @@ mod test_xcm_router { type Ticket = (); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { assert!(destination.is_some()); @@ -597,7 +598,7 @@ mod test_xcm_router { // ParentAsUmp - check dest/msg is valid let dest = (Parent, Here); - let mut dest_wrapper = Some(dest.into()); + let mut dest_wrapper = Some(dest.clone().into()); let mut msg_wrapper = Some(message.clone()); assert!( as SendXcm>::validate( &mut dest_wrapper, @@ -629,7 +630,7 @@ mod test_trader { }, }; use sp_runtime::DispatchError; - use xcm_executor::{traits::Error, Assets}; + use xcm_executor::{traits::Error, AssetsInHolding}; #[test] fn take_first_asset_trader_buy_weight_called_twice_throws_error() { @@ -641,9 +642,9 @@ mod test_trader { type TestBalance = u128; struct TestAssets; impl MatchesFungibles for TestAssets { - fn matches_fungibles(a: &MultiAsset) -> Result<(TestAssetId, TestBalance), Error> { + fn matches_fungibles(a: &Asset) -> Result<(TestAssetId, TestBalance), Error> { match a { - MultiAsset { fun: Fungible(amount), id: Concrete(_id) } => Ok((1, *amount)), + Asset { fun: Fungible(amount), id: AssetId(_id) } => Ok((1, *amount)), _ => Err(Error::AssetNotHandled), } } @@ -730,7 +731,7 @@ mod test_trader { } } impl TakeRevenue for FeeChargerAssetsHandleRefund { - fn take_revenue(_: MultiAsset) {} + fn take_revenue(_: Asset) {} } // create new instance @@ -745,8 +746,8 @@ mod test_trader { let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; // prepare test data - let asset: MultiAsset = (Here, AMOUNT).into(); - let payment = Assets::from(asset); + let asset: Asset = (Here, AMOUNT).into(); + let payment = AssetsInHolding::from(asset); let weight_to_buy = Weight::from_parts(1_000, 1_000); // lets do first call (success) @@ -769,17 +770,17 @@ pub struct ToParentDeliveryHelper>, + ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, > pallet_xcm_benchmarks::EnsureDelivery for ToParentDeliveryHelper { fn ensure_successful_delivery( - origin_ref: &MultiLocation, - _dest: &MultiLocation, + origin_ref: &Location, + _dest: &Location, fee_reason: xcm_executor::traits::FeeReason, - ) -> (Option, Option) { - use xcm::latest::{MAX_INSTRUCTIONS_TO_DECODE, MAX_ITEMS_IN_MULTIASSETS}; + ) -> (Option, Option) { + use xcm::latest::{MAX_INSTRUCTIONS_TO_DECODE, MAX_ITEMS_IN_ASSETS}; use xcm_executor::{traits::FeeManager, FeesMode}; let mut fees_mode = None; @@ -792,8 +793,8 @@ impl< } // overestimate delivery fee - let mut max_assets: Vec = Vec::new(); - for i in 0..MAX_ITEMS_IN_MULTIASSETS { + let mut max_assets: Vec = Vec::new(); + for i in 0..MAX_ITEMS_IN_ASSETS { max_assets.push((GeneralIndex(i as u128), 100u128).into()); } let overestimated_xcm = diff --git a/cumulus/primitives/utility/src/tests/swap_first.rs b/cumulus/primitives/utility/src/tests/swap_first.rs index 222cd005b12a..2e19db498816 100644 --- a/cumulus/primitives/utility/src/tests/swap_first.rs +++ b/cumulus/primitives/utility/src/tests/swap_first.rs @@ -18,18 +18,18 @@ use crate::*; use frame_support::{parameter_types, traits::fungibles::Inspect}; use mock::{setup_pool, AccountId, AssetId, Balance, Fungibles}; use xcm::latest::AssetId as XcmAssetId; -use xcm_executor::Assets as HoldingAsset; +use xcm_executor::AssetsInHolding; -fn create_holding_asset(asset_id: AssetId, amount: Balance) -> HoldingAsset { +fn create_holding_asset(asset_id: AssetId, amount: Balance) -> AssetsInHolding { create_asset(asset_id, amount).into() } -fn create_asset(asset_id: AssetId, amount: Balance) -> MultiAsset { - MultiAsset { id: create_asset_id(asset_id), fun: Fungible(amount) } +fn create_asset(asset_id: AssetId, amount: Balance) -> Asset { + Asset { id: create_asset_id(asset_id), fun: Fungible(amount) } } fn create_asset_id(asset_id: AssetId) -> XcmAssetId { - Concrete(MultiLocation::new(0, X1(GeneralIndex(asset_id.into())))) + AssetId(Location::new(0, [GeneralIndex(asset_id.into())])) } fn xcm_context() -> XcmContext { @@ -319,7 +319,7 @@ fn empty_holding_asset() { let mut trader = Trader::new(); assert_eq!( trader - .buy_weight(Weight::from_all(10), HoldingAsset::new(), &xcm_context()) + .buy_weight(Weight::from_all(10), AssetsInHolding::new(), &xcm_context()) .unwrap_err(), XcmError::AssetNotFound ); @@ -328,8 +328,7 @@ fn empty_holding_asset() { #[test] fn fails_to_match_holding_asset() { let mut trader = Trader::new(); - let holding_asset = - MultiAsset { id: Concrete(MultiLocation::new(1, X1(Parachain(1)))), fun: Fungible(10) }; + let holding_asset = Asset { id: AssetId(Location::new(1, [Parachain(1)])), fun: Fungible(10) }; assert_eq!( trader .buy_weight(Weight::from_all(10), holding_asset.into(), &xcm_context()) @@ -536,14 +535,15 @@ pub mod mock { pub struct FungiblesMatcher; impl MatchesFungibles for FungiblesMatcher { fn matches_fungibles( - a: &MultiAsset, + a: &Asset, ) -> core::result::Result<(AssetId, Balance), xcm_executor::traits::Error> { match a { - MultiAsset { - fun: Fungible(amount), - id: - Concrete(MultiLocation { parents: 0, interior: X1(Junction::GeneralIndex(id)) }), - } => Ok(((*id).try_into().unwrap(), *amount)), + Asset { fun: Fungible(amount), id: AssetId(inner_location) } => + match inner_location.unpack() { + (0, [Junction::GeneralIndex(id)]) => + Ok(((*id).try_into().unwrap(), *amount)), + _ => Err(xcm_executor::traits::Error::AssetNotHandled), + }, _ => Err(xcm_executor::traits::Error::AssetNotHandled), } } diff --git a/cumulus/xcm/xcm-emulator/src/lib.rs b/cumulus/xcm/xcm-emulator/src/lib.rs index c9e4de21d43c..c5cc632574bc 100644 --- a/cumulus/xcm/xcm-emulator/src/lib.rs +++ b/cumulus/xcm/xcm-emulator/src/lib.rs @@ -60,12 +60,9 @@ pub use polkadot_runtime_parachains::inclusion::{AggregateMessageOrigin, UmpQueu // Polkadot pub use polkadot_parachain_primitives::primitives::RelayChainBlockNumber; use sp_core::crypto::AccountId32; -pub use xcm::{ - prelude::{AccountId32 as AccountId32Junction, Here}, - v3::prelude::{ - Ancestor, MultiAssets, MultiLocation, Parachain as ParachainJunction, Parent, WeightLimit, - XcmHash, X1, - }, +pub use xcm::latest::prelude::{ + AccountId32 as AccountId32Junction, Ancestor, Assets, Here, Location, + Parachain as ParachainJunction, Parent, WeightLimit, XcmHash, }; pub use xcm_executor::traits::ConvertLocation; @@ -231,11 +228,11 @@ pub trait RelayChain: Chain { fn init(); - fn child_location_of(id: ParaId) -> MultiLocation { + fn child_location_of(id: ParaId) -> Location { (Ancestor(0), ParachainJunction(id.into())).into() } - fn sovereign_account_id_of(location: MultiLocation) -> AccountIdOf { + fn sovereign_account_id_of(location: Location) -> AccountIdOf { Self::SovereignAccountOf::convert_location(&location).unwrap() } @@ -263,15 +260,15 @@ pub trait Parachain: Chain { Self::ext_wrapper(|| Self::ParachainInfo::get()) } - fn parent_location() -> MultiLocation { + fn parent_location() -> Location { (Parent).into() } - fn sibling_location_of(para_id: ParaId) -> MultiLocation { - (Parent, X1(ParachainJunction(para_id.into()))).into() + fn sibling_location_of(para_id: ParaId) -> Location { + (Parent, ParachainJunction(para_id.into())).into() } - fn sovereign_account_id_of(location: MultiLocation) -> AccountIdOf { + fn sovereign_account_id_of(location: Location) -> AccountIdOf { Self::LocationToAccountId::convert_location(&location).unwrap() } } @@ -1432,10 +1429,10 @@ pub struct TestAccount { /// Default `Args` provided by xcm-emulator to be stored in a `Test` instance #[derive(Clone)] pub struct TestArgs { - pub dest: MultiLocation, - pub beneficiary: MultiLocation, + pub dest: Location, + pub beneficiary: Location, pub amount: Balance, - pub assets: MultiAssets, + pub assets: Assets, pub asset_id: Option, pub fee_asset_item: u32, pub weight_limit: WeightLimit, @@ -1443,7 +1440,7 @@ pub struct TestArgs { impl TestArgs { /// Returns a [`TestArgs`] instance to be used for the Relay Chain across integration tests. - pub fn new_relay(dest: MultiLocation, beneficiary_id: AccountId32, amount: Balance) -> Self { + pub fn new_relay(dest: Location, beneficiary_id: AccountId32, amount: Balance) -> Self { Self { dest, beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(), @@ -1457,10 +1454,10 @@ impl TestArgs { /// Returns a [`TestArgs`] instance to be used for parachains across integration tests. pub fn new_para( - dest: MultiLocation, + dest: Location, beneficiary_id: AccountId32, amount: Balance, - assets: MultiAssets, + assets: Assets, asset_id: Option, fee_asset_item: u32, ) -> Self { diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index d71c626cd98d..a9edb1966270 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -21,7 +21,7 @@ use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::Balance; use sp_runtime::{traits::TryConvert, Perquintill, RuntimeDebug}; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; /// Logic for the author to get a portion of fees. pub struct ToAuthor(sp_std::marker::PhantomData); @@ -107,12 +107,9 @@ pub fn era_payout( )] pub enum VersionedLocatableAsset { #[codec(index = 3)] - V3 { - /// The (relative) location in which the asset ID is meaningful. - location: xcm::v3::MultiLocation, - /// The asset's ID. - asset_id: xcm::v3::AssetId, - }, + V3 { location: xcm::v3::MultiLocation, asset_id: xcm::v3::AssetId }, + #[codec(index = 4)] + V4 { location: xcm::v4::Location, asset_id: xcm::v4::AssetId }, } /// Converts the [`VersionedLocatableAsset`] to the [`xcm_builder::LocatableAssetId`]. @@ -125,22 +122,29 @@ impl TryConvert ) -> Result { match asset { VersionedLocatableAsset::V3 { location, asset_id } => - Ok(xcm_builder::LocatableAssetId { asset_id, location }), + Ok(xcm_builder::LocatableAssetId { + location: location.try_into().map_err(|_| asset.clone())?, + asset_id: asset_id.try_into().map_err(|_| asset.clone())?, + }), + VersionedLocatableAsset::V4 { location, asset_id } => + Ok(xcm_builder::LocatableAssetId { location, asset_id }), } } } -/// Converts the [`VersionedMultiLocation`] to the [`xcm::latest::MultiLocation`]. -pub struct VersionedMultiLocationConverter; -impl TryConvert<&VersionedMultiLocation, xcm::latest::MultiLocation> - for VersionedMultiLocationConverter -{ +/// Converts the [`VersionedLocation`] to the [`xcm::latest::Location`]. +pub struct VersionedLocationConverter; +impl TryConvert<&VersionedLocation, xcm::latest::Location> for VersionedLocationConverter { fn try_convert( - location: &VersionedMultiLocation, - ) -> Result { + location: &VersionedLocation, + ) -> Result { let latest = match location.clone() { - VersionedMultiLocation::V2(l) => l.try_into().map_err(|_| location)?, - VersionedMultiLocation::V3(l) => l, + VersionedLocation::V2(l) => { + let v3: xcm::v3::MultiLocation = l.try_into().map_err(|_| location)?; + v3.try_into().map_err(|_| location)? + }, + VersionedLocation::V3(l) => l.try_into().map_err(|_| location)?, + VersionedLocation::V4(l) => l, }; Ok(latest) } @@ -161,11 +165,14 @@ pub mod benchmarks { pub struct AssetRateArguments; impl AssetKindFactory for AssetRateArguments { fn create_asset_kind(seed: u32) -> VersionedLocatableAsset { - VersionedLocatableAsset::V3 { - location: xcm::v3::MultiLocation::new(0, X1(Parachain(seed))), - asset_id: xcm::v3::MultiLocation::new( + VersionedLocatableAsset::V4 { + location: xcm::v4::Location::new(0, [xcm::v4::Junction::Parachain(seed)]), + asset_id: xcm::v4::Location::new( 0, - X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())), + [ + xcm::v4::Junction::PalletInstance(seed.try_into().unwrap()), + xcm::v4::Junction::GeneralIndex(seed.into()), + ], ) .into(), } @@ -173,29 +180,35 @@ pub mod benchmarks { } /// Provide factory methods for the [`VersionedLocatableAsset`] and the `Beneficiary` of the - /// [`VersionedMultiLocation`]. The location of the asset is determined as a Parachain with an + /// [`VersionedLocation`]. The location of the asset is determined as a Parachain with an /// ID equal to the passed seed. pub struct TreasuryArguments, ParaId = ConstU32<0>>( PhantomData<(Parents, ParaId)>, ); impl, ParaId: Get> - TreasuryArgumentsFactory + TreasuryArgumentsFactory for TreasuryArguments { fn create_asset_kind(seed: u32) -> VersionedLocatableAsset { VersionedLocatableAsset::V3 { - location: xcm::v3::MultiLocation::new(Parents::get(), X1(Parachain(ParaId::get()))), + location: xcm::v3::MultiLocation::new( + Parents::get(), + [xcm::v3::Junction::Parachain(ParaId::get())], + ), asset_id: xcm::v3::MultiLocation::new( 0, - X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())), + [ + xcm::v3::Junction::PalletInstance(seed.try_into().unwrap()), + xcm::v3::Junction::GeneralIndex(seed.into()), + ], ) .into(), } } - fn create_beneficiary(seed: [u8; 32]) -> VersionedMultiLocation { - VersionedMultiLocation::V3(xcm::v3::MultiLocation::new( + fn create_beneficiary(seed: [u8; 32]) -> VersionedLocation { + VersionedLocation::V4(xcm::v4::Location::new( 0, - X1(AccountId32 { network: None, id: seed }), + [xcm::v4::Junction::AccountId32 { network: None, id: seed }], )) } } diff --git a/polkadot/runtime/common/src/xcm_sender.rs b/polkadot/runtime/common/src/xcm_sender.rs index 4d31c92cdd3a..7f1100a13619 100644 --- a/polkadot/runtime/common/src/xcm_sender.rs +++ b/polkadot/runtime/common/src/xcm_sender.rs @@ -35,13 +35,13 @@ pub trait PriceForMessageDelivery { /// Type used for charging different prices to different destinations type Id; /// Return the assets required to deliver `message` to the given `para` destination. - fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> MultiAssets; + fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> Assets; } impl PriceForMessageDelivery for () { type Id = (); - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { - MultiAssets::new() + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { + Assets::new() } } @@ -49,17 +49,17 @@ pub struct NoPriceForMessageDelivery(PhantomData); impl PriceForMessageDelivery for NoPriceForMessageDelivery { type Id = Id; - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { - MultiAssets::new() + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { + Assets::new() } } /// Implementation of [`PriceForMessageDelivery`] which returns a fixed price. pub struct ConstantPrice(sp_std::marker::PhantomData); -impl> PriceForMessageDelivery for ConstantPrice { +impl> PriceForMessageDelivery for ConstantPrice { type Id = (); - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { T::get() } } @@ -84,7 +84,7 @@ impl, B: Get, M: Get, F: FeeTracker> PriceForMessage { type Id = F::Id; - fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> MultiAssets { + fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> Assets { let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); let fee_sum = B::get().saturating_add(msg_fee); let amount = F::get_fee_factor(id).saturating_mul_int(fee_sum); @@ -103,11 +103,11 @@ where type Ticket = (HostConfiguration>, ParaId, Vec); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult<(HostConfiguration>, ParaId, Vec)> { let d = dest.take().ok_or(MissingArgument)?; - let id = if let MultiLocation { parents: 0, interior: X1(Parachain(id)) } = &d { + let id = if let (0, [Parachain(id)]) = d.unpack() { *id } else { *dest = Some(d); @@ -160,7 +160,7 @@ pub struct ToParachainDeliveryHelper< #[cfg(feature = "runtime-benchmarks")] impl< XcmConfig: xcm_executor::Config, - ExistentialDeposit: Get>, + ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, Parachain: Get, ToParachainHelper: EnsureForParachain, @@ -174,10 +174,10 @@ impl< > { fn ensure_successful_delivery( - origin_ref: &MultiLocation, - _dest: &MultiLocation, + origin_ref: &Location, + _dest: &Location, fee_reason: xcm_executor::traits::FeeReason, - ) -> (Option, Option) { + ) -> (Option, Option) { use xcm_executor::{ traits::{FeeManager, TransactAsset}, FeesMode, @@ -234,7 +234,7 @@ mod tests { parameter_types! { pub const BaseDeliveryFee: u128 = 300_000_000; pub const TransactionByteFee: u128 = 1_000_000; - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = AssetId(Here.into()); } struct TestFeeTracker; diff --git a/polkadot/runtime/parachains/src/coretime/migration.rs b/polkadot/runtime/parachains/src/coretime/migration.rs index c720cf0617aa..e64d3fbd6a9e 100644 --- a/polkadot/runtime/parachains/src/coretime/migration.rs +++ b/polkadot/runtime/parachains/src/coretime/migration.rs @@ -46,9 +46,7 @@ mod v_coretime { #[cfg(feature = "try-runtime")] use sp_std::vec::Vec; use sp_std::{iter, prelude::*, result}; - use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, SendError, WeightLimit, Xcm, - }; + use xcm::v4::{send_xcm, Instruction, Junction, Location, SendError, WeightLimit, Xcm}; /// Return information about a legacy lease of a parachain. pub trait GetLegacyLease { @@ -64,7 +62,7 @@ mod v_coretime { sp_std::marker::PhantomData<(T, SendXcm, LegacyLease)>, ); - impl>> + impl>> MigrateToCoretime { fn already_migrated() -> bool { @@ -95,7 +93,7 @@ mod v_coretime { impl< T: Config + crate::dmp::Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, > OnRuntimeUpgrade for MigrateToCoretime { @@ -155,7 +153,7 @@ mod v_coretime { // NOTE: Also migrates coretime_cores config value in configuration::ActiveConfig. fn migrate_to_coretime< T: Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, >() -> Weight { let legacy_paras = paras::Pallet::::parachains(); @@ -209,7 +207,7 @@ mod v_coretime { fn migrate_send_assignments_to_coretime_chain< T: Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, >() -> result::Result<(), SendError> { let legacy_paras = paras::Pallet::::parachains(); @@ -280,10 +278,7 @@ mod v_coretime { for message in messages { send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, + Location::new(0, Junction::Parachain(T::BrokerId::get())), message, )?; } diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index aa074a293c9c..531f5c2e4e47 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -26,10 +26,7 @@ pub use pallet::*; use pallet_broker::{CoreAssignment, CoreIndex as BrokerCoreIndex}; use primitives::{CoreIndex, Id as ParaId}; use sp_arithmetic::traits::SaturatedConversion; -use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, WeightLimit, - Xcm, -}; +use xcm::v4::{send_xcm, Instruction, Junction, Location, OriginKind, SendXcm, WeightLimit, Xcm}; use crate::{ assigner_coretime::{self, PartsOf57600}, @@ -229,10 +226,7 @@ impl Pallet { mk_coretime_call(crate::coretime::CoretimeCalls::NotifyCoreCount(core_count)), ]); if let Err(err) = send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, + Location::new(0, [Junction::Parachain(T::BrokerId::get())]), message, ) { log::error!("Sending `NotifyCoreCount` to coretime chain failed: {:?}", err); diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index fbaab1d24aaf..c08bab0ef0fc 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -52,7 +52,7 @@ use sp_runtime::{ }; use sp_std::collections::vec_deque::VecDeque; use std::{cell::RefCell, collections::HashMap}; -use xcm::v3::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; +use xcm::v4::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlockU32; @@ -384,11 +384,8 @@ impl coretime::Config for Test { pub struct DummyXcmSender; impl SendXcm for DummyXcmSender { type Ticket = (); - fn validate( - _: &mut Option, - _: &mut Option>, - ) -> SendResult { - Ok(((), MultiAssets::new())) + fn validate(_: &mut Option, _: &mut Option>) -> SendResult { + Ok(((), Assets::new())) } /// Actually carry out the delivery operation for a previously validated message sending. diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index eddbfacc3b1d..ac7100d78583 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -22,7 +22,7 @@ use primitives::Balance; use rococo_runtime_constants::currency::*; use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any @@ -95,9 +95,9 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let roc = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; + let roc = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 - let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + let destination: Location = Location::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -138,11 +138,9 @@ where ); // reanchor - let roc_reanchored: MultiAssets = vec![MultiAsset { - id: Concrete(MultiLocation::new(1, Here)), - fun: Fungible(total_to_send), - }] - .into(); + let roc_reanchored: Assets = + vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }] + .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); @@ -172,8 +170,8 @@ where // send let _ = >::send( RawOrigin::Root.into(), - Box::new(VersionedMultiLocation::V3(destination)), - Box::new(VersionedXcm::V3(program)), + Box::new(VersionedLocation::V4(destination)), + Box::new(VersionedXcm::V4(program)), )?; Ok(()) } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index e492caddc8fc..fec82fc86f91 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -35,7 +35,7 @@ use rococo_runtime_constants::system_parachain::BROKER_ID; use runtime_common::{ assigned_slots, auctions, claims, crowdloan, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, traits::Leaser, @@ -99,10 +99,7 @@ use sp_staking::SessionIndex; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::{ - latest::{InteriorMultiLocation, Junction, Junction::PalletInstance}, - VersionedMultiLocation, -}; +use xcm::{latest::prelude::*, VersionedLocation}; use xcm_builder::PayOverXcm; pub use frame_system::Call as SystemCall; @@ -461,7 +458,7 @@ parameter_types! { pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 18). - pub TreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(18).into(); + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(18).into(); pub const TipCountdown: BlockNumber = 1 * DAYS; pub const TipFindersFee: Percent = Percent::from_percent(20); @@ -492,7 +489,7 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = Bounties; type SpendOrigin = TreasurySpender; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Paymaster = PayOverXcm< TreasuryInteriorLocation, @@ -502,7 +499,7 @@ impl pallet_treasury::Config for Runtime { Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; type BalanceConverter = AssetRate; type PayoutPeriod = PayoutSpendPeriod; @@ -538,7 +535,7 @@ impl pallet_bounties::Config for Runtime { parameter_types! { pub const MaxActiveChildBountyCount: u32 = 100; - pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; + pub ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; } impl pallet_child_bounties::Config for Runtime { @@ -1209,7 +1206,7 @@ impl pallet_nis::Config for Runtime { } parameter_types! { - pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); + pub BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); } impl pallet_beefy::Config for Runtime { @@ -2270,7 +2267,7 @@ sp_api::impl_runtime_apis! { }; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -2280,34 +2277,34 @@ sp_api::impl_runtime_apis! { impl frame_system_benchmarking::Config for Runtime {} impl frame_benchmarking::baseline::Config for Runtime {} impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(crate::xcm_config::AssetHub::get()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported to/from AH. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, crate::xcm_config::AssetHub::get(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Relay can reserve transfer native token to some random parachain. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, Parachain(43211234).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, 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. @@ -2325,29 +2322,29 @@ sp_api::impl_runtime_apis! { type AccountIdConverter = LocationConverter; type DeliveryHelper = runtime_common::xcm_sender::ToParachainDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, ToParachain, (), >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(AssetHub::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // Rococo only knows about ROC - vec![MultiAsset{ - id: Concrete(TokenLocation::get()), + vec![Asset{ + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }].into() } } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( AssetHub::get(), - MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2357,9 +2354,9 @@ sp_api::impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1 * UNITS), } } @@ -2373,43 +2370,43 @@ sp_api::impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { // Rococo doesn't support asset exchanges Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { // The XCM executor of Rococo doesn't have a configured `UniversalAliases` Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(AssetHub::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = AssetHub::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { // Rococo doesn't support asset locking Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // Rococo doesn't support exporting messages Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // The XCM executor of Rococo doesn't have a configured `Aliasers` Err(BenchmarkError::Skip) } diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs index cc485dfbaf7e..12f3df897b1e 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/mod.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -33,25 +33,25 @@ pub enum AssetTypes { Unknown, } -impl From<&MultiAsset> for AssetTypes { - fn from(asset: &MultiAsset) -> Self { +impl From<&Asset> for AssetTypes { + fn from(asset: &Asset) -> Self { match asset { - MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + Asset { id: AssetId(Location { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } -trait WeighMultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight; } // Rococo only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() @@ -72,11 +72,11 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() - .map(|m| >::from(m)) + .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, @@ -87,32 +87,28 @@ impl WeighMultiAssets for MultiAssets { pub struct RococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for RococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, @@ -140,45 +136,37 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { // Rococo does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -193,7 +181,7 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -205,13 +193,13 @@ impl XcmWeightInfo for RococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -246,19 +234,19 @@ impl XcmWeightInfo for RococoXcmWeight { // Rococo relay should not support export message operations Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } @@ -271,19 +259,19 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { - let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let assets = AssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); - assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); + assert_eq!(assets.weigh_assets(weight), weight * MAX_ASSETS); } diff --git a/polkadot/runtime/rococo/src/xcm_config.rs b/polkadot/runtime/rococo/src/xcm_config.rs index f3a2ca6f3a6c..bfa9beb82090 100644 --- a/polkadot/runtime/rococo/src/xcm_config.rs +++ b/polkadot/runtime/rococo/src/xcm_config.rs @@ -24,8 +24,8 @@ use super::{ use crate::governance::StakingAdmin; use frame_support::{ - match_types, parameter_types, - traits::{Equals, Everything, Nothing}, + parameter_types, + traits::{Contains, Equals, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -50,10 +50,10 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub TokenLocation: Location = Here.into_location(); + pub RootLocation: Location = Location::here(); pub const ThisNetwork: NetworkId = NetworkId::Rococo; - pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); + pub UniversalLocation: InteriorLocation = ThisNetwork::get().into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); pub TreasuryAccount: AccountId = Treasury::account_id(); @@ -69,7 +69,7 @@ pub type LocationConverter = ( ); /// Our asset transactor. This is what allows us to interest with the runtime facilities from the -/// point of view of XCM-only concepts like `MultiLocation` and `MultiAsset`. +/// point of view of XCM-only concepts like `Location` and `Asset`. /// /// Ours is only aware of the Balances pallet, which is mapped to `RocLocation`. #[allow(deprecated)] @@ -78,7 +78,7 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // We can convert the MultiLocations with our converter above: + // We can convert the Locations with our converter above: LocationConverter, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -100,7 +100,7 @@ parameter_types! { /// The amount of weight an XCM operation takes. This is a safe overestimate. pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -116,25 +116,25 @@ pub type XcmRouter = WithUniqueTopic< >; parameter_types! { - pub const Roc: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); - pub const Contracts: MultiLocation = Parachain(CONTRACTS_ID).into_location(); - pub const Encointer: MultiLocation = Parachain(ENCOINTER_ID).into_location(); - pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); - pub const People: MultiLocation = Parachain(PEOPLE_ID).into_location(); - pub const Broker: MultiLocation = Parachain(BROKER_ID).into_location(); - pub const Tick: MultiLocation = Parachain(100).into_location(); - pub const Trick: MultiLocation = Parachain(110).into_location(); - pub const Track: MultiLocation = Parachain(120).into_location(); - pub const RocForTick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Tick::get()); - pub const RocForTrick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Trick::get()); - pub const RocForTrack: (MultiAssetFilter, MultiLocation) = (Roc::get(), Track::get()); - pub const RocForAssetHub: (MultiAssetFilter, MultiLocation) = (Roc::get(), AssetHub::get()); - pub const RocForContracts: (MultiAssetFilter, MultiLocation) = (Roc::get(), Contracts::get()); - pub const RocForEncointer: (MultiAssetFilter, MultiLocation) = (Roc::get(), Encointer::get()); - pub const RocForBridgeHub: (MultiAssetFilter, MultiLocation) = (Roc::get(), BridgeHub::get()); - pub const RocForPeople: (MultiAssetFilter, MultiLocation) = (Roc::get(), People::get()); - pub const RocForBroker: (MultiAssetFilter, MultiLocation) = (Roc::get(), Broker::get()); + pub Roc: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) }); + pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location(); + pub Contracts: Location = Parachain(CONTRACTS_ID).into_location(); + pub Encointer: Location = Parachain(ENCOINTER_ID).into_location(); + pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location(); + pub People: Location = Parachain(PEOPLE_ID).into_location(); + pub Broker: Location = Parachain(BROKER_ID).into_location(); + pub Tick: Location = Parachain(100).into_location(); + pub Trick: Location = Parachain(110).into_location(); + pub Track: Location = Parachain(120).into_location(); + pub RocForTick: (AssetFilter, Location) = (Roc::get(), Tick::get()); + pub RocForTrick: (AssetFilter, Location) = (Roc::get(), Trick::get()); + pub RocForTrack: (AssetFilter, Location) = (Roc::get(), Track::get()); + pub RocForAssetHub: (AssetFilter, Location) = (Roc::get(), AssetHub::get()); + pub RocForContracts: (AssetFilter, Location) = (Roc::get(), Contracts::get()); + pub RocForEncointer: (AssetFilter, Location) = (Roc::get(), Encointer::get()); + pub RocForBridgeHub: (AssetFilter, Location) = (Roc::get(), BridgeHub::get()); + pub RocForPeople: (AssetFilter, Location) = (Roc::get(), People::get()); + pub RocForBroker: (AssetFilter, Location) = (Roc::get(), Broker::get()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -150,13 +150,18 @@ pub type TrustedTeleporters = ( xcm_builder::Case, ); -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Parachain(_)])) + } +} + +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Plurality { .. }])) + } } /// The barriers one of which must be passed for an XCM message to be executed. @@ -227,26 +232,26 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; } -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// Type to convert an `Origin` type value into a `Location` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 SignedToAccountId32, ); -/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +/// Type to convert the Fellows origin to a Plurality `Location` value. pub type FellowsToPlurality = OriginToPluralityVoice; -/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( - // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, - // Fellows origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // Fellows origin to be used in XCM as a corresponding Plurality `Location` value. FellowsToPlurality, ); diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index f472b619ba75..e80412232d07 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -604,7 +604,7 @@ pub mod pallet_test_notifier { pub enum Event { QueryPrepared(QueryId), NotifyQueryPrepared(QueryId), - ResponseReceived(MultiLocation, QueryId, Response), + ResponseReceived(Location, QueryId, Response), } #[pallet::error] diff --git a/polkadot/runtime/test-runtime/src/xcm_config.rs b/polkadot/runtime/test-runtime/src/xcm_config.rs index ae4faecf7001..d9d3d6e0752d 100644 --- a/polkadot/runtime/test-runtime/src/xcm_config.rs +++ b/polkadot/runtime/test-runtime/src/xcm_config.rs @@ -27,7 +27,7 @@ use xcm_builder::{ }; use xcm_executor::{ traits::{TransactAsset, WeightTrader}, - Assets, + AssetsInHolding, }; parameter_types! { @@ -35,10 +35,10 @@ parameter_types! { pub const AnyNetwork: Option = None; pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 16; - pub const UniversalLocation: xcm::latest::InteriorMultiLocation = xcm::latest::Junctions::Here; + pub const UniversalLocation: xcm::latest::InteriorLocation = xcm::latest::Junctions::Here; } -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// Type to convert an `Origin` type value into a `Location` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 @@ -48,8 +48,8 @@ pub type LocalOriginToLocation = ( pub struct DoNothingRouter; impl SendXcm for DoNothingRouter { type Ticket = (); - fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { - Ok(((), MultiAssets::new())) + fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) } fn deliver(_: ()) -> Result { Ok([0; 32]) @@ -60,20 +60,16 @@ pub type Barrier = AllowUnpaidExecutionFrom; pub struct DummyAssetTransactor; impl TransactAsset for DummyAssetTransactor { - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { - let asset: MultiAsset = (Parent, 100_000).into(); + ) -> Result { + let asset: Asset = (Parent, 100_000).into(); Ok(asset.into()) } } @@ -87,10 +83,10 @@ impl WeightTrader for DummyWeightTrader { fn buy_weight( &mut self, _weight: Weight, - _payment: Assets, + _payment: AssetsInHolding, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 5f23bd373b13..71e6b696a20a 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -22,7 +22,7 @@ use primitives::Balance; use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; use westend_runtime_constants::currency::*; -use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any @@ -95,9 +95,9 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let wnd = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; + let wnd = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 - let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + let destination: Location = Location::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -138,11 +138,9 @@ where ); // reanchor - let wnd_reanchored: MultiAssets = vec![MultiAsset { - id: Concrete(MultiLocation::new(1, Here)), - fun: Fungible(total_to_send), - }] - .into(); + let wnd_reanchored: Assets = + vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }] + .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); @@ -172,8 +170,8 @@ where // send let _ = >::send( RawOrigin::Root.into(), - Box::new(VersionedMultiLocation::V3(destination)), - Box::new(VersionedXcm::V3(program)), + Box::new(VersionedLocation::V4(destination)), + Box::new(VersionedXcm::V4(program)), )?; Ok(()) } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index e1416c4b7543..92efdf0c0c5a 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -59,7 +59,7 @@ use runtime_common::{ elections::OnChainAccuracy, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, BalanceToU256, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, U256ToBalance, @@ -98,8 +98,8 @@ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use sp_version::NativeVersion; use sp_version::RuntimeVersion; use xcm::{ - latest::{InteriorMultiLocation, Junction, Junction::PalletInstance}, - VersionedMultiLocation, + latest::{InteriorLocation, Junction, Junction::PalletInstance}, + VersionedLocation, }; use xcm_builder::PayOverXcm; @@ -714,7 +714,7 @@ parameter_types! { pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 37). - pub TreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(37).into(); + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(37).into(); pub const TipCountdown: BlockNumber = 1 * DAYS; pub const TipFindersFee: Percent = Percent::from_percent(20); @@ -745,7 +745,7 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = (); type SpendOrigin = TreasurySpender; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Paymaster = PayOverXcm< TreasuryInteriorLocation, @@ -755,7 +755,7 @@ impl pallet_treasury::Config for Runtime { Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; type BalanceConverter = AssetRate; type PayoutPeriod = PayoutSpendPeriod; @@ -2286,31 +2286,31 @@ sp_api::impl_runtime_apis! { impl pallet_offences_benchmarking::Config for Runtime {} impl pallet_election_provider_support_benchmarking::Config for Runtime {} impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(crate::xcm_config::AssetHub::get()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported to/from AH. Some(( - MultiAsset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: Concrete(Here.into()) }, + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: AssetId(Here.into()) }, crate::xcm_config::AssetHub::get(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Relay can reserve transfer native token to some random parachain. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, crate::Junction::Parachain(43211234).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, 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. @@ -2329,13 +2329,13 @@ sp_api::impl_runtime_apis! { impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {} use xcm::latest::{ - AssetId::*, Fungibility::*, InteriorMultiLocation, Junction, Junctions::*, - MultiAsset, MultiAssets, MultiLocation, NetworkId, Response, + AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*, + Asset, Assets, Location, NetworkId, Response, }; use xcm_config::{AssetHub, TokenLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -2347,29 +2347,29 @@ sp_api::impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationConverter; type DeliveryHelper = runtime_common::xcm_sender::ToParachainDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, ToParachain, (), >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(AssetHub::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // Westend only knows about WND. - vec![MultiAsset{ - id: Concrete(TokenLocation::get()), + vec![Asset{ + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }].into() } } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( AssetHub::get(), - MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2379,9 +2379,9 @@ sp_api::impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1 * UNITS), } } @@ -2395,43 +2395,43 @@ sp_api::impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { // Westend doesn't support asset exchanges Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { // The XCM executor of Westend doesn't have a configured `UniversalAliases` Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(AssetHub::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = AssetHub::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { // Westend doesn't support asset locking Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // Westend doesn't support exporting messages Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // The XCM executor of Westend doesn't have a configured `Aliasers` Err(BenchmarkError::Skip) } @@ -2503,12 +2503,11 @@ mod remote_tests { mod clean_state_migration { use super::Runtime; + #[cfg(feature = "try-runtime")] + use super::Vec; use frame_support::{pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade}; use pallet_state_trie_migration::MigrationLimits; - #[cfg(not(feature = "std"))] - use sp_std::prelude::*; - #[storage_alias] type AutoLimits = StorageValue, ValueQuery>; diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index d5b3d8257ba5..0162012825ff 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -36,25 +36,25 @@ pub enum AssetTypes { Unknown, } -impl From<&MultiAsset> for AssetTypes { - fn from(asset: &MultiAsset) -> Self { +impl From<&Asset> for AssetTypes { + fn from(asset: &Asset) -> Self { match asset { - MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + Asset { id: AssetId(Location { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } -trait WeighMultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight; } // Westend only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() @@ -75,11 +75,11 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() - .map(|m| >::from(m)) + .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, @@ -90,32 +90,28 @@ impl WeighMultiAssets for MultiAssets { pub struct WestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for WestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, @@ -143,45 +139,37 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_repsonse_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { // Westend does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -196,7 +184,7 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -208,13 +196,13 @@ impl XcmWeightInfo for WestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -249,19 +237,19 @@ impl XcmWeightInfo for WestendXcmWeight { // Westend relay should not support export message operations Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } @@ -274,19 +262,19 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { - let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let assets = AssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); - assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); + assert_eq!(assets.weigh_assets(weight), weight * MAX_ASSETS); } diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs index e4b4f50f663b..3c052057d909 100644 --- a/polkadot/runtime/westend/src/xcm_config.rs +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -23,8 +23,8 @@ use super::{ }; use crate::governance::pallet_custom_origins::Treasurer; use frame_support::{ - match_types, parameter_types, - traits::{Equals, Everything, Nothing}, + parameter_types, + traits::{Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -53,15 +53,15 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); + pub const RootLocation: Location = Location::here(); pub const ThisNetwork: NetworkId = Westend; - pub const UniversalLocation: InteriorMultiLocation = X1(GlobalConsensus(ThisNetwork::get())); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetwork::get())].into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); pub TreasuryAccount: AccountId = Treasury::account_id(); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -81,7 +81,7 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // We can convert the MultiLocations with our converter above: + // We can convert the Locations with our converter above: LocationConverter, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -114,17 +114,17 @@ pub type XcmRouter = WithUniqueTopic< >; parameter_types! { - pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); - pub const Collectives: MultiLocation = Parachain(COLLECTIVES_ID).into_location(); - pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); - pub const People: MultiLocation = Parachain(PEOPLE_ID).into_location(); - pub const Wnd: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const WndForAssetHub: (MultiAssetFilter, MultiLocation) = (Wnd::get(), AssetHub::get()); - pub const WndForCollectives: (MultiAssetFilter, MultiLocation) = (Wnd::get(), Collectives::get()); - pub const WndForBridgeHub: (MultiAssetFilter, MultiLocation) = (Wnd::get(), BridgeHub::get()); - pub const WndForPeople: (MultiAssetFilter, MultiLocation) = (Wnd::get(), People::get()); - pub const MaxInstructions: u32 = 100; - pub const MaxAssetsIntoHolding: u32 = 64; + pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location(); + pub Collectives: Location = Parachain(COLLECTIVES_ID).into_location(); + pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location(); + pub People: Location = Parachain(PEOPLE_ID).into_location(); + pub Wnd: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) }); + pub WndForAssetHub: (AssetFilter, Location) = (Wnd::get(), AssetHub::get()); + pub WndForCollectives: (AssetFilter, Location) = (Wnd::get(), Collectives::get()); + pub WndForBridgeHub: (AssetFilter, Location) = (Wnd::get(), BridgeHub::get()); + pub WndForPeople: (AssetFilter, Location) = (Wnd::get(), People::get()); + pub MaxInstructions: u32 = 100; + pub MaxAssetsIntoHolding: u32 = 64; } pub type TrustedTeleporters = ( @@ -134,17 +134,29 @@ pub type TrustedTeleporters = ( xcm_builder::Case, ); -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type CollectivesOrFellows: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(COLLECTIVES_ID)) } | - MultiLocation { parents: 0, interior: X2(Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }) } - }; - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) + } +} + +pub struct CollectivesOrFellows; +impl Contains for CollectivesOrFellows { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (0, [Parachain(COLLECTIVES_ID)]) | + (0, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }]) + ) + } +} + +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Plurality { .. }])) + } } /// The barriers one of which must be passed for an XCM message to be executed. @@ -218,11 +230,10 @@ parameter_types! { pub const TreasurerBodyId: BodyId = BodyId::Index(TREASURER_INDEX); } -/// Type to convert the `GeneralAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `GeneralAdmin` origin to a Plurality `Location` value. pub type GeneralAdminToPlurality = OriginToPluralityVoice; -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( GeneralAdminToPlurality, @@ -230,25 +241,25 @@ pub type LocalOriginToLocation = ( SignedToAccountId32, ); -/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the `FellowshipAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `FellowshipAdmin` origin to a Plurality `Location` value. pub type FellowshipAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the `Treasurer` origin to a Plurality `MultiLocation` value. +/// Type to convert the `Treasurer` origin to a Plurality `Location` value. pub type TreasurerToPlurality = OriginToPluralityVoice; -/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( - // GeneralAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // GeneralAdmin origin to be used in XCM as a corresponding Plurality `Location` value. GeneralAdminToPlurality, - // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, - // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `Location` value. FellowshipAdminToPlurality, // `Treasurer` origin to be used in XCM as a corresponding Plurality `MultiLocation` value. TreasurerToPlurality, diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 89e3728a3615..1103e07adbbf 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -18,7 +18,7 @@ log = { version = "0.4.17", default-features = false } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] } -serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive", "rc"] } schemars = { version = "0.8.13", default-features = true, optional = true } xcm-procedural = { path = "procedural" } environmental = { version = "1.1.4", default-features = false } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs index d32eb8d4a52f..e96ec48fcba4 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -24,7 +24,7 @@ use frame_support::{ }; use sp_runtime::traits::{Bounded, Zero}; use sp_std::{prelude::*, vec}; -use xcm::latest::{prelude::*, MAX_ITEMS_IN_MULTIASSETS}; +use xcm::latest::{prelude::*, MAX_ITEMS_IN_ASSETS}; use xcm_executor::traits::{ConvertLocation, FeeReason, TransactAsset}; benchmarks_instance_pallet! { @@ -43,7 +43,7 @@ benchmarks_instance_pallet! { withdraw_asset { let (sender_account, sender_location) = account_and_location::(1); let worst_case_holding = T::worst_case_holding(0); - let asset = T::get_multi_asset(); + let asset = T::get_asset(); >::deposit_asset(&asset, &sender_location, None).unwrap(); // check the assets of origin. @@ -63,8 +63,8 @@ benchmarks_instance_pallet! { transfer_asset { let (sender_account, sender_location) = account_and_location::(1); - let asset = T::get_multi_asset(); - let assets: MultiAssets = vec![ asset.clone() ].into(); + let asset = T::get_asset(); + let assets: Assets = vec![ asset.clone() ].into(); // this xcm doesn't use holding let dest_location = T::valid_destination()?; @@ -95,10 +95,10 @@ benchmarks_instance_pallet! { ); let sender_account_balance_before = T::TransactAsset::balance(&sender_account); - let asset = T::get_multi_asset(); + let asset = T::get_asset(); >::deposit_asset(&asset, &sender_location, None).unwrap(); assert!(T::TransactAsset::balance(&sender_account) > sender_account_balance_before); - let assets: MultiAssets = vec![ asset ].into(); + let assets: Assets = vec![asset].into(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); let mut executor = new_executor::(sender_location); @@ -129,7 +129,7 @@ benchmarks_instance_pallet! { BenchmarkResult::from_weight(Weight::MAX) ))?; - let assets: MultiAssets = vec![ transferable_reserve_asset ].into(); + let assets: Assets = vec![ transferable_reserve_asset ].into(); let mut executor = new_executor::(trusted_reserve); let instruction = Instruction::ReserveAssetDeposited(assets.clone()); @@ -143,7 +143,7 @@ benchmarks_instance_pallet! { initiate_reserve_withdraw { let (sender_account, sender_location) = account_and_location::(1); let holding = T::worst_case_holding(1); - let assets_filter = MultiAssetFilter::Definite(holding.clone().into_inner().into_iter().take(MAX_ITEMS_IN_MULTIASSETS).collect::>().into()); + let assets_filter = AssetFilter::Definite(holding.clone().into_inner().into_iter().take(MAX_ITEMS_IN_ASSETS).collect::>().into()); let reserve = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; let (expected_fees_mode, expected_assets_in_holding) = T::DeliveryHelper::ensure_successful_delivery( @@ -188,7 +188,7 @@ benchmarks_instance_pallet! { )?; } - let assets: MultiAssets = vec![ teleportable_asset ].into(); + let assets: Assets = vec![ teleportable_asset ].into(); let mut executor = new_executor::(trusted_teleporter); let instruction = Instruction::ReceiveTeleportedAsset(assets.clone()); @@ -204,7 +204,7 @@ benchmarks_instance_pallet! { } deposit_asset { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); // Add our asset to the holding. @@ -230,7 +230,7 @@ benchmarks_instance_pallet! { } deposit_reserve_asset { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); // Add our asset to the holding. @@ -257,7 +257,7 @@ benchmarks_instance_pallet! { } initiate_teleport { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(0); // Add our asset to the holding. diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs index 43892c31c7cd..bb4b7ff6276f 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -93,10 +93,10 @@ parameter_types! { pub struct MatchAnyFungible; impl xcm_executor::traits::MatchesFungible for MatchAnyFungible { - fn matches_fungible(m: &MultiAsset) -> Option { + fn matches_fungible(m: &Asset) -> Option { use sp_runtime::traits::SaturatedConversion; match m { - MultiAsset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), + Asset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), _ => None, } } @@ -151,13 +151,12 @@ impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; type DeliveryHelper = (); - fn valid_destination() -> Result { - let valid_destination: MultiLocation = - X1(AccountId32 { network: None, id: [0u8; 32] }).into(); + fn valid_destination() -> Result { + let valid_destination: Location = [AccountId32 { network: None, id: [0u8; 32] }].into(); Ok(valid_destination) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> Assets { crate::mock_worst_case_holding( depositable_count, ::MaxAssetsIntoHolding::get(), @@ -170,19 +169,19 @@ pub type TrustedReserves = xcm_builder::Case; parameter_types! { pub const CheckingAccount: Option<(u64, MintLocation)> = Some((100, MintLocation::Local)); - pub const ChildTeleporter: MultiLocation = Parachain(1000).into_location(); - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub ChildTeleporter: Location = Parachain(1000).into_location(); + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( ChildTeleporter::get(), - MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + Asset { id: AssetId(Here.into_location()), fun: Fungible(100) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedReserve: Option<(Location, Asset)> = Some(( ChildTeleporter::get(), - MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + Asset { id: AssetId(Here.into_location()), fun: Fungible(100) }, )); - pub const TeleportConcreteFungible: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); - pub const ReserveConcreteFungible: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub TeleportConcreteFungible: (AssetFilter, Location) = + (Wild(AllOf { fun: WildFungible, id: AssetId(Here.into_location()) }), ChildTeleporter::get()); + pub ReserveConcreteFungible: (AssetFilter, Location) = + (Wild(AllOf { fun: WildFungible, id: AssetId(Here.into_location()) }), ChildTeleporter::get()); } impl xcm_balances_benchmark::Config for Test { @@ -191,10 +190,10 @@ impl xcm_balances_benchmark::Config for Test { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { + fn get_asset() -> Asset { let amount = >::minimum_balance() as u128; - MultiAsset { id: Concrete(Here.into()), fun: Fungible(amount) } + Asset { id: AssetId(Here.into()), fun: Fungible(amount) } } } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs index 292921eb595f..e84355f4092b 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs @@ -37,14 +37,14 @@ pub mod pallet { type CheckedAccount: Get>; /// A trusted location which we allow teleports from, and the asset we allow to teleport. - type TrustedTeleporter: Get>; + type TrustedTeleporter: Get>; /// A trusted location where reserve assets are stored, and the asset we allow to be /// reserves. - type TrustedReserve: Get>; + type TrustedReserve: Get>; /// Give me a fungible asset that your asset transactor is going to accept. - fn get_multi_asset() -> xcm::latest::MultiAsset; + fn get_asset() -> xcm::latest::Asset; } #[pallet::pallet] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 50a7fe45e231..14d53c4ebf53 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -77,7 +77,7 @@ benchmarks! { let mut executor = new_executor::(Default::default()); executor.set_holding(holding); - let fee_asset = Concrete(Here.into()); + let fee_asset = AssetId(Here.into()); let instruction = Instruction::>::BuyExecution { fees: (fee_asset, 100_000_000u128).into(), // should be something inside of holding @@ -95,7 +95,7 @@ benchmarks! { let mut executor = new_executor::(Default::default()); let (query_id, response) = T::worst_case_response(); let max_weight = Weight::MAX; - let querier: Option = Some(Here.into()); + let querier: Option = Some(Here.into()); let instruction = Instruction::QueryResponse { query_id, response, max_weight, querier }; let xcm = Xcm(vec![instruction]); }: { @@ -174,15 +174,15 @@ benchmarks! { descend_origin { let mut executor = new_executor::(Default::default()); - let who = X2(OnlyChild, OnlyChild); - let instruction = Instruction::DescendOrigin(who); + let who = Junctions::from([OnlyChild, OnlyChild]); + let instruction = Instruction::DescendOrigin(who.clone()); let xcm = Xcm(vec![instruction]); } : { executor.bench_process(xcm)?; } verify { assert_eq!( executor.origin(), - &Some(MultiLocation { + &Some(Location { parents: 0, interior: who, }), @@ -242,7 +242,7 @@ benchmarks! { &origin, assets.clone().into(), &XcmContext { - origin: Some(origin), + origin: Some(origin.clone()), message_id: [0; 32], topic: None, }, @@ -279,7 +279,7 @@ benchmarks! { let origin = T::subscribe_origin()?; let query_id = Default::default(); let max_response_weight = Default::default(); - let mut executor = new_executor::(origin); + let mut executor = new_executor::(origin.clone()); let instruction = Instruction::SubscribeVersion { query_id, max_response_weight }; let xcm = Xcm(vec![instruction]); } : { @@ -299,14 +299,14 @@ benchmarks! { query_id, max_response_weight, &XcmContext { - origin: Some(origin), + origin: Some(origin.clone()), message_id: [0; 32], topic: None, }, ).map_err(|_| "Could not start subscription")?; assert!(::SubscriptionService::is_subscribed(&origin)); - let mut executor = new_executor::(origin); + let mut executor = new_executor::(origin.clone()); let instruction = Instruction::UnsubscribeVersion; let xcm = Xcm(vec![instruction]); } : { @@ -545,7 +545,7 @@ benchmarks! { } verify { use frame_support::traits::Get; let universal_location = ::UniversalLocation::get(); - assert_eq!(executor.origin(), &Some(X1(alias).relative_to(&universal_location))); + assert_eq!(executor.origin(), &Some(Junctions::from([alias]).relative_to(&universal_location))); } export_message { @@ -561,8 +561,8 @@ benchmarks! { let (expected_fees_mode, expected_assets_in_holding) = T::DeliveryHelper::ensure_successful_delivery( &origin, - &destination.into(), - FeeReason::Export { network, destination }, + &destination.clone().into(), + FeeReason::Export { network, destination: destination.clone() }, ); let sender_account = T::AccountIdConverter::convert_location(&origin).unwrap(); let sender_account_balance_before = T::TransactAsset::balance(&sender_account); @@ -575,7 +575,7 @@ benchmarks! { executor.set_holding(expected_assets_in_holding.into()); } let xcm = Xcm(vec![ExportMessage { - network, destination, xcm: inner_xcm, + network, destination: destination.clone(), xcm: inner_xcm, }]); }: { executor.bench_process(xcm)?; @@ -632,13 +632,13 @@ benchmarks! { let (unlocker, owner, asset) = T::unlockable_asset()?; - let mut executor = new_executor::(unlocker); + let mut executor = new_executor::(unlocker.clone()); // We first place the asset in lock first... ::AssetLocker::prepare_lock( unlocker, asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -658,13 +658,13 @@ benchmarks! { let (unlocker, owner, asset) = T::unlockable_asset()?; - let mut executor = new_executor::(unlocker); + let mut executor = new_executor::(unlocker.clone()); // We first place the asset in lock first... ::AssetLocker::prepare_lock( unlocker, asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -686,9 +686,9 @@ benchmarks! { // We first place the asset in lock first... ::AssetLocker::prepare_lock( - locker, + locker.clone(), asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -739,7 +739,7 @@ benchmarks! { let mut executor = new_executor::(origin); - let instruction = Instruction::AliasOrigin(target); + let instruction = Instruction::AliasOrigin(target.clone()); let xcm = Xcm(vec![instruction]); }: { executor.bench_process(xcm)?; diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs index 6efd2304e281..4dd677217fcc 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -19,16 +19,16 @@ use crate::{generic, mock::*, *}; use codec::Decode; use frame_support::{ - derive_impl, match_types, parameter_types, - traits::{Everything, OriginTrait}, + derive_impl, parameter_types, + traits::{Contains, Everything, OriginTrait}, weights::Weight, }; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}; use xcm_builder::{ test_utils::{ - Assets, TestAssetExchanger, TestAssetLocker, TestAssetTrap, TestSubscriptionService, - TestUniversalAliases, + AssetsInHolding, TestAssetExchanger, TestAssetLocker, TestAssetTrap, + TestSubscriptionService, TestUniversalAliases, }, AliasForeignAccountId32, AllowUnpaidExecutionFrom, }; @@ -81,19 +81,15 @@ impl frame_system::Config for Test { /// The benchmarks in this pallet should never need an asset transactor to begin with. pub struct NoAssetTransactor; impl xcm_executor::traits::TransactAsset for NoAssetTransactor { - fn deposit_asset( - _: &MultiAsset, - _: &MultiLocation, - _: Option<&XcmContext>, - ) -> Result<(), XcmError> { + fn deposit_asset(_: &Asset, _: &Location, _: Option<&XcmContext>) -> Result<(), XcmError> { unreachable!(); } fn withdraw_asset( - _: &MultiAsset, - _: &MultiLocation, + _: &Asset, + _: &Location, _: Option<&XcmContext>, - ) -> Result { + ) -> Result { unreachable!(); } } @@ -103,10 +99,11 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) + } } type Aliasers = AliasForeignAccountId32; @@ -153,13 +150,13 @@ impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; type DeliveryHelper = (); - fn valid_destination() -> Result { - let valid_destination: MultiLocation = + fn valid_destination() -> Result { + let valid_destination: Location = Junction::AccountId32 { network: None, id: [0u8; 32] }.into(); Ok(valid_destination) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> Assets { crate::mock_worst_case_holding( depositable_count, ::MaxAssetsIntoHolding::get(), @@ -172,48 +169,47 @@ impl generic::Config for Test { type RuntimeCall = RuntimeCall; fn worst_case_response() -> (u64, Response) { - let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + let assets: Assets = (AssetId(Here.into()), 100).into(); (0, Response::Assets(assets)) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Ok(Default::default()) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Ok((Here.into(), GlobalConsensus(ByGenesis([0; 32])))) } fn transact_origin_and_runtime_call( - ) -> Result<(MultiLocation, ::RuntimeCall), BenchmarkError> { + ) -> Result<(Location, ::RuntimeCall), BenchmarkError> { Ok((Default::default(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(Default::default()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let assets: MultiAssets = (Concrete(Here.into()), 100).into(); - let ticket = MultiLocation { parents: 0, interior: X1(GeneralIndex(0)) }; + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { + let assets: Assets = (AssetId(Here.into()), 100).into(); + let ticket = Location { parents: 0, interior: [GeneralIndex(0)].into() }; Ok((Default::default(), ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { - let assets: MultiAsset = (Concrete(Here.into()), 100).into(); + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { + let assets: Asset = (AssetId(Here.into()), 100).into(); Ok((Default::default(), account_id_junction::(1).into(), assets)) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // No MessageExporter in tests Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { - let origin: MultiLocation = - (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); - let target: MultiLocation = AccountId32 { network: None, id: [0; 32] }.into(); + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { + let origin: Location = (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); + let target: Location = AccountId32 { network: None, id: [0; 32] }.into(); Ok((origin, target)) } } @@ -233,9 +229,9 @@ where ::AccountId: Decode, { fn convert_origin( - _origin: impl Into, + _origin: impl Into, _kind: OriginKind, - ) -> Result { + ) -> Result { Ok(RuntimeOrigin::signed( ::AccountId::decode(&mut TrailingZeroInput::zeroes()) .expect("infinite length input; no invalid inputs for type; qed"), diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs index 11f7bba19a98..3728baea9833 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs @@ -26,10 +26,7 @@ pub mod pallet { use frame_benchmarking::BenchmarkError; use frame_support::{dispatch::GetDispatchInfo, pallet_prelude::Encode}; use sp_runtime::traits::Dispatchable; - use xcm::latest::{ - InteriorMultiLocation, Junction, MultiAsset, MultiAssets, MultiLocation, NetworkId, - Response, - }; + use xcm::latest::{Asset, Assets, InteriorLocation, Junction, Location, NetworkId, Response}; #[pallet::config] pub trait Config: frame_system::Config + crate::Config { @@ -53,44 +50,44 @@ pub mod pallet { /// from, whereas the second element represents the assets that are being exchanged to. /// /// If set to `Err`, benchmarks which rely on an `exchange_asset` will be skipped. - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError>; + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError>; - /// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the + /// A `(Location, Junction)` that is one of the `UniversalAliases` configured by the /// XCM executor. /// /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError>; + fn universal_alias() -> Result<(Location, Junction), BenchmarkError>; - /// The `MultiLocation` and `RuntimeCall` used for successful transaction XCMs. + /// The `Location` and `RuntimeCall` used for successful transaction XCMs. /// /// If set to `Err`, benchmarks which rely on a `transact_origin_and_runtime_call` will be /// skipped. fn transact_origin_and_runtime_call( - ) -> Result<(MultiLocation, >::RuntimeCall), BenchmarkError>; + ) -> Result<(Location, >::RuntimeCall), BenchmarkError>; - /// A valid `MultiLocation` we can successfully subscribe to. + /// A valid `Location` we can successfully subscribe to. /// /// If set to `Err`, benchmarks which rely on a `subscribe_origin` will be skipped. - fn subscribe_origin() -> Result; + fn subscribe_origin() -> Result; /// Return an origin, ticket, and assets that can be trapped and claimed. - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError>; + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError>; /// Return an unlocker, owner and assets that can be locked and unlocked. - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError>; + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError>; - /// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message + /// A `(Location, NetworkId, InteriorLocation)` we can successfully export message /// to. /// /// If set to `Err`, benchmarks which rely on `export_message` will be skipped. fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError>; + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError>; - /// A `(MultiLocation, MultiLocation)` that is one of the `Aliasers` configured by the XCM + /// A `(Location, Location)` that is one of the `Aliasers` configured by the XCM /// executor. /// /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError>; + fn alias_origin() -> Result<(Location, Location), BenchmarkError>; /// Returns a valid pallet info for `ExpectPallet` or `QueryPallet` benchmark. /// diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs index 3bf4aea1b25e..6ce8d3e99e8e 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs @@ -41,18 +41,18 @@ pub trait Config: frame_system::Config { /// `TransactAsset` is implemented. type XcmConfig: XcmConfig; - /// A converter between a multi-location to a sovereign account. + /// A converter between a location to a sovereign account. type AccountIdConverter: ConvertLocation; /// Helper that ensures successful delivery for XCM instructions which need `SendXcm`. type DeliveryHelper: EnsureDelivery; /// Does any necessary setup to create a valid destination for XCM messages. - /// Returns that destination's multi-location to be used in benchmarks. - fn valid_destination() -> Result; + /// Returns that destination's location to be used in benchmarks. + fn valid_destination() -> Result; /// Worst case scenario for a holding account in this runtime. - fn worst_case_holding(depositable_count: u32) -> MultiAssets; + fn worst_case_holding(depositable_count: u32) -> Assets; } const SEED: u32 = 0; @@ -66,21 +66,21 @@ pub type AssetTransactorOf = <::XcmConfig as XcmConfig>::AssetTr /// The call type of executor's config. Should eventually resolve to the same overarching call type. pub type XcmCallOf = <::XcmConfig as XcmConfig>::RuntimeCall; -pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> MultiAssets { +pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> Assets { let fungibles_amount: u128 = 100; let holding_fungibles = max_assets / 2 - depositable_count; let holding_non_fungibles = holding_fungibles; (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * i as u128), } .into() }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>() @@ -94,11 +94,11 @@ pub fn asset_instance_from(x: u32) -> AssetInstance { AssetInstance::Array4(instance) } -pub fn new_executor(origin: MultiLocation) -> ExecutorOf { +pub fn new_executor(origin: Location) -> ExecutorOf { ExecutorOf::::new(origin, [0; 32]) } -/// Build a multi-location from an account id. +/// Build a location from an account id. fn account_id_junction(index: u32) -> Junction { let account: T::AccountId = account("account", index, SEED); let mut encoded = account.encode(); @@ -108,8 +108,8 @@ fn account_id_junction(index: u32) -> Junction { Junction::AccountId32 { network: None, id } } -pub fn account_and_location(index: u32) -> (T::AccountId, MultiLocation) { - let location: MultiLocation = account_id_junction::(index).into(); +pub fn account_and_location(index: u32) -> (T::AccountId, Location) { + let location: Location = account_id_junction::(index).into(); let account = T::AccountIdConverter::convert_location(&location).unwrap(); (account, location) @@ -121,21 +121,21 @@ pub trait EnsureDelivery { /// Prepare all requirements for successful `XcmSender: SendXcm` passing (accounts, balances, /// channels ...). Returns: /// - possible `FeesMode` which is expected to be set to executor - /// - possible `MultiAssets` which are expected to be subsume to the Holding Register + /// - possible `Assets` which are expected to be subsume to the Holding Register fn ensure_successful_delivery( - origin_ref: &MultiLocation, - dest: &MultiLocation, + origin_ref: &Location, + dest: &Location, fee_reason: FeeReason, - ) -> (Option, Option); + ) -> (Option, Option); } /// `()` implementation does nothing which means no special requirements for environment. impl EnsureDelivery for () { fn ensure_successful_delivery( - _origin_ref: &MultiLocation, - _dest: &MultiLocation, + _origin_ref: &Location, + _dest: &Location, _fee_reason: FeeReason, - ) -> (Option, Option) { + ) -> (Option, Option) { // doing nothing (None, None) } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs index e02c5bf08615..78a9e5f8a018 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs @@ -22,8 +22,8 @@ use xcm::latest::Weight; pub struct DevNull; impl xcm::opaque::latest::SendXcm for DevNull { type Ticket = (); - fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { - Ok(((), MultiAssets::new())) + fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) } fn deliver(_: ()) -> Result { Ok([0; 32]) @@ -31,13 +31,13 @@ impl xcm::opaque::latest::SendXcm for DevNull { } impl xcm_executor::traits::OnResponse for DevNull { - fn expecting_response(_: &MultiLocation, _: u64, _: Option<&MultiLocation>) -> bool { + fn expecting_response(_: &Location, _: u64, _: Option<&Location>) -> bool { false } fn on_response( - _: &MultiLocation, + _: &Location, _: u64, - _: Option<&MultiLocation>, + _: Option<&Location>, _: Response, _: Weight, _: &XcmContext, @@ -48,9 +48,9 @@ impl xcm_executor::traits::OnResponse for DevNull { pub struct AccountIdConverter; impl xcm_executor::traits::ConvertLocation for AccountIdConverter { - fn convert_location(ml: &MultiLocation) -> Option { - match ml { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, .. }) } => + fn convert_location(ml: &Location) -> Option { + match ml.unpack() { + (0, [Junction::AccountId32 { id, .. }]) => Some(::decode(&mut &*id.to_vec()).unwrap()), _ => None, } @@ -58,14 +58,14 @@ impl xcm_executor::traits::ConvertLocation for AccountIdConverter { } parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Junction::Parachain(101).into(); + pub UniversalLocation: InteriorLocation = Junction::Parachain(101).into(); pub UnitWeightCost: Weight = Weight::from_parts(10, 10); - pub WeightPrice: (AssetId, u128, u128) = (Concrete(Here.into()), 1_000_000, 1024); + pub WeightPrice: (AssetId, u128, u128) = (AssetId(Here.into()), 1_000_000, 1024); } pub struct AllAssetLocationsPass; -impl ContainsPair for AllAssetLocationsPass { - fn contains(_: &MultiAsset, _: &MultiLocation) -> bool { +impl ContainsPair for AllAssetLocationsPass { + fn contains(_: &Asset, _: &Location) -> bool { true } } diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index 28a198f40a05..c7d8fb24e9df 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -32,36 +32,36 @@ pub struct Pallet(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. pub trait Config: crate::Config { - /// A `MultiLocation` that can be reached via `XcmRouter`. Used only in benchmarks. + /// A `Location` that can be reached via `XcmRouter`. Used only in benchmarks. /// /// If `None`, the benchmarks that depend on a reachable destination will be skipped. - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { None } - /// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be + /// A `(Asset, Location)` pair representing asset and the destination it can be /// teleported to. Used only in benchmarks. /// /// Implementation should also make sure `dest` is reachable/connected. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { None } - /// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be + /// A `(Asset, Location)` pair representing asset and the destination it can be /// reserve-transferred to. Used only in benchmarks. /// /// Implementation should also make sure `dest` is reachable/connected. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } /// 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 - /// `(MultiAsset, u32, MultiLocation, dyn FnOnce())` representing the assets to transfer, the + /// `(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 /// `verify()` closure to verify the intended transfer side-effects. /// @@ -71,8 +71,7 @@ pub trait Config: crate::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<(MultiAssets, u32, MultiLocation, Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { None } } @@ -90,7 +89,7 @@ benchmarks! { return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) } let msg = Xcm(vec![ClearOrigin]); - let versioned_dest: VersionedMultiLocation = T::reachable_dest().ok_or( + let versioned_dest: VersionedLocation = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); @@ -106,7 +105,7 @@ benchmarks! { Fungible(amount) => *amount, _ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")), }.into(); - let assets: MultiAssets = asset.into(); + let assets: Assets = asset.into(); let existential_deposit = T::ExistentialDeposit::get(); let caller = whitelisted_caller(); @@ -126,10 +125,10 @@ benchmarks! { } let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) verify { // verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees) @@ -145,7 +144,7 @@ benchmarks! { Fungible(amount) => *amount, _ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")), }.into(); - let assets: MultiAssets = asset.into(); + let assets: Assets = asset.into(); let existential_deposit = T::ExistentialDeposit::get(); let caller = whitelisted_caller(); @@ -165,10 +164,10 @@ benchmarks! { } let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) verify { // verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees) @@ -182,10 +181,10 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let send_origin = RawOrigin::Signed(caller.clone()); let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0, WeightLimit::Unlimited) verify { // run provided verification function @@ -214,7 +213,7 @@ benchmarks! { force_default_xcm_version {}: _(RawOrigin::Root, Some(2)) force_subscribe_version_notify { - let versioned_loc: VersionedMultiLocation = T::reachable_dest().ok_or( + let versioned_loc: VersionedLocation = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); @@ -224,7 +223,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )?; - let versioned_loc: VersionedMultiLocation = loc.into(); + let versioned_loc: VersionedLocation = loc.clone().into(); let _ = crate::Pallet::::request_version_notify(loc); }: _(RawOrigin::Root, Box::new(versioned_loc)) @@ -232,7 +231,7 @@ benchmarks! { migrate_supported_version { let old_version = XCM_VERSION - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); SupportedVersion::::insert(old_version, loc, old_version); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero()); @@ -240,7 +239,7 @@ benchmarks! { migrate_version_notifiers { let old_version = XCM_VERSION - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifiers::::insert(old_version, loc, 0); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero()); @@ -250,7 +249,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads(1))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), current_version)); }: { @@ -261,7 +260,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let current_version = T::AdvertisedXcmVersion::get(); let old_version = current_version - 1; VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), old_version)); @@ -276,7 +275,7 @@ benchmarks! { part: v2::BodyPart::Voice, } .into(); - let bad_loc = VersionedMultiLocation::from(bad_loc); + let bad_loc = VersionedLocation::from(bad_loc); let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, bad_loc, (0, Weight::zero(), current_version)); }: { @@ -286,7 +285,7 @@ benchmarks! { migrate_version_notify_targets { let current_version = T::AdvertisedXcmVersion::get(); let old_version = current_version - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), current_version)); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); @@ -296,7 +295,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let old_version = T::AdvertisedXcmVersion::get() - 1; VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), old_version)); }: { @@ -304,17 +303,17 @@ benchmarks! { } new_query { - let responder = MultiLocation::from(Parent); + let responder = Location::from(Parent); let timeout = 1u32.into(); - let match_querier = MultiLocation::from(Here); + let match_querier = Location::from(Here); }: { crate::Pallet::::new_query(responder, timeout, match_querier); } take_response { - let responder = MultiLocation::from(Parent); + let responder = Location::from(Parent); let timeout = 1u32.into(); - let match_querier = MultiLocation::from(Here); + let match_querier = Location::from(Here); let query_id = crate::Pallet::::new_query(responder, timeout, match_querier); let infos = (0 .. xcm::v3::MaxPalletsInfo::get()).map(|_| PalletInfo::new( u32::MAX, @@ -340,17 +339,17 @@ benchmarks! { pub mod helpers { use super::*; pub fn native_teleport_as_asset_transfer( - native_asset_location: MultiLocation, - destination: MultiLocation, - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> + native_asset_location: Location, + destination: Location, + ) -> Option<(Assets, u32, Location, Box)> where T: Config + pallet_balances::Config, u128: From<::Balance>, { // Relay/native token can be teleported to/from AH. let amount = T::ExistentialDeposit::get() * 100u32.into(); - let assets: MultiAssets = - MultiAsset { fun: Fungible(amount.into()), id: Concrete(native_asset_location) }.into(); + let assets: Assets = + Asset { fun: Fungible(amount.into()), id: AssetId(native_asset_location) }.into(); let fee_index = 0u32; // Give some multiple of transferred amount diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index 2848527f1502..55154198a9b2 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -59,7 +59,7 @@ use xcm_executor::{ DropAssets, MatchesFungible, OnResponse, Properties, QueryHandler, QueryResponseStatus, TransactAsset, TransferType, VersionChangeNotifier, WeightBounds, XcmAssetTransfers, }, - Assets, + AssetsInHolding, }; pub trait WeightInfo { @@ -202,45 +202,39 @@ pub mod pallet { // TODO: We should really use a trait which can handle multiple currencies. type Currency: LockableCurrency>; - /// The `MultiAsset` matcher for `Currency`. + /// The `Asset` matcher for `Currency`. type CurrencyMatcher: MatchesFungible>; - /// Required origin for sending XCM messages. If successful, it resolves to `MultiLocation` + /// Required origin for sending XCM messages. If successful, it resolves to `Location` /// which exists as an interior location within this chain's XCM context. - type SendXcmOrigin: EnsureOrigin< - ::RuntimeOrigin, - Success = MultiLocation, - >; + type SendXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; /// The type used to actually dispatch an XCM to its destination. type XcmRouter: SendXcm; /// Required origin for executing XCM messages, including the teleport functionality. If - /// successful, then it resolves to `MultiLocation` which exists as an interior location + /// successful, then it resolves to `Location` which exists as an interior location /// within this chain's XCM context. - type ExecuteXcmOrigin: EnsureOrigin< - ::RuntimeOrigin, - Success = MultiLocation, - >; + type ExecuteXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; /// Our XCM filter which messages to be executed using `XcmExecutor` must pass. - type XcmExecuteFilter: Contains<(MultiLocation, Xcm<::RuntimeCall>)>; + type XcmExecuteFilter: Contains<(Location, Xcm<::RuntimeCall>)>; /// Something to execute an XCM message. type XcmExecutor: ExecuteXcm<::RuntimeCall> + XcmAssetTransfers; /// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass. - type XcmTeleportFilter: Contains<(MultiLocation, Vec)>; + type XcmTeleportFilter: Contains<(Location, Vec)>; /// Our XCM filter which messages to be reserve-transferred using the dedicated extrinsic /// must pass. - type XcmReserveTransferFilter: Contains<(MultiLocation, Vec)>; + type XcmReserveTransferFilter: Contains<(Location, Vec)>; /// Means of measuring the weight consumed by an XCM message locally. type Weigher: WeightBounds<::RuntimeCall>; /// This chain's Universal Location. - type UniversalLocation: Get; + type UniversalLocation: Get; /// The runtime `Origin` type. type RuntimeOrigin: From + From<::RuntimeOrigin>; @@ -264,9 +258,9 @@ pub mod pallet { /// The assets which we consider a given origin is trusted if they claim to have placed a /// lock. - type TrustedLockers: ContainsPair; + type TrustedLockers: ContainsPair; - /// How to get an `AccountId` value from a `MultiLocation`, useful for handling asset locks. + /// How to get an `AccountId` value from a `Location`, useful for handling asset locks. type SovereignAccountOf: ConvertLocation; /// The maximum number of local XCM locks that a single account may have. @@ -296,15 +290,15 @@ pub mod pallet { max_weight: Weight, ) -> Result { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; - let hash = message.using_encoded(sp_io::hashing::blake2_256); + let mut hash = message.using_encoded(sp_io::hashing::blake2_256); let message = (*message).try_into().map_err(|()| Error::::BadVersion)?; let value = (origin_location, message); ensure!(T::XcmExecuteFilter::contains(&value), Error::::Filtered); let (origin_location, message) = value; - let outcome = T::XcmExecutor::execute_xcm_in_credit( + let outcome = T::XcmExecutor::prepare_and_execute( origin_location, message, - hash, + &mut hash, max_weight, max_weight, ); @@ -323,17 +317,17 @@ pub mod pallet { type WeightInfo = Self; fn send( origin: OriginFor, - dest: Box, + dest: Box, message: Box>, ) -> Result { let origin_location = T::SendXcmOrigin::ensure_origin(origin)?; let interior: Junctions = - origin_location.try_into().map_err(|_| Error::::InvalidOrigin)?; - let dest = MultiLocation::try_from(*dest).map_err(|()| Error::::BadVersion)?; + origin_location.clone().try_into().map_err(|_| Error::::InvalidOrigin)?; + let dest = Location::try_from(*dest).map_err(|()| Error::::BadVersion)?; let message: Xcm<()> = (*message).try_into().map_err(|()| Error::::BadVersion)?; - let message_id = - Self::send_xcm(interior, dest, message.clone()).map_err(Error::::from)?; + let message_id = Self::send_xcm(interior, dest.clone(), message.clone()) + .map_err(Error::::from)?; let e = Event::Sent { origin: origin_location, destination: dest, message, message_id }; Self::deposit_event(e); Ok(message_id) @@ -355,13 +349,13 @@ pub mod pallet { fn query( origin: OriginFor, timeout: BlockNumberFor, - match_querier: VersionedMultiLocation, + match_querier: VersionedLocation, ) -> Result { let responder = ::ExecuteXcmOrigin::ensure_origin(origin)?; let query_id = ::new_query( responder, timeout, - MultiLocation::try_from(match_querier) + Location::try_from(match_querier) .map_err(|_| Into::::into(Error::::BadVersion))?, ); @@ -375,16 +369,11 @@ pub mod pallet { /// Execution of an XCM message was attempted. Attempted { outcome: xcm::latest::Outcome }, /// A XCM message was sent. - Sent { - origin: MultiLocation, - destination: MultiLocation, - message: Xcm<()>, - message_id: XcmHash, - }, + Sent { origin: Location, destination: Location, message: Xcm<()>, message_id: XcmHash }, /// Query response received which does not match a registered query. This may be because a /// matching query was never registered, it may be because it is a duplicate response, or /// because the query timed out. - UnexpectedResponse { origin: MultiLocation, query_id: QueryId }, + UnexpectedResponse { origin: Location, query_id: QueryId }, /// Query response has been received and is ready for taking with `take_response`. There is /// no registered notification call. ResponseReady { query_id: QueryId, response: Response }, @@ -412,9 +401,9 @@ pub mod pallet { /// not match that expected. The query remains registered for a later, valid, response to /// be received and acted upon. InvalidResponder { - origin: MultiLocation, + origin: Location, query_id: QueryId, - expected_location: Option, + expected_location: Option, }, /// Expected query response has been received but the expected origin location placed in /// storage by this runtime previously cannot be decoded. The query remains registered. @@ -423,29 +412,29 @@ pub mod pallet { /// runtime should be readable prior to query timeout) and dangerous since the possibly /// valid response will be dropped. Manual governance intervention is probably going to be /// needed. - InvalidResponderVersion { origin: MultiLocation, query_id: QueryId }, + InvalidResponderVersion { origin: Location, query_id: QueryId }, /// Received query response has been read and removed. ResponseTaken { query_id: QueryId }, /// Some assets have been placed in an asset trap. - AssetsTrapped { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + AssetsTrapped { hash: H256, origin: Location, assets: VersionedAssets }, /// An XCM version change notification message has been attempted to be sent. /// /// The cost of sending it (borne by the chain) is included. VersionChangeNotified { - destination: MultiLocation, + destination: Location, result: XcmVersion, - cost: MultiAssets, + cost: Assets, message_id: XcmHash, }, /// The supported version of a location has been changed. This might be through an /// automatic notification or a manual intervention. - SupportedVersionChanged { location: MultiLocation, version: XcmVersion }, + SupportedVersionChanged { location: Location, version: XcmVersion }, /// A given location which had a version change subscription was dropped owing to an error /// sending the notification to it. - NotifyTargetSendFail { location: MultiLocation, query_id: QueryId, error: XcmError }, + NotifyTargetSendFail { location: Location, query_id: QueryId, error: XcmError }, /// A given location which had a version change subscription was dropped owing to an error /// migrating the location to our new XCM format. - NotifyTargetMigrationFail { location: VersionedMultiLocation, query_id: QueryId }, + NotifyTargetMigrationFail { location: VersionedLocation, query_id: QueryId }, /// Expected query response has been received but the expected querier location placed in /// storage by this runtime previously cannot be decoded. The query remains registered. /// @@ -453,48 +442,40 @@ pub mod pallet { /// runtime should be readable prior to query timeout) and dangerous since the possibly /// valid response will be dropped. Manual governance intervention is probably going to be /// needed. - InvalidQuerierVersion { origin: MultiLocation, query_id: QueryId }, + InvalidQuerierVersion { origin: Location, query_id: QueryId }, /// Expected query response has been received but the querier location of the response does /// not match the expected. The query remains registered for a later, valid, response to /// be received and acted upon. InvalidQuerier { - origin: MultiLocation, + origin: Location, query_id: QueryId, - expected_querier: MultiLocation, - maybe_actual_querier: Option, + expected_querier: Location, + maybe_actual_querier: Option, }, /// A remote has requested XCM version change notification from us and we have honored it. /// A version information message is sent to them and its cost is included. - VersionNotifyStarted { destination: MultiLocation, cost: MultiAssets, message_id: XcmHash }, + VersionNotifyStarted { destination: Location, cost: Assets, message_id: XcmHash }, /// We have requested that a remote chain send us XCM version change notifications. - VersionNotifyRequested { - destination: MultiLocation, - cost: MultiAssets, - message_id: XcmHash, - }, + VersionNotifyRequested { destination: Location, cost: Assets, message_id: XcmHash }, /// We have requested that a remote chain stops sending us XCM version change /// notifications. - VersionNotifyUnrequested { - destination: MultiLocation, - cost: MultiAssets, - message_id: XcmHash, - }, + VersionNotifyUnrequested { destination: Location, cost: Assets, message_id: XcmHash }, /// Fees were paid from a location for an operation (often for using `SendXcm`). - FeesPaid { paying: MultiLocation, fees: MultiAssets }, + FeesPaid { paying: Location, fees: Assets }, /// Some assets have been claimed from an asset trap - AssetsClaimed { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + AssetsClaimed { hash: H256, origin: Location, assets: VersionedAssets }, } #[pallet::origin] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum Origin { /// It comes from somewhere in the XCM space wanting to transact. - Xcm(MultiLocation), + Xcm(Location), /// It comes as an expected response from an XCM location. - Response(MultiLocation), + Response(Location), } - impl From for Origin { - fn from(location: MultiLocation) -> Origin { + impl From for Origin { + fn from(location: Location) -> Origin { Origin::Xcm(location) } } @@ -511,7 +492,7 @@ pub mod pallet { Filtered, /// The message's weight could not be determined. UnweighableMessage, - /// The destination `MultiLocation` provided cannot be inverted. + /// The destination `Location` provided cannot be inverted. DestinationNotInvertible, /// The assets to be sent are empty. Empty, @@ -582,25 +563,25 @@ pub mod pallet { Pending { /// The `QueryResponse` XCM must have this origin to be considered a reply for this /// query. - responder: VersionedMultiLocation, + responder: VersionedLocation, /// The `QueryResponse` XCM must have this value as the `querier` field to be /// considered a reply for this query. If `None` then the querier is ignored. - maybe_match_querier: Option, + maybe_match_querier: Option, maybe_notify: Option<(u8, u8)>, timeout: BlockNumber, }, /// The query is for an ongoing version notification subscription. - VersionNotifier { origin: VersionedMultiLocation, is_active: bool }, + VersionNotifier { origin: VersionedLocation, is_active: bool }, /// A response has been received. Ready { response: VersionedResponse, at: BlockNumber }, } #[derive(Copy, Clone)] - pub(crate) struct LatestVersionedMultiLocation<'a>(pub(crate) &'a MultiLocation); - impl<'a> EncodeLike for LatestVersionedMultiLocation<'a> {} - impl<'a> Encode for LatestVersionedMultiLocation<'a> { + pub(crate) struct LatestVersionedLocation<'a>(pub(crate) &'a Location); + impl<'a> EncodeLike for LatestVersionedLocation<'a> {} + impl<'a> Encode for LatestVersionedLocation<'a> { fn encode(&self) -> Vec { - let mut r = VersionedMultiLocation::from(MultiLocation::default()).encode(); + let mut r = VersionedLocation::from(Location::default()).encode(); r.truncate(1); self.0.using_encoded(|d| r.extend_from_slice(d)); r @@ -633,7 +614,7 @@ pub mod pallet { /// The existing asset traps. /// - /// Key is the blake2 256 hash of (origin, versioned `MultiAssets`) pair. Value is the number of + /// Key is the blake2 256 hash of (origin, versioned `Assets`) pair. Value is the number of /// times this pair has been trapped (usually just 1 if it exists at all). #[pallet::storage] #[pallet::getter(fn asset_trap)] @@ -652,7 +633,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, XcmVersion, OptionQuery, >; @@ -664,7 +645,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, QueryId, OptionQuery, >; @@ -677,7 +658,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, (QueryId, Weight, XcmVersion), OptionQuery, >; @@ -696,7 +677,7 @@ pub mod pallet { #[pallet::whitelist_storage] pub(super) type VersionDiscoveryQueue = StorageValue< _, - BoundedVec<(VersionedMultiLocation, u32), VersionDiscoveryQueueSize>, + BoundedVec<(VersionedLocation, u32), VersionDiscoveryQueueSize>, ValueQuery, >; @@ -711,9 +692,9 @@ pub mod pallet { /// Total amount of the asset held by the remote lock. pub amount: u128, /// The owner of the locked asset. - pub owner: VersionedMultiLocation, + pub owner: VersionedLocation, /// The location which holds the original lock. - pub locker: VersionedMultiLocation, + pub locker: VersionedLocation, /// Local consumers of the remote lock with a consumer identifier and the amount /// of fungible asset every consumer holds. /// Every consumer can hold up to total amount of the remote lock. @@ -747,7 +728,7 @@ pub mod pallet { _, Blake2_128Concat, T::AccountId, - BoundedVec<(BalanceOf, VersionedMultiLocation), T::MaxLockers>, + BoundedVec<(BalanceOf, VersionedLocation), T::MaxLockers>, OptionQuery, >; @@ -795,7 +776,7 @@ pub mod pallet { weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); q.sort_by_key(|i| i.1); while let Some((versioned_dest, _)) = q.pop() { - if let Ok(dest) = MultiLocation::try_from(versioned_dest) { + if let Ok(dest) = Location::try_from(versioned_dest) { if Self::request_version_notify(dest).is_ok() { // TODO: correct weights. weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); @@ -819,12 +800,12 @@ pub mod pallet { #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] enum QueryStatusV0 { Pending { - responder: VersionedMultiLocation, + responder: VersionedLocation, maybe_notify: Option<(u8, u8)>, timeout: BlockNumber, }, VersionNotifier { - origin: VersionedMultiLocation, + origin: VersionedLocation, is_active: bool, }, Ready { @@ -840,7 +821,7 @@ pub mod pallet { responder, maybe_notify, timeout, - maybe_match_querier: Some(MultiLocation::here().into()), + maybe_match_querier: Some(Location::here().into()), }, VersionNotifier { origin, is_active } => QueryStatus::VersionNotifier { origin, is_active }, @@ -889,7 +870,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::send())] pub fn send( origin: OriginFor, - dest: Box, + dest: Box, message: Box>, ) -> DispatchResult { >::send(origin, dest, message)?; @@ -905,9 +886,9 @@ pub mod pallet { /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -916,8 +897,8 @@ pub mod pallet { /// fees. #[pallet::call_index(1)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -934,9 +915,9 @@ pub mod pallet { })] pub fn teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, ) -> DispatchResult { Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, Unlimited) @@ -963,9 +944,9 @@ pub mod pallet { /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -974,8 +955,8 @@ pub mod pallet { /// fees. #[pallet::call_index(2)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -992,9 +973,9 @@ pub mod pallet { })] pub fn reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, ) -> DispatchResult { Self::do_reserve_transfer_assets( @@ -1045,16 +1026,12 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_xcm_version())] pub fn force_xcm_version( origin: OriginFor, - location: Box, + location: Box, version: XcmVersion, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; let location = *location; - SupportedVersion::::insert( - XCM_VERSION, - LatestVersionedMultiLocation(&location), - version, - ); + SupportedVersion::::insert(XCM_VERSION, LatestVersionedLocation(&location), version); Self::deposit_event(Event::SupportedVersionChanged { location, version }); Ok(()) } @@ -1083,10 +1060,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_subscribe_version_notify())] pub fn force_subscribe_version_notify( origin: OriginFor, - location: Box, + location: Box, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|()| Error::::BadLocation)?; Self::request_version_notify(location).map_err(|e| { match e { @@ -1107,10 +1084,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_unsubscribe_version_notify())] pub fn force_unsubscribe_version_notify( origin: OriginFor, - location: Box, + location: Box, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|()| Error::::BadLocation)?; Self::unrequest_version_notify(location).map_err(|e| { match e { @@ -1141,9 +1118,9 @@ pub mod pallet { /// at risk. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -1153,8 +1130,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(8)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1171,9 +1148,9 @@ pub mod pallet { })] pub fn limited_reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { @@ -1195,9 +1172,9 @@ pub mod pallet { /// at risk. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -1207,8 +1184,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(9)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1225,9 +1202,9 @@ pub mod pallet { })] pub fn limited_teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { @@ -1288,8 +1265,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(11)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1309,17 +1286,17 @@ pub mod pallet { })] pub fn transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::transfer_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}, weight_limit {:?}", @@ -1353,17 +1330,25 @@ pub mod pallet { // added to assets transfers XCM programs let fees = assets.remove(fee_asset_item); let (local_xcm, remote_xcm) = match fees_transfer_type { - TransferType::LocalReserve => - Self::local_reserve_fees_instructions(origin, dest, fees, weight_limit)?, + TransferType::LocalReserve => Self::local_reserve_fees_instructions( + origin.clone(), + dest.clone(), + fees, + weight_limit, + )?, TransferType::DestinationReserve => Self::destination_reserve_fees_instructions( - origin, - dest, + origin.clone(), + dest.clone(), fees, weight_limit, )?, - TransferType::Teleport => - Self::teleport_fees_instructions(origin, dest, fees, weight_limit)?, + TransferType::Teleport => Self::teleport_fees_instructions( + origin.clone(), + dest.clone(), + fees, + weight_limit, + )?, TransferType::RemoteReserve(_) => return Err(Error::::InvalidAssetUnsupportedReserve.into()), }; @@ -1390,7 +1375,7 @@ const MAX_ASSETS_FOR_TRANSFER: usize = 2; #[derive(Clone, PartialEq)] enum FeesHandling { /// `fees` asset can be batch-transferred with rest of assets using same XCM instructions. - Batched { fees: MultiAsset }, + Batched { fees: Asset }, /// fees cannot be batched, they are handled separately using XCM programs here. Separate { local_xcm: Xcm<::RuntimeCall>, remote_xcm: Xcm<()> }, } @@ -1416,9 +1401,9 @@ impl QueryHandler for Pallet { /// Attempt to create a new query ID and register it as a query that is yet to respond. fn new_query( - responder: impl Into, + responder: impl Into, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> Self::QueryId { Self::do_new_query(responder, None, timeout, match_querier) } @@ -1427,7 +1412,7 @@ impl QueryHandler for Pallet { /// value. fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> Result { let responder = responder.into(); @@ -1474,9 +1459,9 @@ impl Pallet { /// /// Validate `assets` to all have same `TransferType`. fn find_fee_and_assets_transfer_types( - assets: &[MultiAsset], + assets: &[Asset], fee_asset_item: usize, - dest: &MultiLocation, + dest: &Location, ) -> Result<(TransferType, TransferType), Error> { let mut fees_transfer_type = None; let mut assets_transfer_type = None; @@ -1502,7 +1487,7 @@ impl Pallet { } // single asset also marked as fee item if assets.len() == 1 { - assets_transfer_type = fees_transfer_type + assets_transfer_type = fees_transfer_type.clone() } Ok(( fees_transfer_type.ok_or(Error::::Empty)?, @@ -1512,17 +1497,17 @@ impl Pallet { fn do_reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::do_reserve_transfer_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}", @@ -1558,17 +1543,17 @@ impl Pallet { fn do_teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::do_teleport_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}, weight_limit {:?}", @@ -1598,10 +1583,10 @@ impl Pallet { } fn build_and_execute_xcm_transfer_type( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, transfer_type: TransferType, fees: FeesHandling, weight_limit: WeightLimit, @@ -1615,8 +1600,8 @@ impl Pallet { let (mut local_xcm, remote_xcm) = match transfer_type { TransferType::LocalReserve => { let (local, remote) = Self::local_reserve_transfer_programs( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1626,8 +1611,8 @@ impl Pallet { }, TransferType::DestinationReserve => { let (local, remote) = Self::destination_reserve_transfer_programs( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1641,9 +1626,9 @@ impl Pallet { _ => return Err(Error::::InvalidAssetUnsupportedReserve.into()), }; let local = Self::remote_reserve_transfer_program( - origin, + origin.clone(), reserve, - dest, + dest.clone(), beneficiary, assets, fees, @@ -1653,8 +1638,8 @@ impl Pallet { }, TransferType::Teleport => { let (local, remote) = Self::teleport_assets_program( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1665,9 +1650,14 @@ impl Pallet { }; let weight = T::Weigher::weight(&mut local_xcm).map_err(|()| Error::::UnweighableMessage)?; - let hash = local_xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = - T::XcmExecutor::execute_xcm_in_credit(origin, local_xcm, hash, weight, weight); + let mut hash = local_xcm.using_encoded(sp_io::hashing::blake2_256); + let outcome = T::XcmExecutor::prepare_and_execute( + origin.clone(), + local_xcm, + &mut hash, + weight, + weight, + ); Self::deposit_event(Event::Attempted { outcome: outcome.clone() }); outcome.ensure_complete().map_err(|error| { log::error!( @@ -1678,10 +1668,10 @@ impl Pallet { })?; if let Some(remote_xcm) = remote_xcm { - let (ticket, price) = validate_send::(dest, remote_xcm.clone()) + let (ticket, price) = validate_send::(dest.clone(), remote_xcm.clone()) .map_err(Error::::from)?; if origin != Here.into_location() { - Self::charge_fees(origin, price).map_err(|error| { + Self::charge_fees(origin.clone(), price).map_err(|error| { log::error!( target: "xcm::pallet_xcm::build_and_execute_xcm_transfer_type", "Unable to charge fee with error {:?}", error @@ -1698,7 +1688,7 @@ impl Pallet { } fn add_fees_to_xcm( - dest: MultiLocation, + dest: Location, fees: FeesHandling, weight_limit: WeightLimit, local: &mut Xcm<::RuntimeCall>, @@ -1710,7 +1700,7 @@ impl Pallet { // no custom fees instructions, they are batched together with `assets` transfer; // BuyExecution happens after receiving all `assets` let reanchored_fees = - fees.reanchored(&dest, context).map_err(|_| Error::::CannotReanchor)?; + fees.reanchored(&dest, &context).map_err(|_| Error::::CannotReanchor)?; // buy execution using `fees` batched together with above `reanchored_assets` remote.inner_mut().push(BuyExecution { fees: reanchored_fees, weight_limit }); }, @@ -1728,9 +1718,9 @@ impl Pallet { } fn local_reserve_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1739,7 +1729,7 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; let local_execute_xcm = Xcm(vec![ @@ -1756,10 +1746,10 @@ impl Pallet { } fn local_reserve_transfer_programs( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1770,17 +1760,17 @@ impl Pallet { // max assets is `assets` (+ potentially separately handled fee) let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let context = T::UniversalLocation::get(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XCM instructions to be executed on local chain let mut local_execute_xcm = Xcm(vec![ // locally move `assets` to `dest`s local sovereign account - TransferAsset { assets, beneficiary: dest }, + TransferAsset { assets, beneficiary: dest.clone() }, ]); // XCM instructions to be executed on destination chain let mut xcm_on_dest = Xcm(vec![ @@ -1800,9 +1790,9 @@ impl Pallet { } fn destination_reserve_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1811,9 +1801,9 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; - let fees: MultiAssets = fees.into(); + let fees: Assets = fees.into(); let local_execute_xcm = Xcm(vec![ // withdraw reserve-based fees (derivatives) @@ -1831,10 +1821,10 @@ impl Pallet { } fn destination_reserve_transfer_programs( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1845,11 +1835,11 @@ impl Pallet { // max assets is `assets` (+ potentially separately handled fee) let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let context = T::UniversalLocation::get(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XCM instructions to be executed on local chain @@ -1878,12 +1868,12 @@ impl Pallet { // function assumes fees and assets have the same remote reserve fn remote_reserve_transfer_program( - origin: MultiLocation, - reserve: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, - fees: MultiAsset, + origin: Location, + reserve: Location, + dest: Location, + beneficiary: Location, + assets: Vec, + fees: Asset, weight_limit: WeightLimit, ) -> Result::RuntimeCall>, Error> { let value = (origin, assets); @@ -1897,13 +1887,14 @@ impl Pallet { let (fees_half_1, fees_half_2) = Self::halve_fees(fees)?; // identifies fee item as seen by `reserve` - to be used at reserve chain let reserve_fees = fees_half_1 - .reanchored(&reserve, context) + .reanchored(&reserve, &context) .map_err(|_| Error::::CannotReanchor)?; // identifies fee item as seen by `dest` - to be used at destination chain - let dest_fees = - fees_half_2.reanchored(&dest, context).map_err(|_| Error::::CannotReanchor)?; + let dest_fees = fees_half_2 + .reanchored(&dest, &context) + .map_err(|_| Error::::CannotReanchor)?; // identifies `dest` as seen by `reserve` - let dest = dest.reanchored(&reserve, context).map_err(|_| Error::::CannotReanchor)?; + let dest = dest.reanchored(&reserve, &context).map_err(|_| Error::::CannotReanchor)?; // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ BuyExecution { fees: dest_fees, weight_limit: weight_limit.clone() }, @@ -1925,9 +1916,9 @@ impl Pallet { } fn teleport_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1936,7 +1927,7 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XcmContext irrelevant in teleports checks @@ -1960,7 +1951,7 @@ impl Pallet { &dummy_context, ); - let fees: MultiAssets = fees.into(); + let fees: Assets = fees.into(); let local_execute_xcm = Xcm(vec![ // withdraw fees WithdrawAsset(fees.clone()), @@ -1977,10 +1968,10 @@ impl Pallet { } fn teleport_assets_program( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1992,10 +1983,10 @@ impl Pallet { let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; let context = T::UniversalLocation::get(); - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XcmContext irrelevant in teleports checks @@ -2048,14 +2039,14 @@ impl Pallet { } /// Halve `fees` fungible amount. - pub(crate) fn halve_fees(fees: MultiAsset) -> Result<(MultiAsset, MultiAsset), Error> { + pub(crate) fn halve_fees(fees: Asset) -> Result<(Asset, Asset), Error> { match fees.fun { Fungible(amount) => { let fee1 = amount.saturating_div(2); let fee2 = amount.saturating_sub(fee1); ensure!(fee1 > 0, Error::::FeesNotMet); ensure!(fee2 > 0, Error::::FeesNotMet); - Ok((MultiAsset::from((fees.id, fee1)), MultiAsset::from((fees.id, fee2)))) + Ok((Asset::from((fees.id.clone(), fee1)), Asset::from((fees.id.clone(), fee2)))) }, NonFungible(_) => Err(Error::::FeesNotMet), } @@ -2119,7 +2110,7 @@ impl Pallet { }; while let Some((key, value)) = iter.next() { let (query_id, max_weight, target_xcm_version) = value; - let new_key: MultiLocation = match key.clone().try_into() { + let new_key: Location = match key.clone().try_into() { Ok(k) if target_xcm_version != xcm_version => k, _ => { // We don't early return here since we need to be certain that we @@ -2131,7 +2122,7 @@ impl Pallet { let response = Response::Version(xcm_version); let message = Xcm(vec![QueryResponse { query_id, response, max_weight, querier: None }]); - let event = match send_xcm::(new_key, message) { + let event = match send_xcm::(new_key.clone(), message) { Ok((message_id, cost)) => { let value = (query_id, max_weight, xcm_version); VersionNotifyTargets::::insert(XCM_VERSION, key, value); @@ -2160,7 +2151,7 @@ impl Pallet { for v in 0..XCM_VERSION { for (old_key, value) in VersionNotifyTargets::::drain_prefix(v) { let (query_id, max_weight, target_xcm_version) = value; - let new_key = match MultiLocation::try_from(old_key.clone()) { + let new_key = match Location::try_from(old_key.clone()) { Ok(k) => k, Err(()) => { Self::deposit_event(Event::NotifyTargetMigrationFail { @@ -2175,7 +2166,7 @@ impl Pallet { }, }; - let versioned_key = LatestVersionedMultiLocation(&new_key); + let versioned_key = LatestVersionedLocation(&new_key); if target_xcm_version == xcm_version { VersionNotifyTargets::::insert(XCM_VERSION, versioned_key, value); weight_used.saturating_accrue(vnt_migrate_weight); @@ -2188,7 +2179,7 @@ impl Pallet { max_weight, querier: None, }]); - let event = match send_xcm::(new_key, message) { + let event = match send_xcm::(new_key.clone(), message) { Ok((message_id, cost)) => { VersionNotifyTargets::::insert( XCM_VERSION, @@ -2221,9 +2212,9 @@ impl Pallet { } /// Request that `dest` informs us of its version. - pub fn request_version_notify(dest: impl Into) -> XcmResult { + pub fn request_version_notify(dest: impl Into) -> XcmResult { let dest = dest.into(); - let versioned_dest = VersionedMultiLocation::from(dest); + let versioned_dest = VersionedLocation::from(dest.clone()); let already = VersionNotifiers::::contains_key(XCM_VERSION, &versioned_dest); ensure!(!already, XcmError::InvalidLocation); let query_id = QueryCounter::::mutate(|q| { @@ -2233,7 +2224,7 @@ impl Pallet { }); // TODO #3735: Correct weight. let instruction = SubscribeVersion { query_id, max_response_weight: Weight::zero() }; - let (message_id, cost) = send_xcm::(dest, Xcm(vec![instruction]))?; + let (message_id, cost) = send_xcm::(dest.clone(), Xcm(vec![instruction]))?; Self::deposit_event(Event::VersionNotifyRequested { destination: dest, cost, message_id }); VersionNotifiers::::insert(XCM_VERSION, &versioned_dest, query_id); let query_status = @@ -2243,12 +2234,13 @@ impl Pallet { } /// Request that `dest` ceases informing us of its version. - pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { + pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { let dest = dest.into(); - let versioned_dest = LatestVersionedMultiLocation(&dest); + let versioned_dest = LatestVersionedLocation(&dest); let query_id = VersionNotifiers::::take(XCM_VERSION, versioned_dest) .ok_or(XcmError::InvalidLocation)?; - let (message_id, cost) = send_xcm::(dest, Xcm(vec![UnsubscribeVersion]))?; + let (message_id, cost) = + send_xcm::(dest.clone(), Xcm(vec![UnsubscribeVersion]))?; Self::deposit_event(Event::VersionNotifyUnrequested { destination: dest, cost, @@ -2263,13 +2255,13 @@ impl Pallet { /// are not charged (and instead borne by the chain). pub fn send_xcm( interior: impl Into, - dest: impl Into, + dest: impl Into, mut message: Xcm<()>, ) -> Result { let interior = interior.into(); let dest = dest.into(); let maybe_fee_payer = if interior != Junctions::Here { - message.0.insert(0, DescendOrigin(interior)); + message.0.insert(0, DescendOrigin(interior.clone())); Some(interior.into()) } else { None @@ -2289,10 +2281,10 @@ impl Pallet { /// Create a new expectation of a query response with the querier being here. fn do_new_query( - responder: impl Into, + responder: impl Into, maybe_notify: Option<(u8, u8)>, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> u64 { QueryCounter::::mutate(|q| { let r = *q; @@ -2334,7 +2326,7 @@ impl Pallet { /// may be put in the overweight queue and need to be manually executed. pub fn report_outcome_notify( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, notify: impl Into<::RuntimeCall>, timeout: BlockNumberFor, ) -> Result<(), XcmError> { @@ -2354,10 +2346,10 @@ impl Pallet { /// Attempt to create a new query ID and register it as a query that is yet to respond, and /// which will call a dispatchable when a response happens. pub fn new_notify_query( - responder: impl Into, + responder: impl Into, notify: impl Into<::RuntimeCall>, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> u64 { let notify = notify.into().using_encoded(|mut bytes| Decode::decode(&mut bytes)).expect( "decode input is output of Call encode; Call guaranteed to have two enums; qed", @@ -2367,13 +2359,13 @@ impl Pallet { /// Note that a particular destination to whom we would like to send a message is unknown /// and queue it for version discovery. - fn note_unknown_version(dest: &MultiLocation) { + fn note_unknown_version(dest: &Location) { log::trace!( target: "xcm::pallet_xcm::note_unknown_version", "XCM version is unknown for destination: {:?}", dest, ); - let versioned_dest = VersionedMultiLocation::from(*dest); + let versioned_dest = VersionedLocation::from(dest.clone()); VersionDiscoveryQueue::::mutate(|q| { if let Some(index) = q.iter().position(|i| &i.0 == &versioned_dest) { // exists - just bump the count. @@ -2389,8 +2381,8 @@ impl Pallet { /// Fails if: /// - the `assets` are not known on this chain; /// - the `assets` cannot be withdrawn with that location as the Origin. - fn charge_fees(location: MultiLocation, assets: MultiAssets) -> DispatchResult { - T::XcmExecutor::charge_fees(location, assets.clone()) + fn charge_fees(location: Location, assets: Assets) -> DispatchResult { + T::XcmExecutor::charge_fees(location.clone(), assets.clone()) .map_err(|_| Error::::FeesNotMet)?; Self::deposit_event(Event::FeesPaid { paying: location, fees: assets }); Ok(()) @@ -2400,7 +2392,7 @@ impl Pallet { pub struct LockTicket { sovereign_account: T::AccountId, amount: BalanceOf, - unlocker: MultiLocation, + unlocker: Location, item_index: Option, } @@ -2434,7 +2426,7 @@ impl xcm_executor::traits::Enact for LockTicket { pub struct UnlockTicket { sovereign_account: T::AccountId, amount: BalanceOf, - unlocker: MultiLocation, + unlocker: Location, } impl xcm_executor::traits::Enact for UnlockTicket { @@ -2471,8 +2463,8 @@ impl xcm_executor::traits::Enact for UnlockTicket { pub struct ReduceTicket { key: (u32, T::AccountId, VersionedAssetId), amount: u128, - locker: VersionedMultiLocation, - owner: VersionedMultiLocation, + locker: VersionedLocation, + owner: VersionedLocation, } impl xcm_executor::traits::Enact for ReduceTicket { @@ -2498,9 +2490,9 @@ impl xcm_executor::traits::AssetLock for Pallet { type ReduceTicket = ReduceTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result, xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; @@ -2513,9 +2505,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result, xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; @@ -2529,9 +2521,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - mut owner: MultiLocation, + locker: Location, + asset: Asset, + mut owner: Location, ) -> Result<(), xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; ensure!(T::TrustedLockers::contains(&locker, &asset), NotTrusted); @@ -2558,9 +2550,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - mut owner: MultiLocation, + locker: Location, + asset: Asset, + mut owner: Location, ) -> Result { use xcm_executor::traits::LockError::*; let amount = match asset.fun { @@ -2588,7 +2580,7 @@ impl xcm_executor::traits::AssetLock for Pallet { impl WrapVersion for Pallet { fn wrap_version( - dest: &MultiLocation, + dest: &Location, xcm: impl Into>, ) -> Result, ()> { Self::get_version_for(dest) @@ -2609,8 +2601,8 @@ impl WrapVersion for Pallet { } impl GetVersion for Pallet { - fn get_version_for(dest: &MultiLocation) -> Option { - SupportedVersion::::get(XCM_VERSION, LatestVersionedMultiLocation(dest)) + fn get_version_for(dest: &Location) -> Option { + SupportedVersion::::get(XCM_VERSION, LatestVersionedLocation(dest)) } } @@ -2624,21 +2616,21 @@ impl VersionChangeNotifier for Pallet { /// If the `location` has an ongoing notification and when this function is called, then an /// error should be returned. fn start( - dest: &MultiLocation, + dest: &Location, query_id: QueryId, max_weight: Weight, _context: &XcmContext, ) -> XcmResult { - let versioned_dest = LatestVersionedMultiLocation(dest); + let versioned_dest = LatestVersionedLocation(dest); let already = VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest); ensure!(!already, XcmError::InvalidLocation); let xcm_version = T::AdvertisedXcmVersion::get(); let response = Response::Version(xcm_version); let instruction = QueryResponse { query_id, response, max_weight, querier: None }; - let (message_id, cost) = send_xcm::(*dest, Xcm(vec![instruction]))?; + let (message_id, cost) = send_xcm::(dest.clone(), Xcm(vec![instruction]))?; Self::deposit_event(Event::::VersionNotifyStarted { - destination: *dest, + destination: dest.clone(), cost, message_id, }); @@ -2650,27 +2642,31 @@ impl VersionChangeNotifier for Pallet { /// Stop notifying `location` should the XCM change. This is a no-op if there was never a /// subscription. - fn stop(dest: &MultiLocation, _context: &XcmContext) -> XcmResult { - VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedMultiLocation(dest)); + fn stop(dest: &Location, _context: &XcmContext) -> XcmResult { + VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedLocation(dest)); Ok(()) } /// Return true if a location is subscribed to XCM version changes. - fn is_subscribed(dest: &MultiLocation) -> bool { - let versioned_dest = LatestVersionedMultiLocation(dest); + fn is_subscribed(dest: &Location) -> bool { + let versioned_dest = LatestVersionedLocation(dest); VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest) } } impl DropAssets for Pallet { - fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { + fn drop_assets(origin: &Location, assets: AssetsInHolding, _context: &XcmContext) -> Weight { if assets.is_empty() { return Weight::zero() } - let versioned = VersionedMultiAssets::from(MultiAssets::from(assets)); + let versioned = VersionedAssets::from(Assets::from(assets)); let hash = BlakeTwo256::hash_of(&(&origin, &versioned)); AssetTraps::::mutate(hash, |n| *n += 1); - Self::deposit_event(Event::AssetsTrapped { hash, origin: *origin, assets: versioned }); + Self::deposit_event(Event::AssetsTrapped { + hash, + origin: origin.clone(), + assets: versioned, + }); // TODO #3735: Put the real weight in there. Weight::zero() } @@ -2678,71 +2674,75 @@ impl DropAssets for Pallet { impl ClaimAssets for Pallet { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - assets: &MultiAssets, + origin: &Location, + ticket: &Location, + assets: &Assets, _context: &XcmContext, ) -> bool { - let mut versioned = VersionedMultiAssets::from(assets.clone()); - match (ticket.parents, &ticket.interior) { - (0, X1(GeneralIndex(i))) => + let mut versioned = VersionedAssets::from(assets.clone()); + match ticket.unpack() { + (0, [GeneralIndex(i)]) => versioned = match versioned.into_version(*i as u32) { Ok(v) => v, Err(()) => return false, }, - (0, Here) => (), + (0, []) => (), _ => return false, }; - let hash = BlakeTwo256::hash_of(&(origin, versioned.clone())); + let hash = BlakeTwo256::hash_of(&(origin.clone(), versioned.clone())); match AssetTraps::::get(hash) { 0 => return false, 1 => AssetTraps::::remove(hash), n => AssetTraps::::insert(hash, n - 1), } - Self::deposit_event(Event::AssetsClaimed { hash, origin: *origin, assets: versioned }); + Self::deposit_event(Event::AssetsClaimed { + hash, + origin: origin.clone(), + assets: versioned, + }); return true } } impl OnResponse for Pallet { fn expecting_response( - origin: &MultiLocation, + origin: &Location, query_id: QueryId, - querier: Option<&MultiLocation>, + querier: Option<&Location>, ) -> bool { match Queries::::get(query_id) { Some(QueryStatus::Pending { responder, maybe_match_querier, .. }) => - MultiLocation::try_from(responder).map_or(false, |r| origin == &r) && + Location::try_from(responder).map_or(false, |r| origin == &r) && maybe_match_querier.map_or(true, |match_querier| { - MultiLocation::try_from(match_querier).map_or(false, |match_querier| { + Location::try_from(match_querier).map_or(false, |match_querier| { querier.map_or(false, |q| q == &match_querier) }) }), Some(QueryStatus::VersionNotifier { origin: r, .. }) => - MultiLocation::try_from(r).map_or(false, |r| origin == &r), + Location::try_from(r).map_or(false, |r| origin == &r), _ => false, } } fn on_response( - origin: &MultiLocation, + origin: &Location, query_id: QueryId, - querier: Option<&MultiLocation>, + querier: Option<&Location>, response: Response, max_weight: Weight, _context: &XcmContext, ) -> Weight { - let origin = *origin; + let origin = origin.clone(); match (response, Queries::::get(query_id)) { ( Response::Version(v), Some(QueryStatus::VersionNotifier { origin: expected_origin, is_active }), ) => { - let origin: MultiLocation = match expected_origin.try_into() { + let origin: Location = match expected_origin.try_into() { Ok(o) if o == origin => o, Ok(o) => { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: Some(o), }); @@ -2750,7 +2750,7 @@ impl OnResponse for Pallet { }, _ => { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: None, }); @@ -2762,15 +2762,14 @@ impl OnResponse for Pallet { if !is_active { Queries::::insert( query_id, - QueryStatus::VersionNotifier { origin: origin.into(), is_active: true }, + QueryStatus::VersionNotifier { + origin: origin.clone().into(), + is_active: true, + }, ); } // We're being notified of a version change. - SupportedVersion::::insert( - XCM_VERSION, - LatestVersionedMultiLocation(&origin), - v, - ); + SupportedVersion::::insert(XCM_VERSION, LatestVersionedLocation(&origin), v); Self::deposit_event(Event::SupportedVersionChanged { location: origin, version: v, @@ -2782,16 +2781,19 @@ impl OnResponse for Pallet { Some(QueryStatus::Pending { responder, maybe_notify, maybe_match_querier, .. }), ) => { if let Some(match_querier) = maybe_match_querier { - let match_querier = match MultiLocation::try_from(match_querier) { + let match_querier = match Location::try_from(match_querier) { Ok(mq) => mq, Err(_) => { - Self::deposit_event(Event::InvalidQuerierVersion { origin, query_id }); + Self::deposit_event(Event::InvalidQuerierVersion { + origin: origin.clone(), + query_id, + }); return Weight::zero() }, }; if querier.map_or(true, |q| q != &match_querier) { Self::deposit_event(Event::InvalidQuerier { - origin, + origin: origin.clone(), query_id, expected_querier: match_querier, maybe_actual_querier: querier.cloned(), @@ -2799,16 +2801,19 @@ impl OnResponse for Pallet { return Weight::zero() } } - let responder = match MultiLocation::try_from(responder) { + let responder = match Location::try_from(responder) { Ok(r) => r, Err(_) => { - Self::deposit_event(Event::InvalidResponderVersion { origin, query_id }); + Self::deposit_event(Event::InvalidResponderVersion { + origin: origin.clone(), + query_id, + }); return Weight::zero() }, }; if origin != responder { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: Some(responder), }); @@ -2836,7 +2841,7 @@ impl OnResponse for Pallet { Self::deposit_event(e); return Weight::zero() } - let dispatch_origin = Origin::Response(origin).into(); + let dispatch_origin = Origin::Response(origin.clone()).into(); match call.dispatch(dispatch_origin) { Ok(post_info) => { let e = Event::Notified { query_id, pallet_index, call_index }; @@ -2874,7 +2879,7 @@ impl OnResponse for Pallet { } }, _ => { - let e = Event::UnexpectedResponse { origin, query_id }; + let e = Event::UnexpectedResponse { origin: origin.clone(), query_id }; Self::deposit_event(e); Weight::zero() }, @@ -2884,7 +2889,7 @@ impl OnResponse for Pallet { impl CheckSuspension for Pallet { fn is_suspended( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -2896,7 +2901,7 @@ impl CheckSuspension for Pallet { /// Ensure that the origin `o` represents an XCM (`Transact`) origin. /// /// Returns `Ok` with the location of the XCM sender or an `Err` otherwise. -pub fn ensure_xcm(o: OuterOrigin) -> Result +pub fn ensure_xcm(o: OuterOrigin) -> Result where OuterOrigin: Into>, { @@ -2909,7 +2914,7 @@ where /// Ensure that the origin `o` represents an XCM response origin. /// /// Returns `Ok` with the location of the responder or an `Err` otherwise. -pub fn ensure_response(o: OuterOrigin) -> Result +pub fn ensure_response(o: OuterOrigin) -> Result where OuterOrigin: Into>, { @@ -2919,46 +2924,50 @@ where } } -/// Filter for `MultiLocation` to find those which represent a strict majority approval of an +/// Filter for `Location` to find those which represent a strict majority approval of an /// identified plurality. /// /// May reasonably be used with `EnsureXcm`. pub struct IsMajorityOfBody(PhantomData<(Prefix, Body)>); -impl, Body: Get> Contains +impl, Body: Get> Contains for IsMajorityOfBody { - fn contains(l: &MultiLocation) -> bool { + fn contains(l: &Location) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority()) } } -/// Filter for `MultiLocation` to find those which represent a voice of an identified plurality. +/// Filter for `Location` to find those which represent a voice of an identified plurality. /// /// May reasonably be used with `EnsureXcm`. pub struct IsVoiceOfBody(PhantomData<(Prefix, Body)>); -impl, Body: Get> Contains - for IsVoiceOfBody -{ - fn contains(l: &MultiLocation) -> bool { +impl, Body: Get> Contains for IsVoiceOfBody { + fn contains(l: &Location) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part == &BodyPart::Voice) } } -/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and filter /// the `Origin::Xcm` item. -pub struct EnsureXcm(PhantomData); -impl, F: Contains> EnsureOrigin for EnsureXcm +pub struct EnsureXcm(PhantomData<(F, L)>); +impl< + O: OriginTrait + From, + F: Contains, + L: TryFrom + TryInto + Clone, + > EnsureOrigin for EnsureXcm where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = L; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { caller.try_into().and_then(|o| match o { - Origin::Xcm(location) if F::contains(&location) => Ok(location), + Origin::Xcm(ref location) + if F::contains(&location.clone().try_into().map_err(|_| o.clone().into())?) => + Ok(location.clone().try_into().map_err(|_| o.clone().into())?), Origin::Xcm(location) => Err(Origin::Xcm(location).into()), o => Err(o.into()), }) @@ -2971,15 +2980,14 @@ where } } -/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and filter /// the `Origin::Response` item. pub struct EnsureResponse(PhantomData); -impl, F: Contains> EnsureOrigin - for EnsureResponse +impl, F: Contains> EnsureOrigin for EnsureResponse where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = Location; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { @@ -2996,16 +3004,16 @@ where } } -/// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of +/// A simple passthrough where we reuse the `Location`-typed XCM origin as the inner value of /// this crate's `Origin::Xcm` value. pub struct XcmPassthrough(PhantomData); impl> ConvertOrigin for XcmPassthrough { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); match kind { OriginKind::Xcm => Ok(crate::Origin::Xcm(origin).into()), diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 0ac4205ed949..3ce32fa46d32 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -16,7 +16,7 @@ use codec::Encode; use frame_support::{ - construct_runtime, derive_impl, match_types, parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{ AsEnsureOriginWithArg, ConstU128, ConstU32, Contains, Equals, Everything, EverythingBut, Nothing, @@ -76,7 +76,7 @@ pub mod pallet_test_notifier { pub enum Event { QueryPrepared(QueryId), NotifyQueryPrepared(QueryId), - ResponseReceived(MultiLocation, QueryId, Response), + ResponseReceived(Location, QueryId, Response), } #[pallet::error] @@ -89,7 +89,7 @@ pub mod pallet_test_notifier { impl Pallet { #[pallet::call_index(0)] #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] - pub fn prepare_new_query(origin: OriginFor, querier: MultiLocation) -> DispatchResult { + pub fn prepare_new_query(origin: OriginFor, querier: Location) -> DispatchResult { let who = ensure_signed(origin)?; let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) @@ -105,10 +105,7 @@ pub mod pallet_test_notifier { #[pallet::call_index(1)] #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] - pub fn prepare_new_notify_query( - origin: OriginFor, - querier: MultiLocation, - ) -> DispatchResult { + pub fn prepare_new_notify_query(origin: OriginFor, querier: Location) -> DispatchResult { let who = ensure_signed(origin)?; let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) @@ -144,7 +141,7 @@ construct_runtime!( { System: frame_system::{Pallet, Call, Storage, Config, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Config, Event}, + AssetsPallet: pallet_assets::{Pallet, Call, Storage, Config, Event}, ParasOrigin: origin::{Pallet, Origin}, XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config}, TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, @@ -152,13 +149,13 @@ construct_runtime!( ); thread_local! { - pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); pub static FAIL_SEND_XCM: RefCell = RefCell::new(false); } -pub(crate) fn sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { +pub(crate) fn sent_xcm() -> Vec<(Location, Xcm<()>)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } -pub(crate) fn take_sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { +pub(crate) fn take_sent_xcm() -> Vec<(Location, Xcm<()>)> { SENT_XCM.with(|q| { let mut r = Vec::new(); std::mem::swap(&mut r, &mut *q.borrow_mut()); @@ -171,18 +168,18 @@ pub(crate) fn set_send_xcm_artificial_failure(should_fail: bool) { /// Sender that never returns error. pub struct TestSendXcm; impl SendXcm for TestSendXcm { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if FAIL_SEND_XCM.with(|q| *q.borrow()) { return Err(SendError::Transport("Intentional send failure used in tests")) } let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, MultiAssets::new())) + Ok((pair, Assets::new())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -191,11 +188,11 @@ impl SendXcm for TestSendXcm { /// Sender that returns error if `X8` junction and stops routing pub struct TestSendXcmErrX8; impl SendXcm for TestSendXcmErrX8 { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, _: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if dest.as_ref().unwrap().len() == 8 { dest.take(); Err(SendError::Transport("Destination location full")) @@ -203,7 +200,7 @@ impl SendXcm for TestSendXcmErrX8 { Err(SendError::NotApplicable) } } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -212,18 +209,18 @@ impl SendXcm for TestSendXcmErrX8 { parameter_types! { pub Para3000: u32 = 3000; - pub Para3000Location: MultiLocation = Parachain(Para3000::get()).into(); + pub Para3000Location: Location = Parachain(Para3000::get()).into(); pub Para3000PaymentAmount: u128 = 1; - pub Para3000PaymentMultiAssets: MultiAssets = MultiAssets::from(MultiAsset::from((Here, Para3000PaymentAmount::get()))); + pub Para3000PaymentAssets: Assets = Assets::from(Asset::from((Here, Para3000PaymentAmount::get()))); } /// Sender only sends to `Parachain(3000)` destination requiring payment. pub struct TestPaidForPara3000SendXcm; impl SendXcm for TestPaidForPara3000SendXcm { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if let Some(dest) = dest.as_ref() { if !dest.eq(&Para3000Location::get()) { return Err(SendError::NotApplicable) @@ -233,9 +230,9 @@ impl SendXcm for TestPaidForPara3000SendXcm { } let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, Para3000PaymentMultiAssets::get())) + Ok((pair, Para3000PaymentAssets::get())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -300,17 +297,17 @@ impl pallet_balances::Config for Test { /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> Location { + Location::new(1, [Parachain(id)]) } } impl pallet_assets::Config for Test { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocation; - type AssetIdParameter = MultiLocation; + type AssetId = Location; + type AssetIdParameter = Location; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; @@ -354,61 +351,61 @@ pub const OTHER_PARA_ID: u32 = 2009; pub const FILTERED_PARA_ID: u32 = 2010; parameter_types! { - pub const RelayLocation: MultiLocation = Here.into_location(); - pub const NativeAsset: MultiAsset = MultiAsset { + pub const RelayLocation: Location = Here.into_location(); + pub const NativeAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(Here.into_location()), - }; - pub const SystemParachainLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(SOME_SYSTEM_PARA)) - }; - pub const ForeignReserveLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID)) + id: AssetId(Here.into_location()), }; - pub const ForeignAsset: MultiAsset = MultiAsset { + pub SystemParachainLocation: Location = Location::new( + 0, + [Parachain(SOME_SYSTEM_PARA)] + ); + pub ForeignReserveLocation: Location = Location::new( + 0, + [Parachain(FOREIGN_ASSET_RESERVE_PARA_ID)] + ); + pub ForeignAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X2(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION), - }), + id: AssetId(Location::new( + 0, + [Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION], + )), }; - pub const UsdcReserveLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(USDC_RESERVE_PARA_ID)) - }; - pub const Usdc: MultiAsset = MultiAsset { + pub UsdcReserveLocation: Location = Location::new( + 0, + [Parachain(USDC_RESERVE_PARA_ID)] + ); + pub Usdc: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X2(Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION), - }), + id: AssetId(Location::new( + 0, + [Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION], + )), }; - pub const UsdtTeleportLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(USDT_PARA_ID)) - }; - pub const Usdt: MultiAsset = MultiAsset { + pub UsdtTeleportLocation: Location = Location::new( + 0, + [Parachain(USDT_PARA_ID)] + ); + pub Usdt: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X1(Parachain(USDT_PARA_ID)), - }), + id: AssetId(Location::new( + 0, + [Parachain(USDT_PARA_ID)], + )), }; - pub const FilteredTeleportLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(FILTERED_PARA_ID)) - }; - pub const FilteredTeleportAsset: MultiAsset = MultiAsset { + pub FilteredTeleportLocation: Location = Location::new( + 0, + [Parachain(FILTERED_PARA_ID)] + ); + pub FilteredTeleportAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X1(Parachain(FILTERED_PARA_ID)), - }), + id: AssetId(Location::new( + 0, + [Parachain(FILTERED_PARA_ID)], + )), }; pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; pub CheckingAccount: AccountId = XcmPallet::check_account(); } @@ -420,7 +417,7 @@ pub type SovereignAccountOf = ( ); pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId< - MultiLocation, + Location, Balance, // Excludes relay/parent chain currency EverythingBut<(Equals,)>, @@ -432,7 +429,7 @@ pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId< pub type AssetTransactors = ( XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>, FungiblesAdapter< - Assets, + AssetsPallet, ForeignAssetsConvertedConcreteId, SovereignAccountOf, AccountId, @@ -450,24 +447,29 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); - pub TrustedLocal: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); - pub TrustedSystemPara: (MultiAssetFilter, MultiLocation) = (NativeAsset::get().into(), SystemParachainLocation::get()); - pub TrustedUsdt: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), UsdtTeleportLocation::get()); - pub TrustedFilteredTeleport: (MultiAssetFilter, MultiLocation) = (FilteredTeleportAsset::get().into(), FilteredTeleportLocation::get()); - pub TeleportUsdtToForeign: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), ForeignReserveLocation::get()); - pub TrustedForeign: (MultiAssetFilter, MultiLocation) = (ForeignAsset::get().into(), ForeignReserveLocation::get()); - pub TrustedUsdc: (MultiAssetFilter, MultiLocation) = (Usdc::get().into(), UsdcReserveLocation::get()); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (AssetId(RelayLocation::get()), 1, 1); + pub TrustedLocal: (AssetFilter, Location) = (All.into(), Here.into()); + pub TrustedSystemPara: (AssetFilter, Location) = (NativeAsset::get().into(), SystemParachainLocation::get()); + pub TrustedUsdt: (AssetFilter, Location) = (Usdt::get().into(), UsdtTeleportLocation::get()); + pub TrustedFilteredTeleport: (AssetFilter, Location) = (FilteredTeleportAsset::get().into(), FilteredTeleportLocation::get()); + pub TeleportUsdtToForeign: (AssetFilter, Location) = (Usdt::get().into(), ForeignReserveLocation::get()); + pub TrustedForeign: (AssetFilter, Location) = (ForeignAsset::get().into(), ForeignReserveLocation::get()); + pub TrustedUsdc: (AssetFilter, Location) = (Usdc::get().into(), UsdcReserveLocation::get()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub XcmFeesTargetAccount: AccountId = AccountId::new([167u8; 32]); } pub const XCM_FEES_NOT_WAIVED_USER_ACCOUNT: [u8; 32] = [37u8; 32]; -match_types! { - pub type XcmFeesNotWaivedLocations: impl Contains = { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 {network: None, id: XCM_FEES_NOT_WAIVED_USER_ACCOUNT})} - }; + +pub struct XcmFeesNotWaivedLocations; +impl Contains for XcmFeesNotWaivedLocations { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (0, [Junction::AccountId32 { network: None, id: XCM_FEES_NOT_WAIVED_USER_ACCOUNT }]) + ) + } } pub type Barrier = ( @@ -519,12 +521,12 @@ impl xcm_executor::Config for XcmConfig { pub type LocalOriginToLocation = SignedToAccountId32; parameter_types! { - pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 3; + pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 4; } pub struct XcmTeleportFiltered; -impl Contains<(MultiLocation, Vec)> for XcmTeleportFiltered { - fn contains(t: &(MultiLocation, Vec)) -> bool { +impl Contains<(Location, Vec)> for XcmTeleportFiltered { + fn contains(t: &(Location, Vec)) -> bool { let filtered = FilteredTeleportAsset::get(); t.1.iter().any(|asset| asset == &filtered) } @@ -566,24 +568,23 @@ impl pallet_test_notifier::Config for Test { #[cfg(feature = "runtime-benchmarks")] impl super::benchmarking::Config for Test { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parachain(1000).into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { Some((NativeAsset::get(), SystemParachainLocation::get())) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { Some(( - MultiAsset { fun: Fungible(10), id: Concrete(Here.into_location()) }, + Asset { fun: Fungible(10), id: AssetId(Here.into_location()) }, Parachain(OTHER_PARA_ID).into(), )) } - fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { - use crate::tests::assets_transfer::{into_multiassets_checked, set_up_foreign_asset}; + fn set_up_complex_asset_transfer() -> Option<(Assets, u32, 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. @@ -600,7 +601,7 @@ impl super::benchmarking::Config for Test { ); // create sufficient foreign asset USDT let usdt_initial_local_amount = fee_amount * 10; - let (usdt_chain, _, usdt_id_multilocation) = set_up_foreign_asset( + let (usdt_chain, _, usdt_id_location) = set_up_foreign_asset( USDT_PARA_ID, None, caller.clone(), @@ -610,22 +611,25 @@ 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_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, fee_amount).into(), + (usdt_id_location.clone(), fee_amount).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), asset_amount).into(), + (Location::here(), asset_amount).into(), ); // verify initial balances assert_eq!(Balances::free_balance(&caller), balance); - assert_eq!(Assets::balance(usdt_id_multilocation, &caller), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), &caller), + usdt_initial_local_amount + ); // verify transferred successfully let verify = Box::new(move || { // verify balances after transfer, decreased by transferred amounts assert_eq!(Balances::free_balance(&caller), balance - asset_amount); assert_eq!( - Assets::balance(usdt_id_multilocation, &caller), + AssetsPallet::balance(usdt_id_location, &caller), usdt_initial_local_amount - fee_amount ); }); @@ -641,13 +645,13 @@ pub(crate) fn last_events(n: usize) -> Vec { System::events().into_iter().map(|e| e.event).rev().take(n).rev().collect() } -pub(crate) fn buy_execution(fees: impl Into) -> Instruction { +pub(crate) fn buy_execution(fees: impl Into) -> Instruction { use xcm::latest::prelude::*; BuyExecution { fees: fees.into(), weight_limit: Unlimited } } pub(crate) fn buy_limited_execution( - fees: impl Into, + fees: impl Into, weight_limit: WeightLimit, ) -> Instruction { use xcm::latest::prelude::*; diff --git a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs index 6893bae2b6c1..27be5cce1458 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs @@ -33,8 +33,8 @@ use xcm_executor::traits::ConvertLocation; // Helper function to deduplicate testing different teleport types. fn do_test_and_verify_teleport_assets( - origin_location: MultiLocation, - expected_beneficiary: MultiLocation, + origin_location: Location, + expected_beneficiary: Location, call: Call, expected_weight_limit: WeightLimit, ) { @@ -70,13 +70,15 @@ fn do_test_and_verify_teleport_assets( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -92,11 +94,11 @@ fn do_test_and_verify_teleport_assets( /// local effects. #[test] fn teleport_assets_works() { - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); do_test_and_verify_teleport_assets( - origin_location, - beneficiary, + origin_location.clone(), + beneficiary.clone(), || { assert_ok!(XcmPallet::teleport_assets( RuntimeOrigin::signed(ALICE), @@ -116,13 +118,13 @@ fn teleport_assets_works() { /// local effects. #[test] fn limited_teleport_assets_works() { - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); let weight_limit = WeightLimit::Limited(Weight::from_parts(5000, 5000)); let expected_weight_limit = weight_limit.clone(); do_test_and_verify_teleport_assets( - origin_location, - beneficiary, + origin_location.clone(), + beneficiary.clone(), || { assert_ok!(XcmPallet::limited_teleport_assets( RuntimeOrigin::signed(ALICE), @@ -140,7 +142,7 @@ fn limited_teleport_assets_works() { /// `limited_teleport_assets` should fail for filtered assets #[test] fn limited_teleport_filtered_assets_disallowed() { - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); new_test_ext_with_balances(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { let result = XcmPallet::limited_teleport_assets( RuntimeOrigin::signed(ALICE), @@ -165,7 +167,7 @@ fn limited_teleport_filtered_assets_disallowed() { /// /// Asserts that the sender's balance is decreased and the beneficiary's balance /// is increased. Verifies the correct message is sent and event is emitted. -/// Verifies that XCM router fees (`SendXcm::validate` -> `MultiAssets`) are withdrawn from correct +/// Verifies that XCM router fees (`SendXcm::validate` -> `Assets`) are withdrawn from correct /// user account and deposited to a correct target account (`XcmFeesTargetAccount`). #[test] fn reserve_transfer_assets_with_paid_router_works() { @@ -179,13 +181,13 @@ fn reserve_transfer_assets_with_paid_router_works() { new_test_ext_with_balances(balances).execute_with(|| { let xcm_router_fee_amount = Para3000PaymentAmount::get(); let weight = BaseXcmWeight::get(); - let dest: MultiLocation = - AccountId32 { network: None, id: user_account.clone().into() }.into(); + let dest: Location = + Junction::AccountId32 { network: None, id: user_account.clone().into() }.into(); assert_eq!(Balances::total_balance(&user_account), INITIAL_BALANCE); assert_ok!(XcmPallet::reserve_transfer_assets( RuntimeOrigin::signed(user_account.clone()), Box::new(Parachain(paid_para_id).into()), - Box::new(dest.into()), + Box::new(dest.clone().into()), Box::new((Here, SEND_AMOUNT).into()), 0, )); @@ -206,7 +208,7 @@ fn reserve_transfer_assets_with_paid_router_works() { INITIAL_BALANCE + xcm_router_fee_amount ); - let dest_para: MultiLocation = Parachain(paid_para_id).into(); + let dest_para: Location = Parachain(paid_para_id).into(); assert_eq!( sent_xcm(), vec![( @@ -215,14 +217,16 @@ fn reserve_transfer_assets_with_paid_router_works() { ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, buy_execution((Parent, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]), )] ); let mut last_events = last_events(5).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // balances events last_events.next().unwrap(); @@ -231,7 +235,7 @@ fn reserve_transfer_assets_with_paid_router_works() { last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: dest, - fees: Para3000PaymentMultiAssets::get(), + fees: Para3000PaymentAssets::get(), }) ); assert!(matches!( @@ -247,45 +251,45 @@ pub(crate) fn set_up_foreign_asset( benficiary: AccountId, initial_amount: u128, is_sufficient: bool, -) -> (MultiLocation, AccountId, MultiLocation) { +) -> (Location, AccountId, Location) { let reserve_location = RelayLocation::get().pushed_with_interior(Parachain(reserve_para_id)).unwrap(); let reserve_sovereign_account = SovereignAccountOf::convert_location(&reserve_location).unwrap(); - let foreign_asset_id_multilocation = if let Some(junction) = inner_junction { - reserve_location.pushed_with_interior(junction).unwrap() + let foreign_asset_id_location = if let Some(junction) = inner_junction { + reserve_location.clone().pushed_with_interior(junction).unwrap() } else { - reserve_location + reserve_location.clone() }; - // create sufficient (to be used as fees as well) foreign asset - assert_ok!(Assets::force_create( + // create sufficient (to be used as fees as well) foreign asset (0 total issuance) + assert_ok!(AssetsPallet::force_create( RuntimeOrigin::root(), - foreign_asset_id_multilocation, + foreign_asset_id_location.clone(), BOB, is_sufficient, 1 )); // this asset should have been teleported/reserve-transferred in, but for this test we just // mint it locally. - assert_ok!(Assets::mint( + assert_ok!(AssetsPallet::mint( RuntimeOrigin::signed(BOB), - foreign_asset_id_multilocation, + foreign_asset_id_location.clone(), benficiary, initial_amount )); - (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) + (reserve_location, reserve_sovereign_account, foreign_asset_id_location) } // Helper function that provides correct `fee_index` after `sort()` done by -// `vec![MultiAsset, MultiAsset].into()`. -pub(crate) fn into_multiassets_checked( - fee_asset: MultiAsset, - transfer_asset: MultiAsset, -) -> (MultiAssets, usize, MultiAsset, MultiAsset) { - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset.clone()].into(); +// `vec![Asset, Asset].into()`. +pub(crate) fn into_assets_checked( + fee_asset: Asset, + transfer_asset: Asset, +) -> (Assets, usize, 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) } @@ -302,9 +306,9 @@ fn local_asset_reserve_and_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, @@ -313,12 +317,14 @@ fn local_asset_reserve_and_local_fee_reserve_call( (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let weight_limit = WeightLimit::Limited(Weight::from_parts(5000, 5000)); let expected_weight_limit = weight_limit.clone(); - let expected_beneficiary = beneficiary; - let dest: MultiLocation = Parachain(OTHER_PARA_ID).into(); + let expected_beneficiary = beneficiary.clone(); + let dest: Location = Parachain(OTHER_PARA_ID).into(); new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get(); @@ -326,8 +332,8 @@ fn local_asset_reserve_and_local_fee_reserve_call( // call extrinsic let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new((Here, SEND_AMOUNT).into()), 0, weight_limit, @@ -352,7 +358,7 @@ fn local_asset_reserve_and_local_fee_reserve_call( buy_limited_execution((Parent, SEND_AMOUNT), expected_weight_limit), DepositAsset { assets: AllCounted(1).into(), - beneficiary: expected_beneficiary + beneficiary: expected_beneficiary.clone() }, ]), )] @@ -360,13 +366,15 @@ fn local_asset_reserve_and_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -423,21 +431,22 @@ fn destination_asset_reserve_and_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let weight = BaseXcmWeight::get() * 3; let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -449,27 +458,30 @@ 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_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -483,24 +495,32 @@ fn destination_asset_reserve_and_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // Alice spent (transferred) amount assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Alice used native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - FEE_AMOUNT); // Destination account (parachain account) added native reserve used as fee to balances assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), FEE_AMOUNT); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -514,7 +534,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( buy_limited_execution(expected_fee, Unlimited), WithdrawAsset(expected_asset.into()), ClearOrigin, - DepositAsset { assets: AllCounted(2).into(), beneficiary }, + DepositAsset { assets: AllCounted(2).into(), beneficiary: beneficiary.clone() }, ]) )] ); @@ -522,7 +542,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -582,19 +602,19 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, _, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, _, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -606,15 +626,18 @@ 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_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // try the transfer @@ -629,14 +652,20 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice transferred nothing - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); // Alice spent native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); }); } @@ -698,20 +727,21 @@ fn local_asset_reserve_and_destination_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (usdc_reserve_location, usdc_chain_sovereign_account, usdc_id_multilocation) = + let (usdc_reserve_location, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), @@ -723,27 +753,30 @@ 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_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // usdc for fees (is sufficient on local chain too) - destination reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -758,13 +791,15 @@ fn local_asset_reserve_and_destination_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -774,18 +809,21 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // Alice spent (fees) amount assert_eq!( - Assets::balance(usdc_id_multilocation, ALICE), + AssetsPallet::balance(usdc_id_location.clone(), ALICE), usdc_initial_local_amount - FEE_AMOUNT ); // Alice used native asset for transfer assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); // Sovereign account of dest parachain holds `SEND_AMOUNT` native asset in local reserve assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), SEND_AMOUNT); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC have decreased (burned on reserve-withdraw) let expected_issuance = usdc_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -856,21 +894,22 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // we'll send just this foreign asset back to its reserve location and use it for fees as // well let foreign_initial_amount = 142; - let (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -881,22 +920,25 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // transfer destination is reserve location let dest = reserve_location; - let assets: MultiAssets = vec![(foreign_asset_id_multilocation, SEND_AMOUNT).into()].into(); + let assets: Assets = vec![(foreign_asset_id_location.clone(), SEND_AMOUNT).into()].into(); let fee_index = 0; // reanchor according to test-case let mut expected_assets = assets.clone(); - expected_assets.reanchor(&dest, UniversalLocation::get()).unwrap(); + expected_assets.reanchor(&dest, &UniversalLocation::get()).unwrap(); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index, Unlimited, @@ -911,13 +953,15 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -927,19 +971,25 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // Alice spent (transferred) amount assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Alice's native asset balance is untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Reserve sovereign account has same balances assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -950,7 +1000,7 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( WithdrawAsset(expected_assets.clone()), ClearOrigin, buy_limited_execution(expected_assets.get(0).unwrap().clone(), Unlimited), - DepositAsset { assets: AllCounted(1).into(), beneficiary }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: beneficiary.clone() }, ]), )] ); @@ -1003,19 +1053,19 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 42; - let (usdc_chain, _, usdc_id_multilocation) = set_up_foreign_asset( + let (usdc_chain, _, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1025,7 +1075,7 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, _, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, _, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -1037,16 +1087,22 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // reserve chain) let dest = usdc_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - destination reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1062,14 +1118,23 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1127,19 +1192,19 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1151,15 +1216,18 @@ 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_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1172,15 +1240,21 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( Unlimited, ); assert_eq!(result, expected_result); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Sovereign account of reserve parachain is unchanged assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(dest_sovereign_account), 0); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), expected_usdc_issuance); }); } @@ -1237,19 +1311,19 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 42; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1259,7 +1333,7 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -1272,15 +1346,18 @@ 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_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1295,18 +1372,33 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1377,52 +1469,54 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (usdc_chain, usdc_chain_sovereign_account, usdc_id_multilocation) = - set_up_foreign_asset( - USDC_RESERVE_PARA_ID, - Some(USDC_INNER_JUNCTION), - ALICE, - usdc_initial_local_amount, - true, - ); + let (usdc_chain, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( + USDC_RESERVE_PARA_ID, + Some(USDC_INNER_JUNCTION), + ALICE, + usdc_initial_local_amount, + true, + ); // transfer destination is some other parachain let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let assets: MultiAssets = vec![(usdc_id_multilocation, SEND_AMOUNT).into()].into(); - let fee_index = 0u32; + let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); + let fee_index = 0; // reanchor according to test-case let context = UniversalLocation::get(); - let expected_dest_on_reserve = dest.reanchored(&usdc_chain, context).unwrap(); + 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 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(); - let expected_fee_on_dest = fees_half_2.reanchored(&dest, context).unwrap(); + expected_assets_on_reserve.reanchor(&usdc_chain, &context).unwrap(); + let expected_fee_on_reserve = fees_half_1.reanchored(&usdc_chain, &context).unwrap(); + let expected_fee_on_dest = fees_half_2.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index, Unlimited, @@ -1435,23 +1529,26 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( assert!(matches!( last_event(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(_) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete { .. } }) )); // Alice spent (transferred) amount assert_eq!( - Assets::balance(usdc_id_multilocation, ALICE), + AssetsPallet::balance(usdc_id_location.clone(), ALICE), usdc_initial_local_amount - SEND_AMOUNT ); // Alice's native asset balance is untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Destination account (parachain account) has expected (same) balances assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC have decreased (burned on reserve-withdraw) let expected_usdc_issuance = usdc_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); // Verify sent XCM program assert_eq!( @@ -1523,46 +1620,50 @@ fn local_asset_reserve_and_teleported_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // 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_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -1577,13 +1678,15 @@ fn local_asset_reserve_and_teleported_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -1592,18 +1695,21 @@ fn local_asset_reserve_and_teleported_fee_call( )); // Alice spent (fees) amount assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - FEE_AMOUNT ); // Alice used native asset for transfer assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); // Sovereign account of dest parachain holds `SEND_AMOUNT` native asset in local reserve assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), SEND_AMOUNT); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_usdt_issuance); // Verify sent XCM program assert_eq!( @@ -1672,25 +1778,26 @@ fn destination_asset_reserve_and_teleported_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (_, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (_, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -1703,27 +1810,30 @@ 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_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -1738,13 +1848,15 @@ fn destination_asset_reserve_and_teleported_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -1755,29 +1867,38 @@ fn destination_asset_reserve_and_teleported_fee_call( assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice spent USDT for fees assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - FEE_AMOUNT ); // Alice transferred BLA assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Verify balances of USDT reserve parachain assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify balances of transferred-asset reserve parachain assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); // Verify total and active issuance of USDT have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location.clone()), expected_usdt_issuance); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_bla_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); // Verify sent XCM program assert_eq!( @@ -1844,24 +1965,24 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, reserve_sovereign_account, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -1872,15 +1993,18 @@ 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_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // try the transfer @@ -1895,18 +2019,33 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); let expected_usdt_issuance = usdt_initial_local_amount; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location.clone()), expected_usdt_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1959,21 +2098,24 @@ fn teleport_assets_with_remote_asset_reserve_and_teleported_fee_disallowed() { #[test] fn reserve_transfer_assets_with_teleportable_asset_disallowed() { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; - let assets: MultiAssets = vec![(usdt_id_multilocation, FEE_AMOUNT).into()].into(); + let assets: Assets = vec![(usdt_id_location.clone(), FEE_AMOUNT).into()].into(); let fee_index = 0; // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1996,25 +2138,34 @@ fn reserve_transfer_assets_with_teleportable_asset_disallowed() { // Alice native asset is still same assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice USDT balance is still same - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); // No USDT moved to sovereign account of reserve parachain - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDT are still the same - assert_eq!(Assets::total_issuance(usdt_id_multilocation), usdt_initial_local_amount); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::total_issuance(usdt_id_location.clone()), + usdt_initial_local_amount + ); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), usdt_initial_local_amount); }); } /// Test `transfer_assets` with teleportable fee that is filtered - should fail. #[test] fn transfer_assets_with_filtered_teleported_fee_disallowed() { - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + 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_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // FilteredTeleportAsset for fees - teleportable but filtered FilteredTeleportAsset::get().into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); let result = XcmPallet::transfer_assets( RuntimeOrigin::signed(ALICE), @@ -2043,11 +2194,11 @@ fn transfer_assets_with_filtered_teleported_fee_disallowed() { #[test] fn intermediary_error_reverts_side_effects() { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -2058,11 +2209,14 @@ fn intermediary_error_reverts_side_effects() { // transfer destination is some other parachain let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let assets: MultiAssets = vec![(usdc_id_multilocation, SEND_AMOUNT).into()].into(); + let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); let fee_index = 0; // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // introduce artificial error in sending outbound XCM @@ -2080,14 +2234,23 @@ fn intermediary_error_reverts_side_effects() { .is_err()); // Alice no changes - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Destination account (parachain account) no changes assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC has not changed - assert_eq!(Assets::total_issuance(usdc_id_multilocation), usdc_initial_local_amount); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::total_issuance(usdc_id_location.clone()), + usdc_initial_local_amount + ); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), usdc_initial_local_amount); // Verify no XCM program sent assert_eq!(sent_xcm(), vec![]); }); @@ -2105,47 +2268,50 @@ fn teleport_asset_using_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let weight = BaseXcmWeight::get() * 3; let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, false); // transfer destination is reserve location (no teleport trust) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // USDT to transfer - destination reserve - (usdt_id_multilocation, SEND_AMOUNT).into(), + (usdt_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -2159,24 +2325,29 @@ fn teleport_asset_using_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // Alice spent (transferred) amount assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - SEND_AMOUNT ); // Alice used native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - FEE_AMOUNT); // Destination account (parachain account) added native reserve to balances assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), FEE_AMOUNT); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = usdt_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -2198,7 +2369,7 @@ fn teleport_asset_using_local_fee_reserve_call( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -2255,20 +2426,20 @@ fn teleported_asset_using_destination_reserve_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset BLA to be used for fees let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -2279,34 +2450,37 @@ fn teleported_asset_using_destination_reserve_fee_call( // create non-sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (_, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (_, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, false); // transfer destination is BLA reserve location let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // foreign asset BLA used for fees - destination reserve - (foreign_asset_id_multilocation, FEE_AMOUNT).into(), + (foreign_asset_id_location.clone(), FEE_AMOUNT).into(), // USDT to transfer - teleported - (usdt_id_multilocation, SEND_AMOUNT).into(), + (usdt_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -2321,13 +2495,15 @@ fn teleported_asset_using_destination_reserve_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -2338,29 +2514,38 @@ fn teleported_asset_using_destination_reserve_fee_call( assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice spent USDT for fees assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - SEND_AMOUNT ); // Alice transferred BLA assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - FEE_AMOUNT ); // Verify balances of USDT reserve parachain assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify balances of transferred-asset reserve parachain assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); // Verify total and active issuance of USDT have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_usdt_issuance); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_bla_issuance = foreign_initial_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); // Verify sent XCM program assert_eq!( diff --git a/polkadot/xcm/pallet-xcm/src/tests/mod.rs b/polkadot/xcm/pallet-xcm/src/tests/mod.rs index e7a6fdc9dced..5f9c86ed7b3f 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/mod.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/mod.rs @@ -19,9 +19,8 @@ pub(crate) mod assets_transfer; use crate::{ - mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedMultiLocation, Queries, - QueryStatus, VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, - VersionNotifyTargets, + mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedLocation, Queries, QueryStatus, + VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, VersionNotifyTargets, }; use frame_support::{ assert_noop, assert_ok, @@ -49,9 +48,11 @@ fn report_outcome_notify_works() { (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let mut message = - Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = Xcm(vec![TransferAsset { + assets: (Here, SEND_AMOUNT).into(), + beneficiary: sender.clone(), + }]); let call = pallet_test_notifier::Call::notification_received { query_id: 0, response: Default::default(), @@ -76,12 +77,12 @@ fn report_outcome_notify_works() { TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, ]) ); - let querier: MultiLocation = Here.into(); + let querier: Location = Here.into(); let status = QueryStatus::Pending { - responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(), + responder: Location::from(Parachain(OTHER_PARA_ID)).into(), maybe_notify: Some((5, 2)), timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -91,14 +92,15 @@ fn report_outcome_notify_works() { max_weight: Weight::from_parts(1_000_000, 1_000_000), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(OTHER_PARA_ID), message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_events(2), vec![ @@ -124,9 +126,11 @@ fn report_outcome_works() { (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let mut message = - Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = Xcm(vec![TransferAsset { + assets: (Here, SEND_AMOUNT).into(), + beneficiary: sender.clone(), + }]); new_test_ext_with_balances(balances).execute_with(|| { XcmPallet::report_outcome(&mut message, Parachain(OTHER_PARA_ID).into_location(), 100) .unwrap(); @@ -141,12 +145,12 @@ fn report_outcome_works() { TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, ]) ); - let querier: MultiLocation = Here.into(); + let querier: Location = Here.into(); let status = QueryStatus::Pending { - responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(), + responder: Location::from(Parachain(OTHER_PARA_ID)).into(), maybe_notify: None, timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -156,14 +160,15 @@ fn report_outcome_works() { max_weight: Weight::zero(), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(OTHER_PARA_ID), message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::ResponseReady { @@ -185,16 +190,15 @@ fn custom_querier_works() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let querier: MultiLocation = - (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); + let querier: Location = (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); - let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier); + let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier.clone()); assert_eq!(r, Ok(())); let status = QueryStatus::Pending { - responder: MultiLocation::from(AccountId32 { network: None, id: ALICE.into() }).into(), + responder: Location::from(AccountId32 { network: None, id: ALICE.into() }).into(), maybe_notify: None, timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -205,21 +209,21 @@ fn custom_querier_works() { max_weight: Weight::zero(), querier: None, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), Weight::from_parts(1_000, 1_000), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { origin: AccountId32 { network: None, id: ALICE.into() }.into(), query_id: 0, - expected_querier: querier, + expected_querier: querier.clone(), maybe_actual_querier: None, }), ); @@ -229,24 +233,24 @@ fn custom_querier_works() { query_id: 0, response: Response::ExecutionResult(None), max_weight: Weight::zero(), - querier: Some(MultiLocation::here()), + querier: Some(Location::here()), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), Weight::from_parts(1_000, 1_000), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { origin: AccountId32 { network: None, id: ALICE.into() }.into(), query_id: 0, - expected_querier: querier, - maybe_actual_querier: Some(MultiLocation::here()), + expected_querier: querier.clone(), + maybe_actual_querier: Some(Location::here()), }), ); @@ -257,14 +261,15 @@ fn custom_querier_works() { max_weight: Weight::zero(), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::ResponseReady { @@ -289,12 +294,12 @@ fn send_works() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); let message = Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, buy_execution((Parent, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: sender }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: sender.clone() }, ]); let versioned_dest = Box::new(RelayLocation::get().into()); @@ -304,7 +309,7 @@ fn send_works() { versioned_dest, versioned_message )); - let sent_message = Xcm(Some(DescendOrigin(sender.try_into().unwrap())) + let sent_message = Xcm(Some(DescendOrigin(sender.clone().try_into().unwrap())) .into_iter() .chain(message.0.clone().into_iter()) .collect()); @@ -333,8 +338,7 @@ fn send_fails_when_xcm_router_blocks() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let sender: MultiLocation = - Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let sender: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let message = Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), buy_execution((Parent, SEND_AMOUNT)), @@ -343,7 +347,7 @@ fn send_fails_when_xcm_router_blocks() { assert_noop!( XcmPallet::send( RuntimeOrigin::signed(ALICE), - Box::new(MultiLocation::ancestor(8).into()), + Box::new(Location::ancestor(8).into()), Box::new(VersionedXcm::from(message.clone())), ), crate::Error::::SendFailure @@ -363,7 +367,7 @@ fn execute_withdraw_to_deposit_works() { ]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 3; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); assert_ok!(XcmPallet::execute( RuntimeOrigin::signed(ALICE), @@ -378,7 +382,9 @@ fn execute_withdraw_to_deposit_works() { assert_eq!(Balances::total_balance(&BOB), SEND_AMOUNT); assert_eq!( last_event(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); }); } @@ -389,7 +395,7 @@ fn trapped_assets_can_be_claimed() { let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 6; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_ok!(XcmPallet::execute( RuntimeOrigin::signed(ALICE), @@ -401,15 +407,14 @@ fn trapped_assets_can_be_claimed() { // This will make an error. Trap(0), // This would succeed, but we never get to it. - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]))), weight )); - let source: MultiLocation = - Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let source: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let trapped = AssetTraps::::iter().collect::>(); - let vma = VersionedMultiAssets::from(MultiAssets::from((Here, SEND_AMOUNT))); - let hash = BlakeTwo256::hash_of(&(source, vma.clone())); + let vma = VersionedAssets::from(Assets::from((Here, SEND_AMOUNT))); + let hash = BlakeTwo256::hash_of(&(source.clone(), vma.clone())); assert_eq!( last_events(2), vec![ @@ -419,7 +424,7 @@ fn trapped_assets_can_be_claimed() { assets: vma }), RuntimeEvent::XcmPallet(crate::Event::Attempted { - outcome: Outcome::Complete(BaseXcmWeight::get() * 5) + outcome: Outcome::Complete { used: BaseXcmWeight::get() * 5 } }), ] ); @@ -435,7 +440,7 @@ fn trapped_assets_can_be_claimed() { Box::new(VersionedXcm::from(Xcm(vec![ ClaimAsset { assets: (Here, SEND_AMOUNT).into(), ticket: Here.into() }, buy_execution((Here, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]))), weight )); @@ -454,7 +459,8 @@ fn trapped_assets_can_be_claimed() { ]))), weight )); - let outcome = Outcome::Incomplete(BaseXcmWeight::get(), XcmError::UnknownClaim); + let outcome = + Outcome::Incomplete { used: BaseXcmWeight::get(), error: XcmError::UnknownClaim }; assert_eq!(last_event(), RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome })); }); } @@ -468,10 +474,10 @@ fn incomplete_execute_reverts_side_effects() { let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 4; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); let amount_to_send = INITIAL_BALANCE - ExistentialDeposit::get(); - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let result = XcmPallet::execute( RuntimeOrigin::signed(ALICE), Box::new(VersionedXcm::from(Xcm(vec![ @@ -506,35 +512,38 @@ fn incomplete_execute_reverts_side_effects() { } #[test] -fn fake_latest_versioned_multilocation_works() { +fn fake_latest_versioned_location_works() { use codec::Encode; - let remote: MultiLocation = Parachain(1000).into(); - let versioned_remote = LatestVersionedMultiLocation(&remote); + let remote: Location = Parachain(1000).into(); + let versioned_remote = LatestVersionedLocation(&remote); assert_eq!(versioned_remote.encode(), remote.into_versioned().encode()); } #[test] fn basic_subscription_works() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_eq!( Queries::::iter().collect::>(), - vec![(0, QueryStatus::VersionNotifier { origin: remote.into(), is_active: false })] + vec![( + 0, + QueryStatus::VersionNotifier { origin: remote.clone().into(), is_active: false } + )] ); assert_eq!( VersionNotifiers::::iter().collect::>(), - vec![(XCM_VERSION, remote.into(), 0)] + vec![(XCM_VERSION, remote.clone().into(), 0)] ); assert_eq!( take_sent_xcm(), vec![( - remote, + remote.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), ),] ); @@ -561,16 +570,16 @@ fn basic_subscription_works() { #[test] fn subscriptions_increment_id() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); - let remote2: MultiLocation = Parachain(1001).into(); + let remote2: Location = Parachain(1001).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote2.into()), + Box::new(remote2.clone().into()), )); assert_eq!( @@ -598,10 +607,10 @@ fn subscriptions_increment_id() { #[test] fn double_subscription_fails() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_noop!( XcmPallet::force_subscribe_version_notify( @@ -616,19 +625,19 @@ fn double_subscription_fails() { #[test] fn unsubscribe_works() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_ok!(XcmPallet::force_unsubscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()) + Box::new(remote.clone().into()) )); assert_noop!( XcmPallet::force_unsubscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()) + Box::new(remote.clone().into()) ), Error::::NoSubscription, ); @@ -637,13 +646,13 @@ fn unsubscribe_works() { take_sent_xcm(), vec![ ( - remote, + remote.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), ), - (remote, Xcm(vec![UnsubscribeVersion]),), + (remote.clone(), Xcm(vec![UnsubscribeVersion]),), ] ); }); @@ -655,13 +664,19 @@ fn subscription_side_works() { new_test_ext_with_balances(vec![]).execute_with(|| { AdvertisedXcmVersion::set(1); - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); let weight = BaseXcmWeight::get(); let message = Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let instr = QueryResponse { query_id: 0, @@ -669,7 +684,7 @@ fn subscription_side_works() { response: Response::Version(1), querier: None, }; - assert_eq!(take_sent_xcm(), vec![(remote, Xcm(vec![instr]))]); + assert_eq!(take_sent_xcm(), vec![(remote.clone(), Xcm(vec![instr]))]); // A runtime upgrade which doesn't alter the version sends no notifications. CurrentMigration::::put(VersionMigrationStage::default()); @@ -698,7 +713,7 @@ fn subscription_side_upgrades_work_with_notify() { AdvertisedXcmVersion::set(1); // An entry from a previous runtime with v2 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); @@ -751,7 +766,7 @@ fn subscription_side_upgrades_work_with_notify() { fn subscription_side_upgrades_work_without_notify() { new_test_ext_with_balances(vec![]).execute_with(|| { // An entry from a previous runtime with v2 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); @@ -765,8 +780,8 @@ fn subscription_side_upgrades_work_without_notify() { assert_eq!( contents, vec![ - (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 3)), - (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 4)), + (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 4)), ] ); }); @@ -775,10 +790,10 @@ fn subscription_side_upgrades_work_without_notify() { #[test] fn subscriber_side_subscription_works() { new_test_ext_with_balances_and_xcm_version(vec![], Some(XCM_VERSION)).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_eq!(XcmPallet::get_version_for(&remote), None); take_sent_xcm(); @@ -795,9 +810,15 @@ fn subscriber_side_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(take_sent_xcm(), vec![]); assert_eq!(XcmPallet::get_version_for(&remote), Some(1)); @@ -814,9 +835,15 @@ fn subscriber_side_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(take_sent_xcm(), vec![]); assert_eq!(XcmPallet::get_version_for(&remote), Some(2)); @@ -832,73 +859,79 @@ fn subscriber_side_subscription_works() { #[test] fn auto_subscription_works() { new_test_ext_with_balances_and_xcm_version(vec![], None).execute_with(|| { - let remote_v2: MultiLocation = Parachain(1000).into(); - let remote_v3: MultiLocation = Parachain(1001).into(); + let remote_v2: Location = Parachain(1000).into(); + let remote_v4: Location = Parachain(1001).into(); assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(2))); // Wrapping a version for a destination we don't know elicits a subscription. let msg_v2 = xcm::v2::Xcm::<()>(vec![xcm::v2::Instruction::Trap(0)]); - let msg_v3 = xcm::v3::Xcm::<()>(vec![xcm::v3::Instruction::ClearTopic]); + let msg_v4 = xcm::v4::Xcm::<()>(vec![xcm::v4::Instruction::ClearTopic]); assert_eq!( XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), Ok(VersionedXcm::from(msg_v2.clone())), ); - assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v4.clone()), Err(())); - let expected = vec![(remote_v2.into(), 2)]; + let expected = vec![(remote_v2.clone().into(), 2)]; assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), + XcmPallet::wrap_version(&remote_v4, msg_v2.clone()), Ok(VersionedXcm::from(msg_v2.clone())), ); - assert_eq!(XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v4, msg_v4.clone()), Err(())); - let expected = vec![(remote_v2.into(), 2), (remote_v3.into(), 2)]; + let expected = vec![(remote_v2.clone().into(), 2), (remote_v4.clone().into(), 2)]; assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); XcmPallet::on_initialize(1); assert_eq!( take_sent_xcm(), vec![( - remote_v3, + remote_v4.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), )] ); - // Assume remote_v3 is working ok and XCM version 3. + // Assume remote_v4 is working ok and XCM version 4. let weight = BaseXcmWeight::get(); let message = Xcm(vec![ - // Remote supports XCM v3 + // Remote supports XCM v4 QueryResponse { query_id: 0, max_weight: Weight::zero(), - response: Response::Version(3), + response: Response::Version(4), querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote_v3, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote_v4.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); - // V2 messages can be sent to remote_v3 under XCM v3. + // V2 messages can be sent to remote_v4 under XCM v4. assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), - Ok(VersionedXcm::from(msg_v2.clone()).into_version(3).unwrap()), + XcmPallet::wrap_version(&remote_v4, msg_v2.clone()), + Ok(VersionedXcm::from(msg_v2.clone()).into_version(4).unwrap()), ); - // This message can now be sent to remote_v3 as it's v3. + // This message can now be sent to remote_v4 as it's v4. assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), - Ok(VersionedXcm::from(msg_v3.clone())) + XcmPallet::wrap_version(&remote_v4, msg_v4.clone()), + Ok(VersionedXcm::from(msg_v4.clone())) ); XcmPallet::on_initialize(2); assert_eq!( take_sent_xcm(), vec![( - remote_v2, + remote_v2.clone(), Xcm(vec![SubscribeVersion { query_id: 1, max_response_weight: Weight::zero() }]), )] ); @@ -915,16 +948,22 @@ fn auto_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote_v2, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote_v2.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); - // v3 messages cannot be sent to remote_v2... + // v4 messages cannot be sent to remote_v2... assert_eq!( XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), Ok(VersionedXcm::V2(msg_v2)) ); - assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v4.clone()), Err(())); }) } @@ -934,9 +973,9 @@ fn subscription_side_upgrades_work_with_multistage_notify() { AdvertisedXcmVersion::set(1); // An entry from a previous runtime with v0 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 1)); - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1002).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1002).into()); VersionNotifyTargets::::insert(2, v2_location, (71, Weight::zero(), 1)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 1)); @@ -1003,9 +1042,9 @@ fn subscription_side_upgrades_work_with_multistage_notify() { #[test] fn get_and_wrap_version_works() { new_test_ext_with_balances_and_xcm_version(vec![], None).execute_with(|| { - let remote_a: MultiLocation = Parachain(1000).into(); - let remote_b: MultiLocation = Parachain(1001).into(); - let remote_c: MultiLocation = Parachain(1002).into(); + let remote_a: Location = Parachain(1000).into(); + let remote_b: Location = Parachain(1001).into(); + let remote_c: Location = Parachain(1002).into(); // no `safe_xcm_version` version at `GenesisConfig` assert_eq!(XcmPallet::get_version_for(&remote_a), None); @@ -1023,7 +1062,7 @@ fn get_and_wrap_version_works() { // set XCM version only for `remote_a` assert_ok!(XcmPallet::force_xcm_version( RuntimeOrigin::root(), - Box::new(remote_a), + Box::new(remote_a.clone()), XCM_VERSION )); assert_eq!(XcmPallet::get_version_for(&remote_a), Some(XCM_VERSION)); @@ -1041,7 +1080,10 @@ fn get_and_wrap_version_works() { // does not work because remote_b has unknown version and default is set to 1, and // `XCM_VERSION` cannot be wrapped to the `1` assert_eq!(XcmPallet::wrap_version(&remote_b, xcm.clone()), Err(())); - assert_eq!(VersionDiscoveryQueue::::get().into_inner(), vec![(remote_b.into(), 1)]); + assert_eq!( + VersionDiscoveryQueue::::get().into_inner(), + vec![(remote_b.clone().into(), 1)] + ); // set default to the `XCM_VERSION` assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(XCM_VERSION))); @@ -1053,10 +1095,17 @@ fn get_and_wrap_version_works() { XcmPallet::wrap_version(&remote_b, xcm.clone()), Ok(VersionedXcm::from(xcm.clone())) ); - assert_eq!(VersionDiscoveryQueue::::get().into_inner(), vec![(remote_b.into(), 2)]); + assert_eq!( + VersionDiscoveryQueue::::get().into_inner(), + vec![(remote_b.clone().into(), 2)] + ); // change remote_c to `1` - assert_ok!(XcmPallet::force_xcm_version(RuntimeOrigin::root(), Box::new(remote_c), 1)); + assert_ok!(XcmPallet::force_xcm_version( + RuntimeOrigin::root(), + Box::new(remote_c.clone()), + 1 + )); // does not work because remote_c has `1` and default is `XCM_VERSION` which cannot be // wrapped to the `1` diff --git a/polkadot/xcm/procedural/src/lib.rs b/polkadot/xcm/procedural/src/lib.rs index 7600e817d0e6..4980d84d3282 100644 --- a/polkadot/xcm/procedural/src/lib.rs +++ b/polkadot/xcm/procedural/src/lib.rs @@ -22,6 +22,7 @@ use syn::{parse_macro_input, DeriveInput}; mod builder_pattern; mod v2; mod v3; +mod v4; mod weight_info; #[proc_macro] @@ -31,6 +32,13 @@ pub fn impl_conversion_functions_for_multilocation_v2(input: TokenStream) -> Tok .into() } +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v2(input: TokenStream) -> TokenStream { + v2::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + #[proc_macro_derive(XcmWeightInfoTrait)] pub fn derive_xcm_weight_info(item: TokenStream) -> TokenStream { weight_info::derive(item) @@ -50,6 +58,20 @@ pub fn impl_conversion_functions_for_junctions_v3(input: TokenStream) -> TokenSt .into() } +#[proc_macro] +pub fn impl_conversion_functions_for_location_v4(input: TokenStream) -> TokenStream { + v4::location::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v4(input: TokenStream) -> TokenStream { + v4::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + /// This is called on the `Instruction` enum, not on the `Xcm` struct, /// and allows for the following syntax for building XCMs: /// let message = Xcm::builder() diff --git a/polkadot/xcm/procedural/src/v2.rs b/polkadot/xcm/procedural/src/v2.rs index dc2694a666f0..1a2f281a4982 100644 --- a/polkadot/xcm/procedural/src/v2.rs +++ b/polkadot/xcm/procedural/src/v2.rs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + pub mod multilocation { - use proc_macro2::{Span, TokenStream}; - use quote::{format_ident, quote}; - use syn::{Result, Token}; + use super::*; pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { if !input.is_empty() { @@ -181,3 +183,44 @@ pub mod multilocation { } } } + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")); + } + + let from_slice_syntax = generate_conversion_from_slice_syntax(); + + Ok(quote! { + #from_slice_syntax + }) + } + + fn generate_conversion_from_slice_syntax() -> TokenStream { + quote! { + macro_rules! impl_junction { + ($count:expr, $variant:ident, ($($index:literal),+)) => { + /// Additional helper for building junctions + /// Useful for converting to future XCM versions + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant($(junctions[$index].clone()),*) + } + } + }; + } + + impl_junction!(1, X1, (0)); + impl_junction!(2, X2, (0, 1)); + impl_junction!(3, X3, (0, 1, 2)); + impl_junction!(4, X4, (0, 1, 2, 3)); + impl_junction!(5, X5, (0, 1, 2, 3, 4)); + impl_junction!(6, X6, (0, 1, 2, 3, 4, 5)); + impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6)); + impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7)); + } + } +} diff --git a/polkadot/xcm/procedural/src/v3.rs b/polkadot/xcm/procedural/src/v3.rs index 246f90a46a3e..f0556d5a8d44 100644 --- a/polkadot/xcm/procedural/src/v3.rs +++ b/polkadot/xcm/procedural/src/v3.rs @@ -45,9 +45,8 @@ pub mod multilocation { let interior = if num_junctions == 0 { quote!(Junctions::Here) } else { - let variant = format_ident!("X{}", num_junctions); quote! { - Junctions::#variant( #(#idents .into()),* ) + [#(#idents .into()),*].into() } }; @@ -110,7 +109,7 @@ pub mod multilocation { impl From for MultiLocation { fn from(x: Junction) -> Self { - MultiLocation { parents: 0, interior: Junctions::X1(x) } + MultiLocation { parents: 0, interior: [x].into() } } } @@ -129,10 +128,12 @@ pub mod junctions { // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. let from_v2 = generate_conversion_from_v2(MAX_JUNCTIONS); + let from_v4 = generate_conversion_from_v4(); let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); Ok(quote! { #from_v2 + #from_v4 #from_tuples }) } @@ -143,12 +144,11 @@ pub mod junctions { let idents = (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); - let variant = &format_ident!("X{}", num_junctions); quote! { impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { - Self::#variant( #(#idents .into()),* ) + [#(#idents .into()),*].into() } } } @@ -156,6 +156,45 @@ pub mod junctions { .collect() } + fn generate_conversion_from_v4() -> TokenStream { + let match_variants = (0..8u8) + .map(|current_number| { + let number_ancestors = current_number + 1; + let variant = format_ident!("X{}", number_ancestors); + let idents = + (0..=current_number).map(|i| format_ident!("j{}", i)).collect::>(); + let convert = idents + .iter() + .map(|ident| { + quote! { let #ident = core::convert::TryInto::try_into(#ident.clone())?; } + }) + .collect::>(); + + quote! { + crate::v4::Junctions::#variant( junctions ) => { + let [#(#idents),*] = &*junctions; + #(#convert);* + [#(#idents),*].into() + }, + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + + fn try_from(mut new: crate::v4::Junctions) -> core::result::Result { + use Junctions::*; + Ok(match new { + crate::v4::Junctions::Here => Here, + #match_variants + }) + } + } + } + } + fn generate_conversion_from_v2(max_junctions: usize) -> TokenStream { let match_variants = (0..max_junctions) .map(|cur_num| { diff --git a/polkadot/xcm/procedural/src/v4.rs b/polkadot/xcm/procedural/src/v4.rs new file mode 100644 index 000000000000..5f5e10d3081b --- /dev/null +++ b/polkadot/xcm/procedural/src/v4.rs @@ -0,0 +1,196 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + +const MAX_JUNCTIONS: usize = 8; + +pub mod location { + use super::*; + + /// Generates conversion functions from other types to the `Location` type: + /// - [PalletInstance(50), GeneralIndex(1984)].into() + /// - (Parent, Parachain(1000), AccountId32 { .. }).into() + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + let from_tuples = generate_conversion_from_tuples(8, 8); + + Ok(quote! { + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize, max_parents: usize) -> TokenStream { + let mut from_tuples = (0..=max_junctions) + .map(|num_junctions| { + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let array_size = num_junctions; + let interior = if num_junctions == 0 { + quote!(Junctions::Here) + } else { + let variant = format_ident!("X{}", num_junctions); + quote! { + Junctions::#variant( alloc::sync::Arc::new( [#(#idents .into()),*] ) ) + } + }; + + let mut from_tuple = quote! { + impl< #(#types : Into,)* > From<( Ancestor, #( #types ),* )> for Location { + fn from( ( Ancestor(parents), #(#idents),* ): ( Ancestor, #( #types ),* ) ) -> Self { + Location { parents, interior: #interior } + } + } + + impl From<[Junction; #array_size]> for Location { + fn from(j: [Junction; #array_size]) -> Self { + let [#(#idents),*] = j; + Location { parents: 0, interior: #interior } + } + } + }; + + let from_parent_tuples = (0..=max_parents).map(|cur_parents| { + let parents = + (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl< #(#types : Into,)* > From<( #( #parents , )* #( #types , )* )> for Location { + fn from( ( #(#underscores,)* #(#idents,)* ): ( #(#parents,)* #(#types,)* ) ) -> Self { + Self { parents: #cur_parents as u8, interior: #interior } + } + } + } + }); + + from_tuple.extend(from_parent_tuples); + from_tuple + }) + .collect::(); + + let from_parent_junctions_tuples = (0..=max_parents).map(|cur_parents| { + let parents = (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl From<( #(#parents,)* Junctions )> for Location { + fn from( (#(#underscores,)* junctions): ( #(#parents,)* Junctions ) ) -> Self { + Location { parents: #cur_parents as u8, interior: junctions } + } + } + } + }); + from_tuples.extend(from_parent_junctions_tuples); + + quote! { + impl From<(Ancestor, Junctions)> for Location { + fn from((Ancestor(parents), interior): (Ancestor, Junctions)) -> Self { + Location { parents, interior } + } + } + + impl From for Location { + fn from(x: Junction) -> Self { + Location { parents: 0, interior: [x].into() } + } + } + + #from_tuples + } + } +} + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. + let from_v3 = generate_conversion_from_v3(MAX_JUNCTIONS); + let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); + + Ok(quote! { + #from_v3 + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize) -> TokenStream { + (1..=max_junctions) + .map(|num_junctions| { + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + + quote! { + impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { + fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { + [#(#idents .into()),*].into() + } + } + } + }) + .collect() + } + + fn generate_conversion_from_v3(max_junctions: usize) -> TokenStream { + let match_variants = (0..max_junctions) + .map(|cur_num| { + let num_ancestors = cur_num + 1; + let variant = format_ident!("X{}", num_ancestors); + let idents = (0..=cur_num).map(|i| format_ident!("j{}", i)).collect::>(); + let convert = idents + .iter() + .map(|ident| { + quote! { let #ident = core::convert::TryInto::try_into(#ident.clone())?; } + }) + .collect::>(); + + quote! { + crate::v3::Junctions::#variant( #(#idents),* ) => { + #(#convert);*; + let junctions: Junctions = [#(#idents),*].into(); + junctions + }, + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + fn try_from(mut old: crate::v3::Junctions) -> core::result::Result { + Ok(match old { + crate::v3::Junctions::Here => Junctions::Here, + #match_variants + }) + } + } + } + } +} diff --git a/polkadot/xcm/procedural/tests/builder_pattern.rs b/polkadot/xcm/procedural/tests/builder_pattern.rs index eab9d67121f6..a9a30611dc01 100644 --- a/polkadot/xcm/procedural/tests/builder_pattern.rs +++ b/polkadot/xcm/procedural/tests/builder_pattern.rs @@ -21,12 +21,12 @@ use xcm::latest::prelude::*; #[test] fn builder_pattern_works() { - let asset: MultiAsset = (Here, 100u128).into(); - let beneficiary: MultiLocation = AccountId32 { id: [0u8; 32], network: None }.into(); + let asset: Asset = (Here, 100u128).into(); + let beneficiary: Location = AccountId32 { id: [0u8; 32], network: None }.into(); let message: Xcm<()> = Xcm::builder() .receive_teleported_asset(asset.clone().into()) .buy_execution(asset.clone(), Unlimited) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); assert_eq!( message, @@ -40,8 +40,8 @@ fn builder_pattern_works() { #[test] fn default_builder_requires_buy_execution() { - let asset: MultiAsset = (Here, 100u128).into(); - let beneficiary: MultiLocation = AccountId32 { id: [0u8; 32], network: None }.into(); + let asset: Asset = (Here, 100u128).into(); + let beneficiary: Location = AccountId32 { id: [0u8; 32], network: None }.into(); // This is invalid, since it doesn't pay for fees. // This is enforced by the runtime, because the build() method doesn't exist // on the resulting type. @@ -54,14 +54,14 @@ fn default_builder_requires_buy_execution() { let message: Xcm<()> = Xcm::builder_unpaid() .unpaid_execution(Unlimited, None) .withdraw_asset(asset.clone().into()) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); // This works assert_eq!( message, Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, WithdrawAsset(asset.clone().into()), - DepositAsset { assets: asset.clone().into(), beneficiary }, + DepositAsset { assets: asset.clone().into(), beneficiary: beneficiary.clone() }, ]) ); @@ -69,7 +69,7 @@ fn default_builder_requires_buy_execution() { // only be used when you really know what you're doing. let message: Xcm<()> = Xcm::builder_unsafe() .withdraw_asset(asset.clone().into()) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); assert_eq!( message, diff --git a/polkadot/xcm/procedural/tests/conversion_functions.rs b/polkadot/xcm/procedural/tests/conversion_functions.rs new file mode 100644 index 000000000000..5b6965167fcd --- /dev/null +++ b/polkadot/xcm/procedural/tests/conversion_functions.rs @@ -0,0 +1,24 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use xcm::v2::prelude::*; + +#[test] +fn slice_syntax_in_v2_works() { + let old_junctions = Junctions::X2(Parachain(1), PalletInstance(1)); + let new_junctions = Junctions::from([Parachain(1), PalletInstance(1)]); + assert_eq!(old_junctions, new_junctions); +} diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs index ddad0b5303be..f0cbe985331e 100644 --- a/polkadot/xcm/src/lib.rs +++ b/polkadot/xcm/src/lib.rs @@ -30,13 +30,14 @@ use scale_info::TypeInfo; pub mod v2; pub mod v3; +pub mod v4; pub mod lts { - pub use super::v3::*; + pub use super::v4::*; } pub mod latest { - pub use super::v3::*; + pub use super::v4::*; } mod double_encoded; @@ -79,6 +80,8 @@ macro_rules! versioned_type { ($(#[$attr:meta])* pub enum $n:ident { $(#[$index3:meta])+ V3($v3:ty), + $(#[$index4:meta])+ + V4($v4:ty), }) => { #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative( @@ -94,6 +97,8 @@ macro_rules! versioned_type { pub enum $n { $(#[$index3])* V3($v3), + $(#[$index4])* + V4($v4), } impl $n { pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { @@ -104,6 +109,15 @@ macro_rules! versioned_type { fn try_as(&self) -> Result<&$v3, ()> { match &self { Self::V3(ref x) => Ok(x), + _ => Err(()), + } + } + } + impl TryAs<$v4> for $n { + fn try_as(&self) -> Result<&$v4, ()> { + match &self { + Self::V4(ref x) => Ok(x), + _ => Err(()), } } } @@ -111,21 +125,38 @@ macro_rules! versioned_type { fn into_version(self, n: Version) -> Result { Ok(match n { 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } } - impl> From for $n { - fn from(x: T) -> Self { + impl From<$v3> for $n { + fn from(x: $v3) -> Self { $n::V3(x.into()) } } + impl From<$v4> for $n { + fn from(x: $v4) -> Self { + $n::V4(x.into()) + } + } impl TryFrom<$n> for $v3 { type Error = (); fn try_from(x: $n) -> Result { use $n::*; match x { V3(x) => Ok(x), + V4(x) => x.try_into(), + } + } + } + impl TryFrom<$n> for $v4 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V3(x) => x.try_into().map_err(|_| ()), + V4(x) => Ok(x), } } } @@ -141,6 +172,8 @@ macro_rules! versioned_type { V2($v2:ty), $(#[$index3:meta])+ V3($v3:ty), + $(#[$index4:meta])+ + V4($v4:ty), }) => { #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative( @@ -158,6 +191,8 @@ macro_rules! versioned_type { V2($v2), $(#[$index3])* V3($v3), + $(#[$index4])* + V4($v4), } impl $n { pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { @@ -180,11 +215,20 @@ macro_rules! versioned_type { } } } + impl TryAs<$v4> for $n { + fn try_as(&self) -> Result<&$v4, ()> { + match &self { + Self::V4(ref x) => Ok(x), + _ => Err(()), + } + } + } impl IntoVersion for $n { fn into_version(self, n: Version) -> Result { Ok(match n { 1 | 2 => Self::V2(self.try_into()?), 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } @@ -194,9 +238,9 @@ macro_rules! versioned_type { $n::V2(x) } } - impl> From for $n { + impl> From for $n { fn from(x: T) -> Self { - $n::V3(x.into()) + $n::V4(x.into()) } } impl TryFrom<$n> for $v2 { @@ -206,6 +250,10 @@ macro_rules! versioned_type { match x { V2(x) => Ok(x), V3(x) => x.try_into(), + V4(x) => { + let v3: $v3 = x.try_into().map_err(|_| ())?; + v3.try_into() + }, } } } @@ -216,6 +264,21 @@ macro_rules! versioned_type { match x { V2(x) => x.try_into(), V3(x) => Ok(x), + V4(x) => x.try_into().map_err(|_| ()), + } + } + } + impl TryFrom<$n> for $v4 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V2(x) => { + let v3: $v3 = x.try_into().map_err(|_| ())?; + v3.try_into().map_err(|_| ()) + }, + V3(x) => x.try_into().map_err(|_| ()), + V4(x) => Ok(x), } } } @@ -228,10 +291,12 @@ macro_rules! versioned_type { } versioned_type! { - /// A single version's `Response` value, together with its version code. + /// A single version's `AssetId` value, together with its version code. pub enum VersionedAssetId { #[codec(index = 3)] V3(v3::AssetId), + #[codec(index = 4)] + V4(v4::AssetId), } } @@ -242,6 +307,8 @@ versioned_type! { V2(v2::Response), #[codec(index = 3)] V3(v3::Response), + #[codec(index = 4)] + V4(v4::Response), } } @@ -252,6 +319,8 @@ versioned_type! { V2(v2::NetworkId), #[codec(index = 3)] V3(v3::NetworkId), + #[codec(index = 4)] + V4(v4::NetworkId), } } @@ -262,50 +331,72 @@ versioned_type! { V2(v2::Junction), #[codec(index = 3)] V3(v3::Junction), + #[codec(index = 4)] + V4(v4::Junction), } } versioned_type! { - /// A single `MultiLocation` value, together with its version code. + /// A single `Location` value, together with its version code. #[derive(Ord, PartialOrd)] - pub enum VersionedMultiLocation { + pub enum VersionedLocation { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiLocation), #[codec(index = 3)] V3(v3::MultiLocation), + #[codec(index = 4)] + V4(v4::Location), } } +#[deprecated(note = "Use `VersionedLocation` instead")] +pub type VersionedMultiLocation = VersionedLocation; + versioned_type! { - /// A single `InteriorMultiLocation` value, together with its version code. - pub enum VersionedInteriorMultiLocation { - #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorMultiLocation is introduced in v3 + /// A single `InteriorLocation` value, together with its version code. + pub enum VersionedInteriorLocation { + #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorLocation is introduced in v3 V2(v2::InteriorMultiLocation), #[codec(index = 3)] V3(v3::InteriorMultiLocation), + #[codec(index = 4)] + V4(v4::InteriorLocation), } } +#[deprecated(note = "Use `VersionedInteriorLocation` instead")] +pub type VersionedInteriorMultiLocation = VersionedInteriorLocation; + versioned_type! { - /// A single `MultiAsset` value, together with its version code. - pub enum VersionedMultiAsset { + /// A single `Asset` value, together with its version code. + pub enum VersionedAsset { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiAsset), #[codec(index = 3)] V3(v3::MultiAsset), + #[codec(index = 4)] + V4(v4::Asset), } } +#[deprecated(note = "Use `VersionedAsset` instead")] +pub type VersionedMultiAsset = VersionedAsset; + versioned_type! { /// A single `MultiAssets` value, together with its version code. - pub enum VersionedMultiAssets { + pub enum VersionedAssets { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiAssets), #[codec(index = 3)] V3(v3::MultiAssets), + #[codec(index = 4)] + V4(v4::Assets), } } +#[deprecated(note = "Use `VersionedAssets` instead")] +pub type VersionedMultiAssets = VersionedAssets; + /// A single XCM message, together with its version code. #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] @@ -318,6 +409,8 @@ pub enum VersionedXcm { V2(v2::Xcm), #[codec(index = 3)] V3(v3::Xcm), + #[codec(index = 4)] + V4(v4::Xcm), } impl IntoVersion for VersionedXcm { @@ -325,6 +418,7 @@ impl IntoVersion for VersionedXcm { Ok(match n { 2 => Self::V2(self.try_into()?), 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } @@ -342,6 +436,12 @@ impl From> for VersionedXcm { } } +impl From> for VersionedXcm { + fn from(x: v4::Xcm) -> Self { + VersionedXcm::V4(x) + } +} + impl TryFrom> for v2::Xcm { type Error = (); fn try_from(x: VersionedXcm) -> Result { @@ -349,6 +449,10 @@ impl TryFrom> for v2::Xcm { match x { V2(x) => Ok(x), V3(x) => x.try_into(), + V4(x) => { + let v3: v3::Xcm = x.try_into()?; + v3.try_into() + }, } } } @@ -360,15 +464,31 @@ impl TryFrom> for v3::Xcm { match x { V2(x) => x.try_into(), V3(x) => Ok(x), + V4(x) => x.try_into(), + } + } +} + +impl TryFrom> for v4::Xcm { + type Error = (); + fn try_from(x: VersionedXcm) -> Result { + use VersionedXcm::*; + match x { + V2(x) => { + let v3: v3::Xcm = x.try_into()?; + v3.try_into() + }, + V3(x) => x.try_into(), + V4(x) => Ok(x), } } } -/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will +/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `Location` which will /// interpret it. pub trait WrapVersion { fn wrap_version( - dest: &latest::MultiLocation, + dest: &latest::Location, xcm: impl Into>, ) -> Result, ()>; } @@ -376,14 +496,14 @@ pub trait WrapVersion { /// Check and return the `Version` that should be used for the `Xcm` datum for the destination /// `MultiLocation`, which will interpret it. pub trait GetVersion { - fn get_version_for(dest: &latest::MultiLocation) -> Option; + fn get_version_for(dest: &latest::Location) -> Option; } /// `()` implementation does nothing with the XCM, just sending with whatever version it was /// authored as. impl WrapVersion for () { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(xcm.into()) @@ -395,14 +515,14 @@ impl WrapVersion for () { pub struct AlwaysV2; impl WrapVersion for AlwaysV2 { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(VersionedXcm::::V2(xcm.into().try_into()?)) } } impl GetVersion for AlwaysV2 { - fn get_version_for(_dest: &latest::MultiLocation) -> Option { + fn get_version_for(_dest: &latest::Location) -> Option { Some(v2::VERSION) } } @@ -412,31 +532,48 @@ impl GetVersion for AlwaysV2 { pub struct AlwaysV3; impl WrapVersion for AlwaysV3 { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(VersionedXcm::::V3(xcm.into().try_into()?)) } } impl GetVersion for AlwaysV3 { - fn get_version_for(_dest: &latest::MultiLocation) -> Option { + fn get_version_for(_dest: &latest::Location) -> Option { Some(v3::VERSION) } } +/// `WrapVersion` implementation which attempts to always convert the XCM to version 3 before +/// wrapping it. +pub struct AlwaysV4; +impl WrapVersion for AlwaysV4 { + fn wrap_version( + _: &latest::Location, + xcm: impl Into>, + ) -> Result, ()> { + Ok(VersionedXcm::::V4(xcm.into().try_into()?)) + } +} +impl GetVersion for AlwaysV4 { + fn get_version_for(_dest: &latest::Location) -> Option { + Some(v4::VERSION) + } +} + /// `WrapVersion` implementation which attempts to always convert the XCM to the latest version /// before wrapping it. -pub type AlwaysLatest = AlwaysV3; +pub type AlwaysLatest = AlwaysV4; /// `WrapVersion` implementation which attempts to always convert the XCM to the most recent Long- /// Term-Support version before wrapping it. -pub type AlwaysLts = AlwaysV3; +pub type AlwaysLts = AlwaysV4; pub mod prelude { pub use super::{ - latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, GetVersion, IntoVersion, - Unsupported, Version as XcmVersion, VersionedAssetId, VersionedInteriorMultiLocation, - VersionedMultiAsset, VersionedMultiAssets, VersionedMultiLocation, VersionedResponse, + latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, AlwaysV4, GetVersion, + IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, VersionedAssetId, + VersionedAssets, VersionedInteriorLocation, VersionedLocation, VersionedResponse, VersionedXcm, WrapVersion, }; } @@ -454,13 +591,19 @@ pub mod opaque { // Then override with the opaque types in v3 pub use crate::v3::opaque::{Instruction, Xcm}; } + pub mod v4 { + // Everything from v4 + pub use crate::v4::*; + // Then override with the opaque types in v4 + pub use crate::v4::opaque::{Instruction, Xcm}; + } pub mod latest { - pub use super::v3::*; + pub use super::v4::*; } pub mod lts { - pub use super::v3::*; + pub use super::v4::*; } /// The basic `VersionedXcm` type which just uses the `Vec` as an encoded call. @@ -470,5 +613,56 @@ pub mod opaque { #[test] fn conversion_works() { use latest::prelude::*; - let _: VersionedMultiAssets = (Here, 1u128).into(); + let assets: Assets = (Here, 1u128).into(); + let _: VersionedAssets = assets.into(); +} + +#[test] +fn size_limits() { + extern crate std; + + let mut test_failed = false; + macro_rules! check_sizes { + ($(($kind:ty, $expected:expr),)+) => { + $({ + let s = core::mem::size_of::<$kind>(); + // Since the types often affect the size of other types in which they're included + // it is more convenient to check multiple types at the same time and only fail + // the test at the end. For debugging it's also useful to print out all of the sizes, + // even if they're within the expected range. + if s > $expected { + test_failed = true; + std::eprintln!( + "assertion failed: size of '{}' is {} (which is more than the expected {})", + stringify!($kind), + s, + $expected + ); + } else { + std::println!( + "type '{}' is of size {} which is within the expected {}", + stringify!($kind), + s, + $expected + ); + } + })+ + } + } + + check_sizes! { + (crate::latest::Instruction<()>, 112), + (crate::latest::Asset, 80), + (crate::latest::Location, 24), + (crate::latest::AssetId, 40), + (crate::latest::Junctions, 16), + (crate::latest::Junction, 88), + (crate::latest::Response, 40), + (crate::latest::AssetInstance, 40), + (crate::latest::NetworkId, 48), + (crate::latest::BodyId, 32), + (crate::latest::Assets, 24), + (crate::latest::BodyPart, 12), + } + assert!(!test_failed); } diff --git a/polkadot/xcm/src/tests.rs b/polkadot/xcm/src/tests.rs index a3a60f6477c7..1aabbcef281d 100644 --- a/polkadot/xcm/src/tests.rs +++ b/polkadot/xcm/src/tests.rs @@ -59,79 +59,79 @@ fn encode_decode_versioned_response_v3() { #[test] fn encode_decode_versioned_multi_location_v2() { - let location = VersionedMultiLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); + let location = VersionedLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("010000"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); // this is introduced in v1 - let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_multi_location_v3() { - let location = VersionedMultiLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); + let location = VersionedLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("030000"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_interior_multi_location_v2() { - let location = VersionedInteriorMultiLocation::V2(v2::InteriorMultiLocation::Here); + let location = VersionedInteriorLocation::V2(v2::InteriorMultiLocation::Here); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("0200"), "encode format changed"); assert_eq!(encoded[0], 2, "bad version number"); - let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedInteriorLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_interior_multi_location_v3() { - let location = VersionedInteriorMultiLocation::V3(v3::InteriorMultiLocation::Here); + let location = VersionedInteriorLocation::V3(v3::InteriorMultiLocation::Here); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("0300"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedInteriorLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_multi_asset_v2() { - let asset = VersionedMultiAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); + let asset = VersionedAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); let encoded = asset.encode(); assert_eq!(encoded, hex_literal::hex!("010000000004"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); - let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAsset::decode(&mut &encoded[..]).unwrap(); assert_eq!(asset, decoded); } #[test] fn encode_decode_versioned_multi_asset_v3() { - let asset = VersionedMultiAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); + let asset = VersionedAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); let encoded = asset.encode(); assert_eq!(encoded, hex_literal::hex!("030000000004"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAsset::decode(&mut &encoded[..]).unwrap(); assert_eq!(asset, decoded); } #[test] fn encode_decode_versioned_multi_assets_v2() { - let assets = VersionedMultiAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( + let assets = VersionedAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( (0, v2::Junctions::Here), 1, ))])); @@ -140,13 +140,13 @@ fn encode_decode_versioned_multi_assets_v2() { assert_eq!(encoded, hex_literal::hex!("01040000000004"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); - let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAssets::decode(&mut &encoded[..]).unwrap(); assert_eq!(assets, decoded); } #[test] fn encode_decode_versioned_multi_assets_v3() { - let assets = VersionedMultiAssets::V3(v3::MultiAssets::from(vec![ + let assets = VersionedAssets::V3(v3::MultiAssets::from(vec![ (v3::MultiAsset::from((v3::MultiLocation::default(), 1))), ])); let encoded = assets.encode(); @@ -154,7 +154,7 @@ fn encode_decode_versioned_multi_assets_v3() { assert_eq!(encoded, hex_literal::hex!("03040000000004"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAssets::decode(&mut &encoded[..]).unwrap(); assert_eq!(assets, decoded); } @@ -187,6 +187,8 @@ fn encode_decode_versioned_xcm_v3() { #[test] fn ensure_type_info_is_correct() { let type_info = VersionedXcm::<()>::type_info(); - assert_eq!(type_info.path.segments, vec!["xcm", "VersionedXcm"]); + + let type_info = VersionedAssetId::type_info(); + assert_eq!(type_info.path.segments, vec!["xcm", "VersionedAssetId"]); } diff --git a/polkadot/xcm/src/v2/multilocation.rs b/polkadot/xcm/src/v2/multilocation.rs index 81b67eee9744..60aa1f6ceadf 100644 --- a/polkadot/xcm/src/v2/multilocation.rs +++ b/polkadot/xcm/src/v2/multilocation.rs @@ -75,8 +75,8 @@ impl MultiLocation { MultiLocation { parents, interior: junctions } } - /// Consume `self` and return the equivalent `VersionedMultiLocation` value. - pub fn versioned(self) -> crate::VersionedMultiLocation { + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub fn versioned(self) -> crate::VersionedLocation { self.into() } @@ -240,9 +240,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)); + /// let mut m = MultiLocation::new(1, [PalletInstance(3), OnlyChild].into()); /// assert_eq!( - /// m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3)))), + /// m.match_and_split(&MultiLocation::new(1, [PalletInstance(3)].into())), /// Some(&OnlyChild), /// ); /// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here)), None); @@ -260,10 +260,10 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild)); - /// assert!(m.starts_with(&MultiLocation::new(1, X1(PalletInstance(3))))); - /// assert!(!m.starts_with(&MultiLocation::new(1, X1(GeneralIndex(99))))); - /// assert!(!m.starts_with(&MultiLocation::new(0, X1(PalletInstance(3))))); + /// let m = MultiLocation::new(1, [PalletInstance(3), OnlyChild, OnlyChild].into()); + /// assert!(m.starts_with(&MultiLocation::new(1, [PalletInstance(3)].into()))); + /// assert!(!m.starts_with(&MultiLocation::new(1, [GeneralIndex(99)].into()))); + /// assert!(!m.starts_with(&MultiLocation::new(0, [PalletInstance(3)].into()))); /// ``` pub fn starts_with(&self, prefix: &MultiLocation) -> bool { if self.parents != prefix.parents { @@ -279,9 +279,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(1, X1(Parachain(21))); - /// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(())); - /// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3)))); + /// let mut m = MultiLocation::new(1, [Parachain(21)].into()); + /// assert_eq!(m.append_with([PalletInstance(3)].into()), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, [Parachain(21), PalletInstance(3)].into())); /// ``` pub fn append_with(&mut self, suffix: Junctions) -> Result<(), Junctions> { if self.interior.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { @@ -300,9 +300,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(2, X1(PalletInstance(3))); - /// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild))), Ok(())); - /// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3)))); + /// let mut m = MultiLocation::new(2, [PalletInstance(3)].into()); + /// assert_eq!(m.prepend_with(MultiLocation::new(1, [Parachain(21), OnlyChild].into())), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, [PalletInstance(3)].into())); /// ``` pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> { // prefix self (suffix) @@ -455,6 +455,7 @@ impl> From> for MultiLocation { } xcm_procedural::impl_conversion_functions_for_multilocation_v2!(); +xcm_procedural::impl_conversion_functions_for_junctions_v2!(); /// Maximum number of `Junction`s that a `Junctions` can contain. const MAX_JUNCTIONS: usize = 8; diff --git a/polkadot/xcm/src/v2/traits.rs b/polkadot/xcm/src/v2/traits.rs index 6453f91a1f1e..9cfb9b051ab2 100644 --- a/polkadot/xcm/src/v2/traits.rs +++ b/polkadot/xcm/src/v2/traits.rs @@ -292,11 +292,12 @@ pub type SendResult = result::Result<(), SendError>; /// } /// } /// -/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing. +/// /// A sender that accepts a message that has two junctions, otherwise stops the routing. /// struct Sender2; /// impl SendXcm for Sender2 { /// fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { -/// if let MultiLocation { parents: 0, interior: X2(j1, j2) } = destination.into() { +/// let destination = destination.into(); +/// if destination.parents == 0 && destination.interior.len() == 2 { /// Ok(()) /// } else { /// Err(SendError::Unroutable) diff --git a/polkadot/xcm/src/v3/junction.rs b/polkadot/xcm/src/v3/junction.rs index 6ae339db2ae6..e9e51941b1ac 100644 --- a/polkadot/xcm/src/v3/junction.rs +++ b/polkadot/xcm/src/v3/junction.rs @@ -22,7 +22,8 @@ use crate::{ BodyId as OldBodyId, BodyPart as OldBodyPart, Junction as OldJunction, NetworkId as OldNetworkId, }, - VersionedMultiLocation, + v4::{Junction as NewJunction, NetworkId as NewNetworkId}, + VersionedLocation, }; use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; use core::convert::{TryFrom, TryInto}; @@ -104,6 +105,31 @@ impl TryFrom for NetworkId { } } +impl From for Option { + fn from(new: NewNetworkId) -> Self { + Some(NetworkId::from(new)) + } +} + +impl From for NetworkId { + fn from(new: NewNetworkId) -> Self { + use NewNetworkId::*; + match new { + ByGenesis(hash) => Self::ByGenesis(hash), + ByFork { block_number, block_hash } => Self::ByFork { block_number, block_hash }, + Polkadot => Self::Polkadot, + Kusama => Self::Kusama, + Westend => Self::Westend, + Rococo => Self::Rococo, + Wococo => Self::Wococo, + Ethereum { chain_id } => Self::Ethereum { chain_id }, + BitcoinCore => Self::BitcoinCore, + BitcoinCash => Self::BitcoinCash, + PolkadotBulletin => Self::PolkadotBulletin, + } + } +} + /// An identifier of a pluralistic body. #[derive( Copy, @@ -414,6 +440,29 @@ impl TryFrom for Junction { } } +impl TryFrom for Junction { + type Error = (); + + fn try_from(value: NewJunction) -> Result { + use NewJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network: maybe_network, id } => + Self::AccountId32 { network: maybe_network.map(|network| network.into()), id }, + AccountIndex64 { network: maybe_network, index } => + Self::AccountIndex64 { network: maybe_network.map(|network| network.into()), index }, + AccountKey20 { network: maybe_network, key } => + Self::AccountKey20 { network: maybe_network.map(|network| network.into()), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey { length, data }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id, part }, + GlobalConsensus(network) => Self::GlobalConsensus(network.into()), + }) + } +} + impl Junction { /// Convert `self` into a `MultiLocation` containing 0 parents. /// @@ -430,10 +479,10 @@ impl Junction { MultiLocation { parents: n, interior: Junctions::X1(self) } } - /// Convert `self` into a `VersionedMultiLocation` containing 0 parents. + /// Convert `self` into a `VersionedLocation` containing 0 parents. /// /// Similar to `Into::into`, except that this method can be used in a const evaluation context. - pub const fn into_versioned(self) -> VersionedMultiLocation { + pub const fn into_versioned(self) -> VersionedLocation { self.into_location().into_versioned() } diff --git a/polkadot/xcm/src/v3/junctions.rs b/polkadot/xcm/src/v3/junctions.rs index 88da20cb1a11..9748e81fa55f 100644 --- a/polkadot/xcm/src/v3/junctions.rs +++ b/polkadot/xcm/src/v3/junctions.rs @@ -67,6 +67,27 @@ pub enum Junctions { X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction), } +macro_rules! impl_junction { + ($count:expr, $variant:ident, ($($index:literal),+)) => { + /// Additional helper for building junctions + /// Useful for converting to future XCM versions + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant($(junctions[$index]),*) + } + } + }; +} + +impl_junction!(1, X1, (0)); +impl_junction!(2, X2, (0, 1)); +impl_junction!(3, X3, (0, 1, 2)); +impl_junction!(4, X4, (0, 1, 2, 3)); +impl_junction!(5, X5, (0, 1, 2, 3, 4)); +impl_junction!(6, X6, (0, 1, 2, 3, 4, 5)); +impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6)); +impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7)); + pub struct JunctionsIterator(Junctions); impl Iterator for JunctionsIterator { type Item = Junction; diff --git a/polkadot/xcm/src/v3/mod.rs b/polkadot/xcm/src/v3/mod.rs index 50b7a539122d..1172cbf43e6f 100644 --- a/polkadot/xcm/src/v3/mod.rs +++ b/polkadot/xcm/src/v3/mod.rs @@ -16,9 +16,15 @@ //! Version 3 of the Cross-Consensus Message format data structures. -use super::v2::{ - Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, - Xcm as OldXcm, +use super::{ + v2::{ + Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, + Xcm as OldXcm, + }, + v4::{ + Instruction as NewInstruction, PalletInfo as NewPalletInfo, + QueryResponseInfo as NewQueryResponseInfo, Response as NewResponse, Xcm as NewXcm, + }, }; use crate::DoubleEncoded; use alloc::{vec, vec::Vec}; @@ -48,7 +54,7 @@ pub use multiasset::{ WildFungibility, WildMultiAsset, MAX_ITEMS_IN_MULTIASSETS, }; pub use multilocation::{ - Ancestor, AncestorThen, InteriorMultiLocation, MultiLocation, Parent, ParentThen, + Ancestor, AncestorThen, InteriorMultiLocation, Location, MultiLocation, Parent, ParentThen, }; pub use traits::{ send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Result, SendError, @@ -209,7 +215,7 @@ pub mod prelude { InteriorMultiLocation, Junction::{self, *}, Junctions::{self, *}, - MaybeErrorCode, MultiAsset, + Location, MaybeErrorCode, MultiAsset, MultiAssetFilter::{self, *}, MultiAssets, MultiLocation, NetworkId::{self, *}, @@ -275,6 +281,22 @@ impl PalletInfo { } } +impl TryInto for PalletInfo { + type Error = (); + + fn try_into(self) -> result::Result { + NewPalletInfo::new( + self.index, + self.name.into_inner(), + self.module_name.into_inner(), + self.major, + self.minor, + self.patch, + ) + .map_err(|_| ()) + } +} + #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[scale_info(replace_segment("staging_xcm", "xcm"))] #[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] @@ -324,6 +346,32 @@ impl Default for Response { } } +impl TryFrom for Response { + type Error = (); + + fn try_from(new: NewResponse) -> result::Result { + use NewResponse::*; + Ok(match new { + Null => Self::Null, + Assets(assets) => Self::Assets(assets.try_into()?), + ExecutionResult(result) => + Self::ExecutionResult(result.map(|(num, old_error)| (num, old_error.into()))), + Version(version) => Self::Version(version), + PalletsInfo(pallet_info) => { + let inner = pallet_info + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + Self::PalletsInfo( + BoundedVec::::try_from(inner).map_err(|_| ())?, + ) + }, + DispatchResult(maybe_error) => + Self::DispatchResult(maybe_error.try_into().map_err(|_| ())?), + }) + } +} + /// Information regarding the composition of a query response. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -338,6 +386,18 @@ pub struct QueryResponseInfo { pub max_weight: Weight, } +impl TryFrom for QueryResponseInfo { + type Error = (); + + fn try_from(new: NewQueryResponseInfo) -> result::Result { + Ok(Self { + destination: new.destination.try_into()?, + query_id: new.query_id, + max_weight: new.max_weight, + }) + } +} + /// An optional weight limit. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -367,13 +427,12 @@ impl From for Option { } } -impl TryFrom for WeightLimit { - type Error = (); - fn try_from(x: OldWeightLimit) -> result::Result { +impl From for WeightLimit { + fn from(x: OldWeightLimit) -> Self { use OldWeightLimit::*; match x { - Limited(w) => Ok(Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE))), - Unlimited => Ok(Self::Unlimited), + Limited(w) => Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE)), + Unlimited => Self::Unlimited, } } } @@ -1263,6 +1322,155 @@ impl TryFrom> for Xcm { } } +// Convert from a v4 XCM to a v3 XCM. +impl TryFrom> for Xcm { + type Error = (); + fn try_from(new_xcm: NewXcm) -> result::Result { + Ok(Xcm(new_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v4 instruction to a v3 instruction. +impl TryFrom> for Instruction { + type Error = (); + fn try_from(new_instruction: NewInstruction) -> result::Result { + use NewInstruction::*; + Ok(match new_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, querier: Some(querier) } => + Self::QueryResponse { + query_id, + querier: querier.try_into()?, + response: response.try_into()?, + max_weight, + }, + QueryResponse { query_id, response, max_weight, querier: None } => + Self::QueryResponse { + query_id, + querier: None, + response: response.try_into()?, + max_weight, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Self::Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => Self::ReportError(QueryResponseInfo { + query_id: response_info.query_id, + destination: response_info.destination.try_into().map_err(|_| ())?, + max_weight: response_info.max_weight, + }), + DepositAsset { assets, beneficiary } => { + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, dest, xcm } + }, + ExchangeAsset { give, want, maximal } => { + let give = give.try_into()?; + let want = want.try_into()?; + Self::ExchangeAsset { give, want, maximal } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => { + let response_info = QueryResponseInfo { + destination: response_info.destination.try_into().map_err(|_| ())?, + query_id: response_info.query_id, + max_weight: response_info.max_weight, + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.into(); + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => + Self::SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => Self::UnsubscribeVersion, + BurnAsset(assets) => Self::BurnAsset(assets.try_into()?), + ExpectAsset(assets) => Self::ExpectAsset(assets.try_into()?), + ExpectOrigin(maybe_origin) => + Self::ExpectOrigin(maybe_origin.map(|origin| origin.try_into()).transpose()?), + ExpectError(maybe_error) => Self::ExpectError(maybe_error), + ExpectTransactStatus(maybe_error_code) => Self::ExpectTransactStatus(maybe_error_code), + QueryPallet { module_name, response_info } => + Self::QueryPallet { module_name, response_info: response_info.try_into()? }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + Self::ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => + Self::ReportTransactStatus(response_info.try_into()?), + ClearTransactStatus => Self::ClearTransactStatus, + UniversalOrigin(junction) => Self::UniversalOrigin(junction.try_into()?), + ExportMessage { network, destination, xcm } => Self::ExportMessage { + network: network.into(), + destination: destination.try_into()?, + xcm: xcm.try_into()?, + }, + LockAsset { asset, unlocker } => + Self::LockAsset { asset: asset.try_into()?, unlocker: unlocker.try_into()? }, + UnlockAsset { asset, target } => + Self::UnlockAsset { asset: asset.try_into()?, target: target.try_into()? }, + NoteUnlockable { asset, owner } => + Self::NoteUnlockable { asset: asset.try_into()?, owner: owner.try_into()? }, + RequestUnlock { asset, locker } => + Self::RequestUnlock { asset: asset.try_into()?, locker: locker.try_into()? }, + SetFeesMode { jit_withdraw } => Self::SetFeesMode { jit_withdraw }, + SetTopic(topic) => Self::SetTopic(topic), + ClearTopic => Self::ClearTopic, + AliasOrigin(location) => Self::AliasOrigin(location.try_into()?), + UnpaidExecution { weight_limit, check_origin } => Self::UnpaidExecution { + weight_limit, + check_origin: check_origin.map(|origin| origin.try_into()).transpose()?, + }, + }) + } +} + /// Default value for the proof size weight component when converting from V2. Set at 64 KB. /// NOTE: Make sure this is removed after we properly account for PoV weights. const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; @@ -1343,10 +1551,8 @@ impl TryFrom> for Instruction { }; Self::ReportHolding { response_info, assets: assets.try_into()? } }, - BuyExecution { fees, weight_limit } => Self::BuyExecution { - fees: fees.try_into()?, - weight_limit: weight_limit.try_into()?, - }, + BuyExecution { fees, weight_limit } => + Self::BuyExecution { fees: fees.try_into()?, weight_limit: weight_limit.into() }, ClearOrigin => Self::ClearOrigin, DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), RefundSurplus => Self::RefundSurplus, diff --git a/polkadot/xcm/src/v3/multiasset.rs b/polkadot/xcm/src/v3/multiasset.rs index c8801f5a461d..557ffa568a4c 100644 --- a/polkadot/xcm/src/v3/multiasset.rs +++ b/polkadot/xcm/src/v3/multiasset.rs @@ -27,11 +27,18 @@ //! filtering an XCM holding account. use super::{InteriorMultiLocation, MultiLocation}; -use crate::v2::{ - AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, - MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, - MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, - WildMultiAsset as OldWildMultiAsset, +use crate::{ + v2::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, + MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, + WildMultiAsset as OldWildMultiAsset, + }, + v4::{ + Asset as NewMultiAsset, AssetFilter as NewMultiAssetFilter, AssetId as NewAssetId, + AssetInstance as NewAssetInstance, Assets as NewMultiAssets, Fungibility as NewFungibility, + WildAsset as NewWildMultiAsset, WildFungibility as NewWildFungibility, + }, }; use alloc::{vec, vec::Vec}; use bounded_collections::{BoundedVec, ConstU32}; @@ -86,6 +93,21 @@ impl TryFrom for AssetInstance { } } +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: NewAssetInstance) -> Result { + use NewAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + impl From<()> for AssetInstance { fn from(_: ()) -> Self { Self::Undefined @@ -310,6 +332,17 @@ impl TryFrom for Fungibility { } } +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: NewFungibility) -> Result { + use NewFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + /// Classification of whether an asset is fungible or not. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, @@ -335,6 +368,17 @@ impl TryFrom for WildFungibility { } } +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: NewWildFungibility) -> Result { + use NewWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + /// Classification of an asset being concrete or abstract. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, @@ -378,6 +422,13 @@ impl TryFrom for AssetId { } } +impl TryFrom for AssetId { + type Error = (); + fn try_from(new: NewAssetId) -> Result { + Ok(Self::Concrete(new.0.try_into()?)) + } +} + impl AssetId { /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { @@ -506,6 +557,13 @@ impl TryFrom for MultiAsset { } } +impl TryFrom for MultiAsset { + type Error = (); + fn try_from(new: NewMultiAsset) -> Result { + Ok(Self { id: new.id.try_into()?, fun: new.fun.try_into()? }) + } +} + /// A `Vec` of `MultiAsset`s. /// /// There are a number of invariants which the construction and mutation functions must ensure are @@ -549,6 +607,18 @@ impl TryFrom for MultiAssets { } } +impl TryFrom for MultiAssets { + type Error = (); + fn try_from(new: NewMultiAssets) -> Result { + let v = new + .into_inner() + .into_iter() + .map(MultiAsset::try_from) + .collect::, ()>>()?; + Ok(MultiAssets(v)) + } +} + impl From> for MultiAssets { fn from(mut assets: Vec) -> Self { let mut res = Vec::with_capacity(assets.len()); @@ -747,6 +817,20 @@ impl TryFrom for WildMultiAsset { } } +impl TryFrom for WildMultiAsset { + type Error = (); + fn try_from(new: NewWildMultiAsset) -> Result { + use NewWildMultiAsset::*; + Ok(match new { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + AllOfCounted { id, fun, count } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + All => Self::All, + AllCounted(count) => Self::AllCounted(count), + }) + } +} + impl TryFrom<(OldWildMultiAsset, u32)> for WildMultiAsset { type Error = (); fn try_from(old: (OldWildMultiAsset, u32)) -> Result { @@ -917,6 +1001,17 @@ impl TryFrom for MultiAssetFilter { } } +impl TryFrom for MultiAssetFilter { + type Error = (); + fn try_from(new: NewMultiAssetFilter) -> Result { + use NewMultiAssetFilter::*; + Ok(match new { + Definite(x) => Self::Definite(x.try_into()?), + Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + impl TryFrom<(OldMultiAssetFilter, u32)> for MultiAssetFilter { type Error = (); fn try_from(old: (OldMultiAssetFilter, u32)) -> Result { diff --git a/polkadot/xcm/src/v3/multilocation.rs b/polkadot/xcm/src/v3/multilocation.rs index 9649b1b32073..c588b924ac70 100644 --- a/polkadot/xcm/src/v3/multilocation.rs +++ b/polkadot/xcm/src/v3/multilocation.rs @@ -17,7 +17,9 @@ //! XCM `MultiLocation` datatype. use super::{Junction, Junctions}; -use crate::{v2::MultiLocation as OldMultiLocation, VersionedMultiLocation}; +use crate::{ + v2::MultiLocation as OldMultiLocation, v4::Location as NewMultiLocation, VersionedLocation, +}; use core::{ convert::{TryFrom, TryInto}, result, @@ -74,6 +76,9 @@ pub struct MultiLocation { pub interior: Junctions, } +/// Type alias for a better transition to V4. +pub type Location = MultiLocation; + impl Default for MultiLocation { fn default() -> Self { Self { parents: 0, interior: Junctions::Here } @@ -91,9 +96,9 @@ impl MultiLocation { MultiLocation { parents, interior: interior.into() } } - /// Consume `self` and return the equivalent `VersionedMultiLocation` value. - pub const fn into_versioned(self) -> VersionedMultiLocation { - VersionedMultiLocation::V3(self) + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub const fn into_versioned(self) -> VersionedLocation { + VersionedLocation::V3(self) } /// Creates a new `MultiLocation` with 0 parents and a `Here` interior. @@ -469,6 +474,23 @@ impl TryFrom for MultiLocation { } } +impl TryFrom for Option { + type Error = (); + fn try_from(new: NewMultiLocation) -> result::Result { + Ok(Some(MultiLocation::try_from(new)?)) + } +} + +impl TryFrom for MultiLocation { + type Error = (); + fn try_from(new: NewMultiLocation) -> result::Result { + Ok(MultiLocation { + parents: new.parent_count(), + interior: new.interior().clone().try_into()?, + }) + } +} + /// A unit struct which can be converted into a `MultiLocation` of `parents` value 1. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct Parent; diff --git a/polkadot/xcm/src/v3/traits.rs b/polkadot/xcm/src/v3/traits.rs index 29bd40a6a2d8..9e9b983fdf85 100644 --- a/polkadot/xcm/src/v3/traits.rs +++ b/polkadot/xcm/src/v3/traits.rs @@ -216,52 +216,6 @@ impl From for Error { pub type Result = result::Result<(), Error>; -/* -TODO: XCMv4 -/// Outcome of an XCM execution. -#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] -pub enum Outcome { - /// Execution completed successfully; given weight was used. - Complete { used: Weight }, - /// Execution started, but did not complete successfully due to the given error; given weight - /// was used. - Incomplete { used: Weight, error: Error }, - /// Execution did not start due to the given error. - Error { error: Error }, -} - -impl Outcome { - pub fn ensure_complete(self) -> Result { - match self { - Outcome::Complete { .. } => Ok(()), - Outcome::Incomplete { error, .. } => Err(error), - Outcome::Error { error, .. } => Err(error), - } - } - pub fn ensure_execution(self) -> result::Result { - match self { - Outcome::Complete { used, .. } => Ok(used), - Outcome::Incomplete { used, .. } => Ok(used), - Outcome::Error { error, .. } => Err(error), - } - } - /// How much weight was used by the XCM execution attempt. - pub fn weight_used(&self) -> Weight { - match self { - Outcome::Complete { used, .. } => *used, - Outcome::Incomplete { used, .. } => *used, - Outcome::Error { .. } => Weight::zero(), - } - } -} - -impl From for Outcome { - fn from(error: Error) -> Self { - Self::Error { error, maybe_id: None } - } -} -*/ - /// Outcome of an XCM execution. #[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -337,8 +291,6 @@ pub trait ExecuteXcm { /// /// The weight limit is a basic hard-limit and the implementation may place further /// restrictions or requirements on weight and other aspects. - // TODO: XCMv4 - // #[deprecated = "Use `prepare_and_execute` instead"] fn execute_xcm( origin: impl Into, message: Xcm, @@ -361,8 +313,6 @@ pub trait ExecuteXcm { /// /// Some amount of `weight_credit` may be provided which, depending on the implementation, may /// allow execution without associated payment. - // TODO: XCMv4 - // #[deprecated = "Use `prepare_and_execute` instead"] fn execute_xcm_in_credit( origin: impl Into, message: Xcm, diff --git a/polkadot/xcm/src/v4/asset.rs b/polkadot/xcm/src/v4/asset.rs new file mode 100644 index 000000000000..8aa1cc61437c --- /dev/null +++ b/polkadot/xcm/src/v4/asset.rs @@ -0,0 +1,915 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Cross-Consensus Message format asset data structures. +//! +//! This encompasses four types for representing assets: +//! - `Asset`: A description of a single asset, either an instance of a non-fungible or some amount +//! of a fungible. +//! - `Assets`: A collection of `Asset`s. These are stored in a `Vec` and sorted with fungibles +//! first. +//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific +//! kind. +//! - `AssetFilter`: A combination of `Wild` and `Assets` designed for efficiently filtering an XCM +//! holding account. + +use super::{InteriorLocation, Location, Reanchorable}; +use crate::v3::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldAsset, MultiAssetFilter as OldAssetFilter, MultiAssets as OldAssets, + WildFungibility as OldWildFungibility, WildMultiAsset as OldWildAsset, +}; +use alloc::{vec, vec::Vec}; +use core::{ + cmp::Ordering, + convert::{TryFrom, TryInto}, +}; +use parity_scale_codec::{self as codec, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A general identifier for an instance of a non-fungible asset class. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetInstance { + /// Undefined - used if the non-fungible asset class has only one instance. + Undefined, + + /// A compact index. Technically this could be greater than `u128`, but this implementation + /// supports only values up to `2**128 - 1`. + Index(#[codec(compact)] u128), + + /// A 4-byte fixed-length datum. + Array4([u8; 4]), + + /// An 8-byte fixed-length datum. + Array8([u8; 8]), + + /// A 16-byte fixed-length datum. + Array16([u8; 16]), + + /// A 32-byte fixed-length datum. + Array32([u8; 32]), +} + +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: OldAssetInstance) -> Result { + use OldAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + +impl From<()> for AssetInstance { + fn from(_: ()) -> Self { + Self::Undefined + } +} + +impl From<[u8; 4]> for AssetInstance { + fn from(x: [u8; 4]) -> Self { + Self::Array4(x) + } +} + +impl From<[u8; 8]> for AssetInstance { + fn from(x: [u8; 8]) -> Self { + Self::Array8(x) + } +} + +impl From<[u8; 16]> for AssetInstance { + fn from(x: [u8; 16]) -> Self { + Self::Array16(x) + } +} + +impl From<[u8; 32]> for AssetInstance { + fn from(x: [u8; 32]) -> Self { + Self::Array32(x) + } +} + +impl From for AssetInstance { + fn from(x: u8) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u16) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u32) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u64) -> Self { + Self::Index(x as u128) + } +} + +impl TryFrom for () { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Undefined => Ok(()), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 4] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array4(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 8] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array8(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 16] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array16(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 32] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array32(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for u8 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u16 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u32 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u64 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u128 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => Ok(x), + _ => Err(()), + } + } +} + +/// Classification of whether an asset is fungible or not, along with a mandatory amount or +/// instance. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Fungibility { + /// A fungible asset; we record a number of units, as a `u128` in the inner item. + Fungible(#[codec(compact)] u128), + /// A non-fungible asset. We record the instance identifier in the inner item. Only one asset + /// of each instance identifier may ever be in existence at once. + NonFungible(AssetInstance), +} + +#[derive(Decode)] +enum UncheckedFungibility { + Fungible(#[codec(compact)] u128), + NonFungible(AssetInstance), +} + +impl Decode for Fungibility { + fn decode(input: &mut I) -> Result { + match UncheckedFungibility::decode(input)? { + UncheckedFungibility::Fungible(a) if a != 0 => Ok(Self::Fungible(a)), + UncheckedFungibility::NonFungible(i) => Ok(Self::NonFungible(i)), + UncheckedFungibility::Fungible(_) => + Err("Fungible asset of zero amount is not allowed".into()), + } + } +} + +impl Fungibility { + pub fn is_kind(&self, w: WildFungibility) -> bool { + use Fungibility::*; + use WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}; + matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible)) + } +} + +impl From for Fungibility { + fn from(amount: i32) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount as u128) + } +} + +impl From for Fungibility { + fn from(amount: u128) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount) + } +} + +impl> From for Fungibility { + fn from(instance: T) -> Fungibility { + Fungibility::NonFungible(instance.into()) + } +} + +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: OldFungibility) -> Result { + use OldFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + +/// Classification of whether an asset is fungible or not. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildFungibility { + /// The asset is fungible. + Fungible, + /// The asset is not fungible. + NonFungible, +} + +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: OldWildFungibility) -> Result { + use OldWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + +/// Location to identify an asset. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct AssetId(pub Location); + +impl> From for AssetId { + fn from(x: T) -> Self { + Self(x.into()) + } +} + +impl TryFrom for AssetId { + type Error = (); + fn try_from(old: OldAssetId) -> Result { + use OldAssetId::*; + Ok(match old { + Concrete(l) => Self(l.try_into()?), + Abstract(_) => return Err(()), + }) + } +} + +impl AssetId { + /// Prepend a `Location` to an asset id, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &Location) -> Result<(), ()> { + self.0.prepend_with(prepend.clone()).map_err(|_| ())?; + Ok(()) + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `Asset` value. + pub fn into_asset(self, fun: Fungibility) -> Asset { + Asset { fun, id: self } + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `WildAsset` wildcard (`AllOf`) value. + pub fn into_wild(self, fun: WildFungibility) -> WildAsset { + WildAsset::AllOf { fun, id: self } + } +} + +impl Reanchorable for AssetId { + type Error = (); + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.0.reanchor(target, context)?; + Ok(()) + } + + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(()), + } + } +} + +/// Either an amount of a single fungible asset, or a single well-identified non-fungible asset. +#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Asset { + /// The overall asset identity (aka *class*, in the case of a non-fungible). + pub id: AssetId, + /// The fungibility of the asset, which contains either the amount (in the case of a fungible + /// asset) or the *instance ID*, the secondary asset identifier. + pub fun: Fungibility, +} + +impl PartialOrd for Asset { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Asset { + fn cmp(&self, other: &Self) -> Ordering { + match (&self.fun, &other.fun) { + (Fungibility::Fungible(..), Fungibility::NonFungible(..)) => Ordering::Less, + (Fungibility::NonFungible(..), Fungibility::Fungible(..)) => Ordering::Greater, + _ => (&self.id, &self.fun).cmp(&(&other.id, &other.fun)), + } + } +} + +impl, B: Into> From<(A, B)> for Asset { + fn from((id, fun): (A, B)) -> Asset { + Asset { fun: fun.into(), id: id.into() } + } +} + +impl Asset { + pub fn is_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + pub fn is_non_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + /// Prepend a `Location` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &Location) -> Result<(), ()> { + self.id.prepend_with(prepend) + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + use Fungibility::*; + if self.id == inner.id { + match (&self.fun, &inner.fun) { + (Fungible(a), Fungible(i)) if a >= i => return true, + (NonFungible(a), NonFungible(i)) if a == i => return true, + _ => (), + } + } + false + } +} + +impl Reanchorable for Asset { + type Error = (); + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.id.reanchor(target, context) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + self.id.reanchor(target, context)?; + Ok(self) + } +} + +impl TryFrom for Asset { + type Error = (); + fn try_from(old: OldAsset) -> Result { + Ok(Self { id: old.id.try_into()?, fun: old.fun.try_into()? }) + } +} + +/// A `Vec` of `Asset`s. +/// +/// There are a number of invariants which the construction and mutation functions must ensure are +/// maintained: +/// - It may contain no items of duplicate asset class; +/// - All items must be ordered; +/// - The number of items should grow no larger than `MAX_ITEMS_IN_ASSETS`. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, Default)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Assets(Vec); + +/// Maximum number of items we expect in a single `Assets` value. Note this is not (yet) +/// enforced, and just serves to provide a sensible `max_encoded_len` for `Assets`. +pub const MAX_ITEMS_IN_ASSETS: usize = 20; + +impl MaxEncodedLen for Assets { + fn max_encoded_len() -> usize { + Asset::max_encoded_len() * MAX_ITEMS_IN_ASSETS + } +} + +impl Decode for Assets { + fn decode(input: &mut I) -> Result { + Self::from_sorted_and_deduplicated(Vec::::decode(input)?) + .map_err(|()| "Out of order".into()) + } +} + +impl TryFrom for Assets { + type Error = (); + fn try_from(old: OldAssets) -> Result { + let v = old + .into_inner() + .into_iter() + .map(Asset::try_from) + .collect::, ()>>()?; + Ok(Assets(v)) + } +} + +impl From> for Assets { + fn from(mut assets: Vec) -> Self { + let mut res = Vec::with_capacity(assets.len()); + if !assets.is_empty() { + assets.sort(); + let mut iter = assets.into_iter(); + if let Some(first) = iter.next() { + let last = iter.fold(first, |a, b| -> Asset { + match (a, b) { + ( + Asset { fun: Fungibility::Fungible(a_amount), id: a_id }, + Asset { fun: Fungibility::Fungible(b_amount), id: b_id }, + ) if a_id == b_id => Asset { + id: a_id, + fun: Fungibility::Fungible(a_amount.saturating_add(b_amount)), + }, + ( + Asset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + Asset { fun: Fungibility::NonFungible(b_instance), id: b_id }, + ) if a_id == b_id && a_instance == b_instance => + Asset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + (to_push, to_remember) => { + res.push(to_push); + to_remember + }, + } + }); + res.push(last); + } + } + Self(res) + } +} + +impl> From for Assets { + fn from(x: T) -> Self { + Self(vec![x.into()]) + } +} + +impl Assets { + /// A new (empty) value. + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. + /// If you can't guarantee that `r` is sorted and deduplicated, then use + /// `From::>::from` which is infallible. + pub fn from_sorted_and_deduplicated(r: Vec) -> Result { + if r.is_empty() { + return Ok(Self(Vec::new())) + } + r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&Asset, ()> { + if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) { + Ok(b) + } else { + Err(()) + } + })?; + Ok(Self(r)) + } + + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + #[cfg(test)] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped") + } + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + /// + /// In test mode, this checks anyway and panics on fail. + #[cfg(not(test))] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self(r) + } + + /// Add some asset onto the list, saturating. This is quite a laborious operation since it + /// maintains the ordering. + pub fn push(&mut self, a: Asset) { + for asset in self.0.iter_mut().filter(|x| x.id == a.id) { + match (&a.fun, &mut asset.fun) { + (Fungibility::Fungible(amount), Fungibility::Fungible(balance)) => { + *balance = balance.saturating_add(*amount); + return + }, + (Fungibility::NonFungible(inst1), Fungibility::NonFungible(inst2)) + if inst1 == inst2 => + return, + _ => (), + } + } + self.0.push(a); + self.0.sort(); + } + + /// Returns `true` if this definitely represents no asset. + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + self.0.iter().any(|i| i.contains(inner)) + } + + /// Consume `self` and return the inner vec. + #[deprecated = "Use `into_inner()` instead"] + pub fn drain(self) -> Vec { + self.0 + } + + /// Consume `self` and return the inner vec. + pub fn into_inner(self) -> Vec { + self.0 + } + + /// Return a reference to the inner vec. + pub fn inner(&self) -> &Vec { + &self.0 + } + + /// Return the number of distinct asset instances contained. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Prepend a `Location` to any concrete asset items, giving it a new root location. + pub fn prepend_with(&mut self, prefix: &Location) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix)) + } + + /// Return a reference to an item at a specific index or `None` if it doesn't exist. + pub fn get(&self, index: usize) -> Option<&Asset> { + self.0.get(index) + } +} + +impl Reanchorable for Assets { + type Error = (); + + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.reanchor(target, context))?; + self.0.sort(); + Ok(()) + } + + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(()), + } + } +} + +/// A wildcard representing a set of assets. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildAsset { + /// All assets in Holding. + All, + /// All assets in Holding of a given fungibility and ID. + AllOf { id: AssetId, fun: WildFungibility }, + /// All assets in Holding, up to `u32` individual assets (different instances of non-fungibles + /// are separate assets). + AllCounted(#[codec(compact)] u32), + /// All assets in Holding of a given fungibility and ID up to `count` individual assets + /// (different instances of non-fungibles are separate assets). + AllOfCounted { + id: AssetId, + fun: WildFungibility, + #[codec(compact)] + count: u32, + }, +} + +impl TryFrom for WildAsset { + type Error = (); + fn try_from(old: OldWildAsset) -> Result { + use OldWildAsset::*; + Ok(match old { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + All => Self::All, + AllOfCounted { id, fun, count } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + AllCounted(count) => Self::AllCounted(count), + }) + } +} + +impl WildAsset { + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + use WildAsset::*; + match self { + AllOfCounted { count: 0, .. } | AllCounted(0) => false, + AllOf { fun, id } | AllOfCounted { id, fun, .. } => + inner.fun.is_kind(*fun) && &inner.id == id, + All | AllCounted(_) => true, + } + } + + /// Returns true if the wild element of `self` matches `inner`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + #[deprecated = "Use `contains` instead"] + pub fn matches(&self, inner: &Asset) -> bool { + self.contains(inner) + } + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + pub fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + use WildAsset::*; + match self { + AllOf { ref mut id, .. } | AllOfCounted { ref mut id, .. } => + id.reanchor(target, context), + All | AllCounted(_) => Ok(()), + } + } + + /// Maximum count of assets allowed to match, if any. + pub fn count(&self) -> Option { + use WildAsset::*; + match self { + AllOfCounted { count, .. } | AllCounted(count) => Some(*count), + All | AllOf { .. } => None, + } + } + + /// Explicit limit on number of assets allowed to match, if any. + pub fn limit(&self) -> Option { + self.count() + } + + /// Consume self and return the equivalent version but counted and with the `count` set to the + /// given parameter. + pub fn counted(self, count: u32) -> Self { + use WildAsset::*; + match self { + AllOfCounted { fun, id, .. } | AllOf { fun, id } => AllOfCounted { fun, id, count }, + All | AllCounted(_) => AllCounted(count), + } + } +} + +impl, B: Into> From<(A, B)> for WildAsset { + fn from((id, fun): (A, B)) -> WildAsset { + WildAsset::AllOf { fun: fun.into(), id: id.into() } + } +} + +/// `Asset` collection, defined either by a number of `Assets` or a single wildcard. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetFilter { + /// Specify the filter as being everything contained by the given `Assets` inner. + Definite(Assets), + /// Specify the filter as the given `WildAsset` wildcard. + Wild(WildAsset), +} + +impl> From for AssetFilter { + fn from(x: T) -> Self { + Self::Wild(x.into()) + } +} + +impl From for AssetFilter { + fn from(x: Asset) -> Self { + Self::Definite(vec![x].into()) + } +} + +impl From> for AssetFilter { + fn from(x: Vec) -> Self { + Self::Definite(x.into()) + } +} + +impl From for AssetFilter { + fn from(x: Assets) -> Self { + Self::Definite(x) + } +} + +impl AssetFilter { + /// Returns true if `inner` would be matched by `self`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + pub fn matches(&self, inner: &Asset) -> bool { + match self { + AssetFilter::Definite(ref assets) => assets.contains(inner), + AssetFilter::Wild(ref wild) => wild.contains(inner), + } + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + match self { + AssetFilter::Definite(ref mut assets) => assets.reanchor(target, context), + AssetFilter::Wild(ref mut wild) => wild.reanchor(target, context), + } + } + + /// Maximum count of assets it is possible to match, if known. + pub fn count(&self) -> Option { + use AssetFilter::*; + match self { + Definite(x) => Some(x.len() as u32), + Wild(x) => x.count(), + } + } + + /// Explicit limit placed on the number of items, if any. + pub fn limit(&self) -> Option { + use AssetFilter::*; + match self { + Definite(_) => None, + Wild(x) => x.limit(), + } + } +} + +impl TryFrom for AssetFilter { + type Error = (); + fn try_from(old: OldAssetFilter) -> Result { + Ok(match old { + OldAssetFilter::Definite(x) => Self::Definite(x.try_into()?), + OldAssetFilter::Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + +#[cfg(test)] +mod tests { + use super::super::prelude::*; + + #[test] + fn conversion_works() { + let _: Assets = (Here, 1u128).into(); + } + + #[test] + fn from_sorted_and_deduplicated_works() { + use super::*; + use alloc::vec; + + let empty = vec![]; + let r = Assets::from_sorted_and_deduplicated(empty); + assert_eq!(r, Ok(Assets(vec![]))); + + let dup_fun = vec![(Here, 100).into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(dup_fun); + assert!(r.is_err()); + + let dup_nft = vec![(Here, *b"notgood!").into(), (Here, *b"notgood!").into()]; + let r = Assets::from_sorted_and_deduplicated(dup_nft); + assert!(r.is_err()); + + let good_fun = vec![(Here, 10).into(), (Parent, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(good_fun.clone()); + assert_eq!(r, Ok(Assets(good_fun))); + + let bad_fun = vec![(Parent, 10).into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(bad_fun); + assert!(r.is_err()); + + let good_nft = vec![(Here, ()).into(), (Here, *b"good").into()]; + let r = Assets::from_sorted_and_deduplicated(good_nft.clone()); + assert_eq!(r, Ok(Assets(good_nft))); + + let bad_nft = vec![(Here, *b"bad!").into(), (Here, ()).into()]; + let r = Assets::from_sorted_and_deduplicated(bad_nft); + assert!(r.is_err()); + + let mixed_good = vec![(Here, 10).into(), (Here, *b"good").into()]; + let r = Assets::from_sorted_and_deduplicated(mixed_good.clone()); + assert_eq!(r, Ok(Assets(mixed_good))); + + let mixed_bad = vec![(Here, *b"bad!").into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(mixed_bad); + assert!(r.is_err()); + } +} diff --git a/polkadot/xcm/src/v4/junction.rs b/polkadot/xcm/src/v4/junction.rs new file mode 100644 index 000000000000..b5d10484aa02 --- /dev/null +++ b/polkadot/xcm/src/v4/junction.rs @@ -0,0 +1,317 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Support data structures for `Location`, primarily the `Junction` datatype. + +use super::Location; +pub use crate::v3::{BodyId, BodyPart}; +use crate::{ + v3::{Junction as OldJunction, NetworkId as OldNetworkId}, + VersionedLocation, +}; +use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; +use core::convert::TryFrom; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; + +/// A single item in a path to describe the relative location of a consensus system. +/// +/// Each item assumes a pre-existing location as its context and is defined in terms of it. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum Junction { + /// An indexed parachain belonging to and operated by the context. + /// + /// Generally used when the context is a Polkadot Relay-chain. + Parachain(#[codec(compact)] u32), + /// A 32-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// Generally used when the context is a Substrate-based chain. + AccountId32 { network: Option, id: [u8; 32] }, + /// An 8-byte index for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is a Frame-based chain and includes e.g. an indices pallet. + AccountIndex64 { + network: Option, + #[codec(compact)] + index: u64, + }, + /// A 20-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is an Ethereum or Bitcoin chain or smart-contract. + AccountKey20 { network: Option, key: [u8; 20] }, + /// An instanced, indexed pallet that forms a constituent part of the context. + /// + /// Generally used when the context is a Frame-based chain. + // TODO XCMv4 inner should be `Compact`. + PalletInstance(u8), + /// A non-descript index within the context location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + GeneralIndex(#[codec(compact)] u128), + /// A nondescript array datum, 32 bytes, acting as a key within the context + /// location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + // Note this is implemented as an array with a length rather than using `BoundedVec` owing to + // the bound for `Copy`. + GeneralKey { length: u8, data: [u8; 32] }, + /// The unambiguous child. + /// + /// Not currently used except as a fallback when deriving context. + OnlyChild, + /// A pluralistic body existing within consensus. + /// + /// Typical to be used to represent a governance origin of a chain, but could in principle be + /// used to represent things such as multisigs also. + Plurality { id: BodyId, part: BodyPart }, + /// A global network capable of externalizing its own consensus. This is not generally + /// meaningful outside of the universal level. + GlobalConsensus(NetworkId), +} + +/// A global identifier of a data structure existing within consensus. +/// +/// Maintenance note: Networks with global consensus and which are practically bridgeable within the +/// Polkadot ecosystem are given preference over explicit naming in this enumeration. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum NetworkId { + /// Network specified by the first 32 bytes of its genesis block. + ByGenesis([u8; 32]), + /// Network defined by the first 32-bytes of the hash and number of some block it contains. + ByFork { block_number: u64, block_hash: [u8; 32] }, + /// The Polkadot mainnet Relay-chain. + Polkadot, + /// The Kusama canary-net Relay-chain. + Kusama, + /// The Westend testnet Relay-chain. + Westend, + /// The Rococo testnet Relay-chain. + Rococo, + /// The Wococo testnet Relay-chain. + Wococo, + /// An Ethereum network specified by its chain ID. + Ethereum { + /// The EIP-155 chain ID. + #[codec(compact)] + chain_id: u64, + }, + /// The Bitcoin network, including hard-forks supported by Bitcoin Core development team. + BitcoinCore, + /// The Bitcoin network, including hard-forks supported by Bitcoin Cash developers. + BitcoinCash, + /// The Polkadot Bulletin chain. + PolkadotBulletin, +} + +impl From for Option { + fn from(old: OldNetworkId) -> Self { + Some(NetworkId::from(old)) + } +} + +impl From for NetworkId { + fn from(old: OldNetworkId) -> Self { + use OldNetworkId::*; + match old { + ByGenesis(hash) => Self::ByGenesis(hash), + ByFork { block_number, block_hash } => Self::ByFork { block_number, block_hash }, + Polkadot => Self::Polkadot, + Kusama => Self::Kusama, + Westend => Self::Westend, + Rococo => Self::Rococo, + Wococo => Self::Wococo, + Ethereum { chain_id } => Self::Ethereum { chain_id }, + BitcoinCore => Self::BitcoinCore, + BitcoinCash => Self::BitcoinCash, + PolkadotBulletin => Self::PolkadotBulletin, + } + } +} + +impl From for Junction { + fn from(n: NetworkId) -> Self { + Self::GlobalConsensus(n) + } +} + +impl From<[u8; 32]> for Junction { + fn from(id: [u8; 32]) -> Self { + Self::AccountId32 { network: None, id } + } +} + +impl From>> for Junction { + fn from(key: BoundedVec>) -> Self { + key.as_bounded_slice().into() + } +} + +impl<'a> From>> for Junction { + fn from(key: BoundedSlice<'a, u8, ConstU32<32>>) -> Self { + let mut data = [0u8; 32]; + data[..key.len()].copy_from_slice(&key[..]); + Self::GeneralKey { length: key.len() as u8, data } + } +} + +impl<'a> TryFrom<&'a Junction> for BoundedSlice<'a, u8, ConstU32<32>> { + type Error = (); + fn try_from(key: &'a Junction) -> Result { + match key { + Junction::GeneralKey { length, data } => + BoundedSlice::try_from(&data[..data.len().min(*length as usize)]).map_err(|_| ()), + _ => Err(()), + } + } +} + +impl From<[u8; 20]> for Junction { + fn from(key: [u8; 20]) -> Self { + Self::AccountKey20 { network: None, key } + } +} + +impl From for Junction { + fn from(index: u64) -> Self { + Self::AccountIndex64 { network: None, index } + } +} + +impl From for Junction { + fn from(id: u128) -> Self { + Self::GeneralIndex(id) + } +} + +impl TryFrom for Junction { + type Error = (); + fn try_from(value: OldJunction) -> Result { + use OldJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network: maybe_network, id } => + Self::AccountId32 { network: maybe_network.map(|network| network.into()), id }, + AccountIndex64 { network: maybe_network, index } => + Self::AccountIndex64 { network: maybe_network.map(|network| network.into()), index }, + AccountKey20 { network: maybe_network, key } => + Self::AccountKey20 { network: maybe_network.map(|network| network.into()), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey { length, data }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id, part }, + GlobalConsensus(network) => Self::GlobalConsensus(network.into()), + }) + } +} + +impl Junction { + /// Convert `self` into a `Location` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub fn into_location(self) -> Location { + Location::new(0, [self]) + } + + /// Convert `self` into a `Location` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub fn into_exterior(self, n: u8) -> Location { + Location::new(n, [self]) + } + + /// Convert `self` into a `VersionedLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub fn into_versioned(self) -> VersionedLocation { + self.into_location().into_versioned() + } + + /// Remove the `NetworkId` value. + pub fn remove_network_id(&mut self) { + use Junction::*; + match self { + AccountId32 { ref mut network, .. } | + AccountIndex64 { ref mut network, .. } | + AccountKey20 { ref mut network, .. } => *network = None, + _ => {}, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + #[test] + fn junction_round_trip_works() { + let j = Junction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = OldJunction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = OldJunction::try_from(Junction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = Junction::from(BoundedVec::try_from(vec![1u8, 2, 3, 4]).unwrap()); + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + let s: BoundedSlice<_, _> = (&k).try_into().unwrap(); + assert_eq!(s, &[1u8, 2, 3, 4][..]); + + let j = OldJunction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = OldJunction::try_from(Junction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + } +} diff --git a/polkadot/xcm/src/v4/junctions.rs b/polkadot/xcm/src/v4/junctions.rs new file mode 100644 index 000000000000..48712dd74c6c --- /dev/null +++ b/polkadot/xcm/src/v4/junctions.rs @@ -0,0 +1,723 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! XCM `Junctions`/`InteriorLocation` datatype. + +use super::{Junction, Location, NetworkId}; +use alloc::sync::Arc; +use core::{convert::TryFrom, mem, ops::Range, result}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// Maximum number of `Junction`s that a `Junctions` can contain. +pub(crate) const MAX_JUNCTIONS: usize = 8; + +/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions` +/// implementation uses a Rust `enum` in order to make pattern matching easier. +/// +/// Parent junctions cannot be constructed with this type. Refer to `Location` for +/// instructions on constructing parent junctions. +#[derive( + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub enum Junctions { + /// The interpreting consensus system. + Here, + /// A relative path comprising 1 junction. + X1(Arc<[Junction; 1]>), + /// A relative path comprising 2 junctions. + X2(Arc<[Junction; 2]>), + /// A relative path comprising 3 junctions. + X3(Arc<[Junction; 3]>), + /// A relative path comprising 4 junctions. + X4(Arc<[Junction; 4]>), + /// A relative path comprising 5 junctions. + X5(Arc<[Junction; 5]>), + /// A relative path comprising 6 junctions. + X6(Arc<[Junction; 6]>), + /// A relative path comprising 7 junctions. + X7(Arc<[Junction; 7]>), + /// A relative path comprising 8 junctions. + X8(Arc<[Junction; 8]>), +} + +macro_rules! impl_junctions { + ($count:expr, $variant:ident) => { + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant(Arc::new(junctions)) + } + } + impl PartialEq<[Junction; $count]> for Junctions { + fn eq(&self, rhs: &[Junction; $count]) -> bool { + self.as_slice() == rhs + } + } + }; +} + +impl_junctions!(1, X1); +impl_junctions!(2, X2); +impl_junctions!(3, X3); +impl_junctions!(4, X4); +impl_junctions!(5, X5); +impl_junctions!(6, X6); +impl_junctions!(7, X7); +impl_junctions!(8, X8); + +pub struct JunctionsIterator { + junctions: Junctions, + range: Range, +} + +impl Iterator for JunctionsIterator { + type Item = Junction; + fn next(&mut self) -> Option { + self.junctions.at(self.range.next()?).cloned() + } +} + +impl DoubleEndedIterator for JunctionsIterator { + fn next_back(&mut self) -> Option { + self.junctions.at(self.range.next_back()?).cloned() + } +} + +pub struct JunctionsRefIterator<'a> { + junctions: &'a Junctions, + range: Range, +} + +impl<'a> Iterator for JunctionsRefIterator<'a> { + type Item = &'a Junction; + fn next(&mut self) -> Option<&'a Junction> { + self.junctions.at(self.range.next()?) + } +} + +impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> { + fn next_back(&mut self) -> Option<&'a Junction> { + self.junctions.at(self.range.next_back()?) + } +} +impl<'a> IntoIterator for &'a Junctions { + type Item = &'a Junction; + type IntoIter = JunctionsRefIterator<'a>; + fn into_iter(self) -> Self::IntoIter { + JunctionsRefIterator { junctions: self, range: 0..self.len() } + } +} + +impl IntoIterator for Junctions { + type Item = Junction; + type IntoIter = JunctionsIterator; + fn into_iter(self) -> Self::IntoIter { + JunctionsIterator { range: 0..self.len(), junctions: self } + } +} + +impl Junctions { + /// Convert `self` into a `Location` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into_location(self) -> Location { + Location { parents: 0, interior: self } + } + + /// Convert `self` into a `Location` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub const fn into_exterior(self, n: u8) -> Location { + Location { parents: n, interior: self } + } + + /// Casts `self` into a slice containing `Junction`s. + pub fn as_slice(&self) -> &[Junction] { + match self { + Junctions::Here => &[], + Junctions::X1(ref a) => &a[..], + Junctions::X2(ref a) => &a[..], + Junctions::X3(ref a) => &a[..], + Junctions::X4(ref a) => &a[..], + Junctions::X5(ref a) => &a[..], + Junctions::X6(ref a) => &a[..], + Junctions::X7(ref a) => &a[..], + Junctions::X8(ref a) => &a[..], + } + } + + /// Casts `self` into a mutable slice containing `Junction`s. + pub fn as_slice_mut(&mut self) -> &mut [Junction] { + match self { + Junctions::Here => &mut [], + Junctions::X1(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X2(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X3(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X4(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X5(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X6(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X7(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X8(ref mut a) => &mut Arc::make_mut(a)[..], + } + } + + /// Remove the `NetworkId` value in any `Junction`s. + pub fn remove_network_id(&mut self) { + self.for_each_mut(Junction::remove_network_id); + } + + /// Treating `self` as the universal context, return the location of the local consensus system + /// from the point of view of the given `target`. + pub fn invert_target(&self, target: &Location) -> Result { + let mut itself = self.clone(); + let mut junctions = Self::Here; + for _ in 0..target.parent_count() { + junctions = junctions + .pushed_front_with(itself.take_last().unwrap_or(Junction::OnlyChild)) + .map_err(|_| ())?; + } + let parents = target.interior().len() as u8; + Ok(Location::new(parents, junctions)) + } + + /// Execute a function `f` on every junction. We use this since we cannot implement a mutable + /// `Iterator` without unsafe code. + pub fn for_each_mut(&mut self, x: impl FnMut(&mut Junction)) { + self.as_slice_mut().iter_mut().for_each(x) + } + + /// Extract the network ID treating this value as a universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn global_consensus(&self) -> Result { + if let Some(Junction::GlobalConsensus(network)) = self.first() { + Ok(*network) + } else { + Err(()) + } + } + + /// Extract the network ID and the interior consensus location, treating this value as a + /// universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> { + match self.split_first() { + (location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)), + _ => return Err(()), + } + } + + /// Treat `self` as a universal location and the context of `relative`, returning the universal + /// location of relative. + /// + /// This will return an error if `relative` has as many (or more) parents than there are + /// junctions in `self`, implying that relative refers into a different global consensus. + pub fn within_global(mut self, relative: Location) -> Result { + if self.len() <= relative.parent_count() as usize { + return Err(()) + } + for _ in 0..relative.parent_count() { + self.take_last(); + } + for j in relative.interior() { + self.push(*j).map_err(|_| ())?; + } + Ok(self) + } + + /// Consumes `self` and returns how `viewer` would address it locally. + pub fn relative_to(mut self, viewer: &Junctions) -> Location { + let mut i = 0; + while match (self.first(), viewer.at(i)) { + (Some(x), Some(y)) => x == y, + _ => false, + } { + self = self.split_first().0; + // NOTE: Cannot overflow as loop can only iterate at most `MAX_JUNCTIONS` times. + i += 1; + } + // AUDIT NOTES: + // - above loop ensures that `i <= viewer.len()`. + // - `viewer.len()` is at most `MAX_JUNCTIONS`, so won't overflow a `u8`. + Location::new((viewer.len() - i) as u8, self) + } + + /// Returns first junction, or `None` if the location is empty. + pub fn first(&self) -> Option<&Junction> { + self.as_slice().first() + } + + /// Returns last junction, or `None` if the location is empty. + pub fn last(&self) -> Option<&Junction> { + self.as_slice().last() + } + + /// Splits off the first junction, returning the remaining suffix (first item in tuple) and the + /// first element (second item in tuple) or `None` if it was empty. + pub fn split_first(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(xs) => { + let [a] = *xs; + (Junctions::Here, Some(a)) + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + ([b].into(), Some(a)) + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + ([b, c].into(), Some(a)) + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + ([b, c, d].into(), Some(a)) + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + ([b, c, d, e].into(), Some(a)) + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + ([b, c, d, e, f].into(), Some(a)) + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + ([b, c, d, e, f, g].into(), Some(a)) + }, + Junctions::X8(xs) => { + let [a, b, c, d, e, f, g, h] = *xs; + ([b, c, d, e, f, g, h].into(), Some(a)) + }, + } + } + + /// Splits off the last junction, returning the remaining prefix (first item in tuple) and the + /// last element (second item in tuple) or `None` if it was empty. + pub fn split_last(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(xs) => { + let [a] = *xs; + (Junctions::Here, Some(a)) + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + ([a].into(), Some(b)) + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + ([a, b].into(), Some(c)) + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + ([a, b, c].into(), Some(d)) + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + ([a, b, c, d].into(), Some(e)) + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + ([a, b, c, d, e].into(), Some(f)) + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + ([a, b, c, d, e, f].into(), Some(g)) + }, + Junctions::X8(xs) => { + let [a, b, c, d, e, f, g, h] = *xs; + ([a, b, c, d, e, f, g].into(), Some(h)) + }, + } + } + + /// Removes the first element from `self`, returning it (or `None` if it was empty). + pub fn take_first(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (tail, head) = d.split_first(); + *self = tail; + head + } + + /// Removes the last element from `self`, returning it (or `None` if it was empty). + pub fn take_last(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (head, tail) = d.split_last(); + *self = head; + tail + } + + /// Mutates `self` to be appended with `new` or returns an `Err` with `new` if would overflow. + pub fn push(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Mutates `self` to be prepended with `new` or returns an `Err` with `new` if would overflow. + pub fn push_front(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_front_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_with(self, new: impl Into) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => [new].into(), + Junctions::X1(xs) => { + let [a] = *xs; + [a, new].into() + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + [a, b, new].into() + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + [a, b, c, new].into() + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + [a, b, c, d, new].into() + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + [a, b, c, d, e, new].into() + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + [a, b, c, d, e, f, new].into() + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + [a, b, c, d, e, f, g, new].into() + }, + s => Err((s, new))?, + }) + } + + /// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_front_with( + self, + new: impl Into, + ) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => [new].into(), + Junctions::X1(xs) => { + let [a] = *xs; + [new, a].into() + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + [new, a, b].into() + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + [new, a, b, c].into() + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + [new, a, b, c, d].into() + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + [new, a, b, c, d, e].into() + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + [new, a, b, c, d, e, f].into() + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + [new, a, b, c, d, e, f, g].into() + }, + s => Err((s, new))?, + }) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions, Junction::*, Location}; + /// # fn main() { + /// let mut m = Junctions::from([Parachain(21)]); + /// assert_eq!(m.append_with([PalletInstance(3)]), Ok(())); + /// assert_eq!(m, [Parachain(21), PalletInstance(3)]); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Junctions> { + let suffix = suffix.into(); + if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { + return Err(suffix) + } + for j in suffix.into_iter() { + self.push(j).expect("Already checked the sum of the len()s; qed") + } + Ok(()) + } + + /// Returns the number of junctions in `self`. + pub fn len(&self) -> usize { + self.as_slice().len() + } + + /// Returns the junction at index `i`, or `None` if the location doesn't contain that many + /// elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + self.as_slice().get(i) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't + /// contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + self.as_slice_mut().get_mut(i) + } + + /// Returns a reference iterator over the junctions. + pub fn iter(&self) -> JunctionsRefIterator { + JunctionsRefIterator { junctions: self, range: 0..self.len() } + } + + /// Ensures that self begins with `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions, Junction::*}; + /// # fn main() { + /// let mut m = Junctions::from([Parachain(2), PalletInstance(3), OnlyChild]); + /// assert_eq!(m.match_and_split(&[Parachain(2), PalletInstance(3)].into()), Some(&OnlyChild)); + /// assert_eq!(m.match_and_split(&[Parachain(2)].into()), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> { + if prefix.len() + 1 != self.len() { + return None + } + for i in 0..prefix.len() { + if prefix.at(i) != self.at(i) { + return None + } + } + return self.at(prefix.len()) + } + + pub fn starts_with(&self, prefix: &Junctions) -> bool { + prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y) + } +} + +impl TryFrom for Junctions { + type Error = Location; + fn try_from(x: Location) -> result::Result { + if x.parent_count() > 0 { + Err(x) + } else { + Ok(x.interior().clone()) + } + } +} + +impl> From for Junctions { + fn from(x: T) -> Self { + [x.into()].into() + } +} + +impl From<[Junction; 0]> for Junctions { + fn from(_: [Junction; 0]) -> Self { + Self::Here + } +} + +impl From<()> for Junctions { + fn from(_: ()) -> Self { + Self::Here + } +} + +xcm_procedural::impl_conversion_functions_for_junctions_v4!(); + +#[cfg(test)] +mod tests { + use super::{super::prelude::*, *}; + + #[test] + fn inverting_works() { + let context: InteriorLocation = (Parachain(1000), PalletInstance(42)).into(); + let target = (Parent, PalletInstance(69)).into(); + let expected = (Parent, PalletInstance(42)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + + let context: InteriorLocation = + (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into(); + let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into(); + let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + } + + #[test] + fn relative_to_works() { + use NetworkId::*; + assert_eq!( + Junctions::from([Polkadot.into()]).relative_to(&Junctions::from([Kusama.into()])), + (Parent, Polkadot).into() + ); + let base = Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]); + + // Ancestors. + assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into()); + assert_eq!(Junctions::from([Kusama.into()]).relative_to(&base), (Parent, Parent).into()); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1)]).relative_to(&base), + (Parent,).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]).relative_to(&base), + Here.into() + ); + + // Ancestors with one child. + assert_eq!( + Junctions::from([Polkadot.into()]).relative_to(&base), + (Parent, Parent, Parent, Polkadot).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(2)]).relative_to(&base), + (Parent, Parent, Parachain(2)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2)]).relative_to(&base), + (Parent, PalletInstance(2)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()]) + .relative_to(&base), + ([1u8; 32],).into() + ); + + // Ancestors with grandchildren. + assert_eq!( + Junctions::from([Polkadot.into(), Parachain(1)]).relative_to(&base), + (Parent, Parent, Parent, Polkadot, Parachain(1)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(2), PalletInstance(1)]).relative_to(&base), + (Parent, Parent, Parachain(2), PalletInstance(1)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()]) + .relative_to(&base), + (Parent, PalletInstance(2), [1u8; 32]).into() + ); + assert_eq!( + Junctions::from([ + Kusama.into(), + Parachain(1), + PalletInstance(1), + [1u8; 32].into(), + 1u128.into() + ]) + .relative_to(&base), + ([1u8; 32], 1u128).into() + ); + } + + #[test] + fn global_consensus_works() { + use NetworkId::*; + assert_eq!(Junctions::from([Polkadot.into()]).global_consensus(), Ok(Polkadot)); + assert_eq!(Junctions::from([Kusama.into(), 1u64.into()]).global_consensus(), Ok(Kusama)); + assert_eq!(Here.global_consensus(), Err(())); + assert_eq!(Junctions::from([1u64.into()]).global_consensus(), Err(())); + assert_eq!(Junctions::from([1u64.into(), Kusama.into()]).global_consensus(), Err(())); + } + + #[test] + fn test_conversion() { + use super::{Junction::*, NetworkId::*}; + let x: Junctions = GlobalConsensus(Polkadot).into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)])); + let x: Junctions = Polkadot.into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)])); + let x: Junctions = (Polkadot, Kusama).into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot), GlobalConsensus(Kusama)])); + } + + #[test] + fn encode_decode_junctions_works() { + let original = Junctions::from([ + Polkadot.into(), + Kusama.into(), + 1u64.into(), + GlobalConsensus(Polkadot), + Parachain(123), + PalletInstance(45), + ]); + let encoded = original.encode(); + assert_eq!(encoded, &[6, 9, 2, 9, 3, 2, 0, 4, 9, 2, 0, 237, 1, 4, 45]); + let decoded = Junctions::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, original); + } +} diff --git a/polkadot/xcm/src/v4/location.rs b/polkadot/xcm/src/v4/location.rs new file mode 100644 index 000000000000..db55c3d3034c --- /dev/null +++ b/polkadot/xcm/src/v4/location.rs @@ -0,0 +1,746 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! XCM `Location` datatype. + +use super::{traits::Reanchorable, Junction, Junctions}; +use crate::{v3::MultiLocation as OldLocation, VersionedLocation}; +use core::{ + convert::{TryFrom, TryInto}, + result, +}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A relative path between state-bearing consensus systems. +/// +/// A location in a consensus system is defined as an *isolatable state machine* held within global +/// consensus. The location in question need not have a sophisticated consensus algorithm of its +/// own; a single account within Ethereum, for example, could be considered a location. +/// +/// A very-much non-exhaustive list of types of location include: +/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain. +/// - A layer-0 super-chain, e.g. the Polkadot Relay chain. +/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum. +/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based +/// Substrate chain. +/// - An account. +/// +/// A `Location` is a *relative identifier*, meaning that it can only be used to define the +/// relative path between two locations, and cannot generally be used to refer to a location +/// universally. It is comprised of an integer number of parents specifying the number of times to +/// "escape" upwards into the containing consensus system and then a number of *junctions*, each +/// diving down and specifying some interior portion of state (which may be considered a +/// "sub-consensus" system). +/// +/// This specific `Location` implementation uses a `Junctions` datatype which is a Rust `enum` +/// in order to make pattern matching easier. There are occasions where it is important to ensure +/// that a value is strictly an interior location, in those cases, `Junctions` may be used. +/// +/// The `Location` value of `Null` simply refers to the interpreting consensus system. +#[derive( + Clone, + Decode, + Encode, + Eq, + PartialEq, + Ord, + PartialOrd, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub struct Location { + /// The number of parent junctions at the beginning of this `Location`. + pub parents: u8, + /// The interior (i.e. non-parent) junctions that this `Location` contains. + pub interior: Junctions, +} + +impl Default for Location { + fn default() -> Self { + Self { parents: 0, interior: Junctions::Here } + } +} + +/// A relative location which is constrained to be an interior location of the context. +/// +/// See also `Location`. +pub type InteriorLocation = Junctions; + +impl Location { + /// Creates a new `Location` with the given number of parents and interior junctions. + pub fn new(parents: u8, interior: impl Into) -> Location { + Location { parents, interior: interior.into() } + } + + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub const fn into_versioned(self) -> VersionedLocation { + VersionedLocation::V4(self) + } + + /// Creates a new `Location` with 0 parents and a `Here` interior. + /// + /// The resulting `Location` can be interpreted as the "current consensus system". + pub const fn here() -> Location { + Location { parents: 0, interior: Junctions::Here } + } + + /// Creates a new `Location` which evaluates to the parent context. + pub const fn parent() -> Location { + Location { parents: 1, interior: Junctions::Here } + } + + /// Creates a new `Location` with `parents` and an empty (`Here`) interior. + pub const fn ancestor(parents: u8) -> Location { + Location { parents, interior: Junctions::Here } + } + + /// Whether the `Location` has no parents and has a `Here` interior. + pub fn is_here(&self) -> bool { + self.parents == 0 && self.interior.len() == 0 + } + + /// Remove the `NetworkId` value in any interior `Junction`s. + pub fn remove_network_id(&mut self) { + self.interior.remove_network_id(); + } + + /// Return a reference to the interior field. + pub fn interior(&self) -> &Junctions { + &self.interior + } + + /// Return a mutable reference to the interior field. + pub fn interior_mut(&mut self) -> &mut Junctions { + &mut self.interior + } + + /// Returns the number of `Parent` junctions at the beginning of `self`. + pub const fn parent_count(&self) -> u8 { + self.parents + } + + /// Returns the parent count and the interior [`Junctions`] as a tuple. + /// + /// To be used when pattern matching, for example: + /// + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location}; + /// fn get_parachain_id(loc: &Location) -> Option { + /// match loc.unpack() { + /// (0, [Parachain(id)]) => Some(*id), + /// _ => None + /// } + /// } + /// ``` + pub fn unpack(&self) -> (u8, &[Junction]) { + (self.parents, self.interior.as_slice()) + } + + /// Returns boolean indicating whether `self` contains only the specified amount of + /// parents and no interior junctions. + pub const fn contains_parents_only(&self, count: u8) -> bool { + matches!(self.interior, Junctions::Here) && self.parents == count + } + + /// Returns the number of parents and junctions in `self`. + pub fn len(&self) -> usize { + self.parent_count() as usize + self.interior.len() + } + + /// Returns the first interior junction, or `None` if the location is empty or contains only + /// parents. + pub fn first_interior(&self) -> Option<&Junction> { + self.interior.first() + } + + /// Returns last junction, or `None` if the location is empty or contains only parents. + pub fn last(&self) -> Option<&Junction> { + self.interior.last() + } + + /// Splits off the first interior junction, returning the remaining suffix (first item in tuple) + /// and the first element (second item in tuple) or `None` if it was empty. + pub fn split_first_interior(self) -> (Location, Option) { + let Location { parents, interior: junctions } = self; + let (suffix, first) = junctions.split_first(); + let location = Location { parents, interior: suffix }; + (location, first) + } + + /// Splits off the last interior junction, returning the remaining prefix (first item in tuple) + /// and the last element (second item in tuple) or `None` if it was empty or if `self` only + /// contains parents. + pub fn split_last_interior(self) -> (Location, Option) { + let Location { parents, interior: junctions } = self; + let (prefix, last) = junctions.split_last(); + let location = Location { parents, interior: prefix }; + (location, last) + } + + /// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_interior(&mut self, new: impl Into) -> result::Result<(), Junction> { + self.interior.push(new) + } + + /// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_front_interior( + &mut self, + new: impl Into, + ) -> result::Result<(), Junction> { + self.interior.push_front(new) + } + + /// Consumes `self` and returns a `Location` suffixed with `new`, or an `Err` with + /// theoriginal value of `self` in case of overflow. + pub fn pushed_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_with(new) { + Ok(i) => Ok(Location { interior: i, parents: self.parents }), + Err((i, j)) => Err((Location { interior: i, parents: self.parents }, j)), + } + } + + /// Consumes `self` and returns a `Location` prefixed with `new`, or an `Err` with the + /// original value of `self` in case of overflow. + pub fn pushed_front_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_front_with(new) { + Ok(i) => Ok(Location { interior: i, parents: self.parents }), + Err((i, j)) => Err((Location { interior: i, parents: self.parents }, j)), + } + } + + /// Returns the junction at index `i`, or `None` if the location is a parent or if the location + /// does not contain that many elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at(i - num_parents) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location is a + /// parent or if it doesn't contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at_mut(i - num_parents) + } + + /// Decrements the parent count by 1. + pub fn dec_parent(&mut self) { + self.parents = self.parents.saturating_sub(1); + } + + /// Removes the first interior junction from `self`, returning it + /// (or `None` if it was empty or if `self` contains only parents). + pub fn take_first_interior(&mut self) -> Option { + self.interior.take_first() + } + + /// Removes the last element from `interior`, returning it (or `None` if it was empty or if + /// `self` only contains parents). + pub fn take_last(&mut self) -> Option { + self.interior.take_last() + } + + /// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with + /// the junctions of `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location}; + /// # fn main() { + /// let mut m = Location::new(1, [PalletInstance(3), OnlyChild]); + /// assert_eq!( + /// m.match_and_split(&Location::new(1, [PalletInstance(3)])), + /// Some(&OnlyChild), + /// ); + /// assert_eq!(m.match_and_split(&Location::new(1, Here)), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Location) -> Option<&Junction> { + if self.parents != prefix.parents { + return None + } + self.interior.match_and_split(&prefix.interior) + } + + pub fn starts_with(&self, prefix: &Location) -> bool { + self.parents == prefix.parents && self.interior.starts_with(&prefix.interior) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parachain(21), 69u64).into(); + /// assert_eq!(m.append_with((Parent, PalletInstance(3))), Ok(())); + /// assert_eq!(m, Location::new(1, [Parachain(21), PalletInstance(3)])); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Self> { + let prefix = core::mem::replace(self, suffix.into()); + match self.prepend_with(prefix) { + Ok(()) => Ok(()), + Err(prefix) => Err(core::mem::replace(self, prefix)), + } + } + + /// Consume `self` and return its value suffixed with `suffix`. + /// + /// Returns `Err` with the original value of `self` and `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parachain(21), 69u64).into(); + /// let r = m.appended_with((Parent, PalletInstance(3))).unwrap(); + /// assert_eq!(r, Location::new(1, [Parachain(21), PalletInstance(3)])); + /// # } + /// ``` + pub fn appended_with(mut self, suffix: impl Into) -> Result { + match self.append_with(suffix) { + Ok(()) => Ok(self), + Err(suffix) => Err((self, suffix)), + } + } + + /// Mutate `self` so that it is prefixed with `prefix`. + /// + /// Does not modify `self` and returns `Err` with `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parent, PalletInstance(3)).into(); + /// assert_eq!(m.prepend_with((Parent, Parachain(21), OnlyChild)), Ok(())); + /// assert_eq!(m, Location::new(1, [PalletInstance(3)])); + /// # } + /// ``` + pub fn prepend_with(&mut self, prefix: impl Into) -> Result<(), Self> { + // prefix self (suffix) + // P .. P I .. I p .. p i .. i + let mut prefix = prefix.into(); + let prepend_interior = prefix.interior.len().saturating_sub(self.parents as usize); + let final_interior = self.interior.len().saturating_add(prepend_interior); + if final_interior > super::junctions::MAX_JUNCTIONS { + return Err(prefix) + } + let suffix_parents = (self.parents as usize).saturating_sub(prefix.interior.len()); + let final_parents = (prefix.parents as usize).saturating_add(suffix_parents); + if final_parents > 255 { + return Err(prefix) + } + + // cancel out the final item on the prefix interior for one of the suffix's parents. + while self.parents > 0 && prefix.take_last().is_some() { + self.dec_parent(); + } + + // now we have either removed all suffix's parents or prefix interior. + // this means we can combine the prefix's and suffix's remaining parents/interior since + // we know that with at least one empty, the overall order will be respected: + // prefix self (suffix) + // P .. P (I) p .. p i .. i => P + p .. (no I) i + // -- or -- + // P .. P I .. I (p) i .. i => P (no p) .. I + i + + self.parents = self.parents.saturating_add(prefix.parents); + for j in prefix.interior.into_iter().rev() { + self.push_front_interior(j) + .expect("final_interior no greater than MAX_JUNCTIONS; qed"); + } + Ok(()) + } + + /// Consume `self` and return its value prefixed with `prefix`. + /// + /// Returns `Err` with the original value of `self` and `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let m: Location = (Parent, Parent, PalletInstance(3)).into(); + /// let r = m.prepended_with((Parent, Parachain(21), OnlyChild)).unwrap(); + /// assert_eq!(r, Location::new(1, [PalletInstance(3)])); + /// # } + /// ``` + pub fn prepended_with(mut self, prefix: impl Into) -> Result { + match self.prepend_with(prefix) { + Ok(()) => Ok(self), + Err(prefix) => Err((self, prefix)), + } + } + + /// Remove any unneeded parents/junctions in `self` based on the given context it will be + /// interpreted in. + pub fn simplify(&mut self, context: &Junctions) { + if context.len() < self.parents as usize { + // Not enough context + return + } + while self.parents > 0 { + let maybe = context.at(context.len() - (self.parents as usize)); + match (self.interior.first(), maybe) { + (Some(i), Some(j)) if i == j => { + self.interior.take_first(); + self.parents -= 1; + }, + _ => break, + } + } + } + + /// Return the Location subsection identifying the chain that `self` points to. + pub fn chain_location(&self) -> Location { + let mut clone = self.clone(); + // start popping junctions until we reach chain identifier + while let Some(j) = clone.last() { + if matches!(j, Junction::Parachain(_) | Junction::GlobalConsensus(_)) { + // return chain subsection + return clone + } else { + (clone, _) = clone.split_last_interior(); + } + } + Location::new(clone.parents, Junctions::Here) + } +} + +impl Reanchorable for Location { + type Error = Self; + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + // TODO: https://github.com/paritytech/polkadot/issues/4489 Optimize this. + + // 1. Use our `context` to figure out how the `target` would address us. + let inverted_target = context.invert_target(target)?; + + // 2. Prepend `inverted_target` to `self` to get self's location from the perspective of + // `target`. + self.prepend_with(inverted_target).map_err(|_| ())?; + + // 3. Given that we know some of `target` context, ensure that any parents in `self` are + // strictly needed. + self.simplify(target.interior()); + + Ok(()) + } + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(self), + } + } +} + +impl TryFrom for Option { + type Error = (); + fn try_from(value: OldLocation) -> result::Result { + Ok(Some(Location::try_from(value)?)) + } +} + +impl TryFrom for Location { + type Error = (); + fn try_from(x: OldLocation) -> result::Result { + Ok(Location { parents: x.parents, interior: x.interior.try_into()? }) + } +} + +/// A unit struct which can be converted into a `Location` of `parents` value 1. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Parent; +impl From for Location { + fn from(_: Parent) -> Self { + Location { parents: 1, interior: Junctions::Here } + } +} + +/// A tuple struct which can be converted into a `Location` of `parents` value 1 with the inner +/// interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct ParentThen(pub Junctions); +impl From for Location { + fn from(ParentThen(interior): ParentThen) -> Self { + Location { parents: 1, interior } + } +} + +/// A unit struct which can be converted into a `Location` of the inner `parents` value. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Ancestor(pub u8); +impl From for Location { + fn from(Ancestor(parents): Ancestor) -> Self { + Location { parents, interior: Junctions::Here } + } +} + +/// A unit struct which can be converted into a `Location` of the inner `parents` value and the +/// inner interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct AncestorThen(pub u8, pub Interior); +impl> From> for Location { + fn from(AncestorThen(parents, interior): AncestorThen) -> Self { + Location { parents, interior: interior.into() } + } +} + +xcm_procedural::impl_conversion_functions_for_location_v4!(); + +#[cfg(test)] +mod tests { + use crate::v4::prelude::*; + use parity_scale_codec::{Decode, Encode}; + + #[test] + fn conversion_works() { + let x: Location = Parent.into(); + assert_eq!(x, Location { parents: 1, interior: Here }); + // let x: Location = (Parent,).into(); + // assert_eq!(x, Location { parents: 1, interior: Here }); + // let x: Location = (Parent, Parent).into(); + // assert_eq!(x, Location { parents: 2, interior: Here }); + let x: Location = (Parent, Parent, OnlyChild).into(); + assert_eq!(x, Location { parents: 2, interior: OnlyChild.into() }); + let x: Location = OnlyChild.into(); + assert_eq!(x, Location { parents: 0, interior: OnlyChild.into() }); + let x: Location = (OnlyChild,).into(); + assert_eq!(x, Location { parents: 0, interior: OnlyChild.into() }); + } + + #[test] + fn simplify_basic_works() { + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = [PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [OnlyChild, Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn simplify_incompatible_location_fails() { + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42), GeneralIndex(42)].into(); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000)].into(); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn reanchor_works() { + let mut id: Location = (Parent, Parachain(1000), GeneralIndex(42)).into(); + let context = Parachain(2000).into(); + let target = (Parent, Parachain(1000)).into(); + let expected = GeneralIndex(42).into(); + id.reanchor(&target, &context).unwrap(); + assert_eq!(id, expected); + } + + #[test] + fn encode_and_decode_works() { + let m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + let encoded = m.encode(); + assert_eq!(encoded, [1, 2, 0, 168, 2, 0, 92].to_vec()); + let decoded = Location::decode(&mut &encoded[..]); + assert_eq!(decoded, Ok(m)); + } + + #[test] + fn match_and_split_works() { + let m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + assert_eq!(m.match_and_split(&Location { parents: 1, interior: Here }), None); + assert_eq!( + m.match_and_split(&Location { parents: 1, interior: [Parachain(42)].into() }), + Some(&AccountIndex64 { network: None, index: 23 }) + ); + assert_eq!(m.match_and_split(&m), None); + } + + #[test] + fn append_with_works() { + let acc = AccountIndex64 { network: None, index: 23 }; + let mut m = Location { parents: 1, interior: [Parachain(42)].into() }; + assert_eq!(m.append_with([PalletInstance(3), acc]), Ok(())); + assert_eq!( + m, + Location { parents: 1, interior: [Parachain(42), PalletInstance(3), acc].into() } + ); + + // cannot append to create overly long location + let acc = AccountIndex64 { network: None, index: 23 }; + let m = Location { + parents: 254, + interior: [Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild].into(), + }; + let suffix: Location = (PalletInstance(3), acc, OnlyChild, OnlyChild).into(); + assert_eq!(m.clone().append_with(suffix.clone()), Err(suffix)); + } + + #[test] + fn prepend_with_works() { + let mut m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + assert_eq!(m.prepend_with(Location { parents: 1, interior: [OnlyChild].into() }), Ok(())); + assert_eq!( + m, + Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into() + } + ); + + // cannot prepend to create overly long location + let mut m = Location { parents: 254, interior: [Parachain(42)].into() }; + let prefix = Location { parents: 2, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Err(prefix)); + + let prefix = Location { parents: 1, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Ok(())); + assert_eq!(m, Location { parents: 255, interior: [Parachain(42)].into() }); + } + + #[test] + fn double_ended_ref_iteration_works() { + let m: Junctions = [Parachain(1000), Parachain(3), PalletInstance(5)].into(); + let mut iter = m.iter(); + + let first = iter.next().unwrap(); + assert_eq!(first, &Parachain(1000)); + let third = iter.next_back().unwrap(); + assert_eq!(third, &PalletInstance(5)); + let second = iter.next_back().unwrap(); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + assert_eq!(second, &Parachain(3)); + + let res = Here + .pushed_with(*first) + .unwrap() + .pushed_with(*second) + .unwrap() + .pushed_with(*third) + .unwrap(); + assert_eq!(m, res); + + // make sure there's no funny business with the 0 indexing + let m = Here; + let mut iter = m.iter(); + + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + } + + #[test] + fn conversion_from_other_types_works() { + use crate::v3; + use core::convert::TryInto; + + fn takes_location>(_arg: Arg) {} + + takes_location(Parent); + takes_location(Here); + takes_location([Parachain(42)]); + takes_location((Ancestor(255), PalletInstance(8))); + takes_location((Ancestor(5), Parachain(1), PalletInstance(3))); + takes_location((Ancestor(2), Here)); + takes_location(AncestorThen( + 3, + [Parachain(43), AccountIndex64 { network: None, index: 155 }], + )); + takes_location((Parent, AccountId32 { network: None, id: [0; 32] })); + takes_location((Parent, Here)); + takes_location(ParentThen([Parachain(75)].into())); + takes_location([Parachain(100), PalletInstance(3)]); + + assert_eq!(v3::Location::from(v3::Junctions::Here).try_into(), Ok(Location::here())); + assert_eq!(v3::Location::from(v3::Parent).try_into(), Ok(Location::parent())); + assert_eq!( + v3::Location::from((v3::Parent, v3::Parent, v3::Junction::GeneralIndex(42u128),)) + .try_into(), + Ok(Location { parents: 2, interior: [GeneralIndex(42u128)].into() }), + ); + } +} diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs new file mode 100644 index 000000000000..3b57ba1b1371 --- /dev/null +++ b/polkadot/xcm/src/v4/mod.rs @@ -0,0 +1,1457 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Version 4 of the Cross-Consensus Message format data structures. + +pub use super::v2::GetWeight; +use super::v3::{ + Instruction as OldInstruction, PalletInfo as OldPalletInfo, + QueryResponseInfo as OldQueryResponseInfo, Response as OldResponse, Xcm as OldXcm, +}; +use crate::DoubleEncoded; +use alloc::{vec, vec::Vec}; +use bounded_collections::{parameter_types, BoundedVec}; +use core::{ + convert::{TryFrom, TryInto}, + fmt::Debug, + result, +}; +use derivative::Derivative; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +mod asset; +mod junction; +pub(crate) mod junctions; +mod location; +mod traits; + +pub use asset::{ + Asset, AssetFilter, AssetId, AssetInstance, Assets, Fungibility, WildAsset, WildFungibility, + MAX_ITEMS_IN_ASSETS, +}; +pub use junction::{BodyId, BodyPart, Junction, NetworkId}; +pub use junctions::Junctions; +pub use location::{Ancestor, AncestorThen, InteriorLocation, Location, Parent, ParentThen}; +pub use traits::{ + send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Reanchorable, Result, + SendError, SendResult, SendXcm, Weight, XcmHash, +}; +// These parts of XCM v3 are unchanged in XCM v4, and are re-imported here. +pub use super::v3::{MaybeErrorCode, OriginKind, WeightLimit}; + +/// This module's XCM version. +pub const VERSION: super::Version = 4; + +/// An identifier for a query. +pub type QueryId = u64; + +#[derive(Derivative, Default, Encode, Decode, TypeInfo)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub struct Xcm(pub Vec>); + +pub const MAX_INSTRUCTIONS_TO_DECODE: u8 = 100; + +impl Xcm { + /// Create an empty instance. + pub fn new() -> Self { + Self(vec![]) + } + + /// Return `true` if no instructions are held in `self`. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Return the number of instructions held in `self`. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Return a reference to the inner value. + pub fn inner(&self) -> &[Instruction] { + &self.0 + } + + /// Return a mutable reference to the inner value. + pub fn inner_mut(&mut self) -> &mut Vec> { + &mut self.0 + } + + /// Consume and return the inner value. + pub fn into_inner(self) -> Vec> { + self.0 + } + + /// Return an iterator over references to the items. + pub fn iter(&self) -> impl Iterator> { + self.0.iter() + } + + /// Return an iterator over mutable references to the items. + pub fn iter_mut(&mut self) -> impl Iterator> { + self.0.iter_mut() + } + + /// Consume and return an iterator over the items. + pub fn into_iter(self) -> impl Iterator> { + self.0.into_iter() + } + + /// Consume and either return `self` if it contains some instructions, or if it's empty, then + /// instead return the result of `f`. + pub fn or_else(self, f: impl FnOnce() -> Self) -> Self { + if self.0.is_empty() { + f() + } else { + self + } + } + + /// Return the first instruction, if any. + pub fn first(&self) -> Option<&Instruction> { + self.0.first() + } + + /// Return the last instruction, if any. + pub fn last(&self) -> Option<&Instruction> { + self.0.last() + } + + /// Return the only instruction, contained in `Self`, iff only one exists (`None` otherwise). + pub fn only(&self) -> Option<&Instruction> { + if self.0.len() == 1 { + self.0.first() + } else { + None + } + } + + /// Return the only instruction, contained in `Self`, iff only one exists (returns `self` + /// otherwise). + pub fn into_only(mut self) -> core::result::Result, Self> { + if self.0.len() == 1 { + self.0.pop().ok_or(self) + } else { + Err(self) + } + } +} + +impl From>> for Xcm { + fn from(c: Vec>) -> Self { + Self(c) + } +} + +impl From> for Vec> { + fn from(c: Xcm) -> Self { + c.0 + } +} + +/// A prelude for importing all types typically used when interacting with XCM messages. +pub mod prelude { + mod contents { + pub use super::super::{ + send_xcm, validate_send, Ancestor, AncestorThen, Asset, + AssetFilter::{self, *}, + AssetId, + AssetInstance::{self, *}, + Assets, BodyId, BodyPart, Error as XcmError, ExecuteXcm, + Fungibility::{self, *}, + Instruction::*, + InteriorLocation, + Junction::{self, *}, + Junctions::{self, Here}, + Location, MaybeErrorCode, + NetworkId::{self, *}, + OriginKind, Outcome, PalletInfo, Parent, ParentThen, PreparedMessage, QueryId, + QueryResponseInfo, Reanchorable, Response, Result as XcmResult, SendError, SendResult, + SendXcm, Weight, + WeightLimit::{self, *}, + WildAsset::{self, *}, + WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible}, + XcmContext, XcmHash, XcmWeightInfo, VERSION as XCM_VERSION, + }; + } + pub use super::{Instruction, Xcm}; + pub use contents::*; + pub mod opaque { + pub use super::{ + super::opaque::{Instruction, Xcm}, + contents::*, + }; + } +} + +parameter_types! { + pub MaxPalletNameLen: u32 = 48; + /// Maximum size of the encoded error code coming from a `Dispatch` result, used for + /// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation. + pub MaxDispatchErrorLen: u32 = 128; + pub MaxPalletsInfo: u32 = 64; +} + +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub struct PalletInfo { + #[codec(compact)] + index: u32, + name: BoundedVec, + module_name: BoundedVec, + #[codec(compact)] + major: u32, + #[codec(compact)] + minor: u32, + #[codec(compact)] + patch: u32, +} + +impl TryInto for PalletInfo { + type Error = (); + + fn try_into(self) -> result::Result { + OldPalletInfo::new( + self.index, + self.name.into_inner(), + self.module_name.into_inner(), + self.major, + self.minor, + self.patch, + ) + .map_err(|_| ()) + } +} + +impl PalletInfo { + pub fn new( + index: u32, + name: Vec, + module_name: Vec, + major: u32, + minor: u32, + patch: u32, + ) -> result::Result { + let name = BoundedVec::try_from(name).map_err(|_| Error::Overflow)?; + let module_name = BoundedVec::try_from(module_name).map_err(|_| Error::Overflow)?; + + Ok(Self { index, name, module_name, major, minor, patch }) + } +} + +/// Response data to a query. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub enum Response { + /// No response. Serves as a neutral default. + Null, + /// Some assets. + Assets(Assets), + /// The outcome of an XCM instruction. + ExecutionResult(Option<(u32, Error)>), + /// An XCM version. + Version(super::Version), + /// The index, instance name, pallet name and version of some pallets. + PalletsInfo(BoundedVec), + /// The status of a dispatch attempt using `Transact`. + DispatchResult(MaybeErrorCode), +} + +impl Default for Response { + fn default() -> Self { + Self::Null + } +} + +impl TryFrom for Response { + type Error = (); + + fn try_from(old: OldResponse) -> result::Result { + use OldResponse::*; + Ok(match old { + Null => Self::Null, + Assets(assets) => Self::Assets(assets.try_into()?), + ExecutionResult(result) => + Self::ExecutionResult(result.map(|(num, old_error)| (num, old_error.into()))), + Version(version) => Self::Version(version), + PalletsInfo(pallet_info) => { + let inner = pallet_info + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + Self::PalletsInfo( + BoundedVec::::try_from(inner).map_err(|_| ())?, + ) + }, + DispatchResult(maybe_error) => Self::DispatchResult(maybe_error), + }) + } +} + +/// Information regarding the composition of a query response. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub struct QueryResponseInfo { + /// The destination to which the query response message should be send. + pub destination: Location, + /// The `query_id` field of the `QueryResponse` message. + #[codec(compact)] + pub query_id: QueryId, + /// The `max_weight` field of the `QueryResponse` message. + pub max_weight: Weight, +} + +impl TryFrom for QueryResponseInfo { + type Error = (); + + fn try_from(old: OldQueryResponseInfo) -> result::Result { + Ok(Self { + destination: old.destination.try_into()?, + query_id: old.query_id, + max_weight: old.max_weight, + }) + } +} + +/// Contextual data pertaining to a specific list of XCM instructions. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +pub struct XcmContext { + /// The current value of the Origin register of the `XCVM`. + pub origin: Option, + /// The identity of the XCM; this may be a hash of its versioned encoding but could also be + /// a high-level identity set by an appropriate barrier. + pub message_id: XcmHash, + /// The current value of the Topic register of the `XCVM`. + pub topic: Option<[u8; 32]>, +} + +impl XcmContext { + /// Constructor which sets the message ID to the supplied parameter and leaves the origin and + /// topic unset. + pub fn with_message_id(message_id: XcmHash) -> XcmContext { + XcmContext { origin: None, message_id, topic: None } + } +} + +/// Cross-Consensus Message: A message from one consensus system to another. +/// +/// Consensus systems that may send and receive messages include blockchains and smart contracts. +/// +/// All messages are delivered from a known *origin*, expressed as a `Location`. +/// +/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the +/// outer XCM format, known as `VersionedXcm`. +#[derive( + Derivative, + Encode, + Decode, + TypeInfo, + xcm_procedural::XcmWeightInfoTrait, + xcm_procedural::Builder, +)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub enum Instruction { + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding + /// Register. + /// + /// - `assets`: The asset(s) to be withdrawn into holding. + /// + /// Kind: *Command*. + /// + /// Errors: + #[builder(loads_holding)] + WithdrawAsset(Assets), + + /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` + /// system and equivalent derivatives should be placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into holding. + /// + /// Safety: `origin` must be trusted to have received and be storing `assets` such that they + /// may later be withdrawn should this system send a corresponding message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + #[builder(loads_holding)] + ReserveAssetDeposited(Assets), + + /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should + /// be created and placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into the Holding Register. + /// + /// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding `assets` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + #[builder(loads_holding)] + ReceiveTeleportedAsset(Assets), + + /// Respond with information that the local system is expecting. + /// + /// - `query_id`: The identifier of the query that resulted in this message being sent. + /// - `response`: The message content. + /// - `max_weight`: The maximum weight that handling this response should take. + /// - `querier`: The location responsible for the initiation of the response, if there is one. + /// In general this will tend to be the same location as the receiver of this message. NOTE: + /// As usual, this is interpreted from the perspective of the receiving consensus system. + /// + /// Safety: Since this is information only, there are no immediate concerns. However, it should + /// be remembered that even if the Origin behaves reasonably, it can always be asked to make + /// a response to a third-party chain who may or may not be expecting the response. Therefore + /// the `querier` should be checked to match the expected value. + /// + /// Kind: *Information*. + /// + /// Errors: + QueryResponse { + #[codec(compact)] + query_id: QueryId, + response: Response, + max_weight: Weight, + querier: Option, + }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `beneficiary`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `beneficiary`: The new owner for the assets. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferAsset { assets: Assets, beneficiary: Location }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `dest` within this consensus system (i.e. its sovereign account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given + /// `xcm`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which + /// is sent onwards to `dest`. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferReserveAsset { assets: Assets, dest: Location, xcm: Xcm<()> }, + + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed + /// by the kind of origin `origin_kind`. + /// + /// The Transact Status Register is set according to the result of dispatching the call. + /// + /// - `origin_kind`: The means of expressing the message origin as a dispatch origin. + /// - `require_weight_at_most`: The weight of `call`; this should be at least the chain's + /// calculated weight and will be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + Transact { origin_kind: OriginKind, require_weight_at_most: Weight, call: DoubleEncoded }, + + /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by + /// the relay-chain to a para. + /// + /// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel + /// opening. + /// - `max_message_size`: The maximum size of a message proposed by the sender. + /// - `max_capacity`: The maximum number of messages that can be queued in the channel. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + HrmpNewChannelOpenRequest { + #[codec(compact)] + sender: u32, + #[codec(compact)] + max_message_size: u32, + #[codec(compact)] + max_capacity: u32, + }, + + /// A message to notify about that a previously sent open channel request has been accepted by + /// the recipient. That means that the channel will be opened during the next relay-chain + /// session change. This message is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelAccepted { + // NOTE: We keep this as a structured item to a) keep it consistent with the other Hrmp + // items; and b) because the field's meaning is not obvious/mentioned from the item name. + #[codec(compact)] + recipient: u32, + }, + + /// A message to notify that the other party in an open channel decided to close it. In + /// particular, `initiator` is going to close the channel opened from `sender` to the + /// `recipient`. The close will be enacted at the next relay-chain session change. This message + /// is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelClosing { + #[codec(compact)] + initiator: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + recipient: u32, + }, + + /// Clear the origin. + /// + /// This may be used by the XCM author to ensure that later instructions cannot command the + /// authority of the origin (e.g. if they are being relayed from an untrusted source, as often + /// the case with `ReserveAssetDeposited`). + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + ClearOrigin, + + /// Mutate the origin to some interior location. + /// + /// Kind: *Command* + /// + /// Errors: + DescendOrigin(InteriorLocation), + + /// Immediately report the contents of the Error Register to the given destination via XCM. + /// + /// A `QueryResponse` message of type `ExecutionOutcome` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// + /// Kind: *Command* + /// + /// Errors: + ReportError(QueryResponseInfo), + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `beneficiary` within this consensus system. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `beneficiary`: The new owner for the assets. + /// + /// Kind: *Command* + /// + /// Errors: + DepositAsset { assets: AssetFilter, beneficiary: Location }, + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign + /// account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is + /// sent onwards to `dest`. + /// + /// Kind: *Command* + /// + /// Errors: + DepositReserveAsset { assets: AssetFilter, dest: Location, xcm: Xcm<()> }, + + /// Remove the asset(s) (`want`) from the Holding Register and replace them with alternative + /// assets. + /// + /// The minimum amount of assets to be received into the Holding Register for the order not to + /// fail may be stated. + /// + /// - `give`: The maximum amount of assets to remove from holding. + /// - `want`: The minimum amount of assets which `give` should be exchanged for. + /// - `maximal`: If `true`, then prefer to give as much as possible up to the limit of `give` + /// and receive accordingly more. If `false`, then prefer to give as little as possible in + /// order to receive as little as possible while receiving at least `want`. + /// + /// Kind: *Command* + /// + /// Errors: + ExchangeAsset { give: AssetFilter, want: Assets, maximal: bool }, + + /// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a + /// reserve location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The + /// sovereign account of this consensus system *on the reserve location* will have + /// appropriate assets withdrawn and `effects` will be executed on them. There will typically + /// be only one valid location on any given asset/chain combination. + /// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve + /// location*. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateReserveWithdraw { assets: AssetFilter, reserve: Location, xcm: Xcm<()> }, + + /// Remove the asset(s) (`assets`) from holding and send a `ReceiveTeleportedAsset` XCM message + /// to a `dest` location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: A valid location that respects teleports coming from this location. + /// - `xcm`: The instructions to execute on the assets once arrived *on the destination + /// location*. + /// + /// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for + /// all `assets`. If it does not, then the assets may be lost. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateTeleport { assets: AssetFilter, dest: Location, xcm: Xcm<()> }, + + /// Report to a given destination the contents of the Holding Register. + /// + /// A `QueryResponse` message of type `Assets` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// - `assets`: A filter for the assets that should be reported back. The assets reported back + /// will be, asset-wise, *the lesser of this value and the holding register*. No wildcards + /// will be used when reporting assets back. + /// + /// Kind: *Command* + /// + /// Errors: + ReportHolding { response_info: QueryResponseInfo, assets: AssetFilter }, + + /// Pay for the execution of some XCM `xcm` and `orders` with up to `weight` + /// picoseconds of execution time, paying for this with up to `fees` from the Holding Register. + /// + /// - `fees`: The asset(s) to remove from the Holding Register to pay for fees. + /// - `weight_limit`: The maximum amount of weight to purchase; this must be at least the + /// expected maximum weight of the total XCM to be executed for the + /// `AllowTopLevelPaidExecutionFrom` barrier to allow the XCM be executed. + /// + /// Kind: *Command* + /// + /// Errors: + BuyExecution { fees: Asset, weight_limit: WeightLimit }, + + /// Refund any surplus weight previously bought with `BuyExecution`. + /// + /// Kind: *Command* + /// + /// Errors: None. + RefundSurplus, + + /// Set the Error Handler Register. This is code that should be called in the case of an error + /// happening. + /// + /// An error occurring within execution of this code will _NOT_ result in the error register + /// being set, nor will an error handler be called due to it. The error handler and appendix + /// may each still be set. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous handler and the new + /// handler, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetErrorHandler(Xcm), + + /// Set the Appendix Register. This is code that should be called after code execution + /// (including the error handler if any) is finished. This will be called regardless of whether + /// an error occurred. + /// + /// Any error occurring due to execution of this code will result in the error register being + /// set, and the error handler (if set) firing. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous appendix and the new + /// appendix, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetAppendix(Xcm), + + /// Clear the Error Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearError, + + /// Create some assets which are being held on behalf of the origin. + /// + /// - `assets`: The assets which are to be claimed. This must match exactly with the assets + /// claimable by the origin of the ticket. + /// - `ticket`: The ticket of the asset; this is an abstract identifier to help locate the + /// asset. + /// + /// Kind: *Command* + /// + /// Errors: + #[builder(loads_holding)] + ClaimAsset { assets: Assets, ticket: Location }, + + /// Always throws an error of type `Trap`. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `Trap`: All circumstances, whose inner value is the same as this item's inner value. + Trap(#[codec(compact)] u64), + + /// Ask the destination system to respond with the most recent version of XCM that they + /// support in a `QueryResponse` instruction. Any changes to this should also elicit similar + /// responses when they happen. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + SubscribeVersion { + #[codec(compact)] + query_id: QueryId, + max_response_weight: Weight, + }, + + /// Cancel the effect of a previous `SubscribeVersion` instruction. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + UnsubscribeVersion, + + /// Reduce Holding by up to the given assets. + /// + /// Holding is reduced by as much as possible up to the assets in the parameter. It is not an + /// error if the Holding does not contain the assets (to make this an error, use `ExpectAsset` + /// prior). + /// + /// Kind: *Command* + /// + /// Errors: *Infallible* + BurnAsset(Assets), + + /// Throw an error if Holding does not contain at least the given assets. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter. + ExpectAsset(Assets), + + /// Ensure that the Origin Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Origin Register is not equal to the parameter. + ExpectOrigin(Option), + + /// Ensure that the Error Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter. + ExpectError(Option<(u32, Error)>), + + /// Ensure that the Transact Status Register equals some given value and throw an error if + /// not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the + /// parameter. + ExpectTransactStatus(MaybeErrorCode), + + /// Query the existence of a particular pallet type. + /// + /// - `module_name`: The module name of the pallet to query. + /// - `response_info`: Information for making the response. + /// + /// Sends a `QueryResponse` to Origin whose data field `PalletsInfo` containing the information + /// of all pallets on the local chain whose name is equal to `name`. This is empty in the case + /// that the local chain is not based on Substrate Frame. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + QueryPallet { module_name: Vec, response_info: QueryResponseInfo }, + + /// Ensure that a particular pallet with a particular version exists. + /// + /// - `index: Compact`: The index which identifies the pallet. An error if no pallet exists at + /// this index. + /// - `name: Vec`: Name which must be equal to the name of the pallet. + /// - `module_name: Vec`: Module name which must be equal to the name of the module in + /// which the pallet exists. + /// - `crate_major: Compact`: Version number which must be equal to the major version of the + /// crate which implements the pallet. + /// - `min_crate_minor: Compact`: Version number which must be at most the minor version of the + /// crate which implements the pallet. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: In case any of the expectations are broken. + ExpectPallet { + #[codec(compact)] + index: u32, + name: Vec, + module_name: Vec, + #[codec(compact)] + crate_major: u32, + #[codec(compact)] + min_crate_minor: u32, + }, + + /// Send a `QueryResponse` message containing the value of the Transact Status Register to some + /// destination. + /// + /// - `query_response_info`: The information needed for constructing and sending the + /// `QueryResponse` message. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ReportTransactStatus(QueryResponseInfo), + + /// Set the Transact Status Register to its default, cleared, value. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Infallible*. + ClearTransactStatus, + + /// Set the Origin Register to be some child of the Universal Ancestor. + /// + /// Safety: Should only be usable if the Origin is trusted to represent the Universal Ancestor + /// child in general. In general, no Origin should be able to represent the Universal Ancestor + /// child which is the root of the local consensus system since it would by extension + /// allow it to act as any location within the local consensus. + /// + /// The `Junction` parameter should generally be a `GlobalConsensus` variant since it is only + /// these which are children of the Universal Ancestor. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + UniversalOrigin(Junction), + + /// Send a message on to Non-Local Consensus system. + /// + /// This will tend to utilize some extra-consensus mechanism, the obvious one being a bridge. + /// A fee may be charged; this may be determined based on the contents of `xcm`. It will be + /// taken from the Holding register. + /// + /// - `network`: The remote consensus system to which the message should be exported. + /// - `destination`: The location relative to the remote consensus system to which the message + /// should be sent on arrival. + /// - `xcm`: The message to be exported. + /// + /// As an example, to export a message for execution on Statemine (parachain #1000 in the + /// Kusama network), you would call with `network: NetworkId::Kusama` and + /// `destination: [Parachain(1000)].into()`. Alternatively, to export a message for execution + /// on Polkadot, you would call with `network: NetworkId:: Polkadot` and `destination: Here`. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ExportMessage { network: NetworkId, destination: InteriorLocation, xcm: Xcm<()> }, + + /// Lock the locally held asset and prevent further transfer or withdrawal. + /// + /// This restriction may be removed by the `UnlockAsset` instruction being called with an + /// Origin of `unlocker` and a `target` equal to the current `Origin`. + /// + /// If the locking is successful, then a `NoteUnlockable` instruction is sent to `unlocker`. + /// + /// - `asset`: The asset(s) which should be locked. + /// - `unlocker`: The value which the Origin must be for a corresponding `UnlockAsset` + /// instruction to work. + /// + /// Kind: *Command*. + /// + /// Errors: + LockAsset { asset: Asset, unlocker: Location }, + + /// Remove the lock over `asset` on this chain and (if nothing else is preventing it) allow the + /// asset to be transferred. + /// + /// - `asset`: The asset to be unlocked. + /// - `target`: The owner of the asset on the local chain. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + UnlockAsset { asset: Asset, target: Location }, + + /// Asset (`asset`) has been locked on the `origin` system and may not be transferred. It may + /// only be unlocked with the receipt of the `UnlockAsset` instruction from this chain. + /// + /// - `asset`: The asset(s) which are now unlockable from this origin. + /// - `owner`: The owner of the asset on the chain in which it was locked. This may be a + /// location specific to the origin network. + /// + /// Safety: `origin` must be trusted to have locked the corresponding `asset` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + NoteUnlockable { asset: Asset, owner: Location }, + + /// Send an `UnlockAsset` instruction to the `locker` for the given `asset`. + /// + /// This may fail if the local system is making use of the fact that the asset is locked or, + /// of course, if there is no record that the asset actually is locked. + /// + /// - `asset`: The asset(s) to be unlocked. + /// - `locker`: The location from which a previous `NoteUnlockable` was sent and to which an + /// `UnlockAsset` should be sent. + /// + /// Kind: *Command*. + /// + /// Errors: + RequestUnlock { asset: Asset, locker: Location }, + + /// Sets the Fees Mode Register. + /// + /// - `jit_withdraw`: The fees mode item; if set to `true` then fees for any instructions are + /// withdrawn as needed using the same mechanism as `WithdrawAssets`. + /// + /// Kind: *Command*. + /// + /// Errors: + SetFeesMode { jit_withdraw: bool }, + + /// Set the Topic Register. + /// + /// The 32-byte array identifier in the parameter is not guaranteed to be + /// unique; if such a property is desired, it is up to the code author to + /// enforce uniqueness. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + SetTopic([u8; 32]), + + /// Clear the Topic Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearTopic, + + /// Alter the current Origin to another given origin. + /// + /// Kind: *Command* + /// + /// Errors: If the existing state would not allow such a change. + AliasOrigin(Location), + + /// A directive to indicate that the origin expects free execution of the message. + /// + /// At execution time, this instruction just does a check on the Origin register. + /// However, at the barrier stage messages starting with this instruction can be disregarded if + /// the origin is not acceptable for free execution or the `weight_limit` is `Limited` and + /// insufficient. + /// + /// Kind: *Indication* + /// + /// Errors: If the given origin is `Some` and not equal to the current Origin register. + UnpaidExecution { weight_limit: WeightLimit, check_origin: Option }, +} + +impl Xcm { + pub fn into(self) -> Xcm { + Xcm::from(self) + } + pub fn from(xcm: Xcm) -> Self { + Self(xcm.0.into_iter().map(Instruction::::from).collect()) + } +} + +impl Instruction { + pub fn into(self) -> Instruction { + Instruction::from(self) + } + pub fn from(xcm: Instruction) -> Self { + use Instruction::*; + match xcm { + WithdrawAsset(assets) => WithdrawAsset(assets), + ReserveAssetDeposited(assets) => ReserveAssetDeposited(assets), + ReceiveTeleportedAsset(assets) => ReceiveTeleportedAsset(assets), + QueryResponse { query_id, response, max_weight, querier } => + QueryResponse { query_id, response, max_weight, querier }, + TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary }, + TransferReserveAsset { assets, dest, xcm } => + TransferReserveAsset { assets, dest, xcm }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => ReportError(response_info), + DepositAsset { assets, beneficiary } => DepositAsset { assets, beneficiary }, + DepositReserveAsset { assets, dest, xcm } => DepositReserveAsset { assets, dest, xcm }, + ExchangeAsset { give, want, maximal } => ExchangeAsset { give, want, maximal }, + InitiateReserveWithdraw { assets, reserve, xcm } => + InitiateReserveWithdraw { assets, reserve, xcm }, + InitiateTeleport { assets, dest, xcm } => InitiateTeleport { assets, dest, xcm }, + ReportHolding { response_info, assets } => ReportHolding { response_info, assets }, + BuyExecution { fees, weight_limit } => BuyExecution { fees, weight_limit }, + ClearOrigin => ClearOrigin, + DescendOrigin(who) => DescendOrigin(who), + RefundSurplus => RefundSurplus, + SetErrorHandler(xcm) => SetErrorHandler(xcm.into()), + SetAppendix(xcm) => SetAppendix(xcm.into()), + ClearError => ClearError, + ClaimAsset { assets, ticket } => ClaimAsset { assets, ticket }, + Trap(code) => Trap(code), + SubscribeVersion { query_id, max_response_weight } => + SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => UnsubscribeVersion, + BurnAsset(assets) => BurnAsset(assets), + ExpectAsset(assets) => ExpectAsset(assets), + ExpectOrigin(origin) => ExpectOrigin(origin), + ExpectError(error) => ExpectError(error), + ExpectTransactStatus(transact_status) => ExpectTransactStatus(transact_status), + QueryPallet { module_name, response_info } => + QueryPallet { module_name, response_info }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => ReportTransactStatus(response_info), + ClearTransactStatus => ClearTransactStatus, + UniversalOrigin(j) => UniversalOrigin(j), + ExportMessage { network, destination, xcm } => + ExportMessage { network, destination, xcm }, + LockAsset { asset, unlocker } => LockAsset { asset, unlocker }, + UnlockAsset { asset, target } => UnlockAsset { asset, target }, + NoteUnlockable { asset, owner } => NoteUnlockable { asset, owner }, + RequestUnlock { asset, locker } => RequestUnlock { asset, locker }, + SetFeesMode { jit_withdraw } => SetFeesMode { jit_withdraw }, + SetTopic(topic) => SetTopic(topic), + ClearTopic => ClearTopic, + AliasOrigin(location) => AliasOrigin(location), + UnpaidExecution { weight_limit, check_origin } => + UnpaidExecution { weight_limit, check_origin }, + } + } +} + +// TODO: Automate Generation +impl> GetWeight for Instruction { + fn weight(&self) -> Weight { + use Instruction::*; + match self { + WithdrawAsset(assets) => W::withdraw_asset(assets), + ReserveAssetDeposited(assets) => W::reserve_asset_deposited(assets), + ReceiveTeleportedAsset(assets) => W::receive_teleported_asset(assets), + QueryResponse { query_id, response, max_weight, querier } => + W::query_response(query_id, response, max_weight, querier), + TransferAsset { assets, beneficiary } => W::transfer_asset(assets, beneficiary), + TransferReserveAsset { assets, dest, xcm } => + W::transfer_reserve_asset(&assets, dest, xcm), + Transact { origin_kind, require_weight_at_most, call } => + W::transact(origin_kind, require_weight_at_most, call), + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + W::hrmp_new_channel_open_request(sender, max_message_size, max_capacity), + HrmpChannelAccepted { recipient } => W::hrmp_channel_accepted(recipient), + HrmpChannelClosing { initiator, sender, recipient } => + W::hrmp_channel_closing(initiator, sender, recipient), + ClearOrigin => W::clear_origin(), + DescendOrigin(who) => W::descend_origin(who), + ReportError(response_info) => W::report_error(&response_info), + DepositAsset { assets, beneficiary } => W::deposit_asset(assets, beneficiary), + DepositReserveAsset { assets, dest, xcm } => + W::deposit_reserve_asset(assets, dest, xcm), + ExchangeAsset { give, want, maximal } => W::exchange_asset(give, want, maximal), + InitiateReserveWithdraw { assets, reserve, xcm } => + W::initiate_reserve_withdraw(assets, reserve, xcm), + InitiateTeleport { assets, dest, xcm } => W::initiate_teleport(assets, dest, xcm), + ReportHolding { response_info, assets } => W::report_holding(&response_info, &assets), + BuyExecution { fees, weight_limit } => W::buy_execution(fees, weight_limit), + RefundSurplus => W::refund_surplus(), + SetErrorHandler(xcm) => W::set_error_handler(xcm), + SetAppendix(xcm) => W::set_appendix(xcm), + ClearError => W::clear_error(), + ClaimAsset { assets, ticket } => W::claim_asset(assets, ticket), + Trap(code) => W::trap(code), + SubscribeVersion { query_id, max_response_weight } => + W::subscribe_version(query_id, max_response_weight), + UnsubscribeVersion => W::unsubscribe_version(), + BurnAsset(assets) => W::burn_asset(assets), + ExpectAsset(assets) => W::expect_asset(assets), + ExpectOrigin(origin) => W::expect_origin(origin), + ExpectError(error) => W::expect_error(error), + ExpectTransactStatus(transact_status) => W::expect_transact_status(transact_status), + QueryPallet { module_name, response_info } => + W::query_pallet(module_name, response_info), + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + W::expect_pallet(index, name, module_name, crate_major, min_crate_minor), + ReportTransactStatus(response_info) => W::report_transact_status(response_info), + ClearTransactStatus => W::clear_transact_status(), + UniversalOrigin(j) => W::universal_origin(j), + ExportMessage { network, destination, xcm } => + W::export_message(network, destination, xcm), + LockAsset { asset, unlocker } => W::lock_asset(asset, unlocker), + UnlockAsset { asset, target } => W::unlock_asset(asset, target), + NoteUnlockable { asset, owner } => W::note_unlockable(asset, owner), + RequestUnlock { asset, locker } => W::request_unlock(asset, locker), + SetFeesMode { jit_withdraw } => W::set_fees_mode(jit_withdraw), + SetTopic(topic) => W::set_topic(topic), + ClearTopic => W::clear_topic(), + AliasOrigin(location) => W::alias_origin(location), + UnpaidExecution { weight_limit, check_origin } => + W::unpaid_execution(weight_limit, check_origin), + } + } +} + +pub mod opaque { + /// The basic concrete type of `Xcm`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Xcm = super::Xcm<()>; + + /// The basic concrete type of `Instruction`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Instruction = super::Instruction<()>; +} + +// Convert from a v3 XCM to a v4 XCM +impl TryFrom> for Xcm { + type Error = (); + fn try_from(old_xcm: OldXcm) -> result::Result { + Ok(Xcm(old_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v3 instruction to a v4 instruction +impl TryFrom> for Instruction { + type Error = (); + fn try_from(old_instruction: OldInstruction) -> result::Result { + use OldInstruction::*; + Ok(match old_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, querier: Some(querier) } => + Self::QueryResponse { + query_id, + querier: querier.try_into()?, + response: response.try_into()?, + max_weight, + }, + QueryResponse { query_id, response, max_weight, querier: None } => + Self::QueryResponse { + query_id, + querier: None, + response: response.try_into()?, + max_weight, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Self::Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => Self::ReportError(QueryResponseInfo { + query_id: response_info.query_id, + destination: response_info.destination.try_into().map_err(|_| ())?, + max_weight: response_info.max_weight, + }), + DepositAsset { assets, beneficiary } => { + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, dest, xcm } + }, + ExchangeAsset { give, want, maximal } => { + let give = give.try_into()?; + let want = want.try_into()?; + Self::ExchangeAsset { give, want, maximal } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => { + let response_info = QueryResponseInfo { + destination: response_info.destination.try_into().map_err(|_| ())?, + query_id: response_info.query_id, + max_weight: response_info.max_weight, + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.into(); + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => + Self::SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => Self::UnsubscribeVersion, + BurnAsset(assets) => Self::BurnAsset(assets.try_into()?), + ExpectAsset(assets) => Self::ExpectAsset(assets.try_into()?), + ExpectOrigin(maybe_location) => Self::ExpectOrigin( + maybe_location.map(|location| location.try_into()).transpose().map_err(|_| ())?, + ), + ExpectError(maybe_error) => Self::ExpectError( + maybe_error.map(|error| error.try_into()).transpose().map_err(|_| ())?, + ), + ExpectTransactStatus(maybe_error_code) => Self::ExpectTransactStatus(maybe_error_code), + QueryPallet { module_name, response_info } => Self::QueryPallet { + module_name, + response_info: response_info.try_into().map_err(|_| ())?, + }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + Self::ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => + Self::ReportTransactStatus(response_info.try_into().map_err(|_| ())?), + ClearTransactStatus => Self::ClearTransactStatus, + UniversalOrigin(junction) => + Self::UniversalOrigin(junction.try_into().map_err(|_| ())?), + ExportMessage { network, destination, xcm } => Self::ExportMessage { + network: network.into(), + destination: destination.try_into().map_err(|_| ())?, + xcm: xcm.try_into().map_err(|_| ())?, + }, + LockAsset { asset, unlocker } => Self::LockAsset { + asset: asset.try_into().map_err(|_| ())?, + unlocker: unlocker.try_into().map_err(|_| ())?, + }, + UnlockAsset { asset, target } => Self::UnlockAsset { + asset: asset.try_into().map_err(|_| ())?, + target: target.try_into().map_err(|_| ())?, + }, + NoteUnlockable { asset, owner } => Self::NoteUnlockable { + asset: asset.try_into().map_err(|_| ())?, + owner: owner.try_into().map_err(|_| ())?, + }, + RequestUnlock { asset, locker } => Self::RequestUnlock { + asset: asset.try_into().map_err(|_| ())?, + locker: locker.try_into().map_err(|_| ())?, + }, + SetFeesMode { jit_withdraw } => Self::SetFeesMode { jit_withdraw }, + SetTopic(topic) => Self::SetTopic(topic), + ClearTopic => Self::ClearTopic, + AliasOrigin(location) => Self::AliasOrigin(location.try_into().map_err(|_| ())?), + UnpaidExecution { weight_limit, check_origin } => Self::UnpaidExecution { + weight_limit, + check_origin: check_origin + .map(|location| location.try_into()) + .transpose() + .map_err(|_| ())?, + }, + }) + } +} + +#[cfg(test)] +mod tests { + use super::{prelude::*, *}; + use crate::v3::{ + Junctions::Here as OldHere, MultiAssetFilter as OldMultiAssetFilter, + WildMultiAsset as OldWildMultiAsset, + }; + + #[test] + fn basic_roundtrip_works() { + let xcm = Xcm::<()>(vec![TransferAsset { + assets: (Here, 1u128).into(), + beneficiary: Here.into(), + }]); + let old_xcm = OldXcm::<()>(vec![OldInstruction::TransferAsset { + assets: (OldHere, 1u128).into(), + beneficiary: OldHere.into(), + }]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn teleport_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReceiveTeleportedAsset((Here, 1u128).into()), + ClearOrigin, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm: OldXcm<()> = OldXcm::<()>(vec![ + OldInstruction::ReceiveTeleportedAsset((OldHere, 1u128).into()), + OldInstruction::ClearOrigin, + OldInstruction::DepositAsset { + assets: crate::v3::MultiAssetFilter::Wild(crate::v3::WildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn reserve_deposit_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReserveAssetDeposited((Here, 1u128).into()), + ClearOrigin, + BuyExecution { + fees: (Here, 1u128).into(), + weight_limit: Some(Weight::from_parts(1, 1)).into(), + }, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::ReserveAssetDeposited((OldHere, 1u128).into()), + OldInstruction::ClearOrigin, + OldInstruction::BuyExecution { + fees: (OldHere, 1u128).into(), + weight_limit: WeightLimit::Limited(Weight::from_parts(1, 1)), + }, + OldInstruction::DepositAsset { + assets: crate::v3::MultiAssetFilter::Wild(crate::v3::WildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::DepositAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_reserve_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositReserveAsset { + assets: Wild(AllCounted(1)), + dest: Here.into(), + xcm: Xcm::<()>(vec![]), + }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::DepositReserveAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::AllCounted(1)), + dest: OldHere.into(), + xcm: OldXcm::<()>(vec![]), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } +} diff --git a/polkadot/xcm/src/v4/traits.rs b/polkadot/xcm/src/v4/traits.rs new file mode 100644 index 000000000000..f6136c76d808 --- /dev/null +++ b/polkadot/xcm/src/v4/traits.rs @@ -0,0 +1,312 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Cross-Consensus Message format data structures. + +pub use crate::v3::{Error, Result, SendError, XcmHash}; +use core::result; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +pub use sp_weights::Weight; + +use super::*; + +/// Outcome of an XCM execution. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete { used: Weight }, + /// Execution started, but did not complete successfully due to the given error; given weight + /// was used. + Incomplete { used: Weight, error: Error }, + /// Execution did not start due to the given error. + Error { error: Error }, +} + +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { + Outcome::Complete { .. } => Ok(()), + Outcome::Incomplete { error, .. } => Err(error), + Outcome::Error { error, .. } => Err(error), + } + } + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete { used, .. } => Ok(used), + Outcome::Incomplete { used, .. } => Ok(used), + Outcome::Error { error, .. } => Err(error), + } + } + /// How much weight was used by the XCM execution attempt. + pub fn weight_used(&self) -> Weight { + match self { + Outcome::Complete { used, .. } => *used, + Outcome::Incomplete { used, .. } => *used, + Outcome::Error { .. } => Weight::zero(), + } + } +} + +impl From for Outcome { + fn from(error: Error) -> Self { + Self::Error { error } + } +} + +pub trait PreparedMessage { + fn weight_of(&self) -> Weight; +} + +/// Type of XCM message executor. +pub trait ExecuteXcm { + type Prepared: PreparedMessage; + fn prepare(message: Xcm) -> result::Result>; + fn execute( + origin: impl Into, + pre: Self::Prepared, + id: &mut XcmHash, + weight_credit: Weight, + ) -> Outcome; + fn prepare_and_execute( + origin: impl Into, + message: Xcm, + id: &mut XcmHash, + weight_limit: Weight, + weight_credit: Weight, + ) -> Outcome { + let pre = match Self::prepare(message) { + Ok(x) => x, + Err(_) => return Outcome::Error { error: Error::WeightNotComputable }, + }; + let xcm_weight = pre.weight_of(); + if xcm_weight.any_gt(weight_limit) { + return Outcome::Error { error: Error::WeightLimitReached(xcm_weight) } + } + Self::execute(origin, pre, id, weight_credit) + } + + /// Deduct some `fees` to the sovereign account of the given `location` and place them as per + /// the convention for fees. + fn charge_fees(location: impl Into, fees: Assets) -> Result; +} + +pub enum Weightless {} +impl PreparedMessage for Weightless { + fn weight_of(&self) -> Weight { + unreachable!() + } +} + +impl ExecuteXcm for () { + type Prepared = Weightless; + fn prepare(message: Xcm) -> result::Result> { + Err(message) + } + fn execute(_: impl Into, _: Self::Prepared, _: &mut XcmHash, _: Weight) -> Outcome { + unreachable!() + } + fn charge_fees(_location: impl Into, _fees: Assets) -> Result { + Err(Error::Unimplemented) + } +} + +pub trait Reanchorable: Sized { + /// Type to return in case of an error. + type Error: Debug; + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + fn reanchor( + &mut self, + target: &Location, + context: &InteriorLocation, + ) -> core::result::Result<(), ()>; + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + fn reanchored( + self, + target: &Location, + context: &InteriorLocation, + ) -> core::result::Result; +} + +/// Result value when attempting to send an XCM message. +pub type SendResult = result::Result<(T, Assets), SendError>; + +/// Utility for sending an XCM message to a given location. +/// +/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each +/// router might return `NotApplicable` to pass the execution to the next sender item. Note that +/// each `NotApplicable` might alter the destination and the XCM message for to the next router. +/// +/// # Example +/// ```rust +/// # use parity_scale_codec::Encode; +/// # use staging_xcm::v4::{prelude::*, Weight}; +/// # use staging_xcm::VersionedXcm; +/// # use std::convert::Infallible; +/// +/// /// A sender that only passes the message through and does nothing. +/// struct Sender1; +/// impl SendXcm for Sender1 { +/// type Ticket = Infallible; +/// fn validate(_: &mut Option, _: &mut Option>) -> SendResult { +/// Err(SendError::NotApplicable) +/// } +/// fn deliver(_: Infallible) -> Result { +/// unreachable!() +/// } +/// } +/// +/// /// A sender that accepts a message that has two junctions, otherwise stops the routing. +/// struct Sender2; +/// impl SendXcm for Sender2 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)?.unpack() { +/// (0, [j1, j2]) => Ok(((), Assets::new())), +/// _ => Err(SendError::Unroutable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// /// A sender that accepts a message from a parent, passing through otherwise. +/// struct Sender3; +/// impl SendXcm for Sender3 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)?.unpack() { +/// (1, []) => Ok(((), Assets::new())), +/// _ => Err(SendError::NotApplicable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// // A call to send via XCM. We don't really care about this. +/// # fn main() { +/// let call: Vec = ().encode(); +/// let message = Xcm(vec![Instruction::Transact { +/// origin_kind: OriginKind::Superuser, +/// require_weight_at_most: Weight::zero(), +/// call: call.into(), +/// }]); +/// let message_hash = message.using_encoded(sp_io::hashing::blake2_256); +/// +/// // Sender2 will block this. +/// assert!(send_xcm::<(Sender1, Sender2, Sender3)>(Parent.into(), message.clone()).is_err()); +/// +/// // Sender3 will catch this. +/// assert!(send_xcm::<(Sender1, Sender3)>(Parent.into(), message.clone()).is_ok()); +/// # } +/// ``` +pub trait SendXcm { + /// Intermediate value which connects the two phases of the send operation. + type Ticket; + + /// Check whether the given `_message` is deliverable to the given `_destination` and if so + /// determine the cost which will be paid by this chain to do so, returning a `Validated` token + /// which can be used to enact delivery. + /// + /// The `destination` and `message` must be `Some` (or else an error will be returned) and they + /// may only be consumed if the `Err` is not `NotApplicable`. + /// + /// If it is not a destination which can be reached with this type but possibly could by others, + /// then this *MUST* return `NotApplicable`. Any other error will cause the tuple + /// implementation to exit early without trying other type fields. + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult; + + /// Actually carry out the delivery operation for a previously validated message sending. + fn deliver(ticket: Self::Ticket) -> result::Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl SendXcm for Tuple { + for_tuples! { type Ticket = (#( Option ),* ); } + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut maybe_cost: Option = None; + let one_ticket: Self::Ticket = (for_tuples! { #( + if maybe_cost.is_some() { + None + } else { + match Tuple::validate(destination, message) { + Err(SendError::NotApplicable) => None, + Err(e) => { return Err(e) }, + Ok((v, c)) => { + maybe_cost = Some(c); + Some(v) + }, + } + } + ),* }); + if let Some(cost) = maybe_cost { + Ok((one_ticket, cost)) + } else { + Err(SendError::NotApplicable) + } + } + + fn deliver(one_ticket: Self::Ticket) -> result::Result { + for_tuples!( #( + if let Some(validated) = one_ticket.Tuple { + return Tuple::deliver(validated); + } + )* ); + Err(SendError::Unroutable) + } +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +pub fn validate_send(dest: Location, msg: Xcm<()>) -> SendResult { + T::validate(&mut Some(dest), &mut Some(msg)) +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +/// +/// Returns either `Ok` with the price of the delivery, or `Err` with the reason why the message +/// could not be sent. +/// +/// Generally you'll want to validate and get the price first to ensure that the sender can pay it +/// before actually doing the delivery. +pub fn send_xcm( + dest: Location, + msg: Xcm<()>, +) -> result::Result<(XcmHash, Assets), SendError> { + let (ticket, price) = T::validate(&mut Some(dest), &mut Some(msg))?; + let hash = T::deliver(ticket)?; + Ok((hash, price)) +} diff --git a/polkadot/xcm/xcm-builder/src/asset_conversion.rs b/polkadot/xcm/xcm-builder/src/asset_conversion.rs index 5b76ed764a81..e38af149be54 100644 --- a/polkadot/xcm/xcm-builder/src/asset_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/asset_conversion.rs @@ -23,39 +23,42 @@ use xcm::latest::prelude::*; use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles}; /// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be -/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `MultiLocation` value. -/// The `MultiLocation` value will typically be a `PalletInstance` junction. -pub struct AsPrefixedGeneralIndex( - PhantomData<(Prefix, AssetId, ConvertAssetId)>, +/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `Location` value. +/// The `Location` value will typically be a `PalletInstance` junction. +pub struct AsPrefixedGeneralIndex( + PhantomData<(Prefix, AssetId, ConvertAssetId, L)>, ); impl< - Prefix: Get, + Prefix: Get, AssetId: Clone, ConvertAssetId: MaybeEquivalence, - > MaybeEquivalence - for AsPrefixedGeneralIndex + L: TryInto + TryFrom + Clone, + > MaybeEquivalence for AsPrefixedGeneralIndex { - fn convert(id: &MultiLocation) -> Option { + fn convert(id: &L) -> Option { let prefix = Prefix::get(); - if prefix.parent_count() != id.parent_count() || - prefix + let latest_prefix: Location = prefix.try_into().ok()?; + let latest_id: Location = (*id).clone().try_into().ok()?; + if latest_prefix.parent_count() != latest_id.parent_count() || + latest_prefix .interior() .iter() .enumerate() - .any(|(index, junction)| id.interior().at(index) != Some(junction)) + .any(|(index, junction)| latest_id.interior().at(index) != Some(junction)) { return None } - match id.interior().at(prefix.interior().len()) { - Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(id), + match latest_id.interior().at(latest_prefix.interior().len()) { + Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(&id), _ => None, } } - fn convert_back(what: &AssetId) -> Option { - let mut location = Prefix::get(); + fn convert_back(what: &AssetId) -> Option { + let location = Prefix::get(); + let mut latest_location: Location = location.try_into().ok()?; let id = ConvertAssetId::convert_back(what)?; - location.push_interior(Junction::GeneralIndex(id)).ok()?; - Some(location) + latest_location.push_interior(Junction::GeneralIndex(id)).ok()?; + latest_location.try_into().ok() } } @@ -65,14 +68,14 @@ pub struct ConvertedConcreteId( impl< AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, > MatchesFungibles for ConvertedConcreteId { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), MatchError> { let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Concrete(ref id)) => (amount, id), + (Fungible(ref amount), AssetId(ref id)) => (amount, id), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; @@ -84,14 +87,14 @@ impl< impl< ClassId: Clone, InstanceId: Clone, - ConvertClassId: MaybeEquivalence, + ConvertClassId: MaybeEquivalence, ConvertInstanceId: MaybeEquivalence, > MatchesNonFungibles for ConvertedConcreteId { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> { let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Concrete(ref class)) => (instance, class), + (NonFungible(ref instance), AssetId(ref class)) => (instance, class), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; @@ -101,68 +104,35 @@ impl< } } -pub struct ConvertedAbstractId( - PhantomData<(AssetId, Balance, ConvertAssetId, ConvertOther)>, -); -impl< - AssetId: Clone, - Balance: Clone, - ConvertAssetId: MaybeEquivalence<[u8; 32], AssetId>, - ConvertBalance: MaybeEquivalence, - > MatchesFungibles - for ConvertedAbstractId -{ - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { - let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Abstract(ref id)) => (amount, id), - _ => return Err(MatchError::AssetNotHandled), - }; - let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; - let amount = - ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?; - Ok((what, amount)) +#[deprecated = "Use `ConvertedConcreteId` instead"] +pub type ConvertedConcreteAssetId = ConvertedConcreteId; + +pub struct V4V3LocationConverter; +impl MaybeEquivalence for V4V3LocationConverter { + fn convert(old: &xcm::v4::Location) -> Option { + (*old).clone().try_into().ok() } -} -impl< - ClassId: Clone, - InstanceId: Clone, - ConvertClassId: MaybeEquivalence<[u8; 32], ClassId>, - ConvertInstanceId: MaybeEquivalence, - > MatchesNonFungibles - for ConvertedAbstractId -{ - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { - let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Abstract(ref class)) => (instance, class), - _ => return Err(MatchError::AssetNotHandled), - }; - let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; - let instance = - ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?; - Ok((what, instance)) + + fn convert_back(new: &xcm::v3::Location) -> Option { + (*new).try_into().ok() } } -#[deprecated = "Use `ConvertedConcreteId` instead"] -pub type ConvertedConcreteAssetId = ConvertedConcreteId; -#[deprecated = "Use `ConvertedAbstractId` instead"] -pub type ConvertedAbstractAssetId = ConvertedAbstractId; - pub struct MatchedConvertedConcreteId( PhantomData<(AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertOther)>, ); impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, > MatchesFungibles for MatchedConvertedConcreteId { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), MatchError> { let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Concrete(ref id)) if MatchAssetId::contains(id) => (amount, id), + (Fungible(ref amount), AssetId(ref id)) if MatchAssetId::contains(id) => (amount, id), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; @@ -174,15 +144,15 @@ impl< impl< ClassId: Clone, InstanceId: Clone, - MatchClassId: Contains, - ConvertClassId: MaybeEquivalence, + MatchClassId: Contains, + ConvertClassId: MaybeEquivalence, ConvertInstanceId: MaybeEquivalence, > MatchesNonFungibles for MatchedConvertedConcreteId { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> { let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Concrete(ref class)) if MatchClassId::contains(class) => + (NonFungible(ref instance), AssetId(ref class)) if MatchClassId::contains(class) => (instance, class), _ => return Err(MatchError::AssetNotHandled), }; @@ -200,10 +170,10 @@ mod tests { use xcm_executor::traits::JustTry; struct OnlyParentZero; - impl Contains for OnlyParentZero { - fn contains(a: &MultiLocation) -> bool { + impl Contains for OnlyParentZero { + fn contains(a: &Location) -> bool { match a { - MultiLocation { parents: 0, .. } => true, + Location { parents: 0, .. } => true, _ => false, } } @@ -214,7 +184,7 @@ mod tests { type AssetIdForTrustBackedAssets = u32; type Balance = u128; frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + pub TrustBackedAssetsPalletLocation: Location = PalletInstance(50).into(); } // ConvertedConcreteId cfg @@ -231,13 +201,13 @@ mod tests { >; assert_eq!( TrustBackedAssetsPalletLocation::get(), - MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + Location { parents: 0, interior: [PalletInstance(50)].into() } ); // err - does not match assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(1, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Err(MatchError::AssetNotHandled) @@ -245,10 +215,10 @@ mod tests { // err - matches, but convert fails assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new( + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new( 0, - X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + [PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }] )), fun: Fungible(12345), }), @@ -257,8 +227,8 @@ mod tests { // err - matches, but NonFungible assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Err(MatchError::AssetNotHandled) @@ -266,8 +236,8 @@ mod tests { // ok assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Ok((1, 12345)) @@ -279,7 +249,7 @@ mod tests { type ClassId = u32; type ClassInstanceId = u64; frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + pub TrustBackedAssetsPalletLocation: Location = PalletInstance(50).into(); } // ConvertedConcreteId cfg @@ -303,13 +273,13 @@ mod tests { >; assert_eq!( TrustBackedAssetsPalletLocation::get(), - MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + Location { parents: 0, interior: [PalletInstance(50)].into() } ); // err - does not match assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(1, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Err(MatchError::AssetNotHandled) @@ -317,10 +287,10 @@ mod tests { // err - matches, but convert fails assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new( + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new( 0, - X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + [PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }] )), fun: NonFungible(Index(54321)), }), @@ -329,8 +299,8 @@ mod tests { // err - matches, but Fungible vs NonFungible assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Err(MatchError::AssetNotHandled) @@ -338,8 +308,8 @@ mod tests { // ok assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Ok((1, 54321)) diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index c2b62751c688..80411ab5a224 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -34,7 +34,7 @@ use xcm_executor::traits::{CheckSuspension, OnResponse, Properties, ShouldExecut pub struct TakeWeightCredit; impl ShouldExecute for TakeWeightCredit { fn should_execute( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -60,9 +60,9 @@ const MAX_ASSETS_FOR_BUY_EXECUTION: usize = 2; /// Only allows for `TeleportAsset`, `WithdrawAsset`, `ClaimAsset` and `ReserveAssetDeposit` XCMs /// because they are the only ones that place assets in the Holding Register to pay for execution. pub struct AllowTopLevelPaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { +impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, _properties: &mut Properties, @@ -158,14 +158,11 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro pub struct WithComputedOrigin( PhantomData<(InnerBarrier, LocalUniversal, MaxPrefixes)>, ); -impl< - InnerBarrier: ShouldExecute, - LocalUniversal: Get, - MaxPrefixes: Get, - > ShouldExecute for WithComputedOrigin +impl, MaxPrefixes: Get> + ShouldExecute for WithComputedOrigin { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -175,7 +172,7 @@ impl< "WithComputedOrigin origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", origin, instructions, max_weight, properties, ); - let mut actual_origin = *origin; + let mut actual_origin = origin.clone(); let skipped = Cell::new(0usize); // NOTE: We do not check the validity of `UniversalOrigin` here, meaning that a malicious // origin could place a `UniversalOrigin` in order to spoof some location which gets free @@ -190,10 +187,11 @@ impl< // Note the origin is *relative to local consensus*! So we need to escape // local consensus with the `parents` before diving in into the // `universal_location`. - actual_origin = X1(*new_global).relative_to(&LocalUniversal::get()); + actual_origin = + Junctions::from([*new_global]).relative_to(&LocalUniversal::get()); }, DescendOrigin(j) => { - let Ok(_) = actual_origin.append_with(*j) else { + let Ok(_) = actual_origin.append_with(j.clone()) else { return Err(ProcessMessageError::Unsupported) }; }, @@ -221,7 +219,7 @@ impl< pub struct TrailingSetTopicAsId(PhantomData); impl ShouldExecute for TrailingSetTopicAsId { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -250,7 +248,7 @@ where SuspensionChecker: CheckSuspension, { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -268,9 +266,9 @@ where /// Use only for executions from completely trusted origins, from which no permissionless messages /// can be sent. pub struct AllowUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowUnpaidExecutionFrom { +impl> ShouldExecute for AllowUnpaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -290,9 +288,9 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { /// /// Use only for executions from trusted origin groups. pub struct AllowExplicitUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { +impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, _properties: &mut Properties, @@ -314,11 +312,11 @@ impl> ShouldExecute for AllowExplicitUnpaidExecutionF /// Allows a message only if it is from a system-level child parachain. pub struct IsChildSystemParachain(PhantomData); -impl> Contains for IsChildSystemParachain { - fn contains(l: &MultiLocation) -> bool { +impl> Contains for IsChildSystemParachain { + fn contains(l: &Location) -> bool { matches!( - l.interior(), - Junctions::X1(Junction::Parachain(id)) + l.interior().as_slice(), + [Junction::Parachain(id)] if ParaId::from(*id).is_system() && l.parent_count() == 0, ) } @@ -328,7 +326,7 @@ impl> Contains for IsChildSystemPara pub struct AllowKnownQueryResponses(PhantomData); impl ShouldExecute for AllowKnownQueryResponses { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -354,9 +352,9 @@ impl ShouldExecute for AllowKnownQueryResponses(PhantomData); -impl> ShouldExecute for AllowSubscriptionsFrom { +impl> ShouldExecute for AllowSubscriptionsFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -391,7 +389,7 @@ where Allow: ShouldExecute, { fn should_execute( - origin: &MultiLocation, + origin: &Location, message: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -405,7 +403,7 @@ where pub struct DenyReserveTransferToRelayChain; impl ShouldExecute for DenyReserveTransferToRelayChain { fn should_execute( - origin: &MultiLocation, + origin: &Location, message: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -414,22 +412,18 @@ impl ShouldExecute for DenyReserveTransferToRelayChain { |_| true, |inst| match inst { InitiateReserveWithdraw { - reserve: MultiLocation { parents: 1, interior: Here }, + reserve: Location { parents: 1, interior: Here }, .. } | - DepositReserveAsset { - dest: MultiLocation { parents: 1, interior: Here }, .. - } | - TransferReserveAsset { - dest: MultiLocation { parents: 1, interior: Here }, .. - } => { + DepositReserveAsset { dest: Location { parents: 1, interior: Here }, .. } | + TransferReserveAsset { dest: Location { parents: 1, interior: Here }, .. } => { Err(ProcessMessageError::Unsupported) // Deny }, // An unexpected reserve transfer has arrived from the Relay Chain. Generally, // `IsReserve` should not allow this, but we just log it here. ReserveAssetDeposited { .. } - if matches!(origin, MultiLocation { parents: 1, interior: Here }) => + if matches!(origin, Location { parents: 1, interior: Here }) => { log::warn!( target: "xcm::barrier", diff --git a/polkadot/xcm/xcm-builder/src/controller.rs b/polkadot/xcm/xcm-builder/src/controller.rs index 931d812eaaf1..8ead18b5bd7f 100644 --- a/polkadot/xcm/xcm-builder/src/controller.rs +++ b/polkadot/xcm/xcm-builder/src/controller.rs @@ -45,7 +45,7 @@ pub trait ExecuteControllerWeightInfo { /// Execute an XCM locally, for a given origin. /// /// An implementation of that trait will handle the low-level details of the execution, such as: -/// - Validating and Converting the origin to a MultiLocation. +/// - Validating and Converting the origin to a Location. /// - Handling versioning. /// - Calling the internal executor, which implements [`ExecuteXcm`]. pub trait ExecuteController { @@ -92,7 +92,7 @@ pub trait SendController { /// - `msg`: the XCM to be sent. fn send( origin: Origin, - dest: Box, + dest: Box, message: Box>, ) -> Result; } @@ -127,7 +127,7 @@ pub trait QueryController: QueryHandler { fn query( origin: Origin, timeout: Timeout, - match_querier: VersionedMultiLocation, + match_querier: VersionedLocation, ) -> Result; } @@ -138,7 +138,7 @@ impl ExecuteController for () { _message: Box>, _max_weight: Weight, ) -> Result { - Ok(Outcome::Error(XcmError::Unimplemented)) + Ok(Outcome::Error { error: XcmError::Unimplemented }) } } @@ -152,7 +152,7 @@ impl SendController for () { type WeightInfo = (); fn send( _origin: Origin, - _dest: Box, + _dest: Box, _message: Box>, ) -> Result { Ok(Default::default()) @@ -180,7 +180,7 @@ impl QueryController for () { fn query( _origin: Origin, _timeout: Timeout, - _match_querier: VersionedMultiLocation, + _match_querier: VersionedLocation, ) -> Result { Ok(Default::default()) } diff --git a/polkadot/xcm/xcm-builder/src/currency_adapter.rs b/polkadot/xcm/xcm-builder/src/currency_adapter.rs index 68ca0111174f..fe26b7319bb1 100644 --- a/polkadot/xcm/xcm-builder/src/currency_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/currency_adapter.rs @@ -22,17 +22,17 @@ use super::MintLocation; use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons}; use sp_runtime::traits::CheckedSub; use sp_std::{marker::PhantomData, result}; -use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result, XcmContext}; +use xcm::latest::{Asset, Error as XcmError, Location, Result, XcmContext}; use xcm_executor::{ traits::{ConvertLocation, MatchesFungible, TransactAsset}, - Assets, + AssetsInHolding, }; /// Asset transaction errors. enum Error { /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) AssetNotHandled, - /// `MultiLocation` to `AccountId` conversion failed. + /// `Location` to `AccountId` conversion failed. AccountIdConversionFailed, } @@ -62,7 +62,7 @@ impl From for XcmError { /// /// /// Our relay chain's location. /// parameter_types! { -/// pub RelayChain: MultiLocation = Parent.into(); +/// pub RelayChain: Location = Parent.into(); /// pub CheckingAccount: AccountId = PalletId(*b"checking").into_account_truncating(); /// } /// @@ -142,7 +142,7 @@ impl< > TransactAsset for CurrencyAdapter { - fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> Result { log::trace!(target: "xcm::currency_adapter", "can_check_in origin: {:?}, what: {:?}", _origin, what); // Check we handle this asset. let amount: Currency::Balance = @@ -156,7 +156,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!(target: "xcm::currency_adapter", "check_in origin: {:?}, what: {:?}", _origin, what); if let Some(amount) = Matcher::matches_fungible(what) { match CheckedAccount::get() { @@ -169,7 +169,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + fn can_check_out(_dest: &Location, what: &Asset, _context: &XcmContext) -> Result { log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; match CheckedAccount::get() { @@ -181,7 +181,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); if let Some(amount) = Matcher::matches_fungible(what) { match CheckedAccount::get() { @@ -194,11 +194,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> Result { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> Result { log::trace!(target: "xcm::currency_adapter", "deposit_asset what: {:?}, who: {:?}", what, who); // Check we handle this asset. let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotHandled)?; @@ -209,10 +205,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!(target: "xcm::currency_adapter", "withdraw_asset what: {:?}, who: {:?}", what, who); // Check we handle this asset. let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; @@ -224,11 +220,11 @@ impl< } fn internal_transfer_asset( - asset: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + asset: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to); let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotHandled)?; let from = diff --git a/polkadot/xcm/xcm-builder/src/fee_handling.rs b/polkadot/xcm/xcm-builder/src/fee_handling.rs index c158d5d862d7..e114b3601c84 100644 --- a/polkadot/xcm/xcm-builder/src/fee_handling.rs +++ b/polkadot/xcm/xcm-builder/src/fee_handling.rs @@ -25,27 +25,22 @@ pub trait HandleFee { /// fees. /// /// Returns any part of the fee that wasn't consumed. - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) - -> MultiAssets; + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets; } // Default `HandleFee` implementation that just burns the fee. impl HandleFee for () { - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) -> MultiAssets { - MultiAssets::new() + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) -> Assets { + Assets::new() } } #[impl_trait_for_tuples::impl_for_tuples(1, 30)] impl HandleFee for Tuple { - fn handle_fee( - fee: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets { let mut unconsumed_fee = fee; for_tuples!( #( - unconsumed_fee = Tuple::handle_fee(unconsumed_fee, context, reason); + unconsumed_fee = Tuple::handle_fee(unconsumed_fee, context, reason.clone()); if unconsumed_fee.is_none() { return unconsumed_fee; } @@ -60,15 +55,15 @@ impl HandleFee for Tuple { pub struct XcmFeeManagerFromComponents( PhantomData<(WaivedLocations, HandleFee)>, ); -impl, FeeHandler: HandleFee> FeeManager +impl, FeeHandler: HandleFee> FeeManager for XcmFeeManagerFromComponents { - fn is_waived(origin: Option<&MultiLocation>, _: FeeReason) -> bool { + fn is_waived(origin: Option<&Location>, _: FeeReason) -> bool { let Some(loc) = origin else { return false }; WaivedLocations::contains(loc) } - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) { FeeHandler::handle_fee(fee, context, reason); } } @@ -76,7 +71,7 @@ impl, FeeHandler: HandleFee> FeeManager /// Try to deposit the given fee in the specified account. /// Burns the fee in case of a failure. pub fn deposit_or_burn_fee>( - fee: MultiAssets, + fee: Assets, context: Option<&XcmContext>, receiver: AccountId, ) { @@ -109,13 +104,9 @@ impl< ReceiverAccount: Get, > HandleFee for XcmFeeToAccount { - fn handle_fee( - fee: MultiAssets, - context: Option<&XcmContext>, - _reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, _reason: FeeReason) -> Assets { deposit_or_burn_fee::(fee, context, ReceiverAccount::get()); - MultiAssets::new() + Assets::new() } } diff --git a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs index df81f536f7b7..d80c5d70deea 100644 --- a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs +++ b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs @@ -14,28 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Various implementations of `ContainsPair` or -//! `Contains<(MultiLocation, Vec)>`. +//! Various implementations of `ContainsPair` or +//! `Contains<(Location, Vec)>`. use frame_support::traits::{Contains, ContainsPair, Get}; use sp_std::{marker::PhantomData, vec::Vec}; -use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation, WildMultiAsset}; +use xcm::latest::{Asset, AssetFilter, AssetId, Location, WildAsset}; /// Accepts an asset iff it is a native asset. pub struct NativeAsset; -impl ContainsPair for NativeAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for NativeAsset { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "NativeAsset asset: {:?}, origin: {:?}", asset, origin); - matches!(asset.id, Concrete(ref id) if id == origin) + matches!(asset.id, AssetId(ref id) if id == origin) } } /// Accepts an asset if it is contained in the given `T`'s `Get` implementation. pub struct Case(PhantomData); -impl> ContainsPair - for Case -{ - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for Case { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "Case asset: {:?}, origin: {:?}", asset, origin); let (a, o) = T::get(); a.matches(asset) && &o == origin @@ -44,18 +42,18 @@ impl> ContainsPair( - sp_std::marker::PhantomData<(Location, AssetFilters)>, +/// the `AssetFilter` instances provided by the `Get` implementation of `AssetFilters`. +pub struct LocationWithAssetFilters( + sp_std::marker::PhantomData<(LocationFilter, AssetFilters)>, ); -impl, AssetFilters: Get>> - Contains<(MultiLocation, Vec)> for LocationWithAssetFilters +impl, AssetFilters: Get>> + Contains<(Location, Vec)> for LocationWithAssetFilters { - fn contains((location, assets): &(MultiLocation, Vec)) -> bool { + fn contains((location, assets): &(Location, Vec)) -> bool { log::trace!(target: "xcm::contains", "LocationWithAssetFilters location: {:?}, assets: {:?}", location, assets); // `location` must match the `Location` filter. - if !Location::contains(location) { + if !LocationFilter::contains(location) { return false } @@ -72,12 +70,12 @@ impl, AssetFilters: Get> } } -/// Implementation of `Get>` which accepts every asset. +/// Implementation of `Get>` which accepts every asset. /// (For example, it can be used with `LocationWithAssetFilters`). pub struct AllAssets; -impl Get> for AllAssets { - fn get() -> Vec { - sp_std::vec![MultiAssetFilter::Wild(WildMultiAsset::All)] +impl Get> for AllAssets { + fn get() -> Vec { + sp_std::vec![AssetFilter::Wild(WildAsset::All)] } } @@ -90,24 +88,24 @@ mod tests { #[test] fn location_with_asset_filters_works() { frame_support::parameter_types! { - pub ParaA: MultiLocation = MultiLocation::new(1, X1(Parachain(1001))); - pub ParaB: MultiLocation = MultiLocation::new(1, X1(Parachain(1002))); - pub ParaC: MultiLocation = MultiLocation::new(1, X1(Parachain(1003))); + pub ParaA: Location = Location::new(1, [Parachain(1001)]); + pub ParaB: Location = Location::new(1, [Parachain(1002)]); + pub ParaC: Location = Location::new(1, [Parachain(1003)]); - pub AssetXLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(1111))); - pub AssetYLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(2222))); - pub AssetZLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(3333))); + pub AssetXLocation: Location = Location::new(1, [GeneralIndex(1111)]); + pub AssetYLocation: Location = Location::new(1, [GeneralIndex(2222)]); + pub AssetZLocation: Location = Location::new(1, [GeneralIndex(3333)]); - pub OnlyAssetXOrAssetY: sp_std::vec::Vec = sp_std::vec![ - Wild(AllOf { fun: WildFungible, id: Concrete(AssetXLocation::get()) }), - Wild(AllOf { fun: WildFungible, id: Concrete(AssetYLocation::get()) }), + pub OnlyAssetXOrAssetY: sp_std::vec::Vec = sp_std::vec![ + Wild(AllOf { fun: WildFungible, id: AssetId(AssetXLocation::get()) }), + Wild(AllOf { fun: WildFungible, id: AssetId(AssetYLocation::get()) }), ]; - pub OnlyAssetZ: sp_std::vec::Vec = sp_std::vec![ - Wild(AllOf { fun: WildFungible, id: Concrete(AssetZLocation::get()) }) + pub OnlyAssetZ: sp_std::vec::Vec = sp_std::vec![ + Wild(AllOf { fun: WildFungible, id: AssetId(AssetZLocation::get()) }) ]; } - let test_data: Vec<(MultiLocation, Vec, bool)> = vec![ + let test_data: Vec<(Location, Vec, bool)> = vec![ (ParaA::get(), vec![(AssetXLocation::get(), 1).into()], true), (ParaA::get(), vec![(AssetYLocation::get(), 1).into()], true), (ParaA::get(), vec![(AssetZLocation::get(), 1).into()], false), @@ -202,7 +200,7 @@ mod tests { for (location, assets, expected_result) in test_data { assert_eq!( - Filter::contains(&(location, assets.clone())), + Filter::contains(&(location.clone(), assets.clone())), expected_result, "expected_result: {expected_result} not matched for (location, assets): ({:?}, {:?})!", location, assets, ) diff --git a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs index 90608faa4477..7bea8cdf957e 100644 --- a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs @@ -25,7 +25,10 @@ use frame_support::traits::{ }; use sp_std::{marker::PhantomData, prelude::*, result}; use xcm::latest::prelude::*; -use xcm_executor::traits::{ConvertLocation, Error as MatchError, MatchesFungible, TransactAsset}; +use xcm_executor::{ + traits::{ConvertLocation, Error as MatchError, MatchesFungible, TransactAsset}, + AssetsInHolding, +}; /// [`TransactAsset`] implementation that allows the use of a [`fungible`] implementation for /// handling an asset in the XCM executor. @@ -41,11 +44,11 @@ impl< > TransactAsset for FungibleTransferAdapter { fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungible_adapter", "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", @@ -111,11 +114,7 @@ impl< > TransactAsset for FungibleMutateAdapter { - fn can_check_in( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -132,7 +131,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungible_adapter", "check_in origin: {:?}, what: {:?}", @@ -149,7 +148,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> XcmResult { + fn can_check_out(_dest: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "check_out dest: {:?}, what: {:?}", @@ -166,7 +165,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungible_adapter", "check_out dest: {:?}, what: {:?}", @@ -184,11 +183,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -203,10 +198,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungible_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -236,7 +231,7 @@ impl< > TransactAsset for FungibleAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -246,7 +241,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { FungibleMutateAdapter::< Fungible, Matcher, @@ -256,7 +251,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -266,7 +261,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { FungibleMutateAdapter::< Fungible, Matcher, @@ -276,11 +271,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -291,10 +282,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { FungibleMutateAdapter::< Fungible, Matcher, @@ -305,11 +296,11 @@ impl< } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { FungibleTransferAdapter::::internal_transfer_asset( what, from, to, context ) diff --git a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs index 63ce608824eb..4574d5ed4c68 100644 --- a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs @@ -38,11 +38,11 @@ impl< > TransactAsset for FungiblesTransferAdapter { fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungibles_adapter", "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", @@ -198,11 +198,7 @@ impl< CheckingAccount, > { - fn can_check_in( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -219,7 +215,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungibles_adapter", "check_in origin: {:?}, what: {:?}", @@ -236,11 +232,7 @@ impl< } } - fn can_check_out( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -257,7 +249,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungibles_adapter", "check_out dest: {:?}, what: {:?}", @@ -274,11 +266,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -294,10 +282,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungibles_adapter", "withdraw_asset what: {:?}, who: {:?}", @@ -331,7 +319,7 @@ impl< > TransactAsset for FungiblesAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -342,7 +330,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { FungiblesMutateAdapter::< Assets, Matcher, @@ -353,7 +341,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -364,7 +352,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { FungiblesMutateAdapter::< Assets, Matcher, @@ -375,11 +363,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -391,10 +375,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { FungiblesMutateAdapter::< Assets, Matcher, @@ -406,11 +390,11 @@ impl< } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { FungiblesTransferAdapter::::internal_transfer_asset( what, from, to, context ) diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs index e7431ae02545..c00cd62e8726 100644 --- a/polkadot/xcm/xcm-builder/src/lib.rs +++ b/polkadot/xcm/xcm-builder/src/lib.rs @@ -47,11 +47,11 @@ pub use origin_conversion::{ }; mod asset_conversion; +#[allow(deprecated)] +pub use asset_conversion::ConvertedConcreteAssetId; pub use asset_conversion::{ - AsPrefixedGeneralIndex, ConvertedAbstractId, ConvertedConcreteId, MatchedConvertedConcreteId, + AsPrefixedGeneralIndex, ConvertedConcreteId, MatchedConvertedConcreteId, V4V3LocationConverter, }; -#[allow(deprecated)] -pub use asset_conversion::{ConvertedAbstractAssetId, ConvertedConcreteAssetId}; mod barriers; pub use barriers::{ @@ -96,7 +96,7 @@ mod matches_location; pub use matches_location::{StartsWith, StartsWithExplicitGlobalConsensus}; mod matches_token; -pub use matches_token::{IsAbstract, IsConcrete}; +pub use matches_token::IsConcrete; mod matcher; pub use matcher::{CreateMatcher, MatchXcm, Matcher}; diff --git a/polkadot/xcm/xcm-builder/src/location_conversion.rs b/polkadot/xcm/xcm-builder/src/location_conversion.rs index 25d16f7eb8cc..c9553030817a 100644 --- a/polkadot/xcm/xcm-builder/src/location_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/location_conversion.rs @@ -27,12 +27,12 @@ use xcm_executor::traits::ConvertLocation; pub trait DescribeLocation { /// Create a description of the given `location` if possible. No two locations should have the /// same descriptor. - fn describe_location(location: &MultiLocation) -> Option>; + fn describe_location(location: &Location) -> Option>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl DescribeLocation for Tuple { - fn describe_location(l: &MultiLocation) -> Option> { + fn describe_location(l: &Location) -> Option> { for_tuples!( #( match Tuple::describe_location(l) { Some(result) => return Some(result), @@ -45,9 +45,9 @@ impl DescribeLocation for Tuple { pub struct DescribeTerminus; impl DescribeLocation for DescribeTerminus { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, Here) => Some(Vec::new()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, []) => Some(Vec::new()), _ => return None, } } @@ -55,10 +55,9 @@ impl DescribeLocation for DescribeTerminus { pub struct DescribePalletTerminal; impl DescribeLocation for DescribePalletTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(PalletInstance(i))) => - Some((b"Pallet", Compact::::from(*i as u32)).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [PalletInstance(i)]) => Some((b"Pallet", Compact::::from(*i as u32)).encode()), _ => return None, } } @@ -66,9 +65,9 @@ impl DescribeLocation for DescribePalletTerminal { pub struct DescribeAccountId32Terminal; impl DescribeLocation for DescribeAccountId32Terminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(AccountId32 { id, .. })) => Some((b"AccountId32", id).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [AccountId32 { id, .. }]) => Some((b"AccountId32", id).encode()), _ => return None, } } @@ -76,9 +75,9 @@ impl DescribeLocation for DescribeAccountId32Terminal { pub struct DescribeAccountKey20Terminal; impl DescribeLocation for DescribeAccountKey20Terminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(AccountKey20 { key, .. })) => Some((b"AccountKey20", key).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [AccountKey20 { key, .. }]) => Some((b"AccountKey20", key).encode()), _ => return None, } } @@ -89,9 +88,9 @@ impl DescribeLocation for DescribeAccountKey20Terminal { pub struct DescribeTreasuryVoiceTerminal; impl DescribeLocation for DescribeTreasuryVoiceTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice })) => + fn describe_location(location: &Location) -> Option> { + match location.unpack() { + (0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => Some((b"Treasury", b"Voice").encode()), _ => None, } @@ -102,9 +101,9 @@ pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccou pub struct DescribeBodyTerminal; impl DescribeLocation for DescribeBodyTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(Plurality { id, part })) => Some((b"Body", id, part).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [Plurality { id, part }]) => Some((b"Body", id, part).encode()), _ => return None, } } @@ -121,20 +120,21 @@ pub type DescribeAllTerminal = ( pub struct DescribeFamily(PhantomData); impl DescribeLocation for DescribeFamily { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, l.interior.first()) { + fn describe_location(l: &Location) -> Option> { + match (l.parent_count(), l.first_interior()) { (0, Some(Parachain(index))) => { - let tail = l.interior.split_first().0; + let tail = l.clone().split_first_interior().0; let interior = Suffix::describe_location(&tail.into())?; Some((b"ChildChain", Compact::::from(*index), interior).encode()) }, (1, Some(Parachain(index))) => { - let tail = l.interior.split_first().0; - let interior = Suffix::describe_location(&tail.into())?; + let tail_junctions = l.interior().clone().split_first().0; + let tail = Location::new(0, tail_junctions); + let interior = Suffix::describe_location(&tail)?; Some((b"SiblingChain", Compact::::from(*index), interior).encode()) }, (1, _) => { - let tail = l.interior.into(); + let tail = l.interior().clone().into(); let interior = Suffix::describe_location(&tail)?; Some((b"ParentChain", interior).encode()) }, @@ -147,7 +147,7 @@ pub struct HashedDescription(PhantomData<(AccountId, Descri impl + Clone, Describe: DescribeLocation> ConvertLocation for HashedDescription { - fn convert_location(value: &MultiLocation) -> Option { + fn convert_location(value: &Location) -> Option { Some(blake2_256(&Describe::describe_location(value)?).into()) } } @@ -156,34 +156,26 @@ impl + Clone, Describe: DescribeLocation> ConvertLocat /// are recommended to use the more extensible `HashedDescription` type. pub struct LegacyDescribeForeignChainAccount; impl DescribeLocation for LegacyDescribeForeignChainAccount { - fn describe_location(location: &MultiLocation) -> Option> { - Some(match location { + fn describe_location(location: &Location) -> Option> { + Some(match location.unpack() { // Used on the relay chain for sending paras that use 32 byte accounts - MultiLocation { - parents: 0, - interior: X2(Parachain(para_id), AccountId32 { id, .. }), - } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), + (0, [Parachain(para_id), AccountId32 { id, .. }]) => + LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), // Used on the relay chain for sending paras that use 20 byte accounts - MultiLocation { - parents: 0, - interior: X2(Parachain(para_id), AccountKey20 { key, .. }), - } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), + (0, [Parachain(para_id), AccountKey20 { key, .. }]) => + LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), // Used on para-chain for sending paras that use 32 byte accounts - MultiLocation { - parents: 1, - interior: X2(Parachain(para_id), AccountId32 { id, .. }), - } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), + (1, [Parachain(para_id), AccountId32 { id, .. }]) => + LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), // Used on para-chain for sending paras that use 20 byte accounts - MultiLocation { - parents: 1, - interior: X2(Parachain(para_id), AccountKey20 { key, .. }), - } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), + (1, [Parachain(para_id), AccountKey20 { key, .. }]) => + LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), // Used on para-chain for sending from the relay chain - MultiLocation { parents: 1, interior: X1(AccountId32 { id, .. }) } => + (1, [AccountId32 { id, .. }]) => LegacyDescribeForeignChainAccount::from_relay_32(id, 1), // No other conversions provided @@ -278,16 +270,16 @@ pub struct Account32Hash(PhantomData<(Network, AccountId)>); impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for Account32Hash { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { Some(("multiloc", location).using_encoded(blake2_256).into()) } } -/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the +/// A [`Location`] consisting of a single `Parent` [`Junction`] will be converted to the /// parent `AccountId`. pub struct ParentIsPreset(PhantomData); impl ConvertLocation for ParentIsPreset { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { if location.contains_parents_only(1) { Some( b"Parent" @@ -304,10 +296,9 @@ pub struct ChildParachainConvertsVia(PhantomData<(ParaId, Acc impl + Into + AccountIdConversion, AccountId: Clone> ConvertLocation for ChildParachainConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { parents: 0, interior: X1(Parachain(id)) } => - Some(ParaId::from(*id).into_account_truncating()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (0, [Parachain(id)]) => Some(ParaId::from(*id).into_account_truncating()), _ => None, } } @@ -317,10 +308,9 @@ pub struct SiblingParachainConvertsVia(PhantomData<(ParaId, A impl + Into + AccountIdConversion, AccountId: Clone> ConvertLocation for SiblingParachainConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - Some(ParaId::from(*id).into_account_truncating()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (1, [Parachain(id)]) => Some(ParaId::from(*id).into_account_truncating()), _ => None, } } @@ -331,15 +321,13 @@ pub struct AccountId32Aliases(PhantomData<(Network, AccountI impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for AccountId32Aliases { - fn convert_location(location: &MultiLocation) -> Option { - let id = match *location { - MultiLocation { parents: 0, interior: X1(AccountId32 { id, network: None }) } => id, - MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) } - if network == Network::get() => - id, + fn convert_location(location: &Location) -> Option { + let id = match location.unpack() { + (0, [AccountId32 { id, network: None }]) => id, + (0, [AccountId32 { id, network }]) if *network == Network::get() => id, _ => return None, }; - Some(id.into()) + Some((*id).into()) } } @@ -351,25 +339,23 @@ pub struct LocalTreasuryVoiceConvertsVia( impl, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for LocalTreasuryVoiceConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match *location { - MultiLocation { - parents: 0, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - } => Some((TreasuryAccount::get().into() as [u8; 32]).into()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => + Some((TreasuryAccount::get().into() as [u8; 32]).into()), _ => None, } } } /// Conversion implementation which converts from a `[u8; 32]`-based `AccountId` into a -/// `MultiLocation` consisting solely of a `AccountId32` junction with a fixed value for its +/// `Location` consisting solely of a `AccountId32` junction with a fixed value for its /// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`. pub struct AliasesIntoAccountId32(PhantomData<(Network, AccountId)>); impl<'a, Network: Get>, AccountId: Clone + Into<[u8; 32]> + Clone> - TryConvert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32 + TryConvert<&'a AccountId, Location> for AliasesIntoAccountId32 { - fn try_convert(who: &AccountId) -> Result { + fn try_convert(who: &AccountId) -> Result { Ok(AccountId32 { network: Network::get(), id: who.clone().into() }.into()) } } @@ -378,15 +364,13 @@ pub struct AccountKey20Aliases(PhantomData<(Network, Account impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> ConvertLocation for AccountKey20Aliases { - fn convert_location(location: &MultiLocation) -> Option { - let key = match *location { - MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: None }) } => key, - MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) } - if network == Network::get() => - key, + fn convert_location(location: &Location) -> Option { + let key = match location.unpack() { + (0, [AccountKey20 { key, network: None }]) => key, + (0, [AccountKey20 { key, network }]) if *network == Network::get() => key, _ => return None, }; - Some(key.into()) + Some((*key).into()) } } @@ -402,10 +386,10 @@ impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> pub struct GlobalConsensusConvertsFor( PhantomData<(UniversalLocation, AccountId)>, ); -impl, AccountId: From<[u8; 32]> + Clone> +impl, AccountId: From<[u8; 32]> + Clone> ConvertLocation for GlobalConsensusConvertsFor { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::location_conversion", @@ -413,7 +397,7 @@ impl, AccountId: From<[u8; 32]> + universal_source, location, ); let (remote_network, remote_location) = - ensure_is_remote(universal_source, *location).ok()?; + ensure_is_remote(universal_source, location.clone()).ok()?; match remote_location { Here => Some(AccountId::from(Self::from_params(&remote_network))), @@ -445,21 +429,21 @@ impl GlobalConsensusConvertsFor( PhantomData<(UniversalLocation, AccountId)>, ); -impl, AccountId: From<[u8; 32]> + Clone> +impl, AccountId: From<[u8; 32]> + Clone> ConvertLocation for GlobalConsensusParachainConvertsFor { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::location_conversion", "GlobalConsensusParachainConvertsFor universal_source: {:?}, location: {:?}", universal_source, location, ); - let devolved = ensure_is_remote(universal_source, *location).ok()?; + let devolved = ensure_is_remote(universal_source, location.clone()).ok()?; let (remote_network, remote_location) = devolved; - match remote_location { - X1(Parachain(remote_network_para_id)) => + match remote_location.as_slice() { + [Parachain(remote_network_para_id)] => Some(AccountId::from(Self::from_params(&remote_network, &remote_network_para_id))), _ => None, } @@ -509,12 +493,12 @@ mod tests { #[test] fn inverter_works_in_tree() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X3(Parachain(1), account20(), account20()); + pub UniversalLocation: InteriorLocation = [Parachain(1), account20(), account20()].into(); } - let input = MultiLocation::new(3, X2(Parachain(2), account32())); + let input = Location::new(3, [Parachain(2), account32()]); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); - assert_eq!(inverted, MultiLocation::new(2, X3(Parachain(1), account20(), account20()))); + assert_eq!(inverted, Location::new(2, [Parachain(1), account20(), account20()])); } // Network Topology @@ -524,12 +508,12 @@ mod tests { #[test] fn inverter_uses_context_as_inverted_location() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(account20(), account20()); + pub UniversalLocation: InteriorLocation = [account20(), account20()].into(); } - let input = MultiLocation::grandparent(); + let input = Location::new(2, Here); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); - assert_eq!(inverted, X2(account20(), account20()).into()); + assert_eq!(inverted, [account20(), account20()].into()); } // Network Topology @@ -539,10 +523,10 @@ mod tests { #[test] fn inverter_uses_only_child_on_missing_context() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = PalletInstance(5).into(); + pub UniversalLocation: InteriorLocation = PalletInstance(5).into(); } - let input = MultiLocation::grandparent(); + let input = Location::new(2, Here); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); assert_eq!(inverted, (OnlyChild, PalletInstance(5)).into()); } @@ -550,10 +534,10 @@ mod tests { #[test] fn inverter_errors_when_location_is_too_large() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; } - let input = MultiLocation { parents: 99, interior: X1(Parachain(88)) }; + let input = Location { parents: 99, interior: [Parachain(88)].into() }; let inverted = UniversalLocation::get().invert_target(&input); assert_eq!(inverted, Err(())); } @@ -561,8 +545,8 @@ mod tests { #[test] fn global_consensus_converts_for_works() { parameter_types! { - pub UniversalLocationInNetwork1: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)); - pub UniversalLocationInNetwork2: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)); + pub UniversalLocationInNetwork1: InteriorLocation = [GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)].into(); + pub UniversalLocationInNetwork2: InteriorLocation = [GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)].into(); } let network_1 = UniversalLocationInNetwork1::get().global_consensus().expect("NetworkId"); let network_2 = UniversalLocationInNetwork2::get().global_consensus().expect("NetworkId"); @@ -571,17 +555,17 @@ mod tests { let network_5 = ByGenesis([5; 32]); let test_data = vec![ - (MultiLocation::parent(), false), - (MultiLocation::new(0, Here), false), - (MultiLocation::new(0, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(1, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(2, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(0, X1(GlobalConsensus(network_2))), false), - (MultiLocation::new(1, X1(GlobalConsensus(network_2))), false), - (MultiLocation::new(2, X1(GlobalConsensus(network_2))), true), - (MultiLocation::new(0, X2(GlobalConsensus(network_2), Parachain(1000))), false), - (MultiLocation::new(1, X2(GlobalConsensus(network_2), Parachain(1000))), false), - (MultiLocation::new(2, X2(GlobalConsensus(network_2), Parachain(1000))), false), + (Location::parent(), false), + (Location::new(0, Here), false), + (Location::new(0, [GlobalConsensus(network_1)]), false), + (Location::new(1, [GlobalConsensus(network_1)]), false), + (Location::new(2, [GlobalConsensus(network_1)]), false), + (Location::new(0, [GlobalConsensus(network_2)]), false), + (Location::new(1, [GlobalConsensus(network_2)]), false), + (Location::new(2, [GlobalConsensus(network_2)]), true), + (Location::new(0, [GlobalConsensus(network_2), Parachain(1000)]), false), + (Location::new(1, [GlobalConsensus(network_2), Parachain(1000)]), false), + (Location::new(2, [GlobalConsensus(network_2), Parachain(1000)]), false), ]; for (location, expected_result) in test_data { @@ -596,14 +580,14 @@ mod tests { "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ); - match &location { - MultiLocation { interior: X1(GlobalConsensus(network)), .. } => + match location.unpack() { + (_, [GlobalConsensus(network)]) => assert_eq!( account, GlobalConsensusConvertsFor::::from_params(network), "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ), - _ => panic!("expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location) + _ => panic!("expected_result: {}, conversion passed: {:?}, but Location does not match expected pattern, location: {:?}", expected_result, account, location) } }, None => { @@ -619,32 +603,32 @@ mod tests { // all success let res_1_gc_network_3 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + &Location::new(2, [GlobalConsensus(network_3)]), ) .expect("conversion is ok"); let res_2_gc_network_3 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + &Location::new(2, [GlobalConsensus(network_3)]), ) .expect("conversion is ok"); let res_1_gc_network_4 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + &Location::new(2, [GlobalConsensus(network_4)]), ) .expect("conversion is ok"); let res_2_gc_network_4 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + &Location::new(2, [GlobalConsensus(network_4)]), ) .expect("conversion is ok"); let res_1_gc_network_5 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + &Location::new(2, [GlobalConsensus(network_5)]), ) .expect("conversion is ok"); let res_2_gc_network_5 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + &Location::new(2, [GlobalConsensus(network_5)]), ) .expect("conversion is ok"); @@ -660,42 +644,30 @@ mod tests { #[test] fn global_consensus_parachain_converts_for_works() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)].into(); } let test_data = vec![ - (MultiLocation::parent(), false), - (MultiLocation::new(0, X1(Parachain(1000))), false), - (MultiLocation::new(1, X1(Parachain(1000))), false), + (Location::parent(), false), + (Location::new(0, [Parachain(1000)]), false), + (Location::new(1, [Parachain(1000)]), false), ( - MultiLocation::new( + Location::new( 2, - X3( + [ GlobalConsensus(ByGenesis([0; 32])), Parachain(1000), AccountId32 { network: None, id: [1; 32].into() }, - ), + ], ), false, ), - (MultiLocation::new(2, X1(GlobalConsensus(ByGenesis([0; 32])))), false), - ( - MultiLocation::new(0, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - ( - MultiLocation::new(1, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - (MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), true), - ( - MultiLocation::new(3, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - ( - MultiLocation::new(9, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), + (Location::new(2, [GlobalConsensus(ByGenesis([0; 32]))]), false), + (Location::new(0, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(1, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(2, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), true), + (Location::new(3, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(9, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), ]; for (location, expected_result) in test_data { @@ -710,8 +682,8 @@ mod tests { "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ); - match &location { - MultiLocation { interior: X2(GlobalConsensus(network), Parachain(para_id)), .. } => + match location.unpack() { + (_, [GlobalConsensus(network), Parachain(para_id)]) => assert_eq!( account, GlobalConsensusParachainConvertsFor::::from_params(network, para_id), @@ -720,7 +692,7 @@ mod tests { _ => assert_eq!( true, expected_result, - "expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location + "expected_result: {}, conversion passed: {:?}, but Location does not match expected pattern, location: {:?}", expected_result, account, location ) } }, @@ -737,22 +709,22 @@ mod tests { // all success let res_gc_a_p1000 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1000))), + &Location::new(2, [GlobalConsensus(ByGenesis([3; 32])), Parachain(1000)]), ) .expect("conversion is ok"); let res_gc_a_p1001 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1001))), + &Location::new(2, [GlobalConsensus(ByGenesis([3; 32])), Parachain(1001)]), ) .expect("conversion is ok"); let res_gc_b_p1000 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1000))), + &Location::new(2, [GlobalConsensus(ByGenesis([4; 32])), Parachain(1000)]), ) .expect("conversion is ok"); let res_gc_b_p1001 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1001))), + &Location::new(2, [GlobalConsensus(ByGenesis([4; 32])), Parachain(1001)]), ) .expect("conversion is ok"); assert_ne!(res_gc_a_p1000, res_gc_a_p1001); @@ -765,9 +737,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_para_32() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(1), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -779,19 +751,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2( + interior: [ Parachain(1), AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(2), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -808,9 +781,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_para_20() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -822,19 +795,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2( + interior: [ Parachain(1), AccountKey20 { network: Some(NetworkId::Polkadot), key: [0u8; 20] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -851,9 +825,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_relay() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: None, id: [0u8; 32] }), + interior: [AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -865,16 +839,16 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }), + interior: [AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }].into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: None, id: [1u8; 32] }), + interior: [AccountId32 { network: None, id: [1u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -891,9 +865,9 @@ mod tests { #[test] fn remote_account_convert_on_relay_sending_para_20() { - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -905,9 +879,9 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -924,9 +898,9 @@ mod tests { #[test] fn remote_account_convert_on_relay_sending_para_32() { - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(1), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -938,19 +912,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2( + interior: [ Parachain(1), AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(2), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -966,20 +941,18 @@ mod tests { } #[test] - fn remote_account_fails_with_bad_multilocation() { - let mul = MultiLocation { + fn remote_account_fails_with_bad_location() { + let mul = Location { parents: 1, - interior: X1(AccountKey20 { network: None, key: [0u8; 20] }), + interior: [AccountKey20 { network: None, key: [0u8; 20] }].into(), }; assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none()); } #[test] fn remote_account_convert_on_para_sending_from_remote_para_treasury() { - let relay_treasury_to_para_location = MultiLocation { - parents: 1, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - }; + let relay_treasury_to_para_location = + Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]); let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location( &relay_treasury_to_para_location, ) @@ -993,13 +966,10 @@ mod tests { actual_description ); - let para_to_para_treasury_location = MultiLocation { - parents: 1, - interior: X2( - Parachain(1001), - Plurality { id: BodyId::Treasury, part: BodyPart::Voice }, - ), - }; + let para_to_para_treasury_location = Location::new( + 1, + [Parachain(1001), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }], + ); let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location( ¶_to_para_treasury_location, ) @@ -1016,10 +986,8 @@ mod tests { #[test] fn local_account_convert_on_para_from_relay_treasury() { - let location = MultiLocation { - parents: 0, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - }; + let location = + Location::new(0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]); parameter_types! { pub TreasuryAccountId: AccountId = AccountId::new([42u8; 32]); diff --git a/polkadot/xcm/xcm-builder/src/matcher.rs b/polkadot/xcm/xcm-builder/src/matcher.rs index 9da135dae31e..eae43b290fb2 100644 --- a/polkadot/xcm/xcm-builder/src/matcher.rs +++ b/polkadot/xcm/xcm-builder/src/matcher.rs @@ -18,7 +18,7 @@ use core::ops::ControlFlow; use frame_support::traits::ProcessMessageError; -use xcm::latest::{Instruction, MultiLocation}; +use xcm::latest::{Instruction, Location}; /// Creates an instruction matcher from an XCM. Since XCM versions differ, we need to make a trait /// here to unify the interfaces among them. @@ -67,7 +67,7 @@ impl<'a, Call> CreateMatcher for &'a mut [Instruction] { pub trait MatchXcm { /// The concrete instruction type. Necessary to specify as it changes between XCM versions. type Inst; - /// The `MultiLocation` type. Necessary to specify as it changes between XCM versions. + /// The `Location` type. Necessary to specify as it changes between XCM versions. type Loc; /// The error type to throw when errors happen during matching. type Error; @@ -125,7 +125,7 @@ pub struct Matcher<'a, Call> { impl<'a, Call> MatchXcm for Matcher<'a, Call> { type Error = ProcessMessageError; type Inst = Instruction; - type Loc = MultiLocation; + type Loc = Location; fn assert_remaining_insts(self, n: usize) -> Result where diff --git a/polkadot/xcm/xcm-builder/src/matches_location.rs b/polkadot/xcm/xcm-builder/src/matches_location.rs index cfc71eafd028..a96df9e92de3 100644 --- a/polkadot/xcm/xcm-builder/src/matches_location.rs +++ b/polkadot/xcm/xcm-builder/src/matches_location.rs @@ -14,37 +14,47 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Various implementations and utilities for matching and filtering `MultiLocation` and -//! `InteriorMultiLocation` types. +//! Various implementations and utilities for matching and filtering `Location` and +//! `InteriorLocation` types. use frame_support::traits::{Contains, Get}; -use xcm::latest::{InteriorMultiLocation, MultiLocation, NetworkId}; +use xcm::latest::{InteriorLocation, Location, NetworkId}; -/// An implementation of `Contains` that checks for `MultiLocation` or -/// `InteriorMultiLocation` if starts with the provided type `T`. -pub struct StartsWith(sp_std::marker::PhantomData); -impl> Contains for StartsWith { - fn contains(t: &MultiLocation) -> bool { - t.starts_with(&T::get()) +/// An implementation of `Contains` that checks for `Location` or +/// `InteriorLocation` if starts with the provided type `T`. +pub struct StartsWith(sp_std::marker::PhantomData<(T, L)>); +impl, L: TryInto + Clone> Contains for StartsWith { + fn contains(location: &L) -> bool { + let latest_location: Location = if let Ok(location) = (*location).clone().try_into() { + location + } else { + return false; + }; + let latest_t = if let Ok(location) = T::get().try_into() { + location + } else { + return false; + }; + latest_location.starts_with(&latest_t) } } -impl> Contains for StartsWith { - fn contains(t: &InteriorMultiLocation) -> bool { +impl> Contains for StartsWith { + fn contains(t: &InteriorLocation) -> bool { t.starts_with(&T::get()) } } -/// An implementation of `Contains` that checks for `MultiLocation` or -/// `InteriorMultiLocation` if starts with expected `GlobalConsensus(NetworkId)` provided as type +/// An implementation of `Contains` that checks for `Location` or +/// `InteriorLocation` if starts with expected `GlobalConsensus(NetworkId)` provided as type /// `T`. pub struct StartsWithExplicitGlobalConsensus(sp_std::marker::PhantomData); -impl> Contains for StartsWithExplicitGlobalConsensus { - fn contains(location: &MultiLocation) -> bool { - matches!(location.interior.global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) +impl> Contains for StartsWithExplicitGlobalConsensus { + fn contains(location: &Location) -> bool { + matches!(location.interior().global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) } } -impl> Contains for StartsWithExplicitGlobalConsensus { - fn contains(location: &InteriorMultiLocation) -> bool { +impl> Contains for StartsWithExplicitGlobalConsensus { + fn contains(location: &InteriorLocation) -> bool { matches!(location.global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) } } diff --git a/polkadot/xcm/xcm-builder/src/matches_token.rs b/polkadot/xcm/xcm-builder/src/matches_token.rs index b6a320d89316..e49fd18f88d8 100644 --- a/polkadot/xcm/xcm-builder/src/matches_token.rs +++ b/polkadot/xcm/xcm-builder/src/matches_token.rs @@ -19,25 +19,24 @@ use frame_support::traits::Get; use sp_std::marker::PhantomData; use xcm::latest::{ - AssetId::{Abstract, Concrete}, - AssetInstance, + Asset, AssetId, AssetInstance, Fungibility::{Fungible, NonFungible}, - MultiAsset, MultiLocation, + Location, }; use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; -/// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that +/// Converts a `Asset` into balance `B` if its id is equal to that /// given by `T`'s `Get`. /// /// # Example /// /// ``` -/// use xcm::latest::{MultiLocation, Parent}; +/// use xcm::latest::{Location, Parent}; /// use staging_xcm_builder::IsConcrete; /// use xcm_executor::traits::MatchesFungible; /// /// frame_support::parameter_types! { -/// pub TargetLocation: MultiLocation = Parent.into(); +/// pub TargetLocation: Location = Parent.into(); /// } /// /// # fn main() { @@ -47,62 +46,18 @@ use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; /// # } /// ``` pub struct IsConcrete(PhantomData); -impl, B: TryFrom> MatchesFungible for IsConcrete { - fn matches_fungible(a: &MultiAsset) -> Option { +impl, B: TryFrom> MatchesFungible for IsConcrete { + fn matches_fungible(a: &Asset) -> Option { match (&a.id, &a.fun) { - (Concrete(ref id), Fungible(ref amount)) if id == &T::get() => - (*amount).try_into().ok(), + (AssetId(ref id), Fungible(ref amount)) if id == &T::get() => (*amount).try_into().ok(), _ => None, } } } -impl, I: TryFrom> MatchesNonFungible for IsConcrete { - fn matches_nonfungible(a: &MultiAsset) -> Option { +impl, I: TryFrom> MatchesNonFungible for IsConcrete { + fn matches_nonfungible(a: &Asset) -> Option { match (&a.id, &a.fun) { - (Concrete(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), - _ => None, - } - } -} - -/// Same as [`IsConcrete`] but for a fungible with abstract location. -/// -/// # Example -/// -/// ``` -/// use xcm::latest::prelude::*; -/// use staging_xcm_builder::IsAbstract; -/// use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; -/// -/// frame_support::parameter_types! { -/// pub TargetLocation: [u8; 32] = [7u8; 32]; -/// } -/// -/// # fn main() { -/// let asset = ([7u8; 32], 999u128).into(); -/// // match `asset` if it is an abstract asset in `TargetLocation`. -/// assert_eq!( as MatchesFungible>::matches_fungible(&asset), Some(999)); -/// let nft = ([7u8; 32], [42u8; 4]).into(); -/// assert_eq!( -/// as MatchesNonFungible<[u8; 4]>>::matches_nonfungible(&nft), -/// Some([42u8; 4]) -/// ); -/// # } -/// ``` -pub struct IsAbstract(PhantomData); -impl, B: TryFrom> MatchesFungible for IsAbstract { - fn matches_fungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Abstract(ref id), Fungible(ref amount)) if id == &T::get() => - (*amount).try_into().ok(), - _ => None, - } - } -} -impl, B: TryFrom> MatchesNonFungible for IsAbstract { - fn matches_nonfungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Abstract(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), + (AssetId(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), _ => None, } } diff --git a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs index 357dc534a5f1..b4801d3a23a1 100644 --- a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs @@ -40,11 +40,11 @@ impl< > TransactAsset for NonFungiblesTransferAdapter { fn transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: LOG_TARGET, "transfer_asset what: {:?}, from: {:?}, to: {:?}, context: {:?}", @@ -131,7 +131,7 @@ impl< CheckingAccount, > { - fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { log::trace!( target: LOG_TARGET, "can_check_in origin: {:?}, what: {:?}, context: {:?}", @@ -150,7 +150,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, context: &XcmContext) { log::trace!( target: LOG_TARGET, "check_in origin: {:?}, what: {:?}, context: {:?}", @@ -169,7 +169,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(_dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { log::trace!( target: LOG_TARGET, "can_check_out dest: {:?}, what: {:?}, context: {:?}", @@ -188,7 +188,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, context: &XcmContext) { log::trace!( target: LOG_TARGET, "check_out dest: {:?}, what: {:?}, context: {:?}", @@ -207,11 +207,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { log::trace!( target: LOG_TARGET, "deposit_asset what: {:?}, who: {:?}, context: {:?}", @@ -228,10 +224,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: LOG_TARGET, "withdraw_asset what: {:?}, who: {:?}, maybe_context: {:?}", @@ -267,7 +263,7 @@ impl< > TransactAsset for NonFungiblesAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -278,7 +274,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -289,7 +285,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -300,7 +296,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -311,11 +307,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -327,10 +319,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -342,11 +334,11 @@ impl< } fn transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { NonFungiblesTransferAdapter::::transfer_asset( what, from, to, context, ) diff --git a/polkadot/xcm/xcm-builder/src/origin_aliases.rs b/polkadot/xcm/xcm-builder/src/origin_aliases.rs index 82c5f71b7a12..bbf810463a7c 100644 --- a/polkadot/xcm/xcm-builder/src/origin_aliases.rs +++ b/polkadot/xcm/xcm-builder/src/origin_aliases.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Implementation for `ContainsPair`. +//! Implementation for `ContainsPair`. use frame_support::traits::{Contains, ContainsPair}; use sp_std::marker::PhantomData; @@ -25,13 +25,15 @@ use xcm::latest::prelude::*; /// /// Requires that the prefixed origin `AccountId32` matches the target `AccountId32`. pub struct AliasForeignAccountId32(PhantomData); -impl> ContainsPair +impl> ContainsPair for AliasForeignAccountId32 { - fn contains(origin: &MultiLocation, target: &MultiLocation) -> bool { - if let (prefix, Some(account_id @ AccountId32 { .. })) = origin.split_last_interior() { + fn contains(origin: &Location, target: &Location) -> bool { + if let (prefix, Some(account_id @ AccountId32 { .. })) = + origin.clone().split_last_interior() + { return Prefix::contains(&prefix) && - *target == MultiLocation { parents: 0, interior: X1(account_id) } + *target == Location { parents: 0, interior: [account_id].into() } } false } diff --git a/polkadot/xcm/xcm-builder/src/origin_conversion.rs b/polkadot/xcm/xcm-builder/src/origin_conversion.rs index cced7dedf62d..f64b5660f667 100644 --- a/polkadot/xcm/xcm-builder/src/origin_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/origin_conversion.rs @@ -21,7 +21,7 @@ use frame_system::RawOrigin as SystemRawOrigin; use polkadot_parachain_primitives::primitives::IsSystem; use sp_runtime::traits::TryConvert; use sp_std::marker::PhantomData; -use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind}; +use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, Location, NetworkId, OriginKind}; use xcm_executor::traits::{ConvertLocation, ConvertOrigin}; /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the @@ -35,9 +35,9 @@ where RuntimeOrigin::AccountId: Clone, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", @@ -56,9 +56,9 @@ where pub struct ParentAsSuperuser(PhantomData); impl ConvertOrigin for ParentAsSuperuser { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ParentAsSuperuser origin: {:?}, kind: {:?}", origin, kind); if kind == OriginKind::Superuser && origin.contains_parents_only(1) { @@ -76,17 +76,16 @@ impl, RuntimeOrigin: OriginTrait> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ChildSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind); - match (kind, origin) { - ( - OriginKind::Superuser, - MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, - ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Superuser, (0, [Junction::Parachain(id)])) + if ParaId::from(*id).is_system() => + Ok(RuntimeOrigin::root()), + _ => Err(origin), } } } @@ -98,21 +97,20 @@ impl, RuntimeOrigin: OriginTrait> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SiblingSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Superuser, - MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, - ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Superuser, (1, [Junction::Parachain(id)])) + if ParaId::from(*id).is_system() => + Ok(RuntimeOrigin::root()), + _ => Err(origin), } } } @@ -124,17 +122,15 @@ impl, RuntimeOrigin: From> ConvertOr for ChildParachainAsNative { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ChildParachainAsNative origin: {:?}, kind: {:?}", origin, kind); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, - ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::Parachain(id)])) => + Ok(RuntimeOrigin::from(ParachainOrigin::from(*id))), + _ => Err(origin), } } } @@ -146,21 +142,19 @@ impl, RuntimeOrigin: From> ConvertOr for SiblingParachainAsNative { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SiblingParachainAsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, - ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (1, [Junction::Parachain(id)])) => + Ok(RuntimeOrigin::from(ParachainOrigin::from(*id))), + _ => Err(origin), } } } @@ -173,9 +167,9 @@ impl, RuntimeOrigin> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "RelayChainAsNative origin: {:?}, kind: {:?}", origin, kind); if kind == OriginKind::Native && origin.contains_parents_only(1) { @@ -193,22 +187,20 @@ where RuntimeOrigin::AccountId: From<[u8; 32]>, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SignedAccountId32AsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, network }) }, - ) if matches!(network, None) || network == Network::get() => - Ok(RuntimeOrigin::signed(id.into())), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::AccountId32 { id, network }])) + if matches!(network, None) || *network == Network::get() => + Ok(RuntimeOrigin::signed((*id).into())), + _ => Err(origin), } } } @@ -222,34 +214,32 @@ where RuntimeOrigin::AccountId: From<[u8; 20]>, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SignedAccountKey20AsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::AccountKey20 { key, network }) }, - ) if (matches!(network, None) || network == Network::get()) => - Ok(RuntimeOrigin::signed(key.into())), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::AccountKey20 { key, network }])) + if (matches!(network, None) || *network == Network::get()) => + Ok(RuntimeOrigin::signed((*key).into())), + _ => Err(origin), } } } /// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists. pub struct EnsureXcmOrigin(PhantomData<(RuntimeOrigin, Conversion)>); -impl> +impl> EnsureOrigin for EnsureXcmOrigin where RuntimeOrigin::PalletsOrigin: PartialEq, { - type Success = MultiLocation; + type Success = Location; fn try_origin(o: RuntimeOrigin) -> Result { let o = match Conversion::try_convert(o) { Ok(location) => return Ok(location), @@ -282,13 +272,12 @@ impl< RuntimeOrigin: OriginTrait + Clone, AccountId: Into<[u8; 32]>, Network: Get>, - > TryConvert - for SignedToAccountId32 + > TryConvert for SignedToAccountId32 where RuntimeOrigin::PalletsOrigin: From> + TryInto, Error = RuntimeOrigin::PalletsOrigin>, { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { o.try_with_caller(|caller| match caller.try_into() { Ok(SystemRawOrigin::Signed(who)) => Ok(Junction::AccountId32 { network: Network::get(), id: who.into() }.into()), @@ -299,7 +288,7 @@ where } /// `Convert` implementation to convert from some an origin which implements `Backing` into a -/// corresponding `Plurality` `MultiLocation`. +/// corresponding `Plurality` `Location`. /// /// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an /// XCM from a `Plurality` origin. @@ -307,12 +296,12 @@ pub struct BackingToPlurality( PhantomData<(RuntimeOrigin, COrigin, Body)>, ); impl> - TryConvert for BackingToPlurality + TryConvert for BackingToPlurality where RuntimeOrigin::PalletsOrigin: From + TryInto, { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { o.try_with_caller(|caller| match caller.try_into() { Ok(co) => match co.get_backing() { Some(backing) => Ok(Junction::Plurality { @@ -333,10 +322,10 @@ pub struct OriginToPluralityVoice( PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>, ); impl, Body: Get> - TryConvert + TryConvert for OriginToPluralityVoice { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { match EnsureBodyOrigin::try_origin(o) { Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()), Err(o) => Err(o), diff --git a/polkadot/xcm/xcm-builder/src/pay.rs b/polkadot/xcm/xcm-builder/src/pay.rs index 4c9b9a6088de..6b466483cfad 100644 --- a/polkadot/xcm/xcm-builder/src/pay.rs +++ b/polkadot/xcm/xcm-builder/src/pay.rs @@ -30,7 +30,7 @@ use xcm_executor::traits::{QueryHandler, QueryResponseStatus}; /// ownership of some `Interior` location of the local chain to a particular `Beneficiary`. The /// `AssetKind` value is not itself bounded (to avoid the issue of needing to wrap some preexisting /// datatype), however a converter type `AssetKindToLocatableAsset` must be provided in order to -/// translate it into a `LocatableAsset`, which comprises both an XCM `MultiLocation` describing +/// translate it into a `LocatableAsset`, which comprises both an XCM `Location` describing /// the XCM endpoint on which the asset to be paid resides and an XCM `AssetId` to identify the /// specific asset at that endpoint. /// @@ -65,14 +65,14 @@ pub struct PayOverXcm< )>, ); impl< - Interior: Get, + Interior: Get, Router: SendXcm, Querier: QueryHandler, Timeout: Get, Beneficiary: Clone, AssetKind, AssetKindToLocatableAsset: TryConvert, - BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, MultiLocation>, + BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, Location>, > Pay for PayOverXcm< Interior, @@ -105,7 +105,7 @@ impl< let beneficiary = BeneficiaryRefToLocation::try_convert(&who) .map_err(|_| xcm::latest::Error::InvalidLocation)?; - let query_id = Querier::new_query(asset_location, Timeout::get(), Interior::get()); + let query_id = Querier::new_query(asset_location.clone(), Timeout::get(), Interior::get()); let message = Xcm(vec![ DescendOrigin(Interior::get()), @@ -120,8 +120,7 @@ impl< ])), TransferAsset { beneficiary, - assets: vec![MultiAsset { id: asset_id, fun: Fungibility::Fungible(amount) }] - .into(), + assets: vec![Asset { id: asset_id, fun: Fungibility::Fungible(amount) }].into(), }, ]); @@ -195,16 +194,16 @@ pub struct LocatableAssetId { /// The asset's ID. pub asset_id: AssetId, /// The (relative) location in which the asset ID is meaningful. - pub location: MultiLocation, + pub location: Location, } /// Adapter `struct` which implements a conversion from any `AssetKind` into a [`LocatableAssetId`] /// value using a fixed `Location` for the `location` field. -pub struct FixedLocation(sp_std::marker::PhantomData); -impl, AssetKind: Into> TryConvert - for FixedLocation +pub struct FixedLocation(sp_std::marker::PhantomData); +impl, AssetKind: Into> + TryConvert for FixedLocation { fn try_convert(value: AssetKind) -> Result { - Ok(LocatableAssetId { asset_id: value.into(), location: Location::get() }) + Ok(LocatableAssetId { asset_id: value.into(), location: FixedLocationValue::get() }) } } diff --git a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs index 7334bcd20109..bcf91d8e68c3 100644 --- a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs +++ b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs @@ -30,7 +30,7 @@ pub struct ProcessXcmMessage( PhantomData<(MessageOrigin, XcmExecutor, Call)>, ); impl< - MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, + MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, XcmExecutor: ExecuteXcm, Call, > ProcessMessage for ProcessXcmMessage @@ -82,28 +82,26 @@ impl< let (consumed, result) = match XcmExecutor::execute(origin.into(), pre, id, Weight::zero()) { - Outcome::Complete(w) => { + Outcome::Complete { used } => { log::trace!( target: LOG_TARGET, - "XCM message execution complete, used weight: {w}", + "XCM message execution complete, used weight: {used}", ); - (w, Ok(true)) + (used, Ok(true)) }, - Outcome::Incomplete(w, e) => { + Outcome::Incomplete { used, error } => { log::trace!( target: LOG_TARGET, - "XCM message execution incomplete, used weight: {w}, error: {e:?}", + "XCM message execution incomplete, used weight: {used}, error: {error:?}", ); - - (w, Ok(false)) + (used, Ok(false)) }, // In the error-case we assume the worst case and consume all possible weight. - Outcome::Error(e) => { + Outcome::Error { error } => { log::trace!( target: LOG_TARGET, - "XCM message execution error: {e:?}", + "XCM message execution error: {error:?}", ); - (required, Err(ProcessMessageError::Unsupported)) }, }; diff --git a/polkadot/xcm/xcm-builder/src/routing.rs b/polkadot/xcm/xcm-builder/src/routing.rs index f4c18adddb37..9c0302baee06 100644 --- a/polkadot/xcm/xcm-builder/src/routing.rs +++ b/polkadot/xcm/xcm-builder/src/routing.rs @@ -38,7 +38,7 @@ impl SendXcm for WithUniqueTopic { type Ticket = (Inner::Ticket, [u8; 32]); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let mut message = message.take().ok_or(SendError::MissingArgument)?; @@ -82,7 +82,7 @@ impl SendXcm for WithTopicSource, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let mut message = message.take().ok_or(SendError::MissingArgument)?; diff --git a/polkadot/xcm/xcm-builder/src/test_utils.rs b/polkadot/xcm/xcm-builder/src/test_utils.rs index d0f867ba62d6..3131dece3757 100644 --- a/polkadot/xcm/xcm-builder/src/test_utils.rs +++ b/polkadot/xcm/xcm-builder/src/test_utils.rs @@ -27,11 +27,11 @@ pub use xcm_executor::{ traits::{ AssetExchange, AssetLock, ConvertOrigin, Enact, LockError, OnResponse, TransactAsset, }, - Assets, Config, + AssetsInHolding, Config, }; parameter_types! { - pub static SubscriptionRequests: Vec<(MultiLocation, Option<(QueryId, Weight)>)> = vec![]; + pub static SubscriptionRequests: Vec<(Location, Option<(QueryId, Weight)>)> = vec![]; pub static MaxAssetsIntoHolding: u32 = 4; } @@ -39,39 +39,39 @@ pub struct TestSubscriptionService; impl VersionChangeNotifier for TestSubscriptionService { fn start( - location: &MultiLocation, + location: &Location, query_id: QueryId, max_weight: Weight, _context: &XcmContext, ) -> XcmResult { let mut r = SubscriptionRequests::get(); - r.push((*location, Some((query_id, max_weight)))); + r.push((location.clone(), Some((query_id, max_weight)))); SubscriptionRequests::set(r); Ok(()) } - fn stop(location: &MultiLocation, _context: &XcmContext) -> XcmResult { + fn stop(location: &Location, _context: &XcmContext) -> XcmResult { let mut r = SubscriptionRequests::get(); r.retain(|(l, _q)| l != location); - r.push((*location, None)); + r.push((location.clone(), None)); SubscriptionRequests::set(r); Ok(()) } - fn is_subscribed(location: &MultiLocation) -> bool { + fn is_subscribed(location: &Location) -> bool { let r = SubscriptionRequests::get(); r.iter().any(|(l, q)| l == location && q.is_some()) } } parameter_types! { - pub static TrappedAssets: Vec<(MultiLocation, MultiAssets)> = vec![]; + pub static TrappedAssets: Vec<(Location, Assets)> = vec![]; } pub struct TestAssetTrap; impl DropAssets for TestAssetTrap { - fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { - let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); - t.push((*origin, assets.into())); + fn drop_assets(origin: &Location, assets: AssetsInHolding, _context: &XcmContext) -> Weight { + let mut t: Vec<(Location, Assets)> = TrappedAssets::get(); + t.push((origin.clone(), assets.into())); TrappedAssets::set(t); Weight::from_parts(5, 5) } @@ -79,13 +79,13 @@ impl DropAssets for TestAssetTrap { impl ClaimAssets for TestAssetTrap { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, _context: &XcmContext, ) -> bool { - let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); - if let (0, X1(GeneralIndex(i))) = (ticket.parents, &ticket.interior) { + let mut t: Vec<(Location, Assets)> = TrappedAssets::get(); + if let (0, [GeneralIndex(i)]) = ticket.unpack() { if let Some((l, a)) = t.get(*i as usize) { if l == origin && a == what { t.swap_remove(*i as usize); @@ -102,11 +102,11 @@ pub struct TestAssetExchanger; impl AssetExchange for TestAssetExchanger { fn exchange_asset( - _origin: Option<&MultiLocation>, - _give: Assets, - want: &MultiAssets, + _origin: Option<&Location>, + _give: AssetsInHolding, + want: &Assets, _maximal: bool, - ) -> Result { + ) -> Result { Ok(want.clone().into()) } } @@ -135,17 +135,17 @@ impl PalletsInfoAccess for TestPalletsInfo { } pub struct TestUniversalAliases; -impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { - fn contains(aliases: &(MultiLocation, Junction)) -> bool { +impl Contains<(Location, Junction)> for TestUniversalAliases { + fn contains(aliases: &(Location, Junction)) -> bool { &aliases.0 == &Here.into_location() && &aliases.1 == &GlobalConsensus(ByGenesis([0; 32])) } } parameter_types! { - pub static LockedAssets: Vec<(MultiLocation, MultiAsset)> = vec![]; + pub static LockedAssets: Vec<(Location, Asset)> = vec![]; } -pub struct TestLockTicket(MultiLocation, MultiAsset); +pub struct TestLockTicket(Location, Asset); impl Enact for TestLockTicket { fn enact(self) -> Result<(), LockError> { let mut locked_assets = LockedAssets::get(); @@ -154,7 +154,7 @@ impl Enact for TestLockTicket { Ok(()) } } -pub struct TestUnlockTicket(MultiLocation, MultiAsset); +pub struct TestUnlockTicket(Location, Asset); impl Enact for TestUnlockTicket { fn enact(self) -> Result<(), LockError> { let mut locked_assets = LockedAssets::get(); @@ -183,33 +183,33 @@ impl AssetLock for TestAssetLocker { type ReduceTicket = TestReduceTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - _owner: MultiLocation, + unlocker: Location, + asset: Asset, + _owner: Location, ) -> Result { Ok(TestLockTicket(unlocker, asset)) } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - _owner: MultiLocation, + unlocker: Location, + asset: Asset, + _owner: Location, ) -> Result { Ok(TestUnlockTicket(unlocker, asset)) } fn note_unlockable( - _locker: MultiLocation, - _asset: MultiAsset, - _owner: MultiLocation, + _locker: Location, + _asset: Asset, + _owner: Location, ) -> Result<(), LockError> { Ok(()) } fn prepare_reduce_unlockable( - _locker: MultiLocation, - _asset: MultiAsset, - _owner: MultiLocation, + _locker: Location, + _asset: Asset, + _owner: Location, ) -> Result { Ok(TestReduceTicket) } diff --git a/polkadot/xcm/xcm-builder/src/tests/aliases.rs b/polkadot/xcm/xcm-builder/src/tests/aliases.rs index f686926a2522..89c17b09396d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/aliases.rs +++ b/polkadot/xcm/xcm-builder/src/tests/aliases.rs @@ -66,20 +66,25 @@ fn alias_origin_should_work() { ]); let message = Xcm(vec![AliasOrigin((AccountId32 { network: None, id: [0; 32] }).into())]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parachain(1), AccountId32 { network: None, id: [0; 32] }), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NoPermission } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NoPermission)); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/assets.rs b/polkadot/xcm/xcm-builder/src/tests/assets.rs index e1d61a9d1c6d..b510eab8df53 100644 --- a/polkadot/xcm/xcm-builder/src/tests/assets.rs +++ b/polkadot/xcm/xcm-builder/src/tests/assets.rs @@ -32,10 +32,15 @@ fn exchange_asset_should_work() { maximal: true, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list(Parent), vec![(Here, 100u128).into(), (Parent, 950u128).into()]); assert_eq!(exchange_assets(), vec![(Parent, 50u128).into()].into()); } @@ -56,10 +61,15 @@ fn exchange_asset_without_maximal_should_work() { maximal: false, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list(Parent), vec![(Here, 50u128).into(), (Parent, 950u128).into()]); assert_eq!(exchange_assets(), vec![(Here, 50u128).into(), (Parent, 50u128).into()].into()); } @@ -80,10 +90,18 @@ fn exchange_asset_should_fail_when_no_deal_possible() { maximal: false, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(40, 40), XcmError::NoDeal)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(40, 40), error: XcmError::NoDeal } + ); assert_eq!(asset_list(Parent), vec![(Parent, 1000u128).into()]); assert_eq!(exchange_assets(), vec![(Here, 100u128).into()].into()); } @@ -100,32 +118,39 @@ fn paying_reserve_deposit_should_work() { BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(50, 50); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Here), vec![(Parent, 40u128).into()]); } #[test] fn transfer_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // They want to transfer 100 of them to their sibling parachain #2 let message = Xcm(vec![TransferAsset { assets: (Here, 100u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 100u128).into()] @@ -136,27 +161,31 @@ fn transfer_should_work() { #[test] fn reserve_transfer_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // The remote account owned by gav. - let three: MultiLocation = X1(AccountIndex64 { index: 3, network: None }).into(); + let three: Location = [AccountIndex64 { index: 3, network: None }].into(); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![TransferReserveAsset { assets: (Here, 100u128).into(), dest: Parachain(2).into(), - xcm: Xcm::<()>(vec![DepositAsset { assets: AllCounted(1).into(), beneficiary: three }]), + xcm: Xcm::<()>(vec![DepositAsset { + assets: AllCounted(1).into(), + beneficiary: three.clone(), + }]), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![ ReserveAssetDeposited((Parent, 100u128).into()), @@ -171,7 +200,7 @@ fn reserve_transfer_should_work() { #[test] fn burn_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // They want to burn 100 of them @@ -180,14 +209,15 @@ fn burn_should_work() { BurnAsset((Here, 100u128).into()), DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(sent_xcm(), vec![]); @@ -197,14 +227,15 @@ fn burn_should_work() { BurnAsset((Here, 1000u128).into()), DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Parachain(1)), vec![]); assert_eq!(sent_xcm(), vec![]); } @@ -212,7 +243,7 @@ fn burn_should_work() { #[test] fn basic_asset_trap_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into(), [Parachain(2)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); @@ -224,14 +255,15 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(25, 25))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(25, 25) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); @@ -243,15 +275,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -264,15 +300,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -285,15 +325,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -305,14 +349,15 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!( asset_list(AccountIndex64 { index: 3, network: None }), @@ -327,141 +372,168 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); } #[test] fn max_assets_limit_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. - add_asset(Parachain(1), ([1u8; 32], 1000u128)); - add_asset(Parachain(1), ([2u8; 32], 1000u128)); - add_asset(Parachain(1), ([3u8; 32], 1000u128)); - add_asset(Parachain(1), ([4u8; 32], 1000u128)); - add_asset(Parachain(1), ([5u8; 32], 1000u128)); - add_asset(Parachain(1), ([6u8; 32], 1000u128)); - add_asset(Parachain(1), ([7u8; 32], 1000u128)); - add_asset(Parachain(1), ([8u8; 32], 1000u128)); - add_asset(Parachain(1), ([9u8; 32], 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(0)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(1)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(2)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(3)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(4)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(5)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(6)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(7)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(8)]), 1000u128)); // Attempt to withdraw 8 (=2x4)different assets. This will succeed. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(100, 100), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(85, 85))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(85, 85) }); // Attempt to withdraw 9 different assets will fail. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), - WithdrawAsset(([9u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(8)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(100, 100), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(95, 95), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); // Attempt to withdraw 4 different assets and then the same 4 and then a different 4 will // succeed. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(125, 125))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(125, 125) }); // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(95, 95), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. let message = Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![ - ([1u8; 32], 100u128).into(), - ([2u8; 32], 100u128).into(), - ([3u8; 32], 100u128).into(), - ([4u8; 32], 100u128).into(), - ([5u8; 32], 100u128).into(), - ([6u8; 32], 100u128).into(), - ([7u8; 32], 100u128).into(), - ([8u8; 32], 100u128).into(), + WithdrawAsset(Assets::from(vec![ + (Junctions::from([GeneralIndex(0)]), 100u128).into(), + (Junctions::from([GeneralIndex(1)]), 100u128).into(), + (Junctions::from([GeneralIndex(2)]), 100u128).into(), + (Junctions::from([GeneralIndex(3)]), 100u128).into(), + (Junctions::from([GeneralIndex(4)]), 100u128).into(), + (Junctions::from([GeneralIndex(5)]), 100u128).into(), + (Junctions::from([GeneralIndex(6)]), 100u128).into(), + (Junctions::from([GeneralIndex(7)]), 100u128).into(), ])), - WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(25, 25), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(25, 25), XcmError::HoldingWouldOverflow)); } diff --git a/polkadot/xcm/xcm-builder/src/tests/basic.rs b/polkadot/xcm/xcm-builder/src/tests/basic.rs index 02fcd8962dbf..1482e3d700fd 100644 --- a/polkadot/xcm/xcm-builder/src/tests/basic.rs +++ b/polkadot/xcm/xcm-builder/src/tests/basic.rs @@ -27,14 +27,8 @@ fn basic_setup_works() { assert_eq!(to_account(Parachain(50)), Ok(1050)); assert_eq!(to_account((Parent, Parachain(1))), Ok(2001)); assert_eq!(to_account((Parent, Parachain(50))), Ok(2050)); - assert_eq!( - to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: None }))), - Ok(1), - ); - assert_eq!( - to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: None }))), - Ok(42), - ); + assert_eq!(to_account(Location::new(0, [AccountIndex64 { index: 1, network: None }])), Ok(1),); + assert_eq!(to_account(Location::new(0, [AccountIndex64 { index: 42, network: None }])), Ok(42),); assert_eq!(to_account(Here), Ok(3000)); } @@ -65,7 +59,7 @@ fn code_registers_should_work() { SetErrorHandler(Xcm(vec![ TransferAsset { assets: (Here, 2u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // It was handled fine. ClearError, @@ -73,33 +67,45 @@ fn code_registers_should_work() { // Set the appendix - this will always fire. SetAppendix(Xcm(vec![TransferAsset { assets: (Here, 4u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }])), // First xfer always works ok TransferAsset { assets: (Here, 1u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Second xfer results in error on the second message - our error handler will fire. TransferAsset { assets: (Here, 8u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, ]); // Weight limit of 70 is needed. let limit = ::Weigher::weight(&mut message).unwrap(); assert_eq!(limit, Weight::from_parts(70, 70)); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(50, 50))); // We don't pay the 20 weight for the error handler. + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(50, 50) }); // We don't pay the 20 weight for the error handler. assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 13u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 8u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); // We pay the full weight here. + let r = XcmExecutor::::prepare_and_execute( + Here, + message, + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); // We pay the full weight here. assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 20u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); assert_eq!(sent_xcm(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs index b1361cc85777..ea584bf9d485 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs @@ -21,9 +21,9 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); } type TheBridge = TestBridge>; diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs index 5371abccf666..38ffe2532d58 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs @@ -21,9 +21,9 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); } type TheBridge = TestBridge>; diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs index 0c749b66da61..11f0044fbcaf 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs @@ -37,7 +37,7 @@ mod remote_relay_relay; parameter_types! { pub Local: NetworkId = ByGenesis([0; 32]); pub Remote: NetworkId = ByGenesis([1; 32]); - pub Price: MultiAssets = MultiAssets::from((Here, 100u128)); + pub Price: Assets = Assets::from((Here, 100u128)); pub static UsingTopic: bool = false; } @@ -92,7 +92,7 @@ impl SendXcm for TestTopic { } } fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { Ok(if UsingTopic::get() { @@ -120,26 +120,26 @@ impl HaulBlob for TestBridge { } std::thread_local! { - static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); + static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); } struct TestRemoteIncomingRouter; impl SendXcm for TestRemoteIncomingRouter { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, MultiAssets::new())) + Ok((pair, Assets::new())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_id(); REMOTE_INCOMING_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) } } -fn take_received_remote_messages() -> Vec<(MultiLocation, Xcm<()>)> { +fn take_received_remote_messages() -> Vec<(Location, Xcm<()>)> { REMOTE_INCOMING_XCM.with(|r| r.replace(vec![])) } @@ -152,18 +152,18 @@ struct UnpaidExecutingRouter( fn price( n: NetworkId, c: u32, - s: &InteriorMultiLocation, - d: &InteriorMultiLocation, + s: &InteriorLocation, + d: &InteriorLocation, m: &Xcm<()>, -) -> Result { - Ok(validate_export::(n, c, *s, *d, m.clone())?.1) +) -> Result { + Ok(validate_export::(n, c, s.clone(), d.clone(), m.clone())?.1) } fn deliver( n: NetworkId, c: u32, - s: InteriorMultiLocation, - d: InteriorMultiLocation, + s: InteriorLocation, + d: InteriorLocation, m: Xcm<()>, ) -> Result { export_xcm::(n, c, s, d, m).map(|(hash, _)| hash) @@ -189,7 +189,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S type Ticket = Xcm<()>; fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult> { let expect_dest = Remote::get().relative_to(&Local::get()); @@ -197,7 +197,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S return Err(NotApplicable) } let message = message.take().ok_or(MissingArgument)?; - Ok((message, MultiAssets::new())) + Ok((message, Assets::new())) } fn deliver(message: Xcm<()>) -> Result { @@ -206,7 +206,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S // though it is `Remote`. ExecutorUniversalLocation::set(Remote::get()); let origin = Local::get().relative_to(&Remote::get()); - AllowUnpaidFrom::set(vec![origin]); + AllowUnpaidFrom::set(vec![origin.clone()]); set_exporter_override(price::, deliver::); // The we execute it: let mut id = fake_id(); @@ -222,9 +222,9 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: false }; RoutingLog::mutate(|l| l.push(entry)); match outcome { - Outcome::Complete(..) => Ok(id), - Outcome::Incomplete(..) => Err(Transport("Error executing")), - Outcome::Error(..) => Err(Transport("Unable to execute")), + Outcome::Complete { .. } => Ok(id), + Outcome::Incomplete { .. } => Err(Transport("Error executing")), + Outcome::Error { .. } => Err(Transport("Unable to execute")), } } } @@ -239,7 +239,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S type Ticket = Xcm<()>; fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult> { let expect_dest = Remote::get().relative_to(&Local::get()); @@ -247,7 +247,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S return Err(NotApplicable) } let message = message.take().ok_or(MissingArgument)?; - Ok((message, MultiAssets::new())) + Ok((message, Assets::new())) } fn deliver(message: Xcm<()>) -> Result { @@ -256,7 +256,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S // though it is `Remote`. ExecutorUniversalLocation::set(Remote::get()); let origin = Local::get().relative_to(&Remote::get()); - AllowPaidFrom::set(vec![origin]); + AllowPaidFrom::set(vec![origin.clone()]); set_exporter_override(price::, deliver::); // Then we execute it: let mut id = fake_id(); @@ -272,9 +272,9 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: true }; RoutingLog::mutate(|l| l.push(entry)); match outcome { - Outcome::Complete(..) => Ok(id), - Outcome::Incomplete(..) => Err(Transport("Error executing")), - Outcome::Error(..) => Err(Transport("Unable to execute")), + Outcome::Complete { .. } => Ok(id), + Outcome::Incomplete { .. } => Err(Transport("Error executing")), + Outcome::Error { .. } => Err(Transport("Unable to execute")), } } } diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs index 079eb0175d71..85d6524fb68e 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs @@ -27,15 +27,15 @@ parameter_types! { // 100 to use the bridge (export) and 80 for the remote execution weight (4 instructions x (10 + // 10) weight each). pub SendOverBridgePrice: u128 = 180u128 + if UsingTopic::get() { 20 } else { 0 }; - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(100)); - pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(100)].into(); + pub RelayUniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), None, - MultiLocation::parent(), + Location::parent(), Some((Parent, SendOverBridgePrice::get()).into()) ) ]; @@ -64,7 +64,7 @@ type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgeRouter)>; #[test] fn sending_to_bridged_chain_works() { maybe_with_topic(|| { - let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + let dest: Location = (Parent, Parent, Remote::get()).into(); // Initialize the local relay so that our parachain has funds to pay for export. clear_assets(Parachain(100)); @@ -99,7 +99,7 @@ fn sending_to_bridged_chain_works() { message: xcm_with_topic( maybe_forward_id_for(&[0; 32]), vec![ - WithdrawAsset(MultiAsset::from((Here, price)).into()), + WithdrawAsset(Asset::from((Here, price)).into()), BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, ExportMessage { network: ByGenesis([1; 32]), @@ -109,7 +109,7 @@ fn sending_to_bridged_chain_works() { DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, ], ), - outcome: Outcome::Complete(test_weight(4)), + outcome: Outcome::Complete { used: test_weight(4) }, paid: true, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -117,7 +117,7 @@ fn sending_to_bridged_chain_works() { } #[test] fn sending_to_bridged_chain_without_funds_fails() { - let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + let dest: Location = (Parent, Parent, Remote::get()).into(); // Routing won't work if we don't have enough funds. assert_eq!( send_xcm::(dest, Xcm(vec![Trap(1)])), @@ -138,7 +138,7 @@ fn sending_to_bridged_chain_without_funds_fails() { #[test] fn sending_to_parachain_of_bridged_chain_works() { maybe_with_topic(|| { - let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + let dest: Location = (Parent, Parent, Remote::get(), Parachain(100)).into(); // Initialize the local relay so that our parachain has funds to pay for export. clear_assets(Parachain(100)); @@ -173,7 +173,7 @@ fn sending_to_parachain_of_bridged_chain_works() { message: xcm_with_topic( maybe_forward_id_for(&[0; 32]), vec![ - WithdrawAsset(MultiAsset::from((Here, price)).into()), + WithdrawAsset(Asset::from((Here, price)).into()), BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, ExportMessage { network: ByGenesis([1; 32]), @@ -183,7 +183,7 @@ fn sending_to_parachain_of_bridged_chain_works() { DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, ], ), - outcome: Outcome::Complete(test_weight(4)), + outcome: Outcome::Complete { used: test_weight(4) }, paid: true, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -191,7 +191,7 @@ fn sending_to_parachain_of_bridged_chain_works() { } #[test] fn sending_to_parachain_of_bridged_chain_without_funds_fails() { - let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + let dest: Location = (Parent, Parent, Remote::get(), Parachain(100)).into(); // Routing won't work if we don't have enough funds. assert_eq!( send_xcm::(dest, Xcm(vec![Trap(1)])), diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs index fb6c5da3eb01..b92c59281c65 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs @@ -21,10 +21,10 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); - pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1000)].into(); + pub ParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), @@ -62,7 +62,7 @@ fn sending_to_bridged_chain_works() { send_xcm::((Parent, Parent, Remote::get(), Parachain(1)).into(), msg) .unwrap() .1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); assert_eq!( @@ -94,7 +94,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -116,7 +116,7 @@ fn sending_to_sibling_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( (Parent, Parachain(1000)).into(), @@ -145,7 +145,7 @@ fn sending_to_sibling_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -167,7 +167,7 @@ fn sending_to_relay_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get()).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parent.into(), @@ -196,7 +196,7 @@ fn sending_to_relay_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs index 0b6dc01e2bf1..1d433628825d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs @@ -21,10 +21,10 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub ParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), @@ -62,7 +62,7 @@ fn sending_to_bridged_chain_works() { send_xcm::((Parent, Remote::get(), Parachain(1)).into(), msg) .unwrap() .1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); let expected = vec![( @@ -85,7 +85,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -107,7 +107,7 @@ fn sending_to_sibling_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( (Parent, Parachain(1000)).into(), @@ -129,7 +129,7 @@ fn sending_to_sibling_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -151,7 +151,7 @@ fn sending_to_relay_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Remote::get()).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parent.into(), @@ -173,7 +173,7 @@ fn sending_to_relay_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs index e33c7b15b0af..d40a941c7916 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs @@ -21,15 +21,15 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); - pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1000)].into(); + pub RelayUniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), None, - MultiLocation::parent(), + Location::parent(), None ) ]; @@ -59,7 +59,7 @@ fn sending_to_bridged_chain_works() { let msg = Xcm(vec![Trap(1)]); assert_eq!( send_xcm::((Parent, Parent, Remote::get()).into(), msg).unwrap().1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); assert_eq!( @@ -91,7 +91,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -113,7 +113,7 @@ fn sending_to_parachain_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parachain(1000).into(), @@ -142,7 +142,7 @@ fn sending_to_parachain_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/expecting.rs b/polkadot/xcm/xcm-builder/src/tests/expecting.rs index 6d5e0ff47b51..1b36ef4517c9 100644 --- a/polkadot/xcm/xcm-builder/src/tests/expecting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/expecting.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn expect_pallet_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![ExpectPallet { @@ -28,14 +28,15 @@ fn expect_pallet_should_work() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let message = Xcm(vec![ExpectPallet { index: 1, @@ -44,19 +45,20 @@ fn expect_pallet_should_work() { crate_major: 1, min_crate_minor: 41, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } #[test] fn expect_pallet_should_fail_correctly() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); let message = Xcm(vec![ExpectPallet { index: 1, name: b"Balances".as_ref().into(), @@ -64,14 +66,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 60, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -80,14 +89,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -96,14 +109,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 0, @@ -112,14 +129,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 2, @@ -128,14 +149,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::PalletNotFound } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::PalletNotFound)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -144,14 +169,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 2, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -160,14 +192,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 0, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -176,12 +215,19 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 43, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); } diff --git a/polkadot/xcm/xcm-builder/src/tests/locking.rs b/polkadot/xcm/xcm-builder/src/tests/locking.rs index f4ef618ac0e7..75160e311551 100644 --- a/polkadot/xcm/xcm-builder/src/tests/locking.rs +++ b/polkadot/xcm/xcm-builder/src/tests/locking.rs @@ -34,10 +34,15 @@ fn lock_roundtrip_should_work() { ), LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); let expected_msg = Xcm::<()>(vec![NoteUnlockable { @@ -58,14 +63,15 @@ fn lock_roundtrip_should_work() { // Now we'll unlock it. let message = Xcm(vec![UnlockAsset { asset: (Parent, 100u128).into(), target: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } #[test] @@ -82,10 +88,15 @@ fn auto_fee_paying_should_work() { SetFeesMode { jit_withdraw: true }, LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); } @@ -100,10 +111,18 @@ fn lock_should_fail_correctly() { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::LockError } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); @@ -118,10 +137,18 @@ fn lock_should_fail_correctly() { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotHoldingFees } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); } @@ -140,14 +167,15 @@ fn remote_unlock_roundtrip_should_work() { // This caused Parachain #1 to send us the NoteUnlockable instruction. let message = Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( take_lock_trace(), vec![Note { @@ -165,10 +193,15 @@ fn remote_unlock_roundtrip_should_work() { ), RequestUnlock { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); let expected_msg = Xcm::<()>(vec![UnlockAsset { @@ -201,24 +234,33 @@ fn remote_unlock_should_fail_correctly() { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::LockError } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); // We have been told by Parachain #1 that Account #3 has locked funds which we can unlock. let message = Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let _discard = take_lock_trace(); // We want to unlock 100 of the native parent tokens which were locked for us on parachain. @@ -228,10 +270,18 @@ fn remote_unlock_should_fail_correctly() { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotHoldingFees } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/mock.rs b/polkadot/xcm/xcm-builder/src/tests/mock.rs index c1b3f0cf224e..f561c7d3bd4e 100644 --- a/polkadot/xcm/xcm-builder/src/tests/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/mock.rs @@ -28,7 +28,7 @@ pub use crate::{ use frame_support::traits::{ContainsPair, Everything}; pub use frame_support::{ dispatch::{DispatchInfo, DispatchResultWithPostInfo, GetDispatchInfo, PostDispatchInfo}, - ensure, match_types, parameter_types, + ensure, parameter_types, sp_runtime::{traits::Dispatchable, DispatchError, DispatchErrorWithPostInfo}, traits::{Contains, Get, IsInVec}, }; @@ -45,7 +45,7 @@ pub use xcm_executor::{ AssetExchange, AssetLock, CheckSuspension, ConvertOrigin, Enact, ExportXcm, FeeManager, FeeReason, LockError, OnResponse, TransactAsset, }, - Assets, Config, + AssetsInHolding, Config, }; #[derive(Debug)] @@ -110,52 +110,52 @@ impl GetDispatchInfo for TestCall { } thread_local! { - pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); pub static EXPORTED_XCM: RefCell< - Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> + Vec<(NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash)> > = RefCell::new(Vec::new()); pub static EXPORTER_OVERRIDE: RefCell, - ) -> Result, + ) -> Result, fn( NetworkId, u32, - InteriorMultiLocation, - InteriorMultiLocation, + InteriorLocation, + InteriorLocation, Xcm<()>, ) -> Result, )>> = RefCell::new(None); - pub static SEND_PRICE: RefCell = RefCell::new(MultiAssets::new()); + pub static SEND_PRICE: RefCell = RefCell::new(Assets::new()); pub static SUSPENDED: Cell = Cell::new(false); } -pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { +pub fn sent_xcm() -> Vec<(Location, opaque::Xcm, XcmHash)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } -pub fn set_send_price(p: impl Into) { +pub fn set_send_price(p: impl Into) { SEND_PRICE.with(|l| l.replace(p.into().into())); } pub fn exported_xcm( -) -> Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, opaque::Xcm, XcmHash)> { +) -> Vec<(NetworkId, u32, InteriorLocation, InteriorLocation, opaque::Xcm, XcmHash)> { EXPORTED_XCM.with(|q| (*q.borrow()).clone()) } pub fn set_exporter_override( price: fn( NetworkId, u32, - &InteriorMultiLocation, - &InteriorMultiLocation, + &InteriorLocation, + &InteriorLocation, &Xcm<()>, - ) -> Result, + ) -> Result, deliver: fn( NetworkId, u32, - InteriorMultiLocation, - InteriorMultiLocation, + InteriorLocation, + InteriorLocation, Xcm<()>, ) -> Result, ) { @@ -167,17 +167,17 @@ pub fn clear_exporter_override() { } pub struct TestMessageSender; impl SendXcm for TestMessageSender { - type Ticket = (MultiLocation, Xcm<()>, XcmHash); + type Ticket = (Location, Xcm<()>, XcmHash); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + ) -> SendResult<(Location, Xcm<()>, XcmHash)> { let msg = msg.take().unwrap(); let hash = fake_message_hash(&msg); let triplet = (dest.take().unwrap(), msg, hash); Ok((triplet, SEND_PRICE.with(|l| l.borrow().clone()))) } - fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + fn deliver(triplet: (Location, Xcm<()>, XcmHash)) -> Result { let hash = triplet.2; SENT_XCM.with(|q| q.borrow_mut().push(triplet)); Ok(hash) @@ -185,21 +185,20 @@ impl SendXcm for TestMessageSender { } pub struct TestMessageExporter; impl ExportXcm for TestMessageExporter { - type Ticket = (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash); + type Ticket = (NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash); fn validate( network: NetworkId, channel: u32, - uni_src: &mut Option, - dest: &mut Option, + uni_src: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> - { + ) -> SendResult<(NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash)> { let (s, d, m) = (uni_src.take().unwrap(), dest.take().unwrap(), msg.take().unwrap()); - let r: Result = EXPORTER_OVERRIDE.with(|e| { + let r: Result = EXPORTER_OVERRIDE.with(|e| { if let Some((ref f, _)) = &*e.borrow() { f(network, channel, &s, &d, &m) } else { - Ok(MultiAssets::new()) + Ok(Assets::new()) } }); let h = fake_message_hash(&m); @@ -214,7 +213,7 @@ impl ExportXcm for TestMessageExporter { } } fn deliver( - tuple: (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash), + tuple: (NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash), ) -> Result { EXPORTER_OVERRIDE.with(|e| { if let Some((_, ref f)) = &*e.borrow() { @@ -230,37 +229,42 @@ impl ExportXcm for TestMessageExporter { } thread_local! { - pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); } -pub fn assets(who: impl Into) -> Assets { +pub fn assets(who: impl Into) -> AssetsInHolding { ASSETS.with(|a| a.borrow().get(&who.into()).cloned()).unwrap_or_default() } -pub fn asset_list(who: impl Into) -> Vec { - MultiAssets::from(assets(who)).into_inner() +pub fn asset_list(who: impl Into) -> Vec { + Assets::from(assets(who)).into_inner() } -pub fn add_asset(who: impl Into, what: impl Into) { - ASSETS.with(|a| a.borrow_mut().entry(who.into()).or_insert(Assets::new()).subsume(what.into())); +pub fn add_asset(who: impl Into, what: impl Into) { + ASSETS.with(|a| { + a.borrow_mut() + .entry(who.into()) + .or_insert(AssetsInHolding::new()) + .subsume(what.into()) + }); } -pub fn clear_assets(who: impl Into) { +pub fn clear_assets(who: impl Into) { ASSETS.with(|a| a.borrow_mut().remove(&who.into())); } pub struct TestAssetTransactor; impl TransactAsset for TestAssetTransactor { fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _context: Option<&XcmContext>, ) -> Result<(), XcmError> { - add_asset(*who, what.clone()); + add_asset(who.clone(), what.clone()); Ok(()) } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { ASSETS.with(|a| { a.borrow_mut() .get_mut(who) @@ -271,19 +275,20 @@ impl TransactAsset for TestAssetTransactor { } } -pub fn to_account(l: impl Into) -> Result { - Ok(match l.into() { +pub fn to_account(l: impl Into) -> Result { + let l = l.into(); + Ok(match l.unpack() { // Siblings at 2000+id - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => 2000 + id as u64, + (1, [Parachain(id)]) => 2000 + *id as u64, // Accounts are their number - MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) } => index, + (0, [AccountIndex64 { index, .. }]) => *index, // Children at 1000+id - MultiLocation { parents: 0, interior: X1(Parachain(id)) } => 1000 + id as u64, + (0, [Parachain(id)]) => 1000 + *id as u64, // Self at 3000 - MultiLocation { parents: 0, interior: Here } => 3000, + (0, []) => 3000, // Parent at 3001 - MultiLocation { parents: 1, interior: Here } => 3001, - l => { + (1, []) => 3001, + _ => { // Is it a foreign-consensus? let uni = ExecutorUniversalLocation::get(); if l.parents as usize != uni.len() { @@ -301,36 +306,35 @@ pub fn to_account(l: impl Into) -> Result { pub struct TestOriginConverter; impl ConvertOrigin for TestOriginConverter { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { use OriginKind::*; - match (kind, origin.into()) { + let origin = origin.into(); + match (kind, origin.unpack()) { (Superuser, _) => Ok(TestOrigin::Root), - (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), - (Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) => - Ok(TestOrigin::Parachain(id)), - (Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay), - (Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) => - Ok(TestOrigin::Signed(index)), - (_, origin) => Err(origin), + (SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)), + (Native, (0, [Parachain(id)])) => Ok(TestOrigin::Parachain(*id)), + (Native, (1, [])) => Ok(TestOrigin::Relay), + (Native, (0, [AccountIndex64 { index, .. }])) => Ok(TestOrigin::Signed(*index)), + _ => Err(origin), } } } thread_local! { - pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); - pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); - pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); + pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); + pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); + pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); } -pub fn add_reserve(from: MultiLocation, asset: MultiAssetFilter) { +pub fn add_reserve(from: Location, asset: AssetFilter) { IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } #[allow(dead_code)] -pub fn add_teleporter(from: MultiLocation, asset: MultiAssetFilter) { +pub fn add_teleporter(from: Location, asset: AssetFilter) { IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } -pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { +pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { UNIVERSAL_ALIASES.with(|r| r.borrow_mut().insert((bridge.into(), consensus.into()))); } pub fn clear_universal_aliases() { @@ -338,29 +342,29 @@ pub fn clear_universal_aliases() { } pub struct TestIsReserve; -impl ContainsPair for TestIsReserve { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for TestIsReserve { + fn contains(asset: &Asset, origin: &Location) -> bool { IS_RESERVE .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) } } pub struct TestIsTeleporter; -impl ContainsPair for TestIsTeleporter { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for TestIsTeleporter { + fn contains(asset: &Asset, origin: &Location) -> bool { IS_TELEPORTER .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) } } pub struct TestUniversalAliases; -impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { - fn contains(t: &(MultiLocation, Junction)) -> bool { +impl Contains<(Location, Junction)> for TestUniversalAliases { + fn contains(t: &(Location, Junction)) -> bool { UNIVERSAL_ALIASES.with(|r| r.borrow().contains(t)) } } pub enum ResponseSlot { - Expecting(MultiLocation), + Expecting(Location), Received(Response), } thread_local! { @@ -368,20 +372,16 @@ thread_local! { } pub struct TestResponseHandler; impl OnResponse for TestResponseHandler { - fn expecting_response( - origin: &MultiLocation, - query_id: u64, - _querier: Option<&MultiLocation>, - ) -> bool { + fn expecting_response(origin: &Location, query_id: u64, _querier: Option<&Location>) -> bool { QUERIES.with(|q| match q.borrow().get(&query_id) { Some(ResponseSlot::Expecting(ref l)) => l == origin, _ => false, }) } fn on_response( - _origin: &MultiLocation, + _origin: &Location, query_id: u64, - _querier: Option<&MultiLocation>, + _querier: Option<&Location>, response: xcm::latest::Response, _max_weight: Weight, _context: &XcmContext, @@ -396,7 +396,7 @@ impl OnResponse for TestResponseHandler { Weight::from_parts(10, 10) } } -pub fn expect_response(query_id: u64, from: MultiLocation) { +pub fn expect_response(query_id: u64, from: Location) { QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from))); } pub fn response(query_id: u64) -> Option { @@ -420,9 +420,9 @@ impl QueryHandler type UniversalLocation = T::UniversalLocation; fn new_query( - responder: impl Into, + responder: impl Into, _timeout: Self::BlockNumber, - _match_querier: impl Into, + _match_querier: impl Into, ) -> Self::QueryId { let query_id = 1; expect_response(query_id, responder.into()); @@ -431,7 +431,7 @@ impl QueryHandler fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> Result { let responder = responder.into(); @@ -466,16 +466,16 @@ impl QueryHandler } parameter_types! { - pub static ExecutorUniversalLocation: InteriorMultiLocation + pub static ExecutorUniversalLocation: InteriorLocation = (ByGenesis([0; 32]), Parachain(42)).into(); pub UnitWeightCost: Weight = Weight::from_parts(10, 10); } parameter_types! { // Nothing is allowed to be paid/unpaid by default. - pub static AllowExplicitUnpaidFrom: Vec = vec![]; - pub static AllowUnpaidFrom: Vec = vec![]; - pub static AllowPaidFrom: Vec = vec![]; - pub static AllowSubsFrom: Vec = vec![]; + pub static AllowExplicitUnpaidFrom: Vec = vec![]; + pub static AllowUnpaidFrom: Vec = vec![]; + pub static AllowPaidFrom: Vec = vec![]; + pub static AllowSubsFrom: Vec = vec![]; // 1_000_000_000_000 => 1 unit of asset for 1 unit of ref time weight. // 1024 * 1024 => 1 unit of asset for 1 unit of proof size weight. pub static WeightPrice: (AssetId, u128, u128) = @@ -486,7 +486,7 @@ parameter_types! { pub struct TestSuspender; impl CheckSuspension for TestSuspender { fn is_suspended( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -520,34 +520,34 @@ pub fn set_fee_waiver(waived: Vec) { pub struct TestFeeManager; impl FeeManager for TestFeeManager { - fn is_waived(_: Option<&MultiLocation>, r: FeeReason) -> bool { + fn is_waived(_: Option<&Location>, r: FeeReason) -> bool { IS_WAIVED.with(|l| l.borrow().contains(&r)) } - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) {} + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) {} } #[derive(Clone, Eq, PartialEq, Debug)] pub enum LockTraceItem { - Lock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Unlock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Note { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Reduce { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, + Lock { unlocker: Location, asset: Asset, owner: Location }, + Unlock { unlocker: Location, asset: Asset, owner: Location }, + Note { locker: Location, asset: Asset, owner: Location }, + Reduce { locker: Location, asset: Asset, owner: Location }, } thread_local! { pub static NEXT_INDEX: RefCell = RefCell::new(0); pub static LOCK_TRACE: RefCell> = RefCell::new(Vec::new()); - pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); - pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); } pub fn take_lock_trace() -> Vec { LOCK_TRACE.with(|l| l.replace(Vec::new())) } pub fn allow_unlock( - unlocker: impl Into, - asset: impl Into, - owner: impl Into, + unlocker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() @@ -557,9 +557,9 @@ pub fn allow_unlock( }); } pub fn disallow_unlock( - unlocker: impl Into, - asset: impl Into, - owner: impl Into, + unlocker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() @@ -568,17 +568,17 @@ pub fn disallow_unlock( .saturating_take(asset.into().into()) }); } -pub fn unlock_allowed(unlocker: &MultiLocation, asset: &MultiAsset, owner: &MultiLocation) -> bool { +pub fn unlock_allowed(unlocker: &Location, asset: &Asset, owner: &Location) -> bool { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() - .get(&(*owner, *unlocker)) + .get(&(owner.clone(), unlocker.clone())) .map_or(false, |x| x.contains_asset(asset)) }) } pub fn allow_request_unlock( - locker: impl Into, - asset: impl Into, - owner: impl Into, + locker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() @@ -588,9 +588,9 @@ pub fn allow_request_unlock( }); } pub fn disallow_request_unlock( - locker: impl Into, - asset: impl Into, - owner: impl Into, + locker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() @@ -599,14 +599,10 @@ pub fn disallow_request_unlock( .saturating_take(asset.into().into()) }); } -pub fn request_unlock_allowed( - locker: &MultiLocation, - asset: &MultiAsset, - owner: &MultiLocation, -) -> bool { +pub fn request_unlock_allowed(locker: &Location, asset: &Asset, owner: &Location) -> bool { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() - .get(&(*owner, *locker)) + .get(&(owner.clone(), locker.clone())) .map_or(false, |x| x.contains_asset(asset)) }) } @@ -616,11 +612,11 @@ impl Enact for TestTicket { fn enact(self) -> Result<(), LockError> { match &self.0 { LockTraceItem::Lock { unlocker, asset, owner } => - allow_unlock(*unlocker, asset.clone(), *owner), + allow_unlock(unlocker.clone(), asset.clone(), owner.clone()), LockTraceItem::Unlock { unlocker, asset, owner } => - disallow_unlock(*unlocker, asset.clone(), *owner), + disallow_unlock(unlocker.clone(), asset.clone(), owner.clone()), LockTraceItem::Reduce { locker, asset, owner } => - disallow_request_unlock(*locker, asset.clone(), *owner), + disallow_request_unlock(locker.clone(), asset.clone(), owner.clone()), _ => {}, } LOCK_TRACE.with(move |l| l.borrow_mut().push(self.0)); @@ -635,38 +631,34 @@ impl AssetLock for TestAssetLock { type ReduceTicket = TestTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result { - ensure!(assets(owner).contains_asset(&asset), LockError::AssetNotOwned); + ensure!(assets(owner.clone()).contains_asset(&asset), LockError::AssetNotOwned); Ok(TestTicket(LockTraceItem::Lock { unlocker, asset, owner })) } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result { ensure!(unlock_allowed(&unlocker, &asset, &owner), LockError::NotLocked); Ok(TestTicket(LockTraceItem::Unlock { unlocker, asset, owner })) } - fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, - ) -> Result<(), LockError> { - allow_request_unlock(locker, asset.clone(), owner); + fn note_unlockable(locker: Location, asset: Asset, owner: Location) -> Result<(), LockError> { + allow_request_unlock(locker.clone(), asset.clone(), owner.clone()); let item = LockTraceItem::Note { locker, asset, owner }; LOCK_TRACE.with(move |l| l.borrow_mut().push(item)); Ok(()) } fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result { ensure!(request_unlock_allowed(&locker, &asset, &owner), LockError::NotLocked); Ok(TestTicket(LockTraceItem::Reduce { locker, asset, owner })) @@ -674,26 +666,26 @@ impl AssetLock for TestAssetLock { } thread_local! { - pub static EXCHANGE_ASSETS: RefCell = RefCell::new(Assets::new()); + pub static EXCHANGE_ASSETS: RefCell = RefCell::new(AssetsInHolding::new()); } -pub fn set_exchange_assets(assets: impl Into) { +pub fn set_exchange_assets(assets: impl Into) { EXCHANGE_ASSETS.with(|a| a.replace(assets.into().into())); } -pub fn exchange_assets() -> MultiAssets { +pub fn exchange_assets() -> Assets { EXCHANGE_ASSETS.with(|a| a.borrow().clone().into()) } pub struct TestAssetExchange; impl AssetExchange for TestAssetExchange { fn exchange_asset( - _origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + _origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result { + ) -> Result { let mut have = EXCHANGE_ASSETS.with(|l| l.borrow().clone()); ensure!(have.contains_assets(want), give); let get = if maximal { - std::mem::replace(&mut have, Assets::new()) + std::mem::replace(&mut have, AssetsInHolding::new()) } else { have.saturating_take(want.clone().into()) }; @@ -703,16 +695,25 @@ impl AssetExchange for TestAssetExchange { } } -match_types! { - pub type SiblingPrefix: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; - pub type ChildPrefix: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type ParentPrefix: impl Contains = { - MultiLocation { parents: 1, interior: Here } - }; +pub struct SiblingPrefix; +impl Contains for SiblingPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (1, [Parachain(_)])) + } +} + +pub struct ChildPrefix; +impl Contains for ChildPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Parachain(_)])) + } +} + +pub struct ParentPrefix; +impl Contains for ParentPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (1, [])) + } } pub struct TestConfig; @@ -743,7 +744,7 @@ impl Config for TestConfig { type Aliasers = AliasForeignAccountId32; } -pub fn fungible_multi_asset(location: MultiLocation, amount: u128) -> MultiAsset { +pub fn fungible_multi_asset(location: Location, amount: u128) -> Asset { (AssetId::from(location), Fungibility::Fungible(amount)).into() } diff --git a/polkadot/xcm/xcm-builder/src/tests/origins.rs b/polkadot/xcm/xcm-builder/src/tests/origins.rs index d3d6278eff8e..c717d1e2af8a 100644 --- a/polkadot/xcm/xcm-builder/src/tests/origins.rs +++ b/polkadot/xcm/xcm-builder/src/tests/origins.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn universal_origin_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into(), [Parachain(2)].into()]); clear_universal_aliases(); // Parachain 1 may represent Kusama to us add_universal_alias(Parachain(1), Kusama); @@ -29,48 +29,57 @@ fn universal_origin_should_work() { UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::InvalidLocation } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::InvalidLocation)); let message = Xcm(vec![ UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::NotWithdrawable } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); add_asset((Ancestor(2), GlobalConsensus(Kusama)), (Parent, 100)); let message = Xcm(vec![ UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list((Ancestor(2), GlobalConsensus(Kusama))), vec![]); } #[test] fn export_message_should_work() { // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Local parachain #1 issues a transfer asset on Polkadot Relay-chain, transfering 100 Planck to // Polkadot parachain #2. let expected_message = Xcm(vec![TransferAsset { @@ -83,14 +92,15 @@ fn export_message_should_work() { destination: Here, xcm: expected_message.clone(), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let uni_src = (ByGenesis([0; 32]), Parachain(42), Parachain(1)).into(); assert_eq!( exported_xcm(), @@ -101,40 +111,46 @@ fn export_message_should_work() { #[test] fn unpaid_execution_should_work() { // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Bridge chain (assumed to be Relay) lets Parachain #2 have message execution for free if it // asks. - AllowExplicitUnpaidFrom::set(vec![X1(Parachain(2)).into()]); + AllowExplicitUnpaidFrom::set(vec![[Parachain(2)].into()]); // Asking for unpaid execution of up to 9 weight on the assumption it is origin of #2. let message = Xcm(vec![UnpaidExecution { weight_limit: Limited(Weight::from_parts(9, 9)), check_origin: Some(Parachain(2).into()), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::BadOrigin } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::BadOrigin)); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let message = Xcm(vec![UnpaidExecution { weight_limit: Limited(Weight::from_parts(10, 10)), check_origin: Some(Parachain(2).into()), }]); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 78b9284c689f..01ff8c29f3da 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -115,14 +115,14 @@ impl pallet_assets::Config for Test { } parameter_types! { - pub const RelayLocation: MultiLocation = Here.into_location(); + pub const RelayLocation: Location = Here.into_location(); pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = (ByGenesis([0; 32]), Parachain(42)).into(); + pub UniversalLocation: InteriorLocation = (ByGenesis([0; 32]), Parachain(42)).into(); pub UnitWeightCost: u64 = 1_000; pub static AdvertisedXcmVersion: u32 = 3; pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); - pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (AssetId(RelayLocation::get()), 1, 1); + pub TrustedAssets: (AssetFilter, Location) = (All.into(), Here.into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub CheckingAccount: AccountId = XcmPallet::check_account(); @@ -130,28 +130,25 @@ parameter_types! { type AssetIdForAssets = u128; -pub struct FromMultiLocationToAsset( - core::marker::PhantomData<(MultiLocation, AssetId)>, -); -impl MaybeEquivalence - for FromMultiLocationToAsset +pub struct FromLocationToAsset(core::marker::PhantomData<(Location, AssetId)>); +impl MaybeEquivalence + for FromLocationToAsset { - fn convert(value: &MultiLocation) -> Option { - match value { - MultiLocation { parents: 0, interior: Here } => Some(0 as AssetIdForAssets), - MultiLocation { parents: 1, interior: Here } => Some(1 as AssetIdForAssets), - MultiLocation { parents: 0, interior: X2(PalletInstance(1), GeneralIndex(index)) } - if ![0, 1].contains(index) => + fn convert(value: &Location) -> Option { + match value.unpack() { + (0, []) => Some(0 as AssetIdForAssets), + (1, []) => Some(1 as AssetIdForAssets), + (0, [PalletInstance(1), GeneralIndex(index)]) if ![0, 1].contains(index) => Some(*index as AssetIdForAssets), _ => None, } } - fn convert_back(value: &AssetIdForAssets) -> Option { + fn convert_back(value: &AssetIdForAssets) -> Option { match value { - 0u128 => Some(MultiLocation { parents: 1, interior: Here }), + 0u128 => Some(Location { parents: 1, interior: Here }), para_id @ 1..=1000 => - Some(MultiLocation { parents: 1, interior: X1(Parachain(*para_id as u32)) }), + Some(Location { parents: 1, interior: [Parachain(*para_id as u32)].into() }), _ => None, } } @@ -163,7 +160,7 @@ pub type LocalAssetsTransactor = FungiblesAdapter< ConvertedConcreteId< AssetIdForAssets, Balance, - FromMultiLocationToAsset, + FromLocationToAsset, JustTry, >, SovereignAccountOf, @@ -187,10 +184,10 @@ impl WeightTrader for DummyWeightTrader { fn buy_weight( &mut self, _weight: Weight, - _payment: xcm_executor::Assets, + _payment: xcm_executor::AssetsInHolding, _context: &XcmContext, - ) -> Result { - Ok(xcm_executor::Assets::default()) + ) -> Result { + Ok(xcm_executor::AssetsInHolding::default()) } } @@ -228,13 +225,10 @@ parameter_types! { pub struct TreasuryToAccount; impl ConvertLocation for TreasuryToAccount { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { - parents: 1, - interior: - X2(Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - } => Some(TreasuryAccountId::get()), // Hardcoded test treasury account id + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (1, [Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => + Some(TreasuryAccountId::get()), // Hardcoded test treasury account id _ => None, } } @@ -277,7 +271,7 @@ pub const INITIAL_BALANCE: Balance = 100 * UNITS; pub const MINIMUM_BALANCE: Balance = 1 * UNITS; pub fn sibling_chain_account_id(para_id: u32, account: [u8; 32]) -> AccountId { - let location: MultiLocation = + let location: Location = (Parent, Parachain(para_id), Junction::AccountId32 { id: account, network: None }).into(); SovereignAccountOf::convert_location(&location).unwrap() } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs index 178b93842736..062faee2abd9 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs @@ -22,9 +22,9 @@ use frame_support::{assert_ok, traits::tokens::Pay}; /// Type representing both a location and an asset that is held at that location. /// The id of the held asset is relative to the location where it is being held. -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq)] +#[derive(Encode, Decode, Clone, PartialEq, Eq)] pub struct AssetKind { - destination: MultiLocation, + destination: Location, asset_id: AssetId, } @@ -37,8 +37,8 @@ impl sp_runtime::traits::TryConvert for LocatableAs parameter_types! { pub SenderAccount: AccountId = AccountId::new([3u8; 32]); - pub InteriorAccount: InteriorMultiLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); - pub InteriorBody: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub InteriorAccount: InteriorLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); + pub InteriorBody: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); pub Timeout: BlockNumber = 5; // 5 blocks } @@ -91,13 +91,19 @@ fn pay_over_xcm_works() { vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] ); - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); let message = Xcm::<::RuntimeCall>::from(message.clone()); // Execute message in parachain 2 with parachain 42's origin let origin = (Parent, Parachain(42)); - XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); assert_eq!(mock::Assets::balance(0, &recipient), amount); }); } @@ -152,13 +158,19 @@ fn pay_over_xcm_governance_body() { vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] ); - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); let message = Xcm::<::RuntimeCall>::from(message.clone()); // Execute message in parachain 2 with parachain 42's origin let origin = (Parent, Parachain(42)); - XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); assert_eq!(mock::Assets::balance(relay_asset_index, &recipient), amount); }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs index e490fe326b37..6a2945c6a9b9 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs @@ -25,9 +25,9 @@ use frame_support::{ use sp_runtime::{traits::ConvertToValue, DispatchResult}; parameter_types! { - pub Interior: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub Interior: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); pub Timeout: BlockNumber = 5; - pub AssetHub: MultiLocation = (Parent, Parachain(1)).into(); + pub AssetHub: Location = (Parent, Parachain(1)).into(); pub AssetIdGeneralIndex: u128 = 100; pub AssetHubAssetId: AssetId = (PalletInstance(1), GeneralIndex(AssetIdGeneralIndex::get())).into(); pub LocatableAsset: LocatableAssetId = LocatableAssetId { asset_id: AssetHubAssetId::get(), location: AssetHub::get() }; @@ -140,7 +140,7 @@ fn salary_pay_over_xcm_works() { assert_ok!(Salary::payout(RuntimeOrigin::signed(recipient.clone()))); // Get message from mock transport layer - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); // Change type from `Xcm<()>` to `Xcm` to be able to execute later let message = Xcm::<::RuntimeCall>::from(message.clone()); @@ -164,7 +164,13 @@ fn salary_pay_over_xcm_works() { assert_eq!(message, expected_message); // Execute message as the asset hub - XcmExecutor::::execute_xcm((Parent, Parachain(42)), message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + (Parent, Parachain(42)), + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); // Recipient receives the payment assert_eq!( diff --git a/polkadot/xcm/xcm-builder/src/tests/querying.rs b/polkadot/xcm/xcm-builder/src/tests/querying.rs index 8fbb55eb2542..3b47073d53df 100644 --- a/polkadot/xcm/xcm-builder/src/tests/querying.rs +++ b/polkadot/xcm/xcm-builder/src/tests/querying.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn pallet_query_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![QueryPallet { @@ -29,14 +29,15 @@ fn pallet_query_should_work() { max_weight: Weight::from_parts(50, 50), }, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![QueryResponse { query_id: 1, @@ -50,7 +51,7 @@ fn pallet_query_should_work() { #[test] fn pallet_query_with_results_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![QueryPallet { @@ -61,14 +62,15 @@ fn pallet_query_with_results_should_work() { max_weight: Weight::from_parts(50, 50), }, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![QueryResponse { query_id: 1, @@ -106,15 +108,27 @@ fn prepaid_result_of_query_should_get_free_execution() { max_weight: Weight::from_parts(10, 10), querier: Some(Here.into()), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); // First time the response gets through since we're expecting it... - let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!(response(query_id).unwrap(), the_response); // Second time it doesn't, since we're not. - let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/transacting.rs b/polkadot/xcm/xcm-builder/src/tests/transacting.rs index 743ad7039f7f..a85c8b9986c8 100644 --- a/polkadot/xcm/xcm-builder/src/tests/transacting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/transacting.rs @@ -25,10 +25,16 @@ fn transacting_should_work() { require_weight_at_most: Weight::from_parts(50, 50), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(60, 60) }); } #[test] @@ -40,10 +46,19 @@ fn transacting_should_respect_max_weight_requirement() { require_weight_at_most: Weight::from_parts(40, 40), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(50, 50), XcmError::MaxWeightInvalid)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(50, 50), error: XcmError::MaxWeightInvalid } + ); } #[test] @@ -57,20 +72,26 @@ fn transacting_should_refund_weight() { .encode() .into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); } #[test] fn paid_transacting_should_refund_payment_for_unused_weight() { - let one: MultiLocation = AccountIndex64 { index: 1, network: None }.into(); - AllowPaidFrom::set(vec![one]); + let one: Location = AccountIndex64 { index: 1, network: None }.into(); + AllowPaidFrom::set(vec![one.clone()]); add_asset(AccountIndex64 { index: 1, network: None }, (Parent, 200u128)); WeightPrice::set((Parent.into(), 1_000_000_000_000, 1024 * 1024)); - let origin = one; + let origin = one.clone(); let fees = (Parent, 200u128).into(); let message = Xcm::(vec![ WithdrawAsset((Parent, 200u128).into()), // enough for 200 units of weight. @@ -86,10 +107,16 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { RefundSurplus, DepositAsset { assets: AllCounted(1).into(), beneficiary: one }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(100, 100); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(60, 60) }); assert_eq!( asset_list(AccountIndex64 { index: 1, network: None }), vec![(Parent, 80u128).into()] @@ -112,10 +139,16 @@ fn report_successful_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(MaybeErrorCode::Success), query_id: 42, @@ -142,10 +175,16 @@ fn report_failed_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(vec![2].into()), query_id: 42, @@ -168,10 +207,16 @@ fn expect_successful_transact_status_should_work() { }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let message = Xcm::(vec![ Transact { @@ -181,10 +226,19 @@ fn expect_successful_transact_status_should_work() { }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(70, 70), error: XcmError::ExpectationFalse } + ); } #[test] @@ -199,10 +253,16 @@ fn expect_failed_transact_status_should_work() { }, ExpectTransactStatus(vec![2].into()), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let message = Xcm::(vec![ Transact { @@ -212,10 +272,19 @@ fn expect_failed_transact_status_should_work() { }, ExpectTransactStatus(vec![2].into()), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(70, 70), error: XcmError::ExpectationFalse } + ); } #[test] @@ -235,10 +304,16 @@ fn clear_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(80, 80); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(80, 80))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(80, 80) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(MaybeErrorCode::Success), query_id: 42, diff --git a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs index 44ab7d34c51b..e29e3a546615 100644 --- a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs +++ b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs @@ -25,23 +25,41 @@ fn simple_version_subscriptions_should_work() { SetAppendix(Xcm(vec![])), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let origin = Parachain(1000); let message = Xcm::(vec![SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); - let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( SubscriptionRequests::get(), @@ -53,33 +71,36 @@ fn simple_version_subscriptions_should_work() { fn version_subscription_instruction_should_work() { let origin = Parachain(1000); let message = Xcm::(vec![ - DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + DescendOrigin([AccountIndex64 { index: 1, network: None }].into()), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm_in_credit( + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::BadOrigin } + ); let message = Xcm::(vec![ SetAppendix(Xcm(vec![])), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!( SubscriptionRequests::get(), @@ -93,20 +114,38 @@ fn simple_version_unsubscriptions_should_work() { let origin = Parachain(1000); let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let origin = Parachain(1000); let message = Xcm::(vec![UnsubscribeVersion]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); - let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!(SubscriptionRequests::get(), vec![(Parent.into(), None)]); assert_eq!(sent_xcm(), vec![]); @@ -118,31 +157,34 @@ fn version_unsubscription_instruction_should_work() { // Not allowed to do it when origin has been changed. let message = Xcm::(vec![ - DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + DescendOrigin([AccountIndex64 { index: 1, network: None }].into()), UnsubscribeVersion, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm_in_credit( + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::BadOrigin } + ); // Fine to do it when origin is untouched. let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(SubscriptionRequests::get(), vec![(Parachain(1000).into(), None)]); assert_eq!(sent_xcm(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/weight.rs b/polkadot/xcm/xcm-builder/src/tests/weight.rs index a2fb265413f5..637e30cce998 100644 --- a/polkadot/xcm/xcm-builder/src/tests/weight.rs +++ b/polkadot/xcm/xcm-builder/src/tests/weight.rs @@ -74,45 +74,78 @@ fn errors_should_return_unused_weight() { // First xfer results in an error on the last message only TransferAsset { assets: (Here, 1u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Second xfer results in error third message and after TransferAsset { assets: (Here, 2u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Third xfer results in error second message and after TransferAsset { assets: (Here, 4u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, ]); // Weight limit of 70 is needed. let limit = ::Weigher::weight(&mut message).unwrap(); assert_eq!(limit, Weight::from_parts(30, 30)); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 7u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 4u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(30, 30), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(30, 30), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 10u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); assert_eq!(asset_list(Here), vec![]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message, + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); assert_eq!(asset_list(Here), vec![]); assert_eq!(sent_xcm(), vec![]); @@ -148,8 +181,8 @@ fn weight_bounds_should_respect_instructions_limit() { #[test] fn weight_trader_tuple_should_work() { - let para_1: MultiLocation = Parachain(1).into(); - let para_2: MultiLocation = Parachain(2).into(); + let para_1: Location = Parachain(1).into(); + let para_2: Location = Parachain(2).into(); parameter_types! { pub static HereWeightPrice: (AssetId, u128, u128) = @@ -186,7 +219,11 @@ fn weight_trader_tuple_should_work() { let mut traders = Traders::new(); // trader one failed; trader two buys weight assert_eq!( - traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into(), &ctx), + traders.buy_weight( + Weight::from_parts(5, 5), + fungible_multi_asset(para_1.clone(), 10).into(), + &ctx + ), Ok(vec![].into()), ); // trader two refunds diff --git a/polkadot/xcm/xcm-builder/src/universal_exports.rs b/polkadot/xcm/xcm-builder/src/universal_exports.rs index 4aa6a0ef7a50..1d084e022c92 100644 --- a/polkadot/xcm/xcm-builder/src/universal_exports.rs +++ b/polkadot/xcm/xcm-builder/src/universal_exports.rs @@ -28,18 +28,18 @@ use SendError::*; /// chain, itself situated at `universal_local` within the consensus universe. If /// `dest` is not a location in remote consensus, then an error is returned. pub fn ensure_is_remote( - universal_local: impl Into, - dest: impl Into, -) -> Result<(NetworkId, InteriorMultiLocation), MultiLocation> { + universal_local: impl Into, + dest: impl Into, +) -> Result<(NetworkId, InteriorLocation), Location> { let dest = dest.into(); let universal_local = universal_local.into(); let local_net = match universal_local.global_consensus() { Ok(x) => x, Err(_) => return Err(dest), }; - let universal_destination: InteriorMultiLocation = universal_local + let universal_destination: InteriorLocation = universal_local .into_location() - .appended_with(dest) + .appended_with(dest.clone()) .map_err(|x| x.1)? .try_into()?; let (remote_dest, remote_net) = match universal_destination.split_first() { @@ -59,18 +59,18 @@ pub fn ensure_is_remote( pub struct UnpaidLocalExporter( PhantomData<(Exporter, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for UnpaidLocalExporter { type Ticket = Exporter::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, xcm: &mut Option>, ) -> SendResult { let d = dest.take().ok_or(MissingArgument)?; let universal_source = UniversalLocation::get(); - let devolved = match ensure_is_remote(universal_source, d) { + let devolved = match ensure_is_remote(universal_source.clone(), d) { Ok(x) => x, Err(d) => { *dest = Some(d); @@ -96,18 +96,18 @@ pub trait ExporterFor { /// the bridge chain as well as payment for the use of the `ExportMessage` instruction. fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)>; + ) -> Option<(Location, Option)>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ExporterFor for Tuple { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { for_tuples!( #( if let Some(r) = Tuple::exporter_for(network, remote_location, message) { return Some(r); @@ -125,21 +125,21 @@ pub struct NetworkExportTableItem { /// If `Some`, the requested remote location must be equal to one of the items in the vector. /// These are locations in the remote network. /// If `None`, then the check is skipped. - pub remote_location_filter: Option>, + pub remote_location_filter: Option>, /// Locally-routable bridge with bridging capabilities to the `remote_network` and /// `remote_location`. See [`ExporterFor`] for more details. - pub bridge: MultiLocation, + pub bridge: Location, /// The local payment. /// See [`ExporterFor`] for more details. - pub payment: Option, + pub payment: Option, } impl NetworkExportTableItem { pub fn new( remote_network: NetworkId, - remote_location_filter: Option>, - bridge: MultiLocation, - payment: Option, + remote_location_filter: Option>, + bridge: Location, + payment: Option, ) -> Self { Self { remote_network, remote_location_filter, bridge, payment } } @@ -152,9 +152,9 @@ pub struct NetworkExportTable(sp_std::marker::PhantomData); impl>> ExporterFor for NetworkExportTable { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, _: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { T::get() .into_iter() .find(|item| { @@ -194,16 +194,16 @@ pub fn forward_id_for(original_id: &XcmHash) -> XcmHash { pub struct UnpaidRemoteExporter( PhantomData<(Bridges, Router, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for UnpaidRemoteExporter { type Ticket = Router::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult { - let d = dest.ok_or(MissingArgument)?; + let d = dest.clone().ok_or(MissingArgument)?; let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; let (remote_network, remote_location) = devolved; let xcm = msg.take().ok_or(MissingArgument)?; @@ -261,17 +261,18 @@ impl( PhantomData<(Bridges, Router, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for SovereignPaidRemoteExporter { type Ticket = Router::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult { - let d = *dest.as_ref().ok_or(MissingArgument)?; - let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; + let d = dest.as_ref().ok_or(MissingArgument)?; + let devolved = + ensure_is_remote(UniversalLocation::get(), d.clone()).map_err(|_| NotApplicable)?; let (remote_network, remote_location) = devolved; let xcm = msg.take().ok_or(MissingArgument)?; @@ -299,7 +300,7 @@ impl, } @@ -386,8 +387,8 @@ pub struct BridgeBlobDispatcher( ); impl< Router: SendXcm, - OurPlace: Get, - OurPlaceBridgeInstance: Get>, + OurPlace: Get, + OurPlaceBridgeInstance: Get>, > DispatchBlob for BridgeBlobDispatcher { fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { @@ -396,7 +397,7 @@ impl< our_universal.global_consensus().map_err(|()| DispatchBlobError::Unbridgable)?; let BridgeMessage { universal_dest, message } = Decode::decode(&mut &blob[..]).map_err(|_| DispatchBlobError::InvalidEncoding)?; - let universal_dest: InteriorMultiLocation = universal_dest + let universal_dest: InteriorLocation = universal_dest .try_into() .map_err(|_| DispatchBlobError::UnsupportedLocationVersion)?; // `universal_dest` is the desired destination within the universe: first we need to check @@ -437,9 +438,9 @@ pub struct HaulBlobExporter( /// ``` impl< Bridge: HaulBlob, - BridgedNetwork: Get, + BridgedNetwork: Get, DestinationVersion: GetVersion, - Price: Get, + Price: Get, > ExportXcm for HaulBlobExporter { type Ticket = (Vec, XcmHash); @@ -447,12 +448,12 @@ impl< fn validate( network: NetworkId, _channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, - ) -> Result<((Vec, XcmHash), MultiAssets), SendError> { + ) -> Result<((Vec, XcmHash), Assets), SendError> { let (bridged_network, bridged_network_location_parents) = { - let MultiLocation { parents, interior: mut junctions } = BridgedNetwork::get(); + let Location { parents, interior: mut junctions } = BridgedNetwork::get(); match junctions.take_first() { Some(GlobalConsensus(network)) => (network, parents), _ => return Err(SendError::NotApplicable), @@ -467,8 +468,8 @@ impl< let (universal_dest, version) = match dest.pushed_front_with(GlobalConsensus(bridged_network)) { Ok(d) => { - let version = DestinationVersion::get_version_for(&MultiLocation::from( - AncestorThen(bridged_network_location_parents, d), + let version = DestinationVersion::get_version_for(&Location::from( + AncestorThen(bridged_network_location_parents, d.clone()), )) .ok_or(SendError::DestinationUnsupported)?; (d, version) @@ -501,7 +502,7 @@ impl< let message = VersionedXcm::from(message) .into_version(version) .map_err(|()| SendError::DestinationUnsupported)?; - let universal_dest = VersionedInteriorMultiLocation::from(universal_dest) + let universal_dest = VersionedInteriorLocation::from(universal_dest) .into_version(version) .map_err(|()| SendError::DestinationUnsupported)?; @@ -548,10 +549,10 @@ mod tests { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { - Ok(((), MultiAssets::new())) + Ok(((), Assets::new())) } fn deliver(_ticket: Self::Ticket) -> Result { @@ -562,10 +563,10 @@ mod tests { /// Generic test case asserting that dest and msg is not consumed by `validate` implementation /// of `SendXcm` in case of expected result. fn ensure_validate_does_not_consume_dest_or_msg( - dest: MultiLocation, + dest: Location, assert_result: impl Fn(SendResult), ) { - let mut dest_wrapper = Some(dest); + let mut dest_wrapper = Some(dest.clone()); let msg = Xcm::<()>::new(); let mut msg_wrapper = Some(msg.clone()); @@ -580,19 +581,19 @@ mod tests { fn remote_exporters_does_not_consume_dest_or_msg_on_not_applicable() { frame_support::parameter_types! { pub Local: NetworkId = ByGenesis([0; 32]); - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Local::get()), Parachain(1234)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(Local::get()), Parachain(1234)].into(); pub DifferentRemote: NetworkId = ByGenesis([22; 32]); // no routers pub BridgeTable: Vec = vec![]; } // check with local destination (should be remote) - let local_dest = (Parent, Parachain(5678)).into(); - assert!(ensure_is_remote(UniversalLocation::get(), local_dest).is_err()); + let local_dest: Location = (Parent, Parachain(5678)).into(); + assert!(ensure_is_remote(UniversalLocation::get(), local_dest.clone()).is_err()); ensure_validate_does_not_consume_dest_or_msg::< UnpaidRemoteExporter, OkSender, UniversalLocation>, - >(local_dest, |result| assert_eq!(Err(NotApplicable), result)); + >(local_dest.clone(), |result| assert_eq!(Err(NotApplicable), result)); ensure_validate_does_not_consume_dest_or_msg::< SovereignPaidRemoteExporter< @@ -603,12 +604,12 @@ mod tests { >(local_dest, |result| assert_eq!(Err(NotApplicable), result)); // check with not applicable destination - let remote_dest = (Parent, Parent, DifferentRemote::get()).into(); - assert!(ensure_is_remote(UniversalLocation::get(), remote_dest).is_ok()); + let remote_dest: Location = (Parent, Parent, DifferentRemote::get()).into(); + assert!(ensure_is_remote(UniversalLocation::get(), remote_dest.clone()).is_ok()); ensure_validate_does_not_consume_dest_or_msg::< UnpaidRemoteExporter, OkSender, UniversalLocation>, - >(remote_dest, |result| assert_eq!(Err(NotApplicable), result)); + >(remote_dest.clone(), |result| assert_eq!(Err(NotApplicable), result)); ensure_validate_does_not_consume_dest_or_msg::< SovereignPaidRemoteExporter< @@ -623,15 +624,15 @@ mod tests { fn network_export_table_works() { frame_support::parameter_types! { pub NetworkA: NetworkId = ByGenesis([0; 32]); - pub Parachain1000InNetworkA: InteriorMultiLocation = X1(Parachain(1000)); - pub Parachain2000InNetworkA: InteriorMultiLocation = X1(Parachain(2000)); + pub Parachain1000InNetworkA: InteriorLocation = [Parachain(1000)].into(); + pub Parachain2000InNetworkA: InteriorLocation = [Parachain(2000)].into(); pub NetworkB: NetworkId = ByGenesis([1; 32]); - pub BridgeToALocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); - pub BridgeToBLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(4321))); + pub BridgeToALocation: Location = Location::new(1, [Parachain(1234)]); + pub BridgeToBLocation: Location = Location::new(1, [Parachain(4321)]); - pub PaymentForNetworkAAndParachain2000: MultiAsset = (MultiLocation::parent(), 150).into(); + pub PaymentForNetworkAAndParachain2000: Asset = (Location::parent(), 150).into(); pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ // NetworkA allows `Parachain(1000)` as remote location WITHOUT payment. @@ -658,19 +659,19 @@ mod tests { ]; } - let test_data = vec![ - (NetworkA::get(), X1(Parachain(1000)), Some((BridgeToALocation::get(), None))), - (NetworkA::get(), X2(Parachain(1000), GeneralIndex(1)), None), + let test_data: Vec<(NetworkId, InteriorLocation, Option<(Location, Option)>)> = vec![ + (NetworkA::get(), [Parachain(1000)].into(), Some((BridgeToALocation::get(), None))), + (NetworkA::get(), [Parachain(1000), GeneralIndex(1)].into(), None), ( NetworkA::get(), - X1(Parachain(2000)), + [Parachain(2000)].into(), Some((BridgeToALocation::get(), Some(PaymentForNetworkAAndParachain2000::get()))), ), - (NetworkA::get(), X2(Parachain(2000), GeneralIndex(1)), None), - (NetworkA::get(), X1(Parachain(3000)), None), - (NetworkB::get(), X1(Parachain(1000)), Some((BridgeToBLocation::get(), None))), - (NetworkB::get(), X1(Parachain(2000)), Some((BridgeToBLocation::get(), None))), - (NetworkB::get(), X1(Parachain(3000)), Some((BridgeToBLocation::get(), None))), + (NetworkA::get(), [Parachain(2000), GeneralIndex(1)].into(), None), + (NetworkA::get(), [Parachain(3000)].into(), None), + (NetworkB::get(), [Parachain(1000)].into(), Some((BridgeToBLocation::get(), None))), + (NetworkB::get(), [Parachain(2000)].into(), Some((BridgeToBLocation::get(), None))), + (NetworkB::get(), [Parachain(3000)].into(), Some((BridgeToBLocation::get(), None))), ]; for (network, remote_location, expected_result) in test_data { diff --git a/polkadot/xcm/xcm-builder/src/weight.rs b/polkadot/xcm/xcm-builder/src/weight.rs index c16c52939a38..2ae6a043843f 100644 --- a/polkadot/xcm/xcm-builder/src/weight.rs +++ b/polkadot/xcm/xcm-builder/src/weight.rs @@ -25,10 +25,10 @@ use frame_support::{ use parity_scale_codec::Decode; use sp_runtime::traits::{SaturatedConversion, Saturating, Zero}; use sp_std::{marker::PhantomData, result::Result}; -use xcm::latest::{prelude::*, Weight}; +use xcm::latest::{prelude::*, GetWeight, Weight}; use xcm_executor::{ traits::{WeightBounds, WeightTrader}, - Assets, + AssetsInHolding, }; pub struct FixedWeightBounds(PhantomData<(T, C, M)>); @@ -114,16 +114,16 @@ where } /// Function trait for handling some revenue. Similar to a negative imbalance (credit) handler, but -/// for a `MultiAsset`. Sensible implementations will deposit the asset in some known treasury or +/// for a `Asset`. Sensible implementations will deposit the asset in some known treasury or /// block-author account. pub trait TakeRevenue { - /// Do something with the given `revenue`, which is a single non-wildcard `MultiAsset`. - fn take_revenue(revenue: MultiAsset); + /// Do something with the given `revenue`, which is a single non-wildcard `Asset`. + fn take_revenue(revenue: Asset); } /// Null implementation just burns the revenue. impl TakeRevenue for () { - fn take_revenue(_revenue: MultiAsset) {} + fn take_revenue(_revenue: Asset) {} } /// Simple fee calculator that requires payment in a single fungible at a fixed rate. @@ -143,9 +143,9 @@ impl, R: TakeRevenue> WeightTrader for FixedRateOf fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!( target: "xcm::weight", "FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}, context: {:?}", @@ -165,7 +165,7 @@ impl, R: TakeRevenue> WeightTrader for FixedRateOf Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}, context: {:?}", weight, context); let (id, units_per_second, units_per_mb) = T::get(); let weight = weight.min(self.0); @@ -194,22 +194,22 @@ impl, R: TakeRevenue> Drop for FixedRateOfFungible /// places any weight bought into the right account. pub struct UsingComponents< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetIdValue: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, >( Weight, Currency::Balance, - PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, + PhantomData<(WeightToFee, AssetIdValue, AccountId, Currency, OnUnbalanced)>, ); impl< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetIdValue: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, - > WeightTrader for UsingComponents + > WeightTrader for UsingComponents { fn new() -> Self { Self(Weight::zero(), Zero::zero(), PhantomData) @@ -218,20 +218,20 @@ impl< fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); let amount = WeightToFee::weight_to_fee(&weight); let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; - let required = (Concrete(AssetId::get()), u128_amount).into(); + let required = (AssetId(AssetIdValue::get()), u128_amount).into(); let unused = payment.checked_sub(required).map_err(|_| XcmError::TooExpensive)?; self.0 = self.0.saturating_add(weight); self.1 = self.1.saturating_add(amount); Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}, context: {:?}", weight, context); let weight = weight.min(self.0); let amount = WeightToFee::weight_to_fee(&weight); @@ -239,7 +239,7 @@ impl< self.1 = self.1.saturating_sub(amount); let amount: u128 = amount.saturated_into(); if amount > 0 { - Some((AssetId::get(), amount).into()) + Some((AssetIdValue::get(), amount).into()) } else { None } @@ -247,7 +247,7 @@ impl< } impl< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetId: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 6b4d893f73c7..e08099280baa 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -46,24 +46,24 @@ pub type AccountId = AccountId32; pub type Balance = u128; thread_local! { - pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); } -pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { +pub fn sent_xcm() -> Vec<(Location, opaque::Xcm, XcmHash)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } pub struct TestSendXcm; impl SendXcm for TestSendXcm { - type Ticket = (MultiLocation, Xcm<()>, XcmHash); + type Ticket = (Location, Xcm<()>, XcmHash); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + ) -> SendResult<(Location, Xcm<()>, XcmHash)> { let msg = msg.take().unwrap(); let hash = fake_message_hash(&msg); let triplet = (dest.take().unwrap(), msg, hash); - Ok((triplet, MultiAssets::new())) + Ok((triplet, Assets::new())) } - fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + fn deliver(triplet: (Location, Xcm<()>, XcmHash)) -> Result { let hash = triplet.2; SENT_XCM.with(|q| q.borrow_mut().push(triplet)); Ok(hash) @@ -136,9 +136,9 @@ impl configuration::Config for Runtime { // aims to closely emulate the Kusama XcmConfig parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::here(); + pub const KsmLocation: Location = Location::here(); pub const KusamaNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub CheckAccount: (AccountId, MintLocation) = (XcmPallet::check_account(), MintLocation::Local); } @@ -176,8 +176,8 @@ pub type Barrier = ( ); parameter_types! { - pub KusamaForAssetHub: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { id: Concrete(Here.into()), fun: WildFungible }), Parachain(1000).into()); + pub KusamaForAssetHub: (AssetFilter, Location) = + (Wild(AllOf { id: AssetId(Here.into()), fun: WildFungible }), Parachain(1000).into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 4; } diff --git a/polkadot/xcm/xcm-builder/tests/scenarios.rs b/polkadot/xcm/xcm-builder/tests/scenarios.rs index 36780b9f0078..db37f85acdbb 100644 --- a/polkadot/xcm/xcm-builder/tests/scenarios.rs +++ b/polkadot/xcm/xcm-builder/tests/scenarios.rs @@ -55,9 +55,15 @@ fn withdraw_and_deposit_works() { beneficiary: Parachain(other_para_id).into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); assert_eq!(Balances::free_balance(other_para_acc), amount); @@ -79,19 +85,19 @@ fn transfer_asset_works() { assets: (Here, amount).into(), beneficiary: AccountId32 { network: None, id: bob.clone().into() }.into(), }]); - let hash = fake_message_hash(&message); - // Use `execute_xcm_in_credit` here to pass through the barrier - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + // Use `prepare_and_execute` here to pass through the barrier + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, weight, weight, ); System::assert_last_event( pallet_balances::Event::Transfer { from: ALICE, to: bob.clone(), amount }.into(), ); - assert_eq!(r, Outcome::Complete(weight)); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - amount); assert_eq!(Balances::free_balance(bob), INITIAL_BALANCE + amount); }); @@ -129,14 +135,20 @@ fn report_holding_works() { // is not triggered becasue the deposit fails ReportHolding { response_info: response_info.clone(), assets: All.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); assert_eq!( r, - Outcome::Incomplete( - weight - BaseXcmWeight::get(), - XcmError::FailedToTransactAsset("AccountIdConversionFailed") - ) + Outcome::Incomplete { + used: weight - BaseXcmWeight::get(), + error: XcmError::FailedToTransactAsset("AccountIdConversionFailed") + } ); // there should be no query response sent for the failed deposit assert_eq!(mock::sent_xcm(), vec![]); @@ -153,9 +165,15 @@ fn report_holding_works() { // used to get a notification in case of success ReportHolding { response_info: response_info.clone(), assets: AllCounted(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); assert_eq!(Balances::free_balance(other_para_acc), amount); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); @@ -209,9 +227,15 @@ fn teleport_to_asset_hub_works() { xcm: Xcm(teleport_effects.clone()), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] .into_iter() .chain(teleport_effects.clone().into_iter()) @@ -232,9 +256,15 @@ fn teleport_to_asset_hub_works() { xcm: Xcm(teleport_effects.clone()), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); // 2 * amount because of the other teleport above assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] @@ -282,10 +312,16 @@ fn reserve_based_transfer_works() { xcm: Xcm(transfer_effects.clone()), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight = BaseXcmWeight::get() * 3; - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); let expected_msg = Xcm(vec![ReserveAssetDeposited((Parent, amount).into()), ClearOrigin] .into_iter() diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs index c02cb218885f..79d6cb1c411b 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -65,7 +65,7 @@ fn basic_buy_fees_message_executes() { assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( r.event, polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { - outcome: Outcome::Complete(_) + outcome: Outcome::Complete { .. } }), ))); }); @@ -147,7 +147,7 @@ fn transact_recursion_limit_works() { .filter(|r| matches!( r.event, polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { - outcome: Outcome::Complete(_) + outcome: Outcome::Complete { .. } }), )) .count(), @@ -242,7 +242,7 @@ fn query_response_fires() { assert_eq!( polkadot_test_runtime::Xcm::query(query_id), Some(QueryStatus::Ready { - response: VersionedResponse::V3(Response::ExecutionResult(None)), + response: VersionedResponse::V4(Response::ExecutionResult(None)), at: 2u32.into() }), ) @@ -314,12 +314,12 @@ fn query_response_elicits_handler() { client.state_at(block_hash).expect("state should exist").inspect_state(|| { assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( - r.event, + &r.event, TestNotifier(ResponseReceived( - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { .. }) }, + location, q, Response::ExecutionResult(None), - )) if q == query_id, + )) if *q == query_id && matches!(location.unpack(), (0, [Junction::AccountId32 { .. }])), ))); }); } diff --git a/polkadot/xcm/xcm-executor/src/assets.rs b/polkadot/xcm/xcm-executor/src/assets.rs index 33f2ff218c73..4407752f7024 100644 --- a/polkadot/xcm/xcm-executor/src/assets.rs +++ b/polkadot/xcm/xcm-executor/src/assets.rs @@ -21,16 +21,16 @@ use sp_std::{ prelude::*, }; use xcm::latest::{ - AssetId, AssetInstance, + Asset, AssetFilter, AssetId, AssetInstance, Assets, Fungibility::{Fungible, NonFungible}, - InteriorMultiLocation, MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation, + InteriorLocation, Location, Reanchorable, + WildAsset::{All, AllCounted, AllOf, AllOfCounted}, WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}, - WildMultiAsset::{All, AllCounted, AllOf, AllOfCounted}, }; -/// List of non-wildcard fungible and non-fungible assets. +/// Map of non-wildcard fungible and non-fungible assets held in the holding register. #[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)] -pub struct Assets { +pub struct AssetsInHolding { /// The fungible assets. pub fungible: BTreeMap, @@ -40,16 +40,16 @@ pub struct Assets { pub non_fungible: BTreeSet<(AssetId, AssetInstance)>, } -impl From for Assets { - fn from(asset: MultiAsset) -> Assets { +impl From for AssetsInHolding { + fn from(asset: Asset) -> AssetsInHolding { let mut result = Self::default(); result.subsume(asset); result } } -impl From> for Assets { - fn from(assets: Vec) -> Assets { +impl From> for AssetsInHolding { + fn from(assets: Vec) -> AssetsInHolding { let mut result = Self::default(); for asset in assets.into_iter() { result.subsume(asset) @@ -58,21 +58,21 @@ impl From> for Assets { } } -impl From for Assets { - fn from(assets: MultiAssets) -> Assets { +impl From for AssetsInHolding { + fn from(assets: Assets) -> AssetsInHolding { assets.into_inner().into() } } -impl From for Vec { - fn from(a: Assets) -> Self { +impl From for Vec { + fn from(a: AssetsInHolding) -> Self { a.into_assets_iter().collect() } } -impl From for MultiAssets { - fn from(a: Assets) -> Self { - a.into_assets_iter().collect::>().into() +impl From for Assets { + fn from(a: AssetsInHolding) -> Self { + a.into_assets_iter().collect::>().into() } } @@ -80,10 +80,10 @@ impl From for MultiAssets { #[derive(Debug)] pub enum TakeError { /// There was an attempt to take an asset without saturating (enough of) which did not exist. - AssetUnderflow(MultiAsset), + AssetUnderflow(Asset), } -impl Assets { +impl AssetsInHolding { /// New value, containing no assets. pub fn new() -> Self { Self::default() @@ -100,41 +100,41 @@ impl Assets { } /// A borrowing iterator over the fungible assets. - pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { + pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { self.fungible .iter() - .map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: *id }) + .map(|(id, &amount)| Asset { fun: Fungible(amount), id: id.clone() }) } /// A borrowing iterator over the non-fungible assets. - pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { + pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { self.non_fungible .iter() - .map(|(id, instance)| MultiAsset { fun: NonFungible(*instance), id: *id }) + .map(|(id, instance)| Asset { fun: NonFungible(*instance), id: id.clone() }) } /// A consuming iterator over all assets. - pub fn into_assets_iter(self) -> impl Iterator { + pub fn into_assets_iter(self) -> impl Iterator { self.fungible .into_iter() - .map(|(id, amount)| MultiAsset { fun: Fungible(amount), id }) + .map(|(id, amount)| Asset { fun: Fungible(amount), id }) .chain( self.non_fungible .into_iter() - .map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }), + .map(|(id, instance)| Asset { fun: NonFungible(instance), id }), ) } /// A borrowing iterator over all assets. - pub fn assets_iter(&self) -> impl Iterator + '_ { + pub fn assets_iter(&self) -> impl Iterator + '_ { self.fungible_assets_iter().chain(self.non_fungible_assets_iter()) } /// Mutate `self` to contain all given `assets`, saturating if necessary. /// - /// NOTE: [`Assets`] are always sorted, allowing us to optimize this function from `O(n^2)` to - /// `O(n)`. - pub fn subsume_assets(&mut self, mut assets: Assets) { + /// NOTE: [`AssetsInHolding`] are always sorted, allowing us to optimize this function from + /// `O(n^2)` to `O(n)`. + pub fn subsume_assets(&mut self, mut assets: AssetsInHolding) { let mut f_iter = assets.fungible.iter_mut(); let mut g_iter = self.fungible.iter_mut(); if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) { @@ -166,7 +166,7 @@ impl Assets { /// Mutate `self` to contain the given `asset`, saturating if necessary. /// /// Wildcard values of `asset` do nothing. - pub fn subsume(&mut self, asset: MultiAsset) { + pub fn subsume(&mut self, asset: Asset) { match asset.fun { Fungible(amount) => { self.fungible @@ -180,18 +180,18 @@ impl Assets { } } - /// Swaps two mutable Assets, without deinitializing either one. - pub fn swapped(&mut self, mut with: Assets) -> Self { + /// Swaps two mutable AssetsInHolding, without deinitializing either one. + pub fn swapped(&mut self, mut with: AssetsInHolding) -> Self { mem::swap(&mut *self, &mut with); with } - /// Alter any concretely identified assets by prepending the given `MultiLocation`. + /// Alter any concretely identified assets by prepending the given `Location`. /// /// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's /// responsibility to ensure that any internal asset IDs are able to be prepended without /// overflow. - pub fn prepend_location(&mut self, prepend: &MultiLocation) { + pub fn prepend_location(&mut self, prepend: &Location) { let mut fungible = Default::default(); mem::swap(&mut self.fungible, &mut fungible); self.fungible = fungible @@ -218,8 +218,8 @@ impl Assets { /// Any assets which were unable to be reanchored are introduced into `failed_bin`. pub fn reanchor( &mut self, - target: &MultiLocation, - context: InteriorMultiLocation, + target: &Location, + context: &InteriorLocation, mut maybe_failed_bin: Option<&mut Self>, ) { let mut fungible = Default::default(); @@ -249,22 +249,22 @@ impl Assets { } /// Returns `true` if `asset` is contained within `self`. - pub fn contains_asset(&self, asset: &MultiAsset) -> bool { + pub fn contains_asset(&self, asset: &Asset) -> bool { match asset { - MultiAsset { fun: Fungible(amount), id } => + Asset { fun: Fungible(amount), id } => self.fungible.get(id).map_or(false, |a| a >= amount), - MultiAsset { fun: NonFungible(instance), id } => - self.non_fungible.contains(&(*id, *instance)), + Asset { fun: NonFungible(instance), id } => + self.non_fungible.contains(&(id.clone(), *instance)), } } /// Returns `true` if all `assets` are contained within `self`. - pub fn contains_assets(&self, assets: &MultiAssets) -> bool { + pub fn contains_assets(&self, assets: &Assets) -> bool { assets.inner().iter().all(|a| self.contains_asset(a)) } /// Returns `true` if all `assets` are contained within `self`. - pub fn contains(&self, assets: &Assets) -> bool { + pub fn contains(&self, assets: &AssetsInHolding) -> bool { assets .fungible .iter() @@ -274,16 +274,16 @@ impl Assets { /// Returns an error unless all `assets` are contained in `self`. In the case of an error, the /// first asset in `assets` which is not wholly in `self` is returned. - pub fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> { + pub fn ensure_contains(&self, assets: &Assets) -> Result<(), TakeError> { for asset in assets.inner().iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { if self.fungible.get(id).map_or(true, |a| a < amount) { - return Err(TakeError::AssetUnderflow((*id, *amount).into())) + return Err(TakeError::AssetUnderflow((id.clone(), *amount).into())) } }, - MultiAsset { fun: NonFungible(instance), id } => { - let id_instance = (*id, *instance); + Asset { fun: NonFungible(instance), id } => { + let id_instance = (id.clone(), *instance); if !self.non_fungible.contains(&id_instance) { return Err(TakeError::AssetUnderflow(id_instance.into())) } @@ -308,16 +308,16 @@ impl Assets { /// of) a definite asset to be removed. fn general_take( &mut self, - mask: MultiAssetFilter, + mask: AssetFilter, saturate: bool, - ) -> Result { - let mut taken = Assets::new(); + ) -> Result { + let mut taken = AssetsInHolding::new(); let maybe_limit = mask.limit().map(|x| x as usize); match mask { // TODO: Counted variants where we define `limit`. - MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + AssetFilter::Wild(All) | AssetFilter::Wild(AllCounted(_)) => { if maybe_limit.map_or(true, |l| self.len() <= l) { - return Ok(self.swapped(Assets::new())) + return Ok(self.swapped(AssetsInHolding::new())) } else { let fungible = mem::replace(&mut self.fungible, Default::default()); fungible.into_iter().for_each(|(c, amount)| { @@ -337,15 +337,15 @@ impl Assets { }); } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildFungible, id }) => if maybe_limit.map_or(true, |l| l >= 1) { if let Some((id, amount)) = self.fungible.remove_entry(&id) { taken.fungible.insert(id, amount); } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { + AssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); non_fungible.into_iter().for_each(|(c, instance)| { if c == id && maybe_limit.map_or(true, |l| taken.len() < l) { @@ -355,13 +355,13 @@ impl Assets { } }); }, - MultiAssetFilter::Definite(assets) => { + AssetFilter::Definite(assets) => { if !saturate { self.ensure_contains(&assets)?; } for asset in assets.into_inner().into_iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { let (remove, amount) = match self.fungible.get_mut(&id) { Some(self_amount) => { let amount = amount.min(*self_amount); @@ -374,10 +374,10 @@ impl Assets { self.fungible.remove(&id); } if amount > 0 { - taken.subsume(MultiAsset::from((id, amount)).into()); + taken.subsume(Asset::from((id, amount)).into()); } }, - MultiAsset { fun: NonFungible(instance), id } => { + Asset { fun: NonFungible(instance), id } => { let id_instance = (id, instance); if self.non_fungible.remove(&id_instance) { taken.subsume(id_instance.into()) @@ -395,7 +395,7 @@ impl Assets { /// /// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its /// value minus `mask` if `self` contains `asset`, and return `Err` otherwise. - pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets { + pub fn saturating_take(&mut self, asset: AssetFilter) -> AssetsInHolding { self.general_take(asset, true) .expect("general_take never results in error when saturating") } @@ -405,13 +405,13 @@ impl Assets { /// /// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its /// value minus `asset` if `self` contains `asset`, and return `Err` otherwise. - pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result { + pub fn try_take(&mut self, mask: AssetFilter) -> Result { self.general_take(mask, false) } /// Consumes `self` and returns its original value excluding `asset` iff it contains at least /// `asset`. - pub fn checked_sub(mut self, asset: MultiAsset) -> Result { + pub fn checked_sub(mut self, asset: Asset) -> Result { match asset.fun { Fungible(amount) => { let remove = if let Some(balance) = self.fungible.get_mut(&asset.id) { @@ -446,66 +446,66 @@ impl Assets { /// Example: /// /// ``` - /// use staging_xcm_executor::Assets; + /// use staging_xcm_executor::AssetsInHolding; /// use xcm::latest::prelude::*; - /// let assets_i_have: Assets = vec![ (Here, 100).into(), ([0; 32], 100).into() ].into(); - /// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), ([0; 32], 50).into() ].into(); + /// let assets_i_have: AssetsInHolding = vec![ (Here, 100).into(), (Junctions::from([GeneralIndex(0)]), 100).into() ].into(); + /// let assets_they_want: AssetFilter = vec![ (Here, 200).into(), (Junctions::from([GeneralIndex(0)]), 50).into() ].into(); /// - /// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want); + /// let assets_we_can_trade: AssetsInHolding = assets_i_have.min(&assets_they_want); /// assert_eq!(assets_we_can_trade.into_assets_iter().collect::>(), vec![ - /// (Here, 100).into(), ([0; 32], 50).into(), + /// (Here, 100).into(), (Junctions::from([GeneralIndex(0)]), 50).into(), /// ]); /// ``` - pub fn min(&self, mask: &MultiAssetFilter) -> Assets { - let mut masked = Assets::new(); + pub fn min(&self, mask: &AssetFilter) -> AssetsInHolding { + let mut masked = AssetsInHolding::new(); let maybe_limit = mask.limit().map(|x| x as usize); if maybe_limit.map_or(false, |l| l == 0) { return masked } match mask { - MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + AssetFilter::Wild(All) | AssetFilter::Wild(AllCounted(_)) => { if maybe_limit.map_or(true, |l| self.len() <= l) { return self.clone() } else { - for (&c, &amount) in self.fungible.iter() { - masked.fungible.insert(c, amount); + for (c, &amount) in self.fungible.iter() { + masked.fungible.insert(c.clone(), amount); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } for (c, instance) in self.non_fungible.iter() { - masked.non_fungible.insert((*c, *instance)); + masked.non_fungible.insert((c.clone(), *instance)); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildFungible, id }) => if let Some(&amount) = self.fungible.get(&id) { - masked.fungible.insert(*id, amount); + masked.fungible.insert(id.clone(), amount); }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => for (c, instance) in self.non_fungible.iter() { if c == id { - masked.non_fungible.insert((*c, *instance)); + masked.non_fungible.insert((c.clone(), *instance)); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } }, - MultiAssetFilter::Definite(assets) => + AssetFilter::Definite(assets) => for asset in assets.inner().iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { if let Some(m) = self.fungible.get(id) { - masked.subsume((*id, Fungible(*amount.min(m))).into()); + masked.subsume((id.clone(), Fungible(*amount.min(m))).into()); } }, - MultiAsset { fun: NonFungible(instance), id } => { - let id_instance = (*id, *instance); + Asset { fun: NonFungible(instance), id } => { + let id_instance = (id.clone(), *instance); if self.non_fungible.contains(&id_instance) { masked.subsume(id_instance.into()); } @@ -522,30 +522,18 @@ mod tests { use super::*; use xcm::latest::prelude::*; #[allow(non_snake_case)] - /// Abstract fungible constructor - fn AF(id: u8, amount: u128) -> MultiAsset { - ([id; 32], amount).into() - } - #[allow(non_snake_case)] - /// Abstract non-fungible constructor - fn ANF(class: u8, instance_id: u8) -> MultiAsset { - ([class; 32], [instance_id; 4]).into() - } - #[allow(non_snake_case)] /// Concrete fungible constructor - fn CF(amount: u128) -> MultiAsset { + fn CF(amount: u128) -> Asset { (Here, amount).into() } #[allow(non_snake_case)] /// Concrete non-fungible constructor - fn CNF(instance_id: u8) -> MultiAsset { + fn CNF(instance_id: u8) -> Asset { (Here, [instance_id; 4]).into() } - fn test_assets() -> Assets { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + fn test_assets() -> AssetsInHolding { + let mut assets = AssetsInHolding::new(); assets.subsume(CF(300)); assets.subsume(CNF(40)); assets @@ -554,9 +542,7 @@ mod tests { #[test] fn subsume_assets_works() { let t1 = test_assets(); - let mut t2 = Assets::new(); - t2.subsume(AF(1, 50)); - t2.subsume(ANF(2, 10)); + let mut t2 = AssetsInHolding::new(); t2.subsume(CF(300)); t2.subsume(CNF(50)); let mut r1 = t1.clone(); @@ -571,63 +557,48 @@ mod tests { #[test] fn checked_sub_works() { let t = test_assets(); - let t = t.checked_sub(AF(1, 50)).unwrap(); - let t = t.checked_sub(AF(1, 51)).unwrap_err(); - let t = t.checked_sub(AF(1, 50)).unwrap(); - let t = t.checked_sub(AF(1, 1)).unwrap_err(); let t = t.checked_sub(CF(150)).unwrap(); let t = t.checked_sub(CF(151)).unwrap_err(); let t = t.checked_sub(CF(150)).unwrap(); let t = t.checked_sub(CF(1)).unwrap_err(); - let t = t.checked_sub(ANF(2, 21)).unwrap_err(); - let t = t.checked_sub(ANF(2, 20)).unwrap(); - let t = t.checked_sub(ANF(2, 20)).unwrap_err(); let t = t.checked_sub(CNF(41)).unwrap_err(); let t = t.checked_sub(CNF(40)).unwrap(); let t = t.checked_sub(CNF(40)).unwrap_err(); - assert_eq!(t, Assets::new()); + assert_eq!(t, AssetsInHolding::new()); } #[test] fn into_assets_iter_works() { let assets = test_assets(); let mut iter = assets.into_assets_iter(); - // Order defined by implementation: CF, AF, CNF, ANF + // Order defined by implementation: CF, CNF assert_eq!(Some(CF(300)), iter.next()); - assert_eq!(Some(AF(1, 100)), iter.next()); assert_eq!(Some(CNF(40)), iter.next()); - assert_eq!(Some(ANF(2, 20)), iter.next()); assert_eq!(None, iter.next()); } #[test] fn assets_into_works() { - let mut assets_vec: Vec = Vec::new(); - assets_vec.push(AF(1, 100)); - assets_vec.push(ANF(2, 20)); + let mut assets_vec: Vec = Vec::new(); assets_vec.push(CF(300)); assets_vec.push(CNF(40)); // Push same group of tokens again - assets_vec.push(AF(1, 100)); - assets_vec.push(ANF(2, 20)); assets_vec.push(CF(300)); assets_vec.push(CNF(40)); - let assets: Assets = assets_vec.into(); + let assets: AssetsInHolding = assets_vec.into(); let mut iter = assets.into_assets_iter(); // Fungibles add assert_eq!(Some(CF(600)), iter.next()); - assert_eq!(Some(AF(1, 200)), iter.next()); // Non-fungibles collapse assert_eq!(Some(CNF(40)), iter.next()); - assert_eq!(Some(ANF(2, 20)), iter.next()); assert_eq!(None, iter.next()); } #[test] fn min_all_and_none_works() { let assets = test_assets(); - let none = MultiAssets::new().into(); + let none = Assets::new().into(); let all = All.into(); let none_min = assets.min(&none); @@ -638,43 +609,15 @@ mod tests { #[test] fn min_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let fungible = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); - let non_fungible = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); - let all = WildMultiAsset::AllCounted(6).into(); + let all = WildAsset::AllCounted(6).into(); - let fungible = assets.min(&fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.min(&non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20), ANF(2, 30)]); let all = assets.min(&all); let all = all.assets_iter().collect::>(); - assert_eq!(all, vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),]); - } - - #[test] - fn min_all_abstract_works() { - let assets = test_assets(); - let fungible = Wild(([1u8; 32], WildFungible).into()); - let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); - - let fungible = assets.min(&fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.min(&non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20)]); + assert_eq!(all, vec![CF(3000), CNF(40), CNF(80)]); } #[test] @@ -695,20 +638,16 @@ mod tests { fn min_basic_works() { let assets1 = test_assets(); - let mut assets2 = Assets::new(); - // This is less than 100, so it will decrease to 50 - assets2.subsume(AF(1, 50)); - // This asset does not exist, so not included - assets2.subsume(ANF(2, 40)); + let mut assets2 = AssetsInHolding::new(); // This is more then 300, so it should stay at 300 assets2.subsume(CF(600)); // This asset should be included assets2.subsume(CNF(40)); - let assets2: MultiAssets = assets2.into(); + let assets2: Assets = assets2.into(); let assets_min = assets1.min(&assets2.into()); let assets_min = assets_min.into_assets_iter().collect::>(); - assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(40)]); + assert_eq!(assets_min, vec![CF(300), CNF(40)]); } #[test] @@ -724,23 +663,6 @@ mod tests { assert!(all_iter.eq(test_assets().assets_iter())); } - #[test] - fn saturating_take_all_abstract_works() { - let mut assets = test_assets(); - let fungible = Wild(([1u8; 32], WildFungible).into()); - let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); - - let fungible = assets.saturating_take(fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.saturating_take(non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20)]); - // Assets drained of abstract - let final_assets = assets.assets_iter().collect::>(); - assert_eq!(final_assets, vec![CF(300), CNF(40)]); - } - #[test] fn saturating_take_all_concrete_works() { let mut assets = test_assets(); @@ -753,102 +675,49 @@ mod tests { let non_fungible = assets.saturating_take(non_fungible); let non_fungible = non_fungible.assets_iter().collect::>(); assert_eq!(non_fungible, vec![CNF(40)]); - // Assets drained of concrete - let assets = assets.assets_iter().collect::>(); - assert_eq!(assets, vec![AF(1, 100), ANF(2, 20)]); } #[test] fn saturating_take_basic_works() { let mut assets1 = test_assets(); - let mut assets2 = Assets::new(); - // We should take 50 - assets2.subsume(AF(1, 50)); - // This asset should not be taken - assets2.subsume(ANF(2, 40)); + let mut assets2 = AssetsInHolding::new(); // This is more then 300, so it takes everything assets2.subsume(CF(600)); // This asset should be taken assets2.subsume(CNF(40)); - let assets2: MultiAssets = assets2.into(); + let assets2: Assets = assets2.into(); let taken = assets1.saturating_take(assets2.into()); let taken = taken.into_assets_iter().collect::>(); - assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(40)]); - - let assets = assets1.into_assets_iter().collect::>(); - assert_eq!(assets, vec![AF(1, 50), ANF(2, 20)]); + assert_eq!(taken, vec![CF(300), CNF(40)]); } #[test] fn try_take_all_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let all = assets.try_take(WildMultiAsset::AllCounted(6).into()).unwrap(); - assert_eq!( - MultiAssets::from(all).inner(), - &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),] - ); - assert_eq!(MultiAssets::from(assets).inner(), &vec![ANF(2, 30), ANF(2, 40), ANF(3, 10),]); + let all = assets.try_take(WildAsset::AllCounted(6).into()).unwrap(); + assert_eq!(Assets::from(all).inner(), &vec![CF(3000), CNF(40), CNF(80)]); } #[test] fn try_take_fungibles_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let mask = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); - let taken = assets.try_take(mask).unwrap(); - assert_eq!(MultiAssets::from(taken).inner(), &vec![AF(1, 100)]); - assert_eq!( - MultiAssets::from(assets).inner(), - &vec![ - CF(3000), - AF(10, 50), - CNF(40), - CNF(80), - ANF(2, 20), - ANF(2, 30), - ANF(2, 40), - ANF(3, 10), - ] - ); + assert_eq!(Assets::from(assets).inner(), &vec![CF(3000), CNF(40), CNF(80),]); } #[test] fn try_take_non_fungibles_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let mask = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); - let taken = assets.try_take(mask).unwrap(); - assert_eq!(MultiAssets::from(taken).inner(), &vec![ANF(2, 20), ANF(2, 30),]); - assert_eq!( - MultiAssets::from(assets).inner(), - &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 40), ANF(3, 10),] - ); + assert_eq!(Assets::from(assets).inner(), &vec![CF(3000), CNF(40), CNF(80)]); } } diff --git a/polkadot/xcm/xcm-executor/src/config.rs b/polkadot/xcm/xcm-executor/src/config.rs index 2ff12cd7a539..3f1ea6d1fb8e 100644 --- a/polkadot/xcm/xcm-executor/src/config.rs +++ b/polkadot/xcm/xcm-executor/src/config.rs @@ -41,17 +41,17 @@ pub trait Config { type OriginConverter: ConvertOrigin<::RuntimeOrigin>; /// Combinations of (Asset, Location) pairs which we trust as reserves. - type IsReserve: ContainsPair; + type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. - type IsTeleporter: ContainsPair; + type IsTeleporter: ContainsPair; /// A list of (Origin, Target) pairs allowing a given Origin to be substituted with its /// corresponding Target pair. - type Aliasers: ContainsPair; + type Aliasers: ContainsPair; /// This chain's Universal Location. - type UniversalLocation: Get; + type UniversalLocation: Get; /// Whether we should execute the given XCM at all. type Barrier: ShouldExecute; @@ -98,7 +98,7 @@ pub trait Config { /// The origin locations and specific universal junctions to which they are allowed to elevate /// themselves. - type UniversalAliases: Contains<(MultiLocation, Junction)>; + type UniversalAliases: Contains<(Location, Junction)>; /// The call dispatcher used by XCM. /// diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 665b051c1306..1f5f2eba5e2f 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -36,7 +36,7 @@ use traits::{ }; mod assets; -pub use assets::Assets; +pub use assets::AssetsInHolding; mod config; pub use config::Config; @@ -56,10 +56,10 @@ environmental::environmental!(recursion_count: u8); /// The XCM executor. pub struct XcmExecutor { - holding: Assets, + holding: AssetsInHolding, holding_limit: usize, context: XcmContext, - original_origin: MultiLocation, + original_origin: Location, trader: Config::Trader, /// The most recent error result and instruction index into the fragment in which it occurred, /// if any. @@ -81,10 +81,10 @@ pub struct XcmExecutor { #[cfg(feature = "runtime-benchmarks")] impl XcmExecutor { - pub fn holding(&self) -> &Assets { + pub fn holding(&self) -> &AssetsInHolding { &self.holding } - pub fn set_holding(&mut self, v: Assets) { + pub fn set_holding(&mut self, v: AssetsInHolding) { self.holding = v } pub fn holding_limit(&self) -> &usize { @@ -93,16 +93,16 @@ impl XcmExecutor { pub fn set_holding_limit(&mut self, v: usize) { self.holding_limit = v } - pub fn origin(&self) -> &Option { + pub fn origin(&self) -> &Option { &self.context.origin } - pub fn set_origin(&mut self, v: Option) { + pub fn set_origin(&mut self, v: Option) { self.context.origin = v } - pub fn original_origin(&self) -> &MultiLocation { + pub fn original_origin(&self) -> &Location { &self.original_origin } - pub fn set_original_origin(&mut self, v: MultiLocation) { + pub fn set_original_origin(&mut self, v: Location) { self.original_origin = v } pub fn trader(&self) -> &Config::Trader { @@ -191,14 +191,14 @@ impl ExecuteXcm for XcmExecutor, + origin: impl Into, WeighedMessage(xcm_weight, mut message): WeighedMessage, id: &mut XcmHash, weight_credit: Weight, ) -> Outcome { let origin = origin.into(); log::trace!( - target: "xcm::execute_xcm_in_credit", + target: "xcm::execute", "origin: {origin:?}, message: {message:?}, weight_credit: {weight_credit:?}", ); let mut properties = Properties { weight_credit, message_id: None }; @@ -209,11 +209,11 @@ impl ExecuteXcm for XcmExecutor ExecuteXcm for XcmExecutor ExecuteXcm for XcmExecutor, fees: MultiAssets) -> XcmResult { + fn charge_fees(origin: impl Into, fees: Assets) -> XcmResult { let origin = origin.into(); if !Config::FeeManager::is_waived(Some(&origin), FeeReason::ChargeFees) { for asset in fees.inner() { @@ -275,12 +275,12 @@ impl From for frame_benchmarking::BenchmarkError { } impl XcmExecutor { - pub fn new(origin: impl Into, message_id: XcmHash) -> Self { + pub fn new(origin: impl Into, message_id: XcmHash) -> Self { let origin = origin.into(); Self { - holding: Assets::new(), + holding: AssetsInHolding::new(), holding_limit: Config::MaxAssetsIntoHolding::get() as usize, - context: XcmContext { origin: Some(origin), message_id, topic: None }, + context: XcmContext { origin: Some(origin.clone()), message_id, topic: None }, original_origin: origin, trader: Config::Trader::new(), error: None, @@ -309,7 +309,7 @@ impl XcmExecutor { if !self.holding.is_empty() { log::trace!( - target: "xcm::execute_xcm_in_credit", + target: "xcm::post_process", "Trapping assets in holding register: {:?}, context: {:?} (original_origin: {:?})", self.holding, self.context, self.original_origin, ); @@ -320,28 +320,28 @@ impl XcmExecutor { }; match self.error { - None => Outcome::Complete(weight_used), + None => Outcome::Complete { used: weight_used }, // TODO: #2841 #REALWEIGHT We should deduct the cost of any instructions following // the error which didn't end up being executed. Some((_i, e)) => { - log::trace!(target: "xcm::execute_xcm_in_credit", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); - Outcome::Incomplete(weight_used, e) + log::trace!(target: "xcm::post_process", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); + Outcome::Incomplete { used: weight_used, error: e } }, } } - fn origin_ref(&self) -> Option<&MultiLocation> { + fn origin_ref(&self) -> Option<&Location> { self.context.origin.as_ref() } - fn cloned_origin(&self) -> Option { - self.context.origin + fn cloned_origin(&self) -> Option { + self.context.origin.clone() } /// Send an XCM, charging fees from Holding as needed. fn send( &mut self, - dest: MultiLocation, + dest: Location, msg: Xcm<()>, reason: FeeReason, ) -> Result { @@ -373,14 +373,14 @@ impl XcmExecutor { r } - fn subsume_asset(&mut self, asset: MultiAsset) -> Result<(), XcmError> { + fn subsume_asset(&mut self, asset: Asset) -> Result<(), XcmError> { // worst-case, holding.len becomes 2 * holding_limit. ensure!(self.holding.len() < self.holding_limit * 2, XcmError::HoldingWouldOverflow); self.holding.subsume(asset); Ok(()) } - fn subsume_assets(&mut self, assets: Assets) -> Result<(), XcmError> { + fn subsume_assets(&mut self, assets: AssetsInHolding) -> Result<(), XcmError> { // worst-case, holding.len becomes 2 * holding_limit. // this guarantees that if holding.len() == holding_limit and you have holding_limit more // items (which has a best case outcome of holding.len() == holding_limit), then you'll @@ -403,8 +403,8 @@ impl XcmExecutor { Ok(()) } - fn take_fee(&mut self, fee: MultiAssets, reason: FeeReason) -> XcmResult { - if Config::FeeManager::is_waived(self.origin_ref(), reason) { + fn take_fee(&mut self, fee: Assets, reason: FeeReason) -> XcmResult { + if Config::FeeManager::is_waived(self.origin_ref(), reason.clone()) { return Ok(()) } log::trace!( @@ -430,13 +430,13 @@ impl XcmExecutor { /// Calculates what `local_querier` would be from the perspective of `destination`. fn to_querier( - local_querier: Option, - destination: &MultiLocation, - ) -> Result, XcmError> { + local_querier: Option, + destination: &Location, + ) -> Result, XcmError> { Ok(match local_querier { None => None, Some(q) => Some( - q.reanchored(&destination, Config::UniversalLocation::get()) + q.reanchored(&destination, &Config::UniversalLocation::get()) .map_err(|_| XcmError::ReanchorFailed)?, ), }) @@ -447,7 +447,7 @@ impl XcmExecutor { /// The `local_querier` argument is the querier (if any) specified from the *local* perspective. fn respond( &mut self, - local_querier: Option, + local_querier: Option, response: Response, info: QueryResponseInfo, fee_reason: FeeReason, @@ -459,36 +459,27 @@ impl XcmExecutor { self.send(destination, message, fee_reason) } - fn try_reanchor( - asset: MultiAsset, - destination: &MultiLocation, - ) -> Result<(MultiAsset, InteriorMultiLocation), XcmError> { + fn try_reanchor( + reanchorable: T, + destination: &Location, + ) -> Result<(T, InteriorLocation), XcmError> { let reanchor_context = Config::UniversalLocation::get(); - let asset = asset - .reanchored(&destination, reanchor_context) - .map_err(|()| XcmError::ReanchorFailed)?; - Ok((asset, reanchor_context)) - } - - fn try_reanchor_multilocation( - location: MultiLocation, - destination: &MultiLocation, - ) -> Result<(MultiLocation, InteriorMultiLocation), XcmError> { - let reanchor_context = Config::UniversalLocation::get(); - let location = location - .reanchored(&destination, reanchor_context) - .map_err(|_| XcmError::ReanchorFailed)?; - Ok((location, reanchor_context)) + let reanchored = + reanchorable.reanchored(&destination, &reanchor_context).map_err(|error| { + log::error!(target: "xcm::reanchor", "Failed reanchoring with error {error:?}"); + XcmError::ReanchorFailed + })?; + Ok((reanchored, reanchor_context)) } /// NOTE: Any assets which were unable to be reanchored are introduced into `failed_bin`. fn reanchored( - mut assets: Assets, - dest: &MultiLocation, - maybe_failed_bin: Option<&mut Assets>, - ) -> MultiAssets { + mut assets: AssetsInHolding, + dest: &Location, + maybe_failed_bin: Option<&mut AssetsInHolding>, + ) -> Assets { let reanchor_context = Config::UniversalLocation::get(); - assets.reanchor(dest, reanchor_context, maybe_failed_bin); + assets.reanchor(dest, &reanchor_context, maybe_failed_bin); assets.into_assets_iter().collect::>().into() } @@ -563,8 +554,8 @@ impl XcmExecutor { ); match instr { WithdrawAsset(assets) => { + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // Take `assets` from the origin account (on-chain) and place in holding. - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; for asset in assets.into_inner().into_iter() { Config::AssetTransactor::withdraw_asset(&asset, &origin, Some(&self.context))?; self.subsume_asset(asset)?; @@ -573,8 +564,8 @@ impl XcmExecutor { }, ReserveAssetDeposited(assets) => { // check whether we trust origin to be our reserve location for this asset. - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; for asset in assets.into_inner().into_iter() { + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // Must ensure that we recognise the asset as being managed by the origin. ensure!( Config::IsReserve::contains(&asset, &origin), @@ -604,14 +595,14 @@ impl XcmExecutor { Config::AssetTransactor::transfer_asset(asset, origin, &dest, &self.context)?; } let reanchor_context = Config::UniversalLocation::get(); - assets.reanchor(&dest, reanchor_context).map_err(|()| XcmError::LocationFull)?; + assets.reanchor(&dest, &reanchor_context).map_err(|()| XcmError::LocationFull)?; let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin]; message.extend(xcm.0.into_iter()); self.send(dest, Xcm(message), FeeReason::TransferReserveAsset)?; Ok(()) }, ReceiveTeleportedAsset(assets) => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // check whether we trust origin to teleport this asset to us via config trait. for asset in assets.inner() { // We only trust the origin to send us assets that they identify as their @@ -627,6 +618,7 @@ impl XcmExecutor { Config::AssetTransactor::can_check_in(&origin, asset, &self.context)?; } for asset in assets.into_inner().into_iter() { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; Config::AssetTransactor::check_in(&origin, &asset, &self.context); self.subsume_asset(asset)?; } @@ -634,7 +626,7 @@ impl XcmExecutor { }, Transact { origin_kind, require_weight_at_most, mut call } => { // We assume that the Relay-chain is allowed to use transact on this parachain. - let origin = *self.origin_ref().ok_or_else(|| { + let origin = self.cloned_origin().ok_or_else(|| { log::trace!( target: "xcm::process_instruction::transact", "No origin provided", @@ -667,15 +659,17 @@ impl XcmExecutor { return Err(XcmError::NoPermission) } - let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_kind) - .map_err(|_| { - log::trace!( - target: "xcm::process_instruction::transact", - "Failed to convert origin {origin:?} and origin kind {origin_kind:?} to a local origin." - ); + let dispatch_origin = + Config::OriginConverter::convert_origin(origin.clone(), origin_kind).map_err( + |_| { + log::trace!( + target: "xcm::process_instruction::transact", + "Failed to convert origin {origin:?} and origin kind {origin_kind:?} to a local origin." + ); - XcmError::BadOrigin - })?; + XcmError::BadOrigin + }, + )?; log::trace!( target: "xcm::process_instruction::transact", @@ -964,12 +958,12 @@ impl XcmExecutor { UniversalOrigin(new_global) => { let universal_location = Config::UniversalLocation::get(); ensure!(universal_location.first() != Some(&new_global), XcmError::InvalidLocation); - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let origin_xform = (origin, new_global); let ok = Config::UniversalAliases::contains(&origin_xform); ensure!(ok, XcmError::InvalidLocation); let (_, new_global) = origin_xform; - let new_origin = X1(new_global).relative_to(&universal_location); + let new_origin = Junctions::from([new_global]).relative_to(&universal_location); self.context.origin = Some(new_origin); Ok(()) }, @@ -983,7 +977,7 @@ impl XcmExecutor { // // This only works because the remote chain empowers the bridge // to speak for the local network. - let origin = self.context.origin.ok_or(XcmError::BadOrigin)?; + let origin = self.context.origin.as_ref().ok_or(XcmError::BadOrigin)?.clone(); let universal_source = Config::UniversalLocation::get() .within_global(origin) .map_err(|()| XcmError::Unanchored)?; @@ -996,7 +990,7 @@ impl XcmExecutor { network, channel, universal_source, - destination, + destination.clone(), xcm, )?; self.take_fee(fee, FeeReason::Export { network, destination })?; @@ -1004,11 +998,12 @@ impl XcmExecutor { Ok(()) }, LockAsset { asset, unlocker } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let (remote_asset, context) = Self::try_reanchor(asset.clone(), &unlocker)?; - let lock_ticket = Config::AssetLocker::prepare_lock(unlocker, asset, origin)?; + let lock_ticket = + Config::AssetLocker::prepare_lock(unlocker.clone(), asset, origin.clone())?; let owner = - origin.reanchored(&unlocker, context).map_err(|_| XcmError::ReanchorFailed)?; + origin.reanchored(&unlocker, &context).map_err(|_| XcmError::ReanchorFailed)?; let msg = Xcm::<()>(vec![NoteUnlockable { asset: remote_asset, owner }]); let (ticket, price) = validate_send::(unlocker, msg)?; self.take_fee(price, FeeReason::LockAsset)?; @@ -1017,21 +1012,24 @@ impl XcmExecutor { Ok(()) }, UnlockAsset { asset, target } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; Config::AssetLocker::prepare_unlock(origin, asset, target)?.enact()?; Ok(()) }, NoteUnlockable { asset, owner } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; Config::AssetLocker::note_unlockable(origin, asset, owner)?; Ok(()) }, RequestUnlock { asset, locker } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let remote_asset = Self::try_reanchor(asset.clone(), &locker)?.0; - let remote_target = Self::try_reanchor_multilocation(origin, &locker)?.0; - let reduce_ticket = - Config::AssetLocker::prepare_reduce_unlockable(locker, asset, origin)?; + let remote_target = Self::try_reanchor(origin.clone(), &locker)?.0; + let reduce_ticket = Config::AssetLocker::prepare_reduce_unlockable( + locker.clone(), + asset, + origin.clone(), + )?; let msg = Xcm::<()>(vec![UnlockAsset { asset: remote_asset, target: remote_target }]); let (ticket, price) = validate_send::(locker, msg)?; diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs index 0cb188d348de..432a7498ed4c 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use xcm::prelude::*; /// A service for exchanging assets. @@ -32,21 +32,21 @@ pub trait AssetExchange { /// least want must be in the set. Some assets originally in `give` may also be in this set. In /// the case of returning an `Err`, then `give` is returned. fn exchange_asset( - origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result; + ) -> Result; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl AssetExchange for Tuple { fn exchange_asset( - origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result { + ) -> Result { for_tuples!( #( let give = match Tuple::exchange_asset(origin, give, want, maximal) { Ok(r) => return Ok(r), diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs index b5a2b22f5fc5..b6270c529452 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs @@ -79,9 +79,9 @@ pub trait AssetLock { /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or /// `Self::UnlockTicket`. fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result; /// Prepare to unlock an asset. On success, a `Self::UnlockTicket` it returned, which can be @@ -90,9 +90,9 @@ pub trait AssetLock { /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or /// `Self::UnlockTicket`. fn prepare_unlock( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result; /// Handler for when a location reports to us that an asset has been locked for us to unlock @@ -102,11 +102,7 @@ pub trait AssetLock { /// sending chain can ensure the lock does not remain. /// /// We should only act upon this message if we believe that the `origin` is honest. - fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, - ) -> Result<(), LockError>; + fn note_unlockable(locker: Location, asset: Asset, owner: Location) -> Result<(), LockError>; /// Handler for when an owner wishes to unlock an asset on a remote chain. /// @@ -115,9 +111,9 @@ pub trait AssetLock { /// /// WARNING: Don't call this with an undropped instance of `Self::ReduceTicket`. fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result; } @@ -125,27 +121,19 @@ impl AssetLock for () { type LockTicket = Infallible; type UnlockTicket = Infallible; type ReduceTicket = Infallible; - fn prepare_lock( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, - ) -> Result { + fn prepare_lock(_: Location, _: Asset, _: Location) -> Result { Err(LockError::NotApplicable) } - fn prepare_unlock( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, - ) -> Result { + fn prepare_unlock(_: Location, _: Asset, _: Location) -> Result { Err(LockError::NotApplicable) } - fn note_unlockable(_: MultiLocation, _: MultiAsset, _: MultiLocation) -> Result<(), LockError> { + fn note_unlockable(_: Location, _: Asset, _: Location) -> Result<(), LockError> { Err(LockError::NotApplicable) } fn prepare_reduce_unlockable( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, + _: Location, + _: Asset, + _: Location, ) -> Result { Err(LockError::NotApplicable) } diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs b/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs index 5fdc9b15e015..1fca84f36e22 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs @@ -30,7 +30,7 @@ pub enum Error { } /// Specify which type of asset transfer is required for a particular `(asset, dest)` combination. -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] pub enum TransferType { /// should teleport `asset` to `dest` Teleport, @@ -38,8 +38,8 @@ pub enum TransferType { LocalReserve, /// should reserve-transfer `asset` to `dest`, using `dest` as reserve DestinationReserve, - /// should reserve-transfer `asset` to `dest`, using remote chain `MultiLocation` as reserve - RemoteReserve(MultiLocation), + /// should reserve-transfer `asset` to `dest`, using remote chain `Location` as reserve + RemoteReserve(Location), } /// A trait for identifying asset transfer type based on `IsTeleporter` and `IsReserve` @@ -47,17 +47,17 @@ pub enum TransferType { pub trait XcmAssetTransfers { /// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning /// reserve-based-transfers are to be used for assets matching this filter. - type IsReserve: ContainsPair; + type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are /// to be used for assets matching this filter. - type IsTeleporter: ContainsPair; + type IsTeleporter: ContainsPair; /// How to withdraw and deposit an asset. type AssetTransactor: TransactAsset; /// Determine transfer type to be used for transferring `asset` from local chain to `dest`. - fn determine_for(asset: &MultiAsset, dest: &MultiLocation) -> Result { + fn determine_for(asset: &Asset, dest: &Location) -> Result { if Self::IsTeleporter::contains(asset, dest) { // we trust destination for teleporting asset return Ok(TransferType::Teleport) @@ -67,11 +67,8 @@ pub trait XcmAssetTransfers { } // try to determine reserve location based on asset id/location - let asset_location = match asset.id { - Concrete(location) => Ok(location.chain_location()), - _ => Err(Error::NotConcrete), - }?; - if asset_location == MultiLocation::here() || + let asset_location = asset.id.0.chain_location(); + if asset_location == Location::here() || Self::IsTeleporter::contains(asset, &asset_location) { // if the asset is local, then it's a local reserve diff --git a/polkadot/xcm/xcm-executor/src/traits/conversion.rs b/polkadot/xcm/xcm-executor/src/traits/conversion.rs index 1fcdf2140578..9e2f4c83997a 100644 --- a/polkadot/xcm/xcm-executor/src/traits/conversion.rs +++ b/polkadot/xcm/xcm-executor/src/traits/conversion.rs @@ -22,12 +22,12 @@ use xcm::latest::prelude::*; /// Means of converting a location into an account identifier. pub trait ConvertLocation { /// Convert the `location` into `Some` account ID, or `None` if not possible. - fn convert_location(location: &MultiLocation) -> Option; + fn convert_location(location: &Location) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ConvertLocation for Tuple { - fn convert_location(l: &MultiLocation) -> Option { + fn convert_location(l: &Location) -> Option { for_tuples!( #( match Tuple::convert_location(l) { Some(result) => return Some(result), @@ -45,15 +45,15 @@ impl ConvertLocation for Tuple { /// different `origin` of type `Origin` which is passed to the next convert item. /// /// ```rust -/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind}; +/// # use xcm::latest::{Location, Junctions, Junction, OriginKind}; /// # use staging_xcm_executor::traits::ConvertOrigin; /// // A convertor that will bump the para id and pass it to the next one. /// struct BumpParaId; /// impl ConvertOrigin for BumpParaId { -/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { -/// match origin.into() { -/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } => { -/// Err(Junctions::X1(Junction::Parachain(id + 1)).into()) +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// match origin.into().unpack() { +/// (0, [Junction::Parachain(id)]) => { +/// Err([Junction::Parachain(id + 1)].into()) /// } /// _ => unreachable!() /// } @@ -62,17 +62,18 @@ impl ConvertLocation for Tuple { /// /// struct AcceptPara7; /// impl ConvertOrigin for AcceptPara7 { -/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { -/// match origin.into() { -/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } if id == 7 => { +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// let origin = origin.into(); +/// match origin.unpack() { +/// (0, [Junction::Parachain(id)]) if *id == 7 => { /// Ok(7) /// } -/// o => Err(o) +/// _ => Err(origin) /// } /// } /// } /// # fn main() { -/// let origin: MultiLocation = Junctions::X1(Junction::Parachain(6)).into(); +/// let origin: Location = [Junction::Parachain(6)].into(); /// assert!( /// <(BumpParaId, AcceptPara7) as ConvertOrigin>::convert_origin(origin, OriginKind::Native) /// .is_ok() @@ -81,18 +82,12 @@ impl ConvertLocation for Tuple { /// ``` pub trait ConvertOrigin { /// Attempt to convert `origin` to the generic `Origin` whilst consuming it. - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result; + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ConvertOrigin for Tuple { - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result { + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result { for_tuples!( #( let origin = match Tuple::convert_origin(origin, kind) { Err(o) => o, diff --git a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs index 9753f3a4213f..339d485d9795 100644 --- a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs +++ b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs @@ -14,28 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use core::marker::PhantomData; use frame_support::traits::Contains; -use xcm::latest::{MultiAssets, MultiLocation, Weight, XcmContext}; +use xcm::latest::{Assets, Location, Weight, XcmContext}; -/// Define a handler for when some non-empty `Assets` value should be dropped. +/// Define a handler for when some non-empty `AssetsInHolding` value should be dropped. pub trait DropAssets { /// Handler for receiving dropped assets. Returns the weight consumed by this operation. - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight; + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight; } impl DropAssets for () { - fn drop_assets(_origin: &MultiLocation, _assets: Assets, _context: &XcmContext) -> Weight { + fn drop_assets(_origin: &Location, _assets: AssetsInHolding, _context: &XcmContext) -> Weight { Weight::zero() } } /// Morph a given `DropAssets` implementation into one which can filter based on assets. This can -/// be used to ensure that `Assets` values which hold no value are ignored. +/// be used to ensure that `AssetsInHolding` values which hold no value are ignored. pub struct FilterAssets(PhantomData<(D, A)>); -impl> DropAssets for FilterAssets { - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { +impl> DropAssets for FilterAssets { + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight { if A::contains(&assets) { D::drop_assets(origin, assets, context) } else { @@ -49,8 +49,8 @@ impl> DropAssets for FilterAssets { /// asset trap facility don't get to use it. pub struct FilterOrigin(PhantomData<(D, O)>); -impl> DropAssets for FilterOrigin { - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { +impl> DropAssets for FilterOrigin { + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight { if O::contains(origin) { D::drop_assets(origin, assets, context) } else { @@ -64,9 +64,9 @@ pub trait ClaimAssets { /// Claim any assets available to `origin` and return them in a single `Assets` value, together /// with the weight used by this operation. fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, context: &XcmContext, ) -> bool; } @@ -74,9 +74,9 @@ pub trait ClaimAssets { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ClaimAssets for Tuple { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, context: &XcmContext, ) -> bool { for_tuples!( #( diff --git a/polkadot/xcm/xcm-executor/src/traits/export.rs b/polkadot/xcm/xcm-executor/src/traits/export.rs index 7aeccd44566a..78aa68ce2644 100644 --- a/polkadot/xcm/xcm-executor/src/traits/export.rs +++ b/polkadot/xcm/xcm-executor/src/traits/export.rs @@ -51,8 +51,8 @@ pub trait ExportXcm { fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult; @@ -71,11 +71,11 @@ impl ExportXcm for Tuple { fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { - let mut maybe_cost: Option = None; + let mut maybe_cost: Option = None; let one_ticket: Self::Ticket = (for_tuples! { #( if maybe_cost.is_some() { None @@ -112,8 +112,8 @@ impl ExportXcm for Tuple { pub fn validate_export( network: NetworkId, channel: u32, - universal_source: InteriorMultiLocation, - dest: InteriorMultiLocation, + universal_source: InteriorLocation, + dest: InteriorLocation, msg: Xcm<()>, ) -> SendResult { T::validate(network, channel, &mut Some(universal_source), &mut Some(dest), &mut Some(msg)) @@ -130,10 +130,10 @@ pub fn validate_export( pub fn export_xcm( network: NetworkId, channel: u32, - universal_source: InteriorMultiLocation, - dest: InteriorMultiLocation, + universal_source: InteriorLocation, + dest: InteriorLocation, msg: Xcm<()>, -) -> Result<(XcmHash, MultiAssets), SendError> { +) -> Result<(XcmHash, Assets), SendError> { let (ticket, price) = T::validate( network, channel, diff --git a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs index d7146457f3b9..b6e303daaad8 100644 --- a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs +++ b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs @@ -19,15 +19,15 @@ use xcm::prelude::*; /// Handle stuff to do with taking fees in certain XCM instructions. pub trait FeeManager { /// Determine if a fee should be waived. - fn is_waived(origin: Option<&MultiLocation>, r: FeeReason) -> bool; + fn is_waived(origin: Option<&Location>, r: FeeReason) -> bool; /// Do something with the fee which has been paid. Doing nothing here silently burns the /// fees. - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, r: FeeReason); + fn handle_fee(fee: Assets, context: Option<&XcmContext>, r: FeeReason); } /// Context under which a fee is paid. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum FeeReason { /// When a reporting instruction is called. Report, @@ -42,7 +42,7 @@ pub enum FeeReason { /// When the `QueryPallet` instruction is called. QueryPallet, /// When the `ExportMessage` instruction is called (and includes the network ID). - Export { network: NetworkId, destination: InteriorMultiLocation }, + Export { network: NetworkId, destination: InteriorLocation }, /// The `charge_fees` API. ChargeFees, /// When the `LockAsset` instruction is called. @@ -52,9 +52,9 @@ pub enum FeeReason { } impl FeeManager for () { - fn is_waived(_: Option<&MultiLocation>, _: FeeReason) -> bool { + fn is_waived(_: Option<&Location>, _: FeeReason) -> bool { false } - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) {} + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) {} } diff --git a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs index b162a8b0729d..5d0c32890be9 100644 --- a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs +++ b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs @@ -15,21 +15,21 @@ // along with Polkadot. If not, see . use frame_support::traits::ContainsPair; -use xcm::latest::{MultiAsset, MultiLocation}; +use xcm::latest::{Asset, Location}; /// Filters assets/location pairs. /// /// Can be amalgamated into tuples. If any item returns `true`, it short-circuits, else `false` is /// returned. -#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] +#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] pub trait FilterAssetLocation { /// A filter to distinguish between asset/location pairs. - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool; + fn contains(asset: &Asset, origin: &Location) -> bool; } #[allow(deprecated)] -impl> FilterAssetLocation for T { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> FilterAssetLocation for T { + fn contains(asset: &Asset, origin: &Location) -> bool { T::contains(asset, origin) } } diff --git a/polkadot/xcm/xcm-executor/src/traits/on_response.rs b/polkadot/xcm/xcm-executor/src/traits/on_response.rs index ea41f242a97d..952bd2d0040a 100644 --- a/polkadot/xcm/xcm-executor/src/traits/on_response.rs +++ b/polkadot/xcm/xcm-executor/src/traits/on_response.rs @@ -24,42 +24,34 @@ use parity_scale_codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use sp_arithmetic::traits::Zero; use sp_std::fmt::Debug; use xcm::latest::{ - Error as XcmError, InteriorMultiLocation, MultiLocation, QueryId, Response, - Result as XcmResult, Weight, XcmContext, + Error as XcmError, InteriorLocation, Location, QueryId, Response, Result as XcmResult, Weight, + XcmContext, }; /// Define what needs to be done upon receiving a query response. pub trait OnResponse { /// Returns `true` if we are expecting a response from `origin` for query `query_id` that was /// queried by `querier`. - fn expecting_response( - origin: &MultiLocation, - query_id: u64, - querier: Option<&MultiLocation>, - ) -> bool; + fn expecting_response(origin: &Location, query_id: u64, querier: Option<&Location>) -> bool; /// Handler for receiving a `response` from `origin` relating to `query_id` initiated by /// `querier`. fn on_response( - origin: &MultiLocation, + origin: &Location, query_id: u64, - querier: Option<&MultiLocation>, + querier: Option<&Location>, response: Response, max_weight: Weight, context: &XcmContext, ) -> Weight; } impl OnResponse for () { - fn expecting_response( - _origin: &MultiLocation, - _query_id: u64, - _querier: Option<&MultiLocation>, - ) -> bool { + fn expecting_response(_origin: &Location, _query_id: u64, _querier: Option<&Location>) -> bool { false } fn on_response( - _origin: &MultiLocation, + _origin: &Location, _query_id: u64, - _querier: Option<&MultiLocation>, + _querier: Option<&Location>, _response: Response, _max_weight: Weight, _context: &XcmContext, @@ -79,7 +71,7 @@ pub trait VersionChangeNotifier { /// If the `location` has an ongoing notification and when this function is called, then an /// error should be returned. fn start( - location: &MultiLocation, + location: &Location, query_id: QueryId, max_weight: Weight, context: &XcmContext, @@ -87,20 +79,20 @@ pub trait VersionChangeNotifier { /// Stop notifying `location` should the XCM change. Returns an error if there is no existing /// notification set up. - fn stop(location: &MultiLocation, context: &XcmContext) -> XcmResult; + fn stop(location: &Location, context: &XcmContext) -> XcmResult; /// Return true if a location is subscribed to XCM version changes. - fn is_subscribed(location: &MultiLocation) -> bool; + fn is_subscribed(location: &Location) -> bool; } impl VersionChangeNotifier for () { - fn start(_: &MultiLocation, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { + fn start(_: &Location, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } - fn stop(_: &MultiLocation, _: &XcmContext) -> XcmResult { + fn stop(_: &Location, _: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } - fn is_subscribed(_: &MultiLocation) -> bool { + fn is_subscribed(_: &Location) -> bool { false } } @@ -134,13 +126,13 @@ pub trait QueryHandler { + Copy; type BlockNumber: Zero + Encode; type Error; - type UniversalLocation: Get; + type UniversalLocation: Get; /// Attempt to create a new query ID and register it as a query that is yet to respond. fn new_query( - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, - match_querier: impl Into, + match_querier: impl Into, ) -> QueryId; /// Consume `message` and return another which is equivalent to it except that it reports @@ -157,7 +149,7 @@ pub trait QueryHandler { /// The response can be queried with `take_response`. fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> result::Result; @@ -170,7 +162,7 @@ pub trait QueryHandler { } parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; } impl QueryHandler for () { @@ -183,16 +175,16 @@ impl QueryHandler for () { QueryResponseStatus::NotFound } fn new_query( - _responder: impl Into, + _responder: impl Into, _timeout: Self::BlockNumber, - _match_querier: impl Into, + _match_querier: impl Into, ) -> Self::QueryId { 0u64 } fn report_outcome( _message: &mut Xcm<()>, - _responder: impl Into, + _responder: impl Into, _timeout: Self::BlockNumber, ) -> Result { Err(()) diff --git a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs index d85458b54709..449e82b5a6e2 100644 --- a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs +++ b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs @@ -16,7 +16,7 @@ use frame_support::traits::ProcessMessageError; use sp_std::result::Result; -use xcm::latest::{Instruction, MultiLocation, Weight, XcmHash}; +use xcm::latest::{Instruction, Location, Weight, XcmHash}; /// Properyies of an XCM message and its imminent execution. #[derive(Clone, Eq, PartialEq, Debug)] @@ -43,7 +43,7 @@ pub trait ShouldExecute { /// - `properties`: Various pre-established properties of the message which may be mutated by /// this API. fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -53,7 +53,7 @@ pub trait ShouldExecute { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ShouldExecute for Tuple { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -87,7 +87,7 @@ impl ShouldExecute for Tuple { /// if any of the tuple elements returns true. pub trait CheckSuspension { fn is_suspended( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -97,7 +97,7 @@ pub trait CheckSuspension { #[impl_trait_for_tuples::impl_for_tuples(30)] impl CheckSuspension for Tuple { fn is_suspended( - origin: &MultiLocation, + origin: &Location, instruction: &mut [Instruction], max_weight: Weight, properties: &mut Properties, diff --git a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs index ad65a8630217..e9a7e3ad845d 100644 --- a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs +++ b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs @@ -18,12 +18,12 @@ use sp_std::result; use xcm::latest::prelude::*; pub trait MatchesFungible { - fn matches_fungible(a: &MultiAsset) -> Option; + fn matches_fungible(a: &Asset) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesFungible for Tuple { - fn matches_fungible(a: &MultiAsset) -> Option { + fn matches_fungible(a: &Asset) -> Option { for_tuples!( #( match Tuple::matches_fungible(a) { o @ Some(_) => return o, _ => () } )* ); @@ -33,12 +33,12 @@ impl MatchesFungible for Tuple { } pub trait MatchesNonFungible { - fn matches_nonfungible(a: &MultiAsset) -> Option; + fn matches_nonfungible(a: &Asset) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesNonFungible for Tuple { - fn matches_nonfungible(a: &MultiAsset) -> Option { + fn matches_nonfungible(a: &Asset) -> Option { for_tuples!( #( match Tuple::matches_nonfungible(a) { o @ Some(_) => return o, _ => () } )* ); @@ -52,11 +52,11 @@ impl MatchesNonFungible for Tuple { pub enum Error { /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) AssetNotHandled, - /// `MultiLocation` to `AccountId` conversion failed. + /// `Location` to `AccountId` conversion failed. AccountIdConversionFailed, /// `u128` amount to currency `Balance` conversion failed. AmountToBalanceConversionFailed, - /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + /// `Location` to `AssetId`/`ClassId` conversion failed. AssetIdConversionFailed, /// `AssetInstance` to non-fungibles instance ID conversion failed. InstanceConversionFailed, @@ -77,12 +77,12 @@ impl From for XcmError { } pub trait MatchesFungibles { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error>; + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), Error>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesFungibles for Tuple { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), Error> { for_tuples!( #( match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () } )* ); @@ -92,12 +92,12 @@ impl MatchesFungibles for Tuple { } pub trait MatchesNonFungibles { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error>; + fn matches_nonfungibles(a: &Asset) -> result::Result<(AssetId, Instance), Error>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesNonFungibles for Tuple { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(AssetId, Instance), Error> { for_tuples!( #( match Tuple::matches_nonfungibles(a) { o @ Ok(_) => return o, _ => () } )* ); diff --git a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs index c51befff88a6..e8a52d825685 100644 --- a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use sp_std::result::Result; -use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult, XcmContext}; +use xcm::latest::{Asset, Error as XcmError, Location, Result as XcmResult, XcmContext}; /// Facility for asset transacting. /// /// This should work with as many asset/location combinations as possible. Locations to support may -/// include non-account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different +/// include non-account locations such as a `[Junction::Parachain]`. Different /// chains may handle them in different ways. /// /// Can be amalgamated as a tuple of items that implement this trait. In such executions, if any of @@ -31,11 +31,7 @@ pub trait TransactAsset { /// Ensure that `check_in` will do as expected. /// /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } @@ -56,16 +52,12 @@ pub trait TransactAsset { /// When composed as a tuple, all type-items are called. It is up to the implementer that there /// exists no value for `_what` which can cause side-effects for more than one of the /// type-items. - fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + fn check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) {} /// Ensure that `check_out` will do as expected. /// /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } @@ -82,16 +74,12 @@ pub trait TransactAsset { /// When composed as a tuple, all type-items are called. It is up to the implementer that there /// exists no value for `_what` which can cause side-effects for more than one of the /// type-items. - fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + fn check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) {} /// Deposit the `what` asset into the account of `who`. /// /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Err(XcmError::Unimplemented) } @@ -104,10 +92,10 @@ pub trait TransactAsset { /// /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::Unimplemented) } @@ -121,11 +109,11 @@ pub trait TransactAsset { /// turn has a default implementation that calls `internal_transfer_asset`. As such, **please /// do not call this method directly unless you know what you're doing**. fn internal_transfer_asset( - _asset: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _asset: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::Unimplemented) } @@ -134,11 +122,11 @@ pub trait TransactAsset { /// Attempts to use `internal_transfer_asset` and if not available then falls back to using a /// two-part withdraw/deposit. fn transfer_asset( - asset: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + asset: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> Result { + ) -> Result { match Self::internal_transfer_asset(asset, from, to, context) { Err(XcmError::AssetNotFound | XcmError::Unimplemented) => { let assets = Self::withdraw_asset(asset, from, Some(context))?; @@ -153,7 +141,7 @@ pub trait TransactAsset { #[impl_trait_for_tuples::impl_for_tuples(30)] impl TransactAsset for Tuple { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { for_tuples!( #( match Tuple::can_check_in(origin, what, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -170,13 +158,13 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { for_tuples!( #( Tuple::check_in(origin, what, context); )* ); } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { for_tuples!( #( match Tuple::can_check_out(dest, what, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -193,17 +181,13 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { for_tuples!( #( Tuple::check_out(dest, what, context); )* ); } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { for_tuples!( #( match Tuple::deposit_asset(what, who, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -221,10 +205,10 @@ impl TransactAsset for Tuple { } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { for_tuples!( #( match Tuple::withdraw_asset(what, who, maybe_context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -242,11 +226,11 @@ impl TransactAsset for Tuple { } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> Result { + ) -> Result { for_tuples!( #( match Tuple::internal_transfer_asset(what, from, to, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -275,133 +259,109 @@ mod tests { pub struct NotFoundTransactor; impl TransactAsset for NotFoundTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::AssetNotFound) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::AssetNotFound) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::AssetNotFound) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::AssetNotFound) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::AssetNotFound) } } pub struct OverflowTransactor; impl TransactAsset for OverflowTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Overflow) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Overflow) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::Overflow) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::Overflow) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::Overflow) } } pub struct SuccessfulTransactor; impl TransactAsset for SuccessfulTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/polkadot/xcm/xcm-executor/src/traits/weight.rs b/polkadot/xcm/xcm-executor/src/traits/weight.rs index bc40c10074f5..efb9a2dfb6ef 100644 --- a/polkadot/xcm/xcm-executor/src/traits/weight.rs +++ b/polkadot/xcm/xcm-executor/src/traits/weight.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use sp_std::result::Result; use xcm::latest::{prelude::*, Weight}; @@ -33,7 +33,7 @@ pub trait WeightBounds { /// message. pub trait UniversalWeigher { /// Get the upper limit of weight required for `dest` to execute `message`. - fn weigh(dest: impl Into, message: Xcm<()>) -> Result; + fn weigh(dest: impl Into, message: Xcm<()>) -> Result; } /// Charge for weight in order to execute XCM. @@ -52,15 +52,15 @@ pub trait WeightTrader: Sized { fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result; + ) -> Result; /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight /// was purchased using `buy_weight`. /// /// Default implementation refunds nothing. - fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { + fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { None } } @@ -74,9 +74,9 @@ impl WeightTrader for Tuple { fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { let mut too_expensive_error_found = false; let mut last_error = None; for_tuples!( #( @@ -102,7 +102,7 @@ impl WeightTrader for Tuple { }) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { for_tuples!( #( if let Some(asset) = Tuple.refund_weight(weight, context) { return Some(asset); diff --git a/polkadot/xcm/xcm-simulator/example/src/lib.rs b/polkadot/xcm/xcm-simulator/example/src/lib.rs index 85b8ad1c5cb7..d134957fbc1c 100644 --- a/polkadot/xcm/xcm-simulator/example/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/example/src/lib.rs @@ -148,7 +148,7 @@ mod tests { use xcm_simulator::TestExt; // Helper function for forming buy execution message - fn buy_execution(fees: impl Into) -> Instruction { + fn buy_execution(fees: impl Into) -> Instruction { BuyExecution { fees: fees.into(), weight_limit: Unlimited } } @@ -642,7 +642,7 @@ mod tests { parachain::MsgQueue::received_dmp(), vec![Xcm(vec![QueryResponse { query_id: query_id_set, - response: Response::Assets(MultiAssets::new()), + response: Response::Assets(Assets::new()), max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), querier: Some(Here.into()), }])], diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs index 69db81deff4f..0b6c573f464e 100644 --- a/polkadot/xcm/xcm-simulator/example/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs @@ -115,8 +115,8 @@ impl pallet_balances::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] pub struct UniquesHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_uniques::BenchmarkHelper for UniquesHelper { - fn collection(i: u16) -> MultiLocation { +impl pallet_uniques::BenchmarkHelper for UniquesHelper { + fn collection(i: u16) -> Location { GeneralIndex(i as u128).into() } fn item(i: u16) -> AssetInstance { @@ -126,7 +126,7 @@ impl pallet_uniques::BenchmarkHelper for UniquesHe impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = MultiLocation; + type CollectionId = Location; type ItemId = AssetInstance; type Currency = Balances; type CreateOrigin = ForeignCreators; @@ -148,12 +148,12 @@ impl pallet_uniques::Config for Runtime { // `EnsureOriginWithArg` impl for `CreateOrigin` which allows only XCM origins // which are locations containing the class location. pub struct ForeignCreators; -impl EnsureOriginWithArg for ForeignCreators { +impl EnsureOriginWithArg for ForeignCreators { type Success = AccountId; fn try_origin( o: RuntimeOrigin, - a: &MultiLocation, + a: &Location, ) -> sp_std::result::Result { let origin_location = pallet_xcm::EnsureXcm::::try_origin(o.clone())?; if !a.starts_with(&origin_location) { @@ -163,8 +163,8 @@ impl EnsureOriginWithArg for ForeignCreators { } #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(a: &MultiLocation) -> Result { - Ok(pallet_xcm::Origin::Xcm(*a).into()) + fn try_successful_origin(a: &Location) -> Result { + Ok(pallet_xcm::Origin::Xcm(a.clone()).into()) } } @@ -174,9 +174,9 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const KsmLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type LocationToAccountId = ( @@ -194,17 +194,17 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub ForeignPrefix: MultiLocation = (Parent,).into(); + pub ForeignPrefix: Location = (Parent,).into(); } pub type LocalAssetTransactor = ( FungibleAdapter, LocationToAccountId, AccountId, ()>, NonFungiblesAdapter< ForeignUniques, - ConvertedConcreteId, + ConvertedConcreteId, SovereignAccountOf, AccountId, NoChecking, @@ -216,9 +216,9 @@ pub type XcmRouter = super::ParachainXcmRouter; pub type Barrier = AllowUnpaidExecutionFrom; parameter_types! { - pub NftCollectionOne: MultiAssetFilter - = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); - pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) = (NftCollectionOne::get(), (Parent,).into()); } pub type TrustedTeleporters = xcm_builder::Case; @@ -321,16 +321,23 @@ pub mod mock_msg_queue { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { let location = (Parent, Parachain(sender.into())); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -371,7 +378,7 @@ pub mod mock_msg_queue { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); match maybe_versioned { Err(_) => { @@ -380,7 +387,13 @@ pub mod mock_msg_queue { Ok(versioned) => match Xcm::try_from(versioned) { Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), Ok(x) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, @@ -400,17 +413,15 @@ impl mock_msg_queue::Config for Runtime { pub type LocalOriginToLocation = SignedToAccountId32; pub struct TrustedLockerCase(PhantomData); -impl> ContainsPair - for TrustedLockerCase -{ - fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { let (o, a) = T::get(); a.matches(asset) && &o == origin } } parameter_types! { - pub RelayTokenForRelay: (MultiLocation, MultiAssetFilter) = (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); + pub RelayTokenForRelay: (Location, AssetFilter) = (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); } pub type TrustedLockers = TrustedLockerCase; diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 24fc56eb7174..1bcbe6da2cda 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -127,10 +127,10 @@ impl configuration::Config for Runtime { } parameter_types! { - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); pub RelayNetwork: NetworkId = ByGenesis([0; 32]); pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; } @@ -162,7 +162,7 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); pub TokensPerSecondPerByte: (AssetId, u128, u128) = - (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs index 0893c7c086f8..7026d5467c8b 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs @@ -158,7 +158,7 @@ fn run_input(xcm_messages: [XcmMessage; 5]) { if xcm_message.source % 4 == 0 { // We get the destination for the message let parachain_id = (xcm_message.destination % 3) + 1; - let destination: MultiLocation = Parachain(parachain_id).into(); + let destination: Location = Parachain(parachain_id).into(); #[cfg(not(fuzzing))] { println!(" source: Relay Chain"); @@ -176,7 +176,7 @@ fn run_input(xcm_messages: [XcmMessage; 5]) { _ => ParaC::execute_with, }; // We get the destination for the message - let destination: MultiLocation = match xcm_message.destination % 4 { + let destination: Location = match xcm_message.destination % 4 { n @ 1..=3 => (Parent, Parachain(n)).into(), _ => Parent.into(), }; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index 2262d18e8604..41fc5af97088 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -109,9 +109,9 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const KsmLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type LocationToAccountId = ( @@ -128,7 +128,7 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -237,16 +237,23 @@ pub mod mock_msg_queue { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { - let location = MultiLocation::new(1, X1(Parachain(sender.into()))); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + let location = Location::new(1, [Parachain(sender.into())]); + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -287,7 +294,7 @@ pub mod mock_msg_queue { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_msg = VersionedXcm::::decode(&mut &data[..]) .map(Xcm::::try_from); match maybe_msg { @@ -298,7 +305,13 @@ pub mod mock_msg_queue { Self::deposit_event(Event::UnsupportedVersion(id)); }, Ok(Ok(x)) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index bbf4f1e6cc5b..c066cc5e813e 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -107,10 +107,10 @@ impl configuration::Config for Runtime { } parameter_types! { - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); pub const ThisNetwork: NetworkId = NetworkId::ByGenesis([0; 32]); pub const AnyNetwork: Option = None; - pub const UniversalLocation: InteriorMultiLocation = Here; + pub const UniversalLocation: InteriorLocation = Here; } pub type SovereignAccountOf = @@ -129,7 +129,7 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(TokenLocation::get()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(TokenLocation::get()), 1, 1); pub const MaxInstructions: u32 = u32::MAX; pub const MaxAssetsIntoHolding: u32 = 64; } diff --git a/polkadot/xcm/xcm-simulator/src/lib.rs b/polkadot/xcm/xcm-simulator/src/lib.rs index b38465b3d4a2..7efbc658bbfb 100644 --- a/polkadot/xcm/xcm-simulator/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/src/lib.rs @@ -258,9 +258,9 @@ macro_rules! __impl_ext { } thread_local! { - pub static PARA_MESSAGE_BUS: RefCell)>> + pub static PARA_MESSAGE_BUS: RefCell)>> = RefCell::new(VecDeque::new()); - pub static RELAY_MESSAGE_BUS: RefCell)>> + pub static RELAY_MESSAGE_BUS: RefCell)>> = RefCell::new(VecDeque::new()); } @@ -318,8 +318,8 @@ macro_rules! decl_test_network { while let Some((para_id, destination, message)) = $crate::PARA_MESSAGE_BUS.with( |b| b.borrow_mut().pop_front()) { - match destination.interior() { - $crate::Junctions::Here if destination.parent_count() == 1 => { + match destination.unpack() { + (1, []) => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump); let mut _id = [0; 32]; let r = <$relay_chain>::process_message( @@ -336,7 +336,7 @@ macro_rules! decl_test_network { } }, $( - $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 1 => { + (1, [$crate::Parachain(id)]) if *id == $para_id => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp); let messages = vec![(para_id, 1, &encoded[..])]; let _weight = <$parachain>::handle_xcmp_messages( @@ -360,9 +360,9 @@ macro_rules! decl_test_network { while let Some((destination, message)) = $crate::RELAY_MESSAGE_BUS.with( |b| b.borrow_mut().pop_front()) { - match destination.interior() { + match destination.unpack() { $( - $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 0 => { + (0, [$crate::Parachain(id)]) if *id == $para_id => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp); // NOTE: RelayChainBlockNumber is hard-coded to 1 let messages = vec![(1, encoded)]; @@ -382,18 +382,18 @@ macro_rules! decl_test_network { pub struct ParachainXcmRouter($crate::PhantomData); impl> $crate::SendXcm for ParachainXcmRouter { - type Ticket = ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>); + type Ticket = ($crate::ParaId, $crate::Location, $crate::Xcm<()>); fn validate( - destination: &mut Option<$crate::MultiLocation>, + destination: &mut Option<$crate::Location>, message: &mut Option<$crate::Xcm<()>>, - ) -> $crate::SendResult<($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>)> { + ) -> $crate::SendResult<($crate::ParaId, $crate::Location, $crate::Xcm<()>)> { use $crate::XcmpMessageHandlerT; let d = destination.take().ok_or($crate::SendError::MissingArgument)?; - match (d.interior(), d.parent_count()) { - ($crate::Junctions::Here, 1) => {}, + match d.unpack() { + (1, []) => {}, $( - ($crate::X1($crate::Parachain(id)), 1) if id == &$para_id => {} + (1, [$crate::Parachain(id)]) if id == &$para_id => {} )* _ => { *destination = Some(d); @@ -401,10 +401,10 @@ macro_rules! decl_test_network { }, } let m = message.take().ok_or($crate::SendError::MissingArgument)?; - Ok(((T::get(), d, m), $crate::MultiAssets::new())) + Ok(((T::get(), d, m), $crate::Assets::new())) } fn deliver( - triple: ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>), + triple: ($crate::ParaId, $crate::Location, $crate::Xcm<()>), ) -> Result<$crate::XcmHash, $crate::SendError> { let hash = $crate::fake_message_hash(&triple.2); $crate::PARA_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(triple)); @@ -415,17 +415,17 @@ macro_rules! decl_test_network { /// XCM router for relay chain. pub struct RelayChainXcmRouter; impl $crate::SendXcm for RelayChainXcmRouter { - type Ticket = ($crate::MultiLocation, $crate::Xcm<()>); + type Ticket = ($crate::Location, $crate::Xcm<()>); fn validate( - destination: &mut Option<$crate::MultiLocation>, + destination: &mut Option<$crate::Location>, message: &mut Option<$crate::Xcm<()>>, - ) -> $crate::SendResult<($crate::MultiLocation, $crate::Xcm<()>)> { + ) -> $crate::SendResult<($crate::Location, $crate::Xcm<()>)> { use $crate::DmpMessageHandlerT; let d = destination.take().ok_or($crate::SendError::MissingArgument)?; - match (d.interior(), d.parent_count()) { + match d.unpack() { $( - ($crate::X1($crate::Parachain(id)), 0) if id == &$para_id => {}, + (0, [$crate::Parachain(id)]) if id == &$para_id => {}, )* _ => { *destination = Some(d); @@ -433,10 +433,10 @@ macro_rules! decl_test_network { }, } let m = message.take().ok_or($crate::SendError::MissingArgument)?; - Ok(((d, m), $crate::MultiAssets::new())) + Ok(((d, m), $crate::Assets::new())) } fn deliver( - pair: ($crate::MultiLocation, $crate::Xcm<()>), + pair: ($crate::Location, $crate::Xcm<()>), ) -> Result<$crate::XcmHash, $crate::SendError> { let hash = $crate::fake_message_hash(&pair.1); $crate::RELAY_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(pair)); diff --git a/prdoc/pr_1230.prdoc b/prdoc/pr_1230.prdoc new file mode 100644 index 000000000000..8eea1816cb5a --- /dev/null +++ b/prdoc/pr_1230.prdoc @@ -0,0 +1,20 @@ +title: XCMv4 + +doc: + - audience: Runtime Dev + description: | + A new version of the XCM format. + The main changes are: + - Removed `Multi` prefix from types + - Removed `Abstract` asset id + - `Outcome` is now a named fields struct + - Added `Reanchorable` trait, implemented for both `Location` and `Asset` + - New syntax for building `Location`s and `Junction`s using slices. + You build them like `let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]);` + and match on them like `match location.unpack() { + (1, [Parachain(id)]) => ... + (0, Here) => ..., + (1, [_]) => ..., + }` + +crates: [] diff --git a/substrate/frame/assets/src/benchmarking.rs b/substrate/frame/assets/src/benchmarking.rs index 8fe5a7e2493a..1b65bb953d77 100644 --- a/substrate/frame/assets/src/benchmarking.rs +++ b/substrate/frame/assets/src/benchmarking.rs @@ -45,7 +45,7 @@ fn create_default_asset, I: 'static>( let root = SystemOrigin::Root.into(); assert!(Assets::::force_create( root, - asset_id, + asset_id.clone(), caller_lookup.clone(), is_sufficient, 1u32.into(), @@ -64,7 +64,7 @@ pub fn create_default_minted_asset, I: 'static>( } assert!(Assets::::mint( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), caller_lookup.clone(), amount, ) @@ -91,7 +91,7 @@ fn add_sufficients, I: 'static>(minter: T::AccountId, n: u32) { let target_lookup = T::Lookup::unlookup(target); assert!(Assets::::mint( origin.clone().into(), - asset_id, + asset_id.clone(), target_lookup, 100u32.into() ) @@ -108,8 +108,13 @@ fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { ); let minter_lookup = T::Lookup::unlookup(minter.clone()); let origin = SystemOrigin::Signed(minter); - Assets::::mint(origin.clone().into(), asset_id, minter_lookup, (100 * (n + 1)).into()) - .unwrap(); + Assets::::mint( + origin.clone().into(), + asset_id.clone(), + minter_lookup, + (100 * (n + 1)).into(), + ) + .unwrap(); let enough = T::Currency::minimum_balance(); for i in 0..n { let target = account("approval", i, SEED); @@ -117,7 +122,7 @@ fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { let target_lookup = T::Lookup::unlookup(target); Assets::::approve_transfer( origin.clone().into(), - asset_id, + asset_id.clone(), target_lookup, 100u32.into(), ) @@ -136,12 +141,12 @@ fn assert_event, I: 'static>(generic_event: >::Runti benchmarks_instance_pallet! { create { let asset_id = default_asset_id::(); - let origin = T::CreateOrigin::try_successful_origin(&asset_id.into()) + let origin = T::CreateOrigin::try_successful_origin(&asset_id.clone().into()) .map_err(|_| BenchmarkError::Weightless)?; - let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.into()).unwrap(); + let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.clone().into()).unwrap(); let caller_lookup = T::Lookup::unlookup(caller.clone()); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(origin, asset_id, caller_lookup, 1u32.into()) + }: _(origin, asset_id.clone(), caller_lookup, 1u32.into()) verify { assert_last_event::(Event::Created { asset_id: asset_id.into(), creator: caller.clone(), owner: caller }.into()); } @@ -150,7 +155,7 @@ benchmarks_instance_pallet! { let asset_id = default_asset_id::(); let caller: T::AccountId = whitelisted_caller(); let caller_lookup = T::Lookup::unlookup(caller.clone()); - }: _(SystemOrigin::Root, asset_id, caller_lookup, true, 1u32.into()) + }: _(SystemOrigin::Root, asset_id.clone(), caller_lookup, true, 1u32.into()) verify { assert_last_event::(Event::ForceCreated { asset_id: asset_id.into(), owner: caller }.into()); } @@ -159,9 +164,9 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - }:_(SystemOrigin::Signed(caller), asset_id) + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::DestructionStarted { asset_id: asset_id.into() }.into()); } @@ -172,10 +177,10 @@ benchmarks_instance_pallet! { add_sufficients::(caller.clone(), c); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::AccountsDestroyed { asset_id: asset_id.into(), @@ -190,10 +195,10 @@ benchmarks_instance_pallet! { add_approvals::(caller.clone(), a); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::ApprovalsDestroyed { asset_id: asset_id.into(), @@ -206,10 +211,10 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_asset::(true); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::Destroyed { asset_id: asset_id.into(), @@ -220,7 +225,7 @@ benchmarks_instance_pallet! { mint { let (asset_id, caller, caller_lookup) = create_default_asset::(true); let amount = T::Balance::from(100u32); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount) verify { assert_last_event::(Event::Issued { asset_id: asset_id.into(), owner: caller, amount }.into()); } @@ -228,7 +233,7 @@ benchmarks_instance_pallet! { burn { let amount = T::Balance::from(100u32); let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount) verify { assert_last_event::(Event::Burned { asset_id: asset_id.into(), owner: caller, balance: amount }.into()); } @@ -238,7 +243,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount) verify { assert_last_event::(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()); } @@ -249,7 +254,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, mint_amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount) verify { assert!(frame_system::Pallet::::account_exists(&caller)); assert_last_event::(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()); @@ -260,7 +265,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, target_lookup, amount) verify { assert_last_event::( Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into() @@ -269,7 +274,7 @@ benchmarks_instance_pallet! { freeze { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Frozen { asset_id: asset_id.into(), who: caller }.into()); } @@ -278,17 +283,17 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), caller_lookup.clone(), )?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Thawed { asset_id: asset_id.into(), who: caller }.into()); } freeze_asset { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone()) verify { assert_last_event::(Event::AssetFrozen { asset_id: asset_id.into() }.into()); } @@ -297,9 +302,9 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone()) verify { assert_last_event::(Event::AssetThawed { asset_id: asset_id.into() }.into()); } @@ -308,7 +313,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, _) = create_default_asset::(true); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller), asset_id, target_lookup) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), target_lookup) verify { assert_last_event::(Event::OwnerChanged { asset_id: asset_id.into(), owner: target }.into()); } @@ -318,7 +323,7 @@ benchmarks_instance_pallet! { let target0 = T::Lookup::unlookup(account("target", 0, SEED)); let target1 = T::Lookup::unlookup(account("target", 1, SEED)); let target2 = T::Lookup::unlookup(account("target", 2, SEED)); - }: _(SystemOrigin::Signed(caller), asset_id, target0, target1, target2) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), target0, target1, target2) verify { assert_last_event::(Event::TeamChanged { asset_id: asset_id.into(), @@ -338,7 +343,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, _) = create_default_asset::(true); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(SystemOrigin::Signed(caller), asset_id, name.clone(), symbol.clone(), decimals) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), name.clone(), symbol.clone(), decimals) verify { assert_last_event::(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into()); } @@ -348,8 +353,8 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); let dummy = vec![0u8; T::StringLimit::get() as usize]; let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?; - }: _(SystemOrigin::Signed(caller), asset_id) + Assets::::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?; + }: _(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::MetadataCleared { asset_id: asset_id.into() }.into()); } @@ -367,7 +372,7 @@ benchmarks_instance_pallet! { let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let call = Call::::force_set_metadata { - id: asset_id, + id: asset_id.clone(), name: name.clone(), symbol: symbol.clone(), decimals, @@ -383,11 +388,11 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); let dummy = vec![0u8; T::StringLimit::get() as usize]; let origin = SystemOrigin::Signed(caller).into(); - Assets::::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?; + Assets::::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?; let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let call = Call::::force_clear_metadata { id: asset_id }; + let call = Call::::force_clear_metadata { id: asset_id.clone() }; }: { call.dispatch_bypass_filter(origin)? } verify { assert_last_event::(Event::MetadataCleared { asset_id: asset_id.into() }.into()); @@ -399,7 +404,7 @@ benchmarks_instance_pallet! { let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let call = Call::::force_asset_status { - id: asset_id, + id: asset_id.clone(), owner: caller_lookup.clone(), issuer: caller_lookup.clone(), admin: caller_lookup.clone(), @@ -420,7 +425,7 @@ benchmarks_instance_pallet! { let delegate: T::AccountId = account("delegate", 0, SEED); let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup, amount) verify { assert_last_event::(Event::ApprovedTransfer { asset_id: asset_id.into(), source: caller, delegate, amount }.into()); } @@ -434,11 +439,11 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(owner.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup, amount)?; + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup, amount)?; let dest: T::AccountId = account("dest", 0, SEED); let dest_lookup = T::Lookup::unlookup(dest.clone()); - }: _(SystemOrigin::Signed(delegate.clone()), asset_id, owner_lookup, dest_lookup, amount) + }: _(SystemOrigin::Signed(delegate.clone()), asset_id.clone(), owner_lookup, dest_lookup, amount) verify { assert!(T::Currency::reserved_balance(&owner).is_zero()); assert_event::(Event::Transferred { asset_id: asset_id.into(), from: owner, to: dest, amount }.into()); @@ -452,8 +457,8 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup) + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?; + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup) verify { assert_last_event::(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into()); } @@ -466,15 +471,15 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, delegate_lookup) + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?; + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, delegate_lookup) verify { assert_last_event::(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into()); } set_min_balance { let (asset_id, caller, caller_lookup) = create_default_asset::(false); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, 50u32.into()) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), 50u32.into()) verify { assert_last_event::(Event::AssetMinBalanceChanged { asset_id: asset_id.into(), new_min_balance: 50u32.into() }.into()); } @@ -484,8 +489,8 @@ benchmarks_instance_pallet! { let new_account: T::AccountId = account("newaccount", 1, SEED); T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::::max_value()); assert_ne!(asset_owner, new_account); - assert!(!Account::::contains_key(asset_id.into(), &new_account)); - }: _(SystemOrigin::Signed(new_account.clone()), asset_id) + assert!(!Account::::contains_key(asset_id.clone().into(), &new_account)); + }: _(SystemOrigin::Signed(new_account.clone()), asset_id.clone()) verify { assert!(Account::::contains_key(asset_id.into(), &new_account)); } @@ -496,8 +501,8 @@ benchmarks_instance_pallet! { let new_account_lookup = T::Lookup::unlookup(new_account.clone()); T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::::max_value()); assert_ne!(asset_owner, new_account); - assert!(!Account::::contains_key(asset_id.into(), &new_account)); - }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup) + assert!(!Account::::contains_key(asset_id.clone().into(), &new_account)); + }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id.clone(), new_account_lookup) verify { assert!(Account::::contains_key(asset_id.into(), &new_account)); } @@ -509,12 +514,12 @@ benchmarks_instance_pallet! { assert_ne!(asset_owner, new_account); assert!(Assets::::touch( SystemOrigin::Signed(new_account.clone()).into(), - asset_id + asset_id.clone() ).is_ok()); // `touch` should reserve balance of the caller according to the `AssetAccountDeposit` amount... assert_eq!(T::Currency::reserved_balance(&new_account), T::AssetAccountDeposit::get()); // ...and also create an `Account` entry. - assert!(Account::::contains_key(asset_id.into(), &new_account)); + assert!(Account::::contains_key(asset_id.clone().into(), &new_account)); }: _(SystemOrigin::Signed(new_account.clone()), asset_id, true) verify { // `refund`ing should of course repatriate the reserve @@ -529,12 +534,12 @@ benchmarks_instance_pallet! { assert_ne!(asset_owner, new_account); assert!(Assets::::touch_other( SystemOrigin::Signed(asset_owner.clone()).into(), - asset_id, + asset_id.clone(), new_account_lookup.clone() ).is_ok()); // `touch` should reserve balance of the caller according to the `AssetAccountDeposit` amount... assert_eq!(T::Currency::reserved_balance(&asset_owner), T::AssetAccountDeposit::get()); - assert!(Account::::contains_key(asset_id.into(), &new_account)); + assert!(Account::::contains_key(asset_id.clone().into(), &new_account)); }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup.clone()) verify { // this should repatriate the reserved balance of the freezer @@ -543,7 +548,7 @@ benchmarks_instance_pallet! { block { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Blocked { asset_id: asset_id.into(), who: caller }.into()); } diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs index f3ae03d667b4..cafe7bb1a3b5 100644 --- a/substrate/frame/assets/src/lib.rs +++ b/substrate/frame/assets/src/lib.rs @@ -259,11 +259,7 @@ pub mod pallet { /// This type includes the `From` bound, since tightly coupled pallets may /// want to convert an `AssetId` into a parameter for calling dispatchable functions /// directly. - type AssetIdParameter: Parameter - + Copy - + From - + Into - + MaxEncodedLen; + type AssetIdParameter: Parameter + From + Into + MaxEncodedLen; /// The currency mechanism. type Currency: ReservableCurrency; diff --git a/substrate/frame/contracts/mock-network/src/lib.rs b/substrate/frame/contracts/mock-network/src/lib.rs index 345c69541b6f..eea9dde062c8 100644 --- a/substrate/frame/contracts/mock-network/src/lib.rs +++ b/substrate/frame/contracts/mock-network/src/lib.rs @@ -24,7 +24,7 @@ mod tests; use crate::primitives::{AccountId, UNITS}; use sp_runtime::BuildStorage; -use xcm::latest::{prelude::*, MultiLocation}; +use xcm::latest::prelude::*; use xcm_executor::traits::ConvertLocation; use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; @@ -67,12 +67,12 @@ decl_test_network! { } pub fn relay_sovereign_account_id() -> AccountId { - let location: MultiLocation = (Parent,).into(); + let location: Location = (Parent,).into(); parachain::SovereignAccountOf::convert_location(&location).unwrap() } pub fn parachain_sovereign_account_id(para: u32) -> AccountId { - let location: MultiLocation = (Parachain(para),).into(); + let location: Location = (Parachain(para),).into(); relay_chain::SovereignAccountOf::convert_location(&location).unwrap() } @@ -80,7 +80,7 @@ pub fn parachain_account_sovereign_account_id( para: u32, who: sp_runtime::AccountId32, ) -> AccountId { - let location: MultiLocation = ( + let location: Location = ( Parachain(para), AccountId32 { network: Some(relay_chain::RelayNetwork::get()), id: who.into() }, ) diff --git a/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs b/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs index 82fb8590e269..cc81b6bd636e 100644 --- a/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs +++ b/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs @@ -96,16 +96,23 @@ pub mod pallet { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { let location = (Parent, Parachain(sender.into())); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -146,7 +153,7 @@ pub mod pallet { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); match maybe_versioned { Err(_) => { @@ -155,7 +162,13 @@ pub mod pallet { Ok(versioned) => match Xcm::try_from(versioned) { Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), Ok(x) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, diff --git a/substrate/frame/contracts/mock-network/src/parachain.rs b/substrate/frame/contracts/mock-network/src/parachain.rs index a79b7e4e2d6d..90fc23af48d3 100644 --- a/substrate/frame/contracts/mock-network/src/parachain.rs +++ b/substrate/frame/contracts/mock-network/src/parachain.rs @@ -143,10 +143,10 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const KsmLocation: Location = Location::parent(); + pub const TokenLocation: Location = Here.into_location(); pub const RelayNetwork: NetworkId = ByGenesis([0; 32]); - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type XcmOriginToCallOrigin = ( @@ -158,13 +158,13 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const XcmInstructionWeight: Weight = Weight::from_parts(1_000, 1_000); - pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1_000_000_000_000, 1024 * 1024); + pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub ForeignPrefix: MultiLocation = (Parent,).into(); + pub ForeignPrefix: Location = (Parent,).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub TrustedLockPairs: (MultiLocation, MultiAssetFilter) = - (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); + pub TrustedLockPairs: (Location, AssetFilter) = + (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); } pub fn estimate_message_fee(number_of_instructions: u64) -> u128 { @@ -188,20 +188,19 @@ pub fn estimate_fee_for_weight(weight: Weight) -> u128 { pub type LocalBalancesTransactor = XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; -pub struct FromMultiLocationToAsset(PhantomData<(MultiLocation, AssetId)>); -impl MaybeEquivalence - for FromMultiLocationToAsset +pub struct FromLocationToAsset(PhantomData<(Location, AssetId)>); +impl MaybeEquivalence + for FromLocationToAsset { - fn convert(value: &MultiLocation) -> Option { - match *value { - MultiLocation { parents: 1, interior: Here } => Some(0 as AssetIdForAssets), - MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } => - Some(para_id as AssetIdForAssets), + fn convert(value: &Location) -> Option { + match value.unpack() { + (1, []) => Some(0 as AssetIdForAssets), + (1, [Parachain(para_id)]) => Some(*para_id as AssetIdForAssets), _ => None, } } - fn convert_back(_id: &AssetIdForAssets) -> Option { + fn convert_back(_id: &AssetIdForAssets) -> Option { None } } @@ -211,7 +210,7 @@ pub type ForeignAssetsTransactor = FungiblesAdapter< ConvertedConcreteId< AssetIdForAssets, Balance, - FromMultiLocationToAsset, + FromLocationToAsset, JustTry, >, SovereignAccountOf, @@ -224,18 +223,15 @@ pub type ForeignAssetsTransactor = FungiblesAdapter< pub type AssetTransactors = (LocalBalancesTransactor, ForeignAssetsTransactor); pub struct ParentRelay; -impl Contains for ParentRelay { - fn contains(location: &MultiLocation) -> bool { +impl Contains for ParentRelay { + fn contains(location: &Location) -> bool { location.contains_parents_only(1) } } pub struct ThisParachain; -impl Contains for ThisParachain { - fn contains(location: &MultiLocation) -> bool { - matches!( - location, - MultiLocation { parents: 0, interior: Junctions::X1(Junction::AccountId32 { .. }) } - ) +impl Contains for ThisParachain { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Junction::AccountId32 { .. }])) } } @@ -251,12 +247,12 @@ pub type Barrier = ( ); parameter_types! { - pub NftCollectionOne: MultiAssetFilter - = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); - pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) = (NftCollectionOne::get(), Parent.into()); - pub RelayNativeAsset: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete((Parent, Here).into()) }); - pub RelayNativeAssetForRelay: (MultiAssetFilter, MultiLocation) = (RelayNativeAsset::get(), Parent.into()); + pub RelayNativeAsset: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId((Parent, Here).into()) }); + pub RelayNativeAssetForRelay: (AssetFilter, Location) = (RelayNativeAsset::get(), Parent.into()); } pub type TrustedTeleporters = (xcm_builder::Case, xcm_builder::Case); @@ -298,10 +294,8 @@ impl mock_msg_queue::Config for Runtime { pub type LocalOriginToLocation = SignedToAccountId32; pub struct TrustedLockerCase(PhantomData); -impl> ContainsPair - for TrustedLockerCase -{ - fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { let (o, a) = T::get(); a.matches(asset) && &o == origin } diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index 136cc2e3ed67..4e5523f74427 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -107,8 +107,8 @@ impl configuration::Config for Runtime { parameter_types! { pub RelayNetwork: NetworkId = ByGenesis([0; 32]); - pub const TokenLocation: MultiLocation = Here.into_location(); - pub UniversalLocation: InteriorMultiLocation = Here; + pub const TokenLocation: Location = Here.into_location(); + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; } @@ -134,15 +134,15 @@ type LocalOriginConverter = ( parameter_types! { pub const XcmInstructionWeight: Weight = Weight::from_parts(1_000, 1_000); pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = - (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } pub struct ChildrenParachains; -impl Contains for ChildrenParachains { - fn contains(location: &MultiLocation) -> bool { - matches!(location, MultiLocation { parents: 0, interior: X1(Parachain(_)) }) +impl Contains for ChildrenParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) } } diff --git a/substrate/frame/contracts/mock-network/src/tests.rs b/substrate/frame/contracts/mock-network/src/tests.rs index a66b2b080196..c25373bcbe3a 100644 --- a/substrate/frame/contracts/mock-network/src/tests.rs +++ b/substrate/frame/contracts/mock-network/src/tests.rs @@ -31,7 +31,7 @@ use frame_support::{ use pallet_balances::{BalanceLock, Reasons}; use pallet_contracts::{Code, CollectEvents, DebugInfo, Determinism}; use pallet_contracts_fixtures::compile_module; -use xcm::{v3::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{v4::prelude::*, VersionedLocation, VersionedXcm}; use xcm_simulator::TestExt; type ParachainContracts = pallet_contracts::Pallet; @@ -82,7 +82,7 @@ fn test_xcm_execute() { let amount: u128 = 10 * CENTS; // The XCM used to transfer funds to Bob. - let message: xcm_simulator::Xcm<()> = Xcm(vec![ + let message: Xcm<()> = Xcm(vec![ WithdrawAsset(vec![(Here, amount).into()].into()), DepositAsset { assets: All.into(), @@ -96,7 +96,7 @@ fn test_xcm_execute() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -106,7 +106,7 @@ fn test_xcm_execute() { let mut data = &result.data[..]; let outcome = Outcome::decode(&mut data).expect("Failed to decode xcm_execute Outcome"); - assert_matches!(outcome, Outcome::Complete(_)); + assert_matches!(outcome, Outcome::Complete { .. }); // Check if the funds are subtracted from the account of Alice and added to the account of // Bob. @@ -137,7 +137,7 @@ fn test_xcm_execute_filtered_call() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -178,7 +178,7 @@ fn test_xcm_execute_reentrant_call() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -188,7 +188,10 @@ fn test_xcm_execute_reentrant_call() { let mut data = &result.data[..]; let outcome = Outcome::decode(&mut data).expect("Failed to decode xcm_execute Outcome"); - assert_matches!(outcome, Outcome::Incomplete(_, XcmError::ExpectationFalse)); + assert_matches!( + outcome, + Outcome::Incomplete { used: _, error: XcmError::ExpectationFalse } + ); // Funds should not change hands as the XCM transact failed. assert_eq!(ParachainBalances::free_balance(BOB), INITIAL_BALANCE); @@ -203,15 +206,15 @@ fn test_xcm_send() { // Send XCM instructions through the contract, to lock some funds on the relay chain. ParaA::execute_with(|| { - let dest = MultiLocation::from(Parent); - let dest = VersionedMultiLocation::V3(dest); + let dest = Location::from(Parent); + let dest = VersionedLocation::V4(dest); - let message: xcm_simulator::Xcm<()> = Xcm(vec![ + let message: Xcm<()> = Xcm(vec![ WithdrawAsset((Here, fee).into()), BuyExecution { fees: (Here, fee).into(), weight_limit: WeightLimit::Unlimited }, LockAsset { asset: (Here, 5 * CENTS).into(), unlocker: (Parachain(1)).into() }, ]); - let message = VersionedXcm::V3(message); + let message = VersionedXcm::V4(message); let exec = ParachainContracts::bare_call( ALICE, contract_addr.clone(), diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index a7f329005f91..3e49b68f86b6 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -2169,11 +2169,11 @@ pub mod env { msg_len: u32, output_ptr: u32, ) -> Result { - use xcm::{VersionedMultiLocation, VersionedXcm}; + use xcm::{VersionedLocation, VersionedXcm}; use xcm_builder::{SendController, SendControllerWeightInfo}; ctx.charge_gas(RuntimeCosts::CopyFromContract(msg_len))?; - let dest: VersionedMultiLocation = ctx.read_sandbox_memory_as(memory, dest_ptr)?; + let dest: VersionedLocation = ctx.read_sandbox_memory_as(memory, dest_ptr)?; let message: VersionedXcm<()> = ctx.read_sandbox_memory_as_unbounded(memory, msg_ptr, msg_len)?; diff --git a/substrate/frame/support/src/traits/tokens/pay.rs b/substrate/frame/support/src/traits/tokens/pay.rs index 4d1d80b5b507..62d7a056a3f1 100644 --- a/substrate/frame/support/src/traits/tokens/pay.rs +++ b/substrate/frame/support/src/traits/tokens/pay.rs @@ -26,7 +26,7 @@ use sp_std::fmt::Debug; use super::{fungible, fungibles, Balance, Preservation::Expendable}; /// Can be implemented by `PayFromAccount` using a `fungible` impl, but can also be implemented with -/// XCM/MultiAsset and made generic over assets. +/// XCM/Asset and made generic over assets. pub trait Pay { /// The type by which we measure units of the currency in which we make payments. type Balance: Balance;