diff --git a/cumulus/Cargo.lock b/cumulus/Cargo.lock index 2ad5b4bf6b..600781d654 100644 --- a/cumulus/Cargo.lock +++ b/cumulus/Cargo.lock @@ -6109,6 +6109,8 @@ dependencies = [ "sp-runtime", "sp-std", "substrate-wasm-builder", + "xcm", + "xcm-executor", ] [[package]] @@ -8367,6 +8369,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-xcm", "parachain-info", + "parachains-common", "parity-scale-codec", "polkadot-parachain", "scale-info", diff --git a/cumulus/polkadot-parachains/parachains-common/Cargo.toml b/cumulus/polkadot-parachains/parachains-common/Cargo.toml index 25227bb454..5c6a66b600 100644 --- a/cumulus/polkadot-parachains/parachains-common/Cargo.toml +++ b/cumulus/polkadot-parachains/parachains-common/Cargo.toml @@ -28,6 +28,8 @@ node-primitives = { git = 'https://github.com/paritytech/substrate', branch = "m # Polkadot dependencies polkadot-runtime-common = { git = 'https://github.com/paritytech/polkadot', branch = "master", default-features = false } polkadot-primitives = { git = 'https://github.com/paritytech/polkadot', branch = "master", default-features = false } +xcm = { git = 'https://github.com/paritytech/polkadot', branch = "master", default-features = false } +xcm-executor = { git = 'https://github.com/paritytech/polkadot', branch = "master", default-features = false } # Local dependencies pallet-collator-selection = { path = '../../pallets/collator-selection', default-features = false } diff --git a/cumulus/polkadot-parachains/parachains-common/src/impls.rs b/cumulus/polkadot-parachains/parachains-common/src/impls.rs index 303f4fae59..84fdbdd4f4 100644 --- a/cumulus/polkadot-parachains/parachains-common/src/impls.rs +++ b/cumulus/polkadot-parachains/parachains-common/src/impls.rs @@ -16,7 +16,11 @@ //! Auxillary struct/enums for parachain runtimes. //! Taken from polkadot/runtime/common (at a21cd64) and adapted for parachains. -use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; +use frame_support::traits::{fungibles, Contains, Currency, Get, Imbalance, OnUnbalanced}; +use sp_runtime::traits::Zero; +use sp_std::marker::PhantomData; +use xcm::latest::{AssetId, Fungibility::Fungible, MultiAsset, MultiLocation}; +use xcm_executor::traits::FilterAssetLocation; pub type NegativeImbalance = as Currency< ::AccountId, @@ -42,6 +46,7 @@ where } } +/// Merge the fees into one item and pass them on to the staking pot. pub struct DealWithFees(sp_std::marker::PhantomData); impl OnUnbalanced> for DealWithFees where @@ -60,6 +65,29 @@ where } } +/// Allow checking in assets that have issuance > 0. +pub struct NonZeroIssuance(PhantomData<(AccountId, Assets)>); +impl Contains<>::AssetId> + for NonZeroIssuance +where + Assets: fungibles::Inspect, +{ + fn contains(id: &>::AssetId) -> bool { + !Assets::total_issuance(*id).is_zero() + } +} + +/// Asset filter that allows all assets from a certain location. +pub struct AssetsFrom(PhantomData); +impl> FilterAssetLocation for AssetsFrom { + fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool { + let loc = T::get(); + &loc == origin && + matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + if asset_loc.match_and_split(&loc).is_some()) + } +} + #[cfg(test)] mod tests { use super::*; @@ -77,6 +105,7 @@ mod tests { traits::{BlakeTwo256, IdentityLookup}, Perbill, }; + use xcm::prelude::*; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -207,4 +236,24 @@ mod tests { assert_eq!(Balances::free_balance(CollatorSelection::account_id()), 30); }); } + + #[test] + fn assets_from_filters_correctly() { + parameter_types! { + pub SomeSiblingParachain: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); + } + + let asset_location = SomeSiblingParachain::get() + .clone() + .pushed_with_interior(GeneralIndex(42)) + .expect("multilocation will only have 2 junctions; qed"); + let asset = MultiAsset { id: Concrete(asset_location), fun: 1_000_000.into() }; + assert!( + AssetsFrom::::filter_asset_location( + &asset, + &SomeSiblingParachain::get() + ), + "AssetsFrom should allow assets from any of its interior locations" + ); + } } diff --git a/cumulus/polkadot-parachains/parachains-common/src/lib.rs b/cumulus/polkadot-parachains/parachains-common/src/lib.rs index a9462f0009..23f90e55e5 100644 --- a/cumulus/polkadot-parachains/parachains-common/src/lib.rs +++ b/cumulus/polkadot-parachains/parachains-common/src/lib.rs @@ -51,6 +51,9 @@ mod types { // Aura consensus authority. pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; + + // Id used for identifying assets. + pub type AssetId = u32; } /// Common constants of parachains. diff --git a/cumulus/polkadot-parachains/rococo/Cargo.toml b/cumulus/polkadot-parachains/rococo/Cargo.toml index 5916989bf0..59d454ed75 100644 --- a/cumulus/polkadot-parachains/rococo/Cargo.toml +++ b/cumulus/polkadot-parachains/rococo/Cargo.toml @@ -39,6 +39,8 @@ pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", pallet-aura = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" } +parachains-common = { path = "../parachains-common", default-features = false } + # Cumulus dependencies cumulus-pallet-aura-ext = { path = "../../pallets/aura-ext", default-features = false } cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system", default-features = false } diff --git a/cumulus/polkadot-parachains/rococo/src/lib.rs b/cumulus/polkadot-parachains/rococo/src/lib.rs index daeff9699b..55e36b9252 100644 --- a/cumulus/polkadot-parachains/rococo/src/lib.rs +++ b/cumulus/polkadot-parachains/rococo/src/lib.rs @@ -45,7 +45,10 @@ pub use frame_support::{ }, StorageValue, }; -use frame_system::limits::{BlockLength, BlockWeights}; +use frame_system::{ + limits::{BlockLength, BlockWeights}, + EnsureOneOf, EnsureRoot, +}; pub use pallet_balances::Call as BalancesCall; pub use pallet_timestamp::Call as TimestampCall; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -53,6 +56,13 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; +use parachains_common::{ + impls::{AssetsFrom, NonZeroIssuance}, + AssetId, +}; +use xcm_builder::{AsPrefixedGeneralIndex, ConvertedConcreteAssetId, FungiblesAdapter}; +use xcm_executor::traits::JustTry; + // XCM imports use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough}; use polkadot_parachain::primitives::Sibling; @@ -258,6 +268,7 @@ parameter_types! { pub const RococoNetwork: NetworkId = NetworkId::Polkadot; pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); pub Ancestry: MultiLocation = 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 @@ -273,7 +284,7 @@ pub type LocationToAccountId = ( ); /// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< +pub type CurrencyTransactor = CurrencyAdapter< // Use this currency: Balances, // Use this currency when it is a fungible asset matching the given location or name: @@ -286,6 +297,30 @@ pub type LocalAssetTransactor = CurrencyAdapter< (), >; +/// Means for transacting assets besides the native currency on this chain. +pub type FungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + Assets, + // Use this currency when it is a fungible asset matching the given location or name: + ConvertedConcreteAssetId< + AssetId, + u64, + AsPrefixedGeneralIndex, + JustTry, + >, + // 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 only want to allow teleports of known assets. We use non-zero issuance as an indication + // that this asset is known. + NonZeroIssuance, + // The account to use for tracking teleports. + CheckingAccount, +>; +/// Means for transacting assets on this chain. +pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); + /// 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 /// biases the kind of local `Origin` it will become. @@ -324,22 +359,34 @@ match_type! { MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } }; } +match_type! { + pub type Statemint: impl Contains = { + MultiLocation { parents: 1, interior: X1(Parachain(1000)) } + }; +} pub type Barrier = ( TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, // ^^^ Parent & its unit plurality gets free execution + AllowUnpaidExecutionFrom, ); +parameter_types! { + pub StatemintLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); +} + +pub type Reserves = (NativeAsset, AssetsFrom); + pub struct XcmConfig; impl Config for XcmConfig { type Call = Call; type XcmSender = XcmRouter; // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; + type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = NativeAsset; + type IsReserve = Reserves; type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of ROC type LocationInverter = LocationInverter; type Barrier = Barrier; @@ -416,12 +463,16 @@ parameter_types! { } /// A majority of the Unit body from Rococo over XCM is our required administration origin. -pub type AdminOrigin = EnsureXcm>; +pub type AdminOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + EnsureXcm>, +>; impl pallet_assets::Config for Runtime { type Event = Event; type Balance = u64; - type AssetId = u32; + type AssetId = AssetId; type Currency = Balances; type ForceOrigin = AdminOrigin; type AssetDeposit = AssetDeposit; diff --git a/cumulus/polkadot-parachains/statemine/src/lib.rs b/cumulus/polkadot-parachains/statemine/src/lib.rs index 33f30f2a6d..6b184d345d 100644 --- a/cumulus/polkadot-parachains/statemine/src/lib.rs +++ b/cumulus/polkadot-parachains/statemine/src/lib.rs @@ -31,7 +31,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, + ApplyExtrinsicResult, Perbill, }; use sp_std::prelude::*; @@ -56,11 +56,10 @@ use frame_system::{ }; pub use parachains_common as common; use parachains_common::{ - impls::DealWithFees, opaque, AccountId, AuraId, Balance, BlockNumber, Hash, Header, Index, - Signature, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, - SLOT_DURATION, + impls::{DealWithFees, NonZeroIssuance}, + opaque, AccountId, AssetId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature, + AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; -use sp_runtime::Perbill; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -71,13 +70,14 @@ use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate}; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter, EnsureXcmOrigin, + FixedWeightBounds, FungiblesAdapter, IsConcrete, LocationInverter, NativeAsset, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, }; -use xcm_executor::{Config, XcmExecutor}; +use xcm_executor::{traits::JustTry, Config, XcmExecutor}; impl_opaque_keys! { pub struct SessionKeys { @@ -238,7 +238,7 @@ pub type AssetsForceOrigin = EnsureOneOf< impl pallet_assets::Config for Runtime { type Event = Event; type Balance = Balance; - type AssetId = u32; + type AssetId = AssetId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = AssetDeposit; @@ -465,6 +465,8 @@ parameter_types! { pub const RelayNetwork: NetworkId = NetworkId::Kusama; pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub const Local: MultiLocation = Here.into(); + pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used @@ -479,20 +481,44 @@ pub type LocationToAccountId = ( AccountId32Aliases, ); -/// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< +/// Means for transacting the native currency on this chain. +pub type CurrencyTransactor = CurrencyAdapter< // Use this currency: 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: + // 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 don't track any teleports. + // We don't track any teleports of `Balances`. (), >; +/// Means for transacting assets besides the native currency on this chain. +pub type FungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + Assets, + // Use this currency when it is a fungible asset matching the given location or name: + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + // 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 only want to allow teleports of known assets. We use non-zero issuance as an indication + // that this asset is known. + NonZeroIssuance, + // The account to use for tracking teleports. + CheckingAccount, +>; +/// Means for transacting assets on this chain. +pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); + /// 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 /// biases the kind of local `Origin` it will become. @@ -542,7 +568,7 @@ impl Config for XcmConfig { type Call = Call; type XcmSender = XcmRouter; // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; + type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; type IsReserve = NativeAsset; type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of KSM diff --git a/cumulus/polkadot-parachains/statemint/src/lib.rs b/cumulus/polkadot-parachains/statemint/src/lib.rs index bfd20fe1ea..1494da84f4 100644 --- a/cumulus/polkadot-parachains/statemint/src/lib.rs +++ b/cumulus/polkadot-parachains/statemint/src/lib.rs @@ -31,7 +31,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, + ApplyExtrinsicResult, Perbill, }; use sp_std::prelude::*; @@ -56,11 +56,10 @@ use frame_system::{ }; pub use parachains_common as common; use parachains_common::{ - impls::DealWithFees, opaque, AccountId, AuraId, Balance, BlockNumber, Hash, Header, Index, - Signature, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, - SLOT_DURATION, + impls::{DealWithFees, NonZeroIssuance}, + opaque, AccountId, AssetId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature, + AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; -use sp_runtime::Perbill; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -71,13 +70,14 @@ use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate}; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter, EnsureXcmOrigin, + FixedWeightBounds, FungiblesAdapter, IsConcrete, LocationInverter, NativeAsset, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, }; -use xcm_executor::{Config, XcmExecutor}; +use xcm_executor::{traits::JustTry, Config, XcmExecutor}; impl_opaque_keys! { pub struct SessionKeys { @@ -233,7 +233,7 @@ pub type AssetsForceOrigin = EnsureOneOf< impl pallet_assets::Config for Runtime { type Event = Event; type Balance = Balance; - type AssetId = u32; + type AssetId = AssetId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = AssetDeposit; @@ -430,6 +430,8 @@ parameter_types! { pub const RelayNetwork: NetworkId = NetworkId::Polkadot; pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub const Local: MultiLocation = Here.into(); + pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used @@ -444,20 +446,44 @@ pub type LocationToAccountId = ( AccountId32Aliases, ); -/// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< +/// Means for transacting the native currency on this chain. +pub type CurrencyTransactor = CurrencyAdapter< // Use this currency: 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: + // 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 don't track any teleports. + // We don't track any teleports of `Balances`. (), >; +/// Means for transacting assets besides the native currency on this chain. +pub type FungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + Assets, + // Use this currency when it is a fungible asset matching the given location or name: + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + // 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 only want to allow teleports of known assets. We use non-zero issuance as an indication + // that this asset is known. + NonZeroIssuance, + // The account to use for tracking teleports. + CheckingAccount, +>; +/// Means for transacting assets on this chain. +pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); + /// 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 /// biases the kind of local `Origin` it will become. @@ -506,8 +532,7 @@ pub struct XcmConfig; impl Config for XcmConfig { type Call = Call; type XcmSender = XcmRouter; - // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; + type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; type IsReserve = NativeAsset; type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of DOT diff --git a/cumulus/polkadot-parachains/westmint/src/lib.rs b/cumulus/polkadot-parachains/westmint/src/lib.rs index d4fd8199da..9767ac1694 100644 --- a/cumulus/polkadot-parachains/westmint/src/lib.rs +++ b/cumulus/polkadot-parachains/westmint/src/lib.rs @@ -31,7 +31,7 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, + ApplyExtrinsicResult, Perbill, }; use sp_std::prelude::*; @@ -56,11 +56,10 @@ use frame_system::{ }; pub use parachains_common as common; use parachains_common::{ - impls::DealWithFees, opaque, AccountId, AuraId, Balance, BlockNumber, Hash, Header, Index, - Signature, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, - SLOT_DURATION, + impls::{DealWithFees, NonZeroIssuance}, + opaque, AccountId, AssetId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature, + AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; -use sp_runtime::Perbill; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -71,13 +70,14 @@ use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::{BlockHashCount, RocksDbWeight, SlowAdjustingFeeUpdate}; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + AsPrefixedGeneralIndex, ConvertedConcreteAssetId, CurrencyAdapter, EnsureXcmOrigin, + FixedWeightBounds, FungiblesAdapter, IsConcrete, LocationInverter, NativeAsset, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, }; -use xcm_executor::{Config, XcmExecutor}; +use xcm_executor::{traits::JustTry, Config, XcmExecutor}; impl_opaque_keys! { pub struct SessionKeys { @@ -232,7 +232,7 @@ parameter_types! { impl pallet_assets::Config for Runtime { type Event = Event; type Balance = Balance; - type AssetId = u32; + type AssetId = AssetId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = AssetDeposit; @@ -429,6 +429,8 @@ parameter_types! { pub RelayNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec()); pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub const Local: MultiLocation = Here.into(); + pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used @@ -443,20 +445,44 @@ pub type LocationToAccountId = ( AccountId32Aliases, ); -/// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< +/// Means for transacting the native currency on this chain. +pub type CurrencyTransactor = CurrencyAdapter< // Use this currency: 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: + // 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 don't track any teleports. + // We don't track any teleports of `Balances`. (), >; +/// Means for transacting assets besides the native currency on this chain. +pub type FungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + Assets, + // Use this currency when it is a fungible asset matching the given location or name: + ConvertedConcreteAssetId< + AssetId, + Balance, + AsPrefixedGeneralIndex, + JustTry, + >, + // 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 only want to allow teleports of known assets. We use non-zero issuance as an indication + // that this asset is known. + NonZeroIssuance, + // The account to use for tracking teleports. + CheckingAccount, +>; +/// Means for transacting assets on this chain. +pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); + /// 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 /// biases the kind of local `Origin` it will become. @@ -504,8 +530,7 @@ pub struct XcmConfig; impl Config for XcmConfig { type Call = Call; type XcmSender = XcmRouter; - // How to withdraw and deposit an asset. - type AssetTransactor = LocalAssetTransactor; + type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; type IsReserve = NativeAsset; type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of WND