From 415dd81c79287329d82c4715da4504441a11451d Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Tue, 23 May 2023 17:13:19 +0200 Subject: [PATCH] Add Foreign Assets to Statemint (#2540) * add foreign assets to statemint * make review changes * two dots --------- Co-authored-by: parity-processbot <> --- .../assets/statemine/src/xcm_config.rs | 10 +- .../runtimes/assets/statemint/src/lib.rs | 62 +++++++- .../assets/statemint/src/xcm_config.rs | 98 +++++++++++- .../runtimes/assets/statemint/tests/tests.rs | 145 ++++++++++++++++-- .../assets/westmint/src/xcm_config.rs | 6 +- 5 files changed, 290 insertions(+), 31 deletions(-) diff --git a/parachains/runtimes/assets/statemine/src/xcm_config.rs b/parachains/runtimes/assets/statemine/src/xcm_config.rs index 76bc685fd9c..788a0ec5616 100644 --- a/parachains/runtimes/assets/statemine/src/xcm_config.rs +++ b/parachains/runtimes/assets/statemine/src/xcm_config.rs @@ -112,9 +112,9 @@ 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 {parent: 1, X*(Parachain(xyz))} - // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont be accepted here + // 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 outside our consensus with the same `GlobalConsensus(NetworkId)` won't be accepted here StartsWithExplicitGlobalConsensus, ), Balance, @@ -491,9 +491,7 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -use pallet_assets::BenchmarkHelper; -#[cfg(feature = "runtime-benchmarks")] -impl BenchmarkHelper for XcmBenchmarkHelper { +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { fn create_asset_id_parameter(id: u32) -> MultiLocation { MultiLocation { parents: 1, interior: X1(Parachain(id)) } } diff --git a/parachains/runtimes/assets/statemint/src/lib.rs b/parachains/runtimes/assets/statemint/src/lib.rs index 0f5de5b3072..0a78178ba75 100644 --- a/parachains/runtimes/assets/statemint/src/lib.rs +++ b/parachains/runtimes/assets/statemint/src/lib.rs @@ -57,6 +57,9 @@ pub mod constants; mod weights; pub mod xcm_config; +use assets_common::{ + foreign_creators::ForeignCreators, matching::FromSiblingParachain, MultiLocationForAssetId, +}; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -95,8 +98,8 @@ use parachains_common::{ MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; use xcm_config::{ - DotLocation, FellowshipLocation, GovernanceLocation, TrustBackedAssetsConvertedConcreteId, - XcmConfig, XcmOriginToTransactDispatchOrigin, + DotLocation, FellowshipLocation, ForeignAssetsConvertedConcreteId, GovernanceLocation, + TrustBackedAssetsConvertedConcreteId, XcmConfig, XcmOriginToTransactDispatchOrigin, }; #[cfg(any(feature = "std", test))] @@ -108,6 +111,7 @@ use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; use xcm::latest::BodyId; use xcm_executor::XcmExecutor; +use crate::xcm_config::ForeignCreatorsSovereignAccountOf; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; impl_opaque_keys! { @@ -279,6 +283,48 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } +parameter_types! { + // we just reuse the same deposits + pub const ForeignAssetsAssetDeposit: Balance = AssetDeposit::get(); + pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get(); + pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get(); + pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get(); + pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get(); + pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get(); +} + +/// Assets managed by some foreign location. Note: we do not declare a `ForeignAssetsCall` type, as +/// this type is used in proxy definitions. We assume that a foreign location would not want to set +/// an individual, local account as a proxy for the issuance of their assets. This issuance should +/// be managed by the foreign location's governance. +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 Currency = Balances; + type CreateOrigin = ForeignCreators< + (FromSiblingParachain>,), + ForeignCreatorsSovereignAccountOf, + AccountId, + >; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = ForeignAssetsAssetDeposit; + type MetadataDepositBase = ForeignAssetsMetadataDepositBase; + type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte; + type ApprovalDeposit = ForeignAssetsApprovalDeposit; + type StringLimit = ForeignAssetsAssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = weights::pallet_assets::WeightInfo; + type CallbackHandle = (); + type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit; + type RemoveItemsLimit = frame_support::traits::ConstU32<1000>; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = xcm_config::XcmBenchmarkHelper; +} + parameter_types! { // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. pub const DepositBase: Balance = deposit(1, 88); @@ -704,6 +750,7 @@ construct_runtime!( Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, Nfts: pallet_nfts::{Pallet, Call, Storage, Event} = 52, + ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 53, } ); @@ -753,6 +800,7 @@ mod benches { define_benchmarks!( [frame_system, SystemBench::] [pallet_assets, Assets] + [pallet_assets, ForeignAssets] [pallet_balances, Balances] [pallet_multisig, Multisig] [pallet_nfts, Nfts] @@ -928,11 +976,17 @@ impl_runtime_apis! { }, // collect pallet_assets (TrustBackedAssets) convert::<_, _, _, _, TrustBackedAssetsConvertedConcreteId>( - Assets::account_balances(account) + Assets::account_balances(account.clone()) + .iter() + .filter(|(_, balance)| balance > &0) + )?, + // collect pallet_assets (ForeignAssets) + convert::<_, _, _, _, ForeignAssetsConvertedConcreteId>( + ForeignAssets::account_balances(account) .iter() .filter(|(_, balance)| balance > &0) )?, - // collect ... e.g. pallet_assets ForeignAssets + // collect ... e.g. other tokens ].concat().into()) } } diff --git a/parachains/runtimes/assets/statemint/src/xcm_config.rs b/parachains/runtimes/assets/statemint/src/xcm_config.rs index 5960b35d9cf..c045b39286f 100644 --- a/parachains/runtimes/assets/statemint/src/xcm_config.rs +++ b/parachains/runtimes/assets/statemint/src/xcm_config.rs @@ -14,10 +14,13 @@ // limitations under the License. use super::{ - AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ParachainInfo, - ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ForeignAssets, + ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; +use assets_common::matching::{ + FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus, +}; use frame_support::{ match_types, parameter_types, traits::{ConstU32, Contains, Everything, Nothing, PalletInfoAccess}, @@ -36,8 +39,8 @@ use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin, - FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, ParentAsSuperuser, ParentIsPreset, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, NoChecking, ParentAsSuperuser, + ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds, WithComputedOrigin, }; @@ -49,6 +52,7 @@ parameter_types! { pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); @@ -102,8 +106,38 @@ pub type FungiblesTransactor = FungiblesAdapter< // The account to use for tracking teleports. CheckingAccount, >; + +/// `AssetId/Balance` converter for `TrustBackedAssets` +pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< + ( + // 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 outside our consensus with the same `GlobalConsensus(NetworkId)` won't be accepted here + StartsWithExplicitGlobalConsensus, + ), + Balance, +>; + +/// Means for transacting foreign assets from different global consensus. +pub type ForeignFungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + 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: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont need to check teleports here. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// Means for transacting assets on this chain. -pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); +pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can @@ -205,6 +239,7 @@ impl Contains for SafeCallFilter { pallet_assets::Call::thaw_asset { .. } | pallet_assets::Call::transfer_ownership { .. } | pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | pallet_assets::Call::clear_metadata { .. } | pallet_assets::Call::force_clear_metadata { .. } | pallet_assets::Call::force_asset_status { .. } | @@ -214,7 +249,35 @@ impl Contains for SafeCallFilter { pallet_assets::Call::transfer_approved { .. } | pallet_assets::Call::touch { .. } | pallet_assets::Call::refund { .. }, - ) | RuntimeCall::Nfts( + ) | RuntimeCall::ForeignAssets( + pallet_assets::Call::create { .. } | + pallet_assets::Call::force_create { .. } | + pallet_assets::Call::start_destroy { .. } | + pallet_assets::Call::destroy_accounts { .. } | + pallet_assets::Call::destroy_approvals { .. } | + pallet_assets::Call::finish_destroy { .. } | + pallet_assets::Call::mint { .. } | + pallet_assets::Call::burn { .. } | + pallet_assets::Call::transfer { .. } | + pallet_assets::Call::transfer_keep_alive { .. } | + pallet_assets::Call::force_transfer { .. } | + pallet_assets::Call::freeze { .. } | + pallet_assets::Call::thaw { .. } | + pallet_assets::Call::freeze_asset { .. } | + pallet_assets::Call::thaw_asset { .. } | + pallet_assets::Call::transfer_ownership { .. } | + pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | + pallet_assets::Call::clear_metadata { .. } | + pallet_assets::Call::force_clear_metadata { .. } | + pallet_assets::Call::force_asset_status { .. } | + pallet_assets::Call::approve_transfer { .. } | + pallet_assets::Call::cancel_approval { .. } | + pallet_assets::Call::force_cancel_approval { .. } | + pallet_assets::Call::transfer_approved { .. } | + pallet_assets::Call::touch { .. } | + pallet_assets::Call::refund { .. }, + ) | RuntimeCall::Nfts( pallet_nfts::Call::create { .. } | pallet_nfts::Call::force_create { .. } | pallet_nfts::Call::destroy { .. } | @@ -321,7 +384,13 @@ impl xcm_executor::Config for XcmConfig { // Statemint acting _as_ a reserve location for DOT and assets created under `pallet-assets`. // For DOT, users must use teleport where allowed (e.g. with the Relay Chain). type IsReserve = (); - type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of DOT + // We allow: + // - teleportation of DOT + // - teleportation of sibling parachain's assets (as ForeignCreators) + type IsTeleporter = ( + NativeAsset, + IsForeignConcreteAsset>>, + ); type UniversalLocation = UniversalLocation; type Barrier = Barrier; type Weigher = WeightInfoBounds< @@ -415,3 +484,18 @@ impl cumulus_pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type XcmExecutor = XcmExecutor; } + +pub type ForeignCreatorsSovereignAccountOf = ( + SiblingParachainConvertsVia, + AccountId32Aliases, + ParentIsPreset, +); + +/// 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)) } + } +} diff --git a/parachains/runtimes/assets/statemint/tests/tests.rs b/parachains/runtimes/assets/statemint/tests/tests.rs index 82491fa27f5..bb4d52a1452 100644 --- a/parachains/runtimes/assets/statemint/tests/tests.rs +++ b/parachains/runtimes/assets/statemint/tests/tests.rs @@ -1,5 +1,5 @@ use asset_test_utils::{CollatorSessionKeys, ExtBuilder, RuntimeHelper}; -use codec::Decode; +use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ assert_noop, assert_ok, @@ -11,17 +11,18 @@ use parachains_common::{ }; use statemint_runtime::xcm_config::{ AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation, - TrustBackedAssetsPalletLocation, + ForeignCreatorsSovereignAccountOf, TrustBackedAssetsPalletLocation, XcmConfig, }; pub use statemint_runtime::{ - constants::fee::WeightToFee, xcm_config::XcmConfig, AssetDeposit, Assets, Balances, - ExistentialDeposit, ParachainSystem, Runtime, RuntimeEvent, SessionKeys, System, - TrustBackedAssetsInstance, + constants::fee::WeightToFee, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, + ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, + RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance, }; use xcm::latest::prelude::*; -use xcm_executor::traits::{Convert, WeightTrader}; +use xcm_executor::traits::{Convert, Identity, JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; +const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = assets_common::AssetIdForTrustBackedAssetsConvert; @@ -390,9 +391,15 @@ 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)) }; // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); + assert_eq!( + ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + 0 + ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() @@ -423,18 +430,40 @@ fn test_assets_balances_api_works() { minimum_asset_balance )); + // create foreign asset + let foreign_asset_minimum_asset_balance = 3333333_u128; + assert_ok!(ForeignAssets::force_create( + RuntimeHelper::::root_origin(), + foreign_asset_id_multilocation, + AccountId::from(SOME_ASSET_ADMIN).into(), + false, + foreign_asset_minimum_asset_balance + )); + + // 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, + AccountId::from(ALICE).into(), + 6 * foreign_asset_minimum_asset_balance + )); + // check after assert_eq!( Assets::balance(local_asset_id, AccountId::from(ALICE)), minimum_asset_balance ); + assert_eq!( + ForeignAssets::balance(foreign_asset_id_multilocation, 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)) .unwrap() .try_into() .unwrap(); - assert_eq!(result.len(), 2); + assert_eq!(result.len(), 3); // check currency assert!(result.inner().iter().any(|asset| asset.eq( @@ -449,6 +478,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ) .into()))); + // check foreign asset + assert!(result.inner().iter().any(|asset| asset.eq(&( + Identity::reverse_ref(foreign_asset_id_multilocation).unwrap(), + 6 * foreign_asset_minimum_asset_balance + ) + .into()))); }); } @@ -475,6 +510,34 @@ asset_test_utils::include_teleports_for_native_asset_works!( 1000 ); +asset_test_utils::include_teleports_for_foreign_assets_works!( + Runtime, + XcmConfig, + CheckingAccount, + WeightToFee, + ParachainSystem, + ForeignCreatorsSovereignAccountOf, + ForeignAssetsInstance, + asset_test_utils::CollatorSessionKeys::new( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) } + ), + ExistentialDeposit::get(), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event), + _ => None, + } + }), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::XcmpQueue(event)) => Some(event), + _ => None, + } + }) +); + asset_test_utils::include_asset_transactor_transfer_with_local_consensus_currency_works!( Runtime, XcmConfig, @@ -482,14 +545,16 @@ asset_test_utils::include_asset_transactor_transfer_with_local_consensus_currenc ExistentialDeposit::get(), Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); + assert!(ForeignAssets::asset_ids().collect::>().is_empty()); }), Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); + assert!(ForeignAssets::asset_ids().collect::>().is_empty()); }) ); asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_works!( - asset_transactor_transfer_with_pallet_assets_instance_works, + asset_transactor_transfer_with_trust_backed_assets_works, Runtime, XcmConfig, TrustBackedAssetsInstance, @@ -498,6 +563,66 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ collator_session_keys(), ExistentialDeposit::get(), 12345, - Box::new(|| {}), - Box::new(|| {}) + Box::new(|| { + assert!(ForeignAssets::asset_ids().collect::>().is_empty()); + }), + Box::new(|| { + assert!(ForeignAssets::asset_ids().collect::>().is_empty()); + }) +); + +asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_works!( + asset_transactor_transfer_with_foreign_assets_works, + Runtime, + XcmConfig, + ForeignAssetsInstance, + MultiLocation, + JustTry, + asset_test_utils::CollatorSessionKeys::new( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) } + ), + ExistentialDeposit::get(), + MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + Box::new(|| { + assert!(Assets::asset_ids().collect::>().is_empty()); + }), + Box::new(|| { + assert!(Assets::asset_ids().collect::>().is_empty()); + }) +); + +asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_parachain_assets_works!( + Runtime, + XcmConfig, + WeightToFee, + ForeignCreatorsSovereignAccountOf, + ForeignAssetsInstance, + MultiLocation, + JustTry, + asset_test_utils::CollatorSessionKeys::new( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) } + ), + ExistentialDeposit::get(), + AssetDeposit::get(), + MetadataDepositBase::get(), + MetadataDepositPerByte::get(), + Box::new(|pallet_asset_call| RuntimeCall::ForeignAssets(pallet_asset_call).encode()), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::ForeignAssets(pallet_asset_event)) => Some(pallet_asset_event), + _ => None, + } + }), + Box::new(|| { + assert!(Assets::asset_ids().collect::>().is_empty()); + assert!(ForeignAssets::asset_ids().collect::>().is_empty()); + }), + Box::new(|| { + assert!(Assets::asset_ids().collect::>().is_empty()); + assert_eq!(ForeignAssets::asset_ids().collect::>().len(), 1); + }) ); diff --git a/parachains/runtimes/assets/westmint/src/xcm_config.rs b/parachains/runtimes/assets/westmint/src/xcm_config.rs index c802e99e26b..92aad0fbbe3 100644 --- a/parachains/runtimes/assets/westmint/src/xcm_config.rs +++ b/parachains/runtimes/assets/westmint/src/xcm_config.rs @@ -112,7 +112,7 @@ 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 {parent: 1, X*(Parachain(xyz))} + // - foreign assets from our consensus should be: `MultiLocation {parents: 1, X*(Parachain(xyz), ..)} // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont be accepted here StartsWithExplicitGlobalConsensus, ), @@ -487,9 +487,7 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -use pallet_assets::BenchmarkHelper; -#[cfg(feature = "runtime-benchmarks")] -impl BenchmarkHelper for XcmBenchmarkHelper { +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { fn create_asset_id_parameter(id: u32) -> MultiLocation { MultiLocation { parents: 1, interior: X1(Parachain(id)) } }