diff --git a/Cargo.lock b/Cargo.lock index 50e6128a7f0a..0877a5628de6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4368,6 +4368,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-weights", + "xcm", ] [[package]] @@ -8405,6 +8406,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-weights", + "xcm", ] [[package]] @@ -9779,6 +9781,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-weights", + "xcm", ] [[package]] @@ -14685,6 +14688,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-weights", + "xcm", ] [[package]] diff --git a/runtime/kusama/constants/Cargo.toml b/runtime/kusama/constants/Cargo.toml index 293c91bbd543..6f700111e2b3 100644 --- a/runtime/kusama/constants/Cargo.toml +++ b/runtime/kusama/constants/Cargo.toml @@ -15,6 +15,8 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", default-features sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +xcm = { package = "xcm", path = "../../../xcm", default-features = false } + [features] default = ["std"] std = [ @@ -23,5 +25,6 @@ std = [ "runtime-common/std", "sp-core/std", "sp-runtime/std", - "sp-weights/std" + "sp-weights/std", + "xcm/std", ] diff --git a/runtime/kusama/constants/src/lib.rs b/runtime/kusama/constants/src/lib.rs index 78f96b351065..3edac3b302ad 100644 --- a/runtime/kusama/constants/src/lib.rs +++ b/runtime/kusama/constants/src/lib.rs @@ -97,6 +97,24 @@ pub mod fee { } } +/// System Parachains. +pub mod system_parachain { + use xcm::latest::prelude::*; + + /// Network's Asset Hub parachain ID. + pub const ASSET_HUB_ID: u32 = 1000; + /// Encointer parachain ID. + pub const ENCOINTER_ID: u32 = 1001; + /// BridgeHub parachain ID. + pub const BRIDGE_HUB_ID: u32 = 1002; + + frame_support::match_types! { + pub type SystemParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(ASSET_HUB_ID | ENCOINTER_ID | BRIDGE_HUB_ID)) } + }; + } +} + #[cfg(test)] mod tests { use super::{ diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 0248b02e12f6..6c4ba35c665d 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -2106,7 +2106,7 @@ sp_api::impl_runtime_apis! { use frame_benchmarking::baseline::Pallet as Baseline; use xcm::latest::prelude::*; use xcm_config::{ - LocalCheckAccount, SovereignAccountOf, Statemine, TokenLocation, XcmConfig, + LocalCheckAccount, SovereignAccountOf, AssetHub, TokenLocation, XcmConfig, }; impl pallet_session_benchmarking::Config for Runtime {} @@ -2121,7 +2121,7 @@ sp_api::impl_runtime_apis! { type XcmConfig = XcmConfig; type AccountIdConverter = SovereignAccountOf; fn valid_destination() -> Result { - Ok(Statemine::get()) + Ok(AssetHub::get()) } fn worst_case_holding(_depositable_count: u32) -> MultiAssets { // Kusama only knows about KSM. @@ -2134,7 +2134,7 @@ sp_api::impl_runtime_apis! { parameter_types! { pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( - Statemine::get(), + AssetHub::get(), MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, )); pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; @@ -2173,15 +2173,15 @@ sp_api::impl_runtime_apis! { } fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { - Ok((Statemine::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } fn subscribe_origin() -> Result { - Ok(Statemine::get()) + Ok(AssetHub::get()) } fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let origin = Statemine::get(); + let origin = AssetHub::get(); let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); let ticket = MultiLocation { parents: 0, interior: Here }; Ok((origin, ticket, assets)) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 5725f54eddd5..df58f9196656 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ parachains_origin, AccountId, AllPalletsWithSystem, Balances, Dmp, Fellows, ParaId, Runtime, - RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, TransactionByteFee, WeightToFee, - XcmPallet, + RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, TransactionByteFee, Treasury, + WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -27,7 +27,7 @@ use frame_support::{ weights::Weight, }; use frame_system::EnsureRoot; -use kusama_runtime_constants::currency::CENTS; +use kusama_runtime_constants::{currency::CENTS, system_parachain::*}; use runtime_common::{ crowdloan, paras_registrar, xcm_sender::{ChildParachainRouter, ExponentialPrice}, @@ -42,7 +42,7 @@ use xcm_builder::{ CurrencyAdapter as XcmCurrencyAdapter, IsChildSystemParachain, IsConcrete, MintLocation, OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, - WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, + WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeesToAccount, }; use xcm_executor::traits::WithOriginFilter; @@ -61,6 +61,8 @@ parameter_types! { pub CheckAccount: AccountId = XcmPallet::check_account(); /// The check account that is allowed to mint assets locally. pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); + /// The treasury account where XCM fees would be sent to. + pub TreasuryAccount: Option = Some(Treasury::account_id()); } /// The canonical means of converting a `MultiLocation` into an `AccountId`, used when we want to @@ -126,14 +128,19 @@ pub type XcmRouter = WithUniqueTopic<( parameter_types! { pub const Ksm: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const Statemine: MultiLocation = Parachain(1000).into_location(); - pub const Encointer: MultiLocation = Parachain(1001).into_location(); - pub const KsmForStatemine: (MultiAssetFilter, MultiLocation) = (Ksm::get(), Statemine::get()); + pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); + pub const Encointer: MultiLocation = Parachain(ENCOINTER_ID).into_location(); + pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); + pub const KsmForAssetHub: (MultiAssetFilter, MultiLocation) = (Ksm::get(), AssetHub::get()); pub const KsmForEncointer: (MultiAssetFilter, MultiLocation) = (Ksm::get(), Encointer::get()); + pub const KsmForBridgeHub: (MultiAssetFilter, MultiLocation) = (Ksm::get(), BridgeHub::get()); pub const MaxAssetsIntoHolding: u32 = 64; } -pub type TrustedTeleporters = - (xcm_builder::Case, xcm_builder::Case); +pub type TrustedTeleporters = ( + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, +); match_types! { pub type OnlyParachains: impl Contains = { @@ -339,7 +346,7 @@ impl xcm_executor::Config for XcmConfig { type SubscriptionService = XcmPallet; type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type FeeManager = (); + type FeeManager = XcmFeesToAccount; // No bridges yet... type MessageExporter = (); type UniversalAliases = Nothing; @@ -357,7 +364,7 @@ parameter_types! { #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = Some(Parachain(1000).into()); + pub ReachableDest: Option = Some(Parachain(ASSET_HUB_ID).into()); } /// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior diff --git a/runtime/polkadot/constants/Cargo.toml b/runtime/polkadot/constants/Cargo.toml index 42a9c685ea82..bbc4d23c63ef 100644 --- a/runtime/polkadot/constants/Cargo.toml +++ b/runtime/polkadot/constants/Cargo.toml @@ -15,6 +15,8 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", default-features sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +xcm = { package = "xcm", path = "../../../xcm", default-features = false } + [features] default = ["std"] std = [ @@ -23,5 +25,6 @@ std = [ "runtime-common/std", "sp-core/std", "sp-runtime/std", - "sp-weights/std" + "sp-weights/std", + "xcm/std", ] diff --git a/runtime/polkadot/constants/src/lib.rs b/runtime/polkadot/constants/src/lib.rs index 304d86d1dd7c..9c0df0bba39f 100644 --- a/runtime/polkadot/constants/src/lib.rs +++ b/runtime/polkadot/constants/src/lib.rs @@ -113,10 +113,20 @@ pub mod xcm { /// System Parachains. pub mod system_parachain { - /// Statemint parachain ID. - pub const STATEMINT_ID: u32 = 1000; + use xcm::latest::prelude::*; + + /// Network's Asset Hub parachain ID. + pub const ASSET_HUB_ID: u32 = 1000; /// Collectives parachain ID. pub const COLLECTIVES_ID: u32 = 1001; + /// BridgeHub parachain ID. + pub const BRIDGE_HUB_ID: u32 = 1002; + + frame_support::match_types! { + pub type SystemParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(ASSET_HUB_ID | COLLECTIVES_ID | BRIDGE_HUB_ID)) } + }; + } } #[cfg(test)] diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index fbf896cdedc5..5f7d4dec8f19 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -2062,7 +2062,7 @@ sp_api::impl_runtime_apis! { use frame_system_benchmarking::Pallet as SystemBench; use frame_benchmarking::baseline::Pallet as Baseline; use xcm::latest::prelude::*; - use xcm_config::{XcmConfig, StatemintLocation, TokenLocation, LocalCheckAccount, SovereignAccountOf}; + use xcm_config::{XcmConfig, AssetHubLocation, TokenLocation, LocalCheckAccount, SovereignAccountOf}; impl pallet_session_benchmarking::Config for Runtime {} impl pallet_offences_benchmarking::Config for Runtime {} @@ -2080,7 +2080,7 @@ sp_api::impl_runtime_apis! { type XcmConfig = XcmConfig; type AccountIdConverter = SovereignAccountOf; fn valid_destination() -> Result { - Ok(StatemintLocation::get()) + Ok(AssetHubLocation::get()) } fn worst_case_holding(_depositable_count: u32) -> MultiAssets { // Polkadot only knows about DOT @@ -2090,7 +2090,7 @@ sp_api::impl_runtime_apis! { parameter_types! { pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( - StatemintLocation::get(), + AssetHubLocation::get(), MultiAsset { id: Concrete(TokenLocation::get()), fun: Fungible(1 * UNITS) } )); pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; @@ -2129,15 +2129,15 @@ sp_api::impl_runtime_apis! { } fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { - Ok((StatemintLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + Ok((AssetHubLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } fn subscribe_origin() -> Result { - Ok(StatemintLocation::get()) + Ok(AssetHubLocation::get()) } fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let origin = StatemintLocation::get(); + let origin = AssetHubLocation::get(); let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); let ticket = MultiLocation { parents: 0, interior: Here }; Ok((origin, ticket, assets)) diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index faae2e1d2619..9481a971ff90 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, FellowshipAdmin, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, - TransactionByteFee, WeightToFee, XcmPallet, + TransactionByteFee, Treasury, WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -44,7 +44,7 @@ use xcm_builder::{ ChildParachainAsNative, ChildParachainConvertsVia, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation, OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, - WeightInfoBounds, WithComputedOrigin, + WeightInfoBounds, WithComputedOrigin, XcmFeesToAccount, }; use xcm_executor::traits::WithOriginFilter; @@ -61,6 +61,8 @@ parameter_types! { pub CheckAccount: AccountId = XcmPallet::check_account(); /// The Checking Account along with the indication that the local chain is able to mint tokens. pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); + /// The treasury account where XCM fees would be sent to. + pub TreasuryAccount: Option = Some(Treasury::account_id()); } /// The canonical means of converting a `MultiLocation` into an `AccountId`, used when we want to @@ -131,16 +133,21 @@ pub type XcmRouter = ( parameter_types! { pub const Dot: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const StatemintLocation: MultiLocation = Parachain(STATEMINT_ID).into_location(); - pub const DotForStatemint: (MultiAssetFilter, MultiLocation) = (Dot::get(), StatemintLocation::get()); + pub const AssetHubLocation: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); + pub const DotForAssetHub: (MultiAssetFilter, MultiLocation) = (Dot::get(), AssetHubLocation::get()); pub const CollectivesLocation: MultiLocation = Parachain(COLLECTIVES_ID).into_location(); pub const DotForCollectives: (MultiAssetFilter, MultiLocation) = (Dot::get(), CollectivesLocation::get()); + pub const DotForBridgeHub: (MultiAssetFilter, MultiLocation) = (Dot::get(), Parachain(BRIDGE_HUB_ID).into_location()); pub const MaxAssetsIntoHolding: u32 = 64; } -/// Polkadot Relay recognizes/respects the Statemint chain as a teleporter. -pub type TrustedTeleporters = - (xcm_builder::Case, xcm_builder::Case); +/// Polkadot Relay recognizes/respects the Asset Hub, Collectives and Bridge hub chains as a +/// teleporter. +pub type TrustedTeleporters = ( + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, +); match_types! { pub type OnlyParachains: impl Contains = { @@ -340,7 +347,7 @@ impl xcm_executor::Config for XcmConfig { type SubscriptionService = XcmPallet; type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type FeeManager = (); + type FeeManager = XcmFeesToAccount; // No bridges yet... type MessageExporter = (); type UniversalAliases = Nothing; diff --git a/runtime/rococo/constants/Cargo.toml b/runtime/rococo/constants/Cargo.toml index e7bc81f199a1..d9a95beeb2fd 100644 --- a/runtime/rococo/constants/Cargo.toml +++ b/runtime/rococo/constants/Cargo.toml @@ -15,6 +15,8 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", default-features sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +xcm = { package = "xcm", path = "../../../xcm", default-features = false } + [features] default = ["std"] std = [ @@ -23,5 +25,6 @@ std = [ "runtime-common/std", "sp-core/std", "sp-runtime/std", - "sp-weights/std" + "sp-weights/std", + "xcm/std", ] diff --git a/runtime/rococo/constants/src/lib.rs b/runtime/rococo/constants/src/lib.rs index 214e2f3fa980..bda05db149a2 100644 --- a/runtime/rococo/constants/src/lib.rs +++ b/runtime/rococo/constants/src/lib.rs @@ -99,6 +99,26 @@ pub mod fee { } } +/// System Parachains. +pub mod system_parachain { + use xcm::latest::prelude::*; + + /// Network's Asset Hub parachain ID. + pub const ASSET_HUB_ID: u32 = 1000; + /// Contracts parachain ID. + pub const CONTRACTS_ID: u32 = 1002; + /// Encointer parachain ID. + pub const ENCOINTER_ID: u32 = 1003; + /// BridgeHub parachain ID. + pub const BRIDGE_HUB_ID: u32 = 1013; + + frame_support::match_types! { + pub type SystemParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(ASSET_HUB_ID | CONTRACTS_ID | ENCOINTER_ID | BRIDGE_HUB_ID)) } + }; + } +} + #[cfg(test)] mod tests { use super::{ diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index d923437a67e5..e3e3776b603e 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -2091,7 +2091,7 @@ sp_api::impl_runtime_apis! { use frame_benchmarking::baseline::Pallet as Baseline; use xcm::latest::prelude::*; use xcm_config::{ - LocalCheckAccount, LocationConverter, Rockmine, TokenLocation, XcmConfig, + LocalCheckAccount, LocationConverter, AssetHub, TokenLocation, XcmConfig, }; impl frame_system_benchmarking::Config for Runtime {} @@ -2100,7 +2100,7 @@ sp_api::impl_runtime_apis! { type XcmConfig = XcmConfig; type AccountIdConverter = LocationConverter; fn valid_destination() -> Result { - Ok(Rockmine::get()) + Ok(AssetHub::get()) } fn worst_case_holding(_depositable_count: u32) -> MultiAssets { // Rococo only knows about ROC @@ -2113,10 +2113,13 @@ sp_api::impl_runtime_apis! { parameter_types! { pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( - Rockmine::get(), + AssetHub::get(), + MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + )); + pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some(( + AssetHub::get(), MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2152,15 +2155,15 @@ sp_api::impl_runtime_apis! { } fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { - Ok((Rockmine::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } fn subscribe_origin() -> Result { - Ok(Rockmine::get()) + Ok(AssetHub::get()) } fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let origin = Rockmine::get(); + let origin = AssetHub::get(); let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); let ticket = MultiLocation { parents: 0, interior: Here }; Ok((origin, ticket, assets)) diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 75e06391c56b..f0b6e509dda0 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -18,7 +18,8 @@ use super::{ parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, - Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmPallet, + Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, Treasury, WeightToFee, + XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -26,7 +27,7 @@ use frame_support::{ weights::Weight, }; use frame_system::EnsureRoot; -use rococo_runtime_constants::currency::CENTS; +use rococo_runtime_constants::{currency::CENTS, system_parachain::*}; use runtime_common::{ crowdloan, paras_registrar, xcm_sender::{ChildParachainRouter, ExponentialPrice}, @@ -41,7 +42,7 @@ use xcm_builder::{ CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete, MintLocation, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, - WithUniqueTopic, + WithUniqueTopic, XcmFeesToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -51,6 +52,7 @@ parameter_types! { pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); + pub TreasuryAccount: Option = Some(Treasury::account_id()); } pub type LocationConverter = @@ -107,18 +109,20 @@ pub type XcmRouter = WithUniqueTopic<( parameter_types! { pub const Roc: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const Rockmine: MultiLocation = Parachain(1000).into_location(); - pub const Contracts: MultiLocation = Parachain(1002).into_location(); - pub const Encointer: MultiLocation = Parachain(1003).into_location(); + 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 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 RocForRockmine: (MultiAssetFilter, MultiLocation) = (Roc::get(), Rockmine::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 MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -126,9 +130,10 @@ pub type TrustedTeleporters = ( xcm_builder::Case, xcm_builder::Case, xcm_builder::Case, - xcm_builder::Case, + xcm_builder::Case, xcm_builder::Case, xcm_builder::Case, + xcm_builder::Case, ); match_types! { @@ -314,7 +319,7 @@ impl xcm_executor::Config for XcmConfig { type SubscriptionService = XcmPallet; type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type FeeManager = (); + type FeeManager = XcmFeesToAccount; type MessageExporter = (); type UniversalAliases = Nothing; type CallDispatcher = WithOriginFilter; @@ -332,7 +337,7 @@ parameter_types! { #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = Some(Parachain(1000).into()); + pub ReachableDest: Option = Some(Parachain(ASSET_HUB_ID).into()); } /// Type to convert the council origin to a Plurality `MultiLocation` value. diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs index 2113bbae66ad..400658b13863 100644 --- a/runtime/test-runtime/src/xcm_config.rs +++ b/runtime/test-runtime/src/xcm_config.rs @@ -60,7 +60,11 @@ pub type Barrier = AllowUnpaidExecutionFrom; pub struct DummyAssetTransactor; impl TransactAsset for DummyAssetTransactor { - fn deposit_asset(_what: &MultiAsset, _who: &MultiLocation, _context: &XcmContext) -> XcmResult { + fn deposit_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> XcmResult { Ok(()) } diff --git a/runtime/westend/constants/Cargo.toml b/runtime/westend/constants/Cargo.toml index 63e9ad34a7f2..d2e1dca51b5d 100644 --- a/runtime/westend/constants/Cargo.toml +++ b/runtime/westend/constants/Cargo.toml @@ -14,6 +14,7 @@ runtime-common = { package = "polkadot-runtime-common", path = "../../common", d sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +xcm = { path = "../../../xcm", default-features = false } [features] default = ["std"] @@ -23,5 +24,6 @@ std = [ "runtime-common/std", "sp-core/std", "sp-runtime/std", - "sp-weights/std" + "sp-weights/std", + "xcm/std", ] diff --git a/runtime/westend/constants/src/lib.rs b/runtime/westend/constants/src/lib.rs index f9830dab3325..930743ce162a 100644 --- a/runtime/westend/constants/src/lib.rs +++ b/runtime/westend/constants/src/lib.rs @@ -96,6 +96,27 @@ pub mod fee { } } +/// System Parachains. +pub mod system_parachain { + use xcm::latest::prelude::*; + + /// Network's Asset Hub parachain ID. + pub const ASSET_HUB_ID: u32 = 1000; + /// Collectives parachain ID. + pub const COLLECTIVES_ID: u32 = 1001; + /// BridgeHub parachain ID. + pub const BRIDGE_HUB_ID: u32 = 1002; + + frame_support::match_types! { + pub type SystemParachains: impl Contains = { + MultiLocation { + parents: 0, + interior: X1(Parachain(ASSET_HUB_ID | COLLECTIVES_ID | BRIDGE_HUB_ID)), + } + }; + } +} + #[cfg(test)] mod tests { use super::{ diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 9c322d6b8436..29273ce4059f 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1855,13 +1855,13 @@ sp_api::impl_runtime_apis! { AssetId::*, Fungibility::*, InteriorMultiLocation, Junction, Junctions::*, MultiAsset, MultiAssets, MultiLocation, NetworkId, Response, }; - use xcm_config::{Westmint, TokenLocation}; + use xcm_config::{AssetHub, TokenLocation}; impl pallet_xcm_benchmarks::Config for Runtime { type XcmConfig = xcm_config::XcmConfig; type AccountIdConverter = xcm_config::LocationConverter; fn valid_destination() -> Result { - Ok(Westmint::get()) + Ok(AssetHub::get()) } fn worst_case_holding(_depositable_count: u32) -> MultiAssets { // Westend only knows about WND. @@ -1874,7 +1874,7 @@ sp_api::impl_runtime_apis! { parameter_types! { pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( - Westmint::get(), + AssetHub::get(), MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, )); pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; @@ -1913,15 +1913,15 @@ sp_api::impl_runtime_apis! { } fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { - Ok((Westmint::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) + Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } fn subscribe_origin() -> Result { - Ok(Westmint::get()) + Ok(AssetHub::get()) } fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let origin = Westmint::get(); + let origin = AssetHub::get(); let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); let ticket = MultiLocation { parents: 0, interior: Here }; Ok((origin, ticket, assets)) diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index a83c38c9f66f..06490a3e9edf 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -31,7 +31,7 @@ use runtime_common::{ ToAuthor, }; use sp_core::ConstU32; -use westend_runtime_constants::currency::CENTS; +use westend_runtime_constants::{currency::CENTS, system_parachain::*}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -90,22 +90,27 @@ pub type XcmRouter = WithUniqueTopic<( )>; parameter_types! { - pub const Westmint: MultiLocation = Parachain(1000).into_location(); - pub const Collectives: MultiLocation = Parachain(1001).into_location(); + 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 Wnd: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const WndForWestmint: (MultiAssetFilter, MultiLocation) = (Wnd::get(), Westmint::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 MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = Some(Parachain(1000).into()); + pub ReachableDest: Option = Some(Parachain(ASSET_HUB_ID).into()); } -pub type TrustedTeleporters = - (xcm_builder::Case, xcm_builder::Case); +pub type TrustedTeleporters = ( + xcm_builder::Case, + xcm_builder::Case, + xcm_builder::Case, +); /// The barriers one of which must be passed for an XCM message to be executed. pub type Barrier = TrailingSetTopicAsId<( diff --git a/scripts/ci/gitlab/lingua.dic b/scripts/ci/gitlab/lingua.dic index d9dad4540277..57b28afa6b74 100644 --- a/scripts/ci/gitlab/lingua.dic +++ b/scripts/ci/gitlab/lingua.dic @@ -256,7 +256,6 @@ SS58 SSL startup/MS stateful -Statemine str struct/MS subcommand/SM diff --git a/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs index 504b79540399..9e51fa83de90 100644 --- a/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs +++ b/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -44,15 +44,7 @@ benchmarks_instance_pallet! { let worst_case_holding = T::worst_case_holding(0); let asset = T::get_multi_asset(); - >::deposit_asset( - &asset, - &sender_location, - &XcmContext { - origin: Some(sender_location.clone()), - message_id: [0; 32], - topic: None, - }, - ).unwrap(); + >::deposit_asset(&asset, &sender_location, None).unwrap(); // check the assets of origin. assert!(!T::TransactAsset::balance(&sender_account).is_zero()); @@ -77,15 +69,7 @@ benchmarks_instance_pallet! { let dest_location = T::valid_destination()?; let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); - >::deposit_asset( - &asset, - &sender_location, - &XcmContext { - origin: Some(sender_location.clone()), - message_id: [0; 32], - topic: None, - }, - ).unwrap(); + >::deposit_asset(&asset, &sender_location, None).unwrap(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); let mut executor = new_executor::(sender_location); @@ -104,15 +88,7 @@ benchmarks_instance_pallet! { let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap(); let asset = T::get_multi_asset(); - >::deposit_asset( - &asset, - &sender_location, - &XcmContext { - origin: Some(sender_location.clone()), - message_id: [0; 32], - topic: None, - }, - ).unwrap(); + >::deposit_asset(&asset, &sender_location, None).unwrap(); let assets: MultiAssets = vec![ asset ].into(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); diff --git a/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/xcm/pallet-xcm-benchmarks/src/generic/mock.rs index 1b244f316de9..6f9d42df553d 100644 --- a/xcm/pallet-xcm-benchmarks/src/generic/mock.rs +++ b/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -79,7 +79,11 @@ 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, _: &XcmContext) -> Result<(), XcmError> { + fn deposit_asset( + _: &MultiAsset, + _: &MultiLocation, + _: Option<&XcmContext>, + ) -> Result<(), XcmError> { unreachable!(); } diff --git a/xcm/src/v3/mod.rs b/xcm/src/v3/mod.rs index 360867957862..f13814cfa274 100644 --- a/xcm/src/v3/mod.rs +++ b/xcm/src/v3/mod.rs @@ -906,7 +906,7 @@ pub enum Instruction { /// 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 + /// As an example, to export a message for execution on Asset Hub (parachain #1000 in the /// Kusama network), you would call with `network: NetworkId::Kusama` and /// `destination: X1(Parachain(1000))`. Alternatively, to export a message for execution on /// Polkadot, you would call with `network: NetworkId:: Polkadot` and `destination: Here`. diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs index 4dbd4fe8bcd0..ff56eb392d60 100644 --- a/xcm/xcm-builder/src/currency_adapter.rs +++ b/xcm/xcm-builder/src/currency_adapter.rs @@ -191,7 +191,11 @@ impl< } } - fn deposit_asset(what: &MultiAsset, who: &MultiLocation, _context: &XcmContext) -> Result { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + _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)?; diff --git a/xcm/xcm-builder/src/fee_handling.rs b/xcm/xcm-builder/src/fee_handling.rs new file mode 100644 index 000000000000..207d58d1fa00 --- /dev/null +++ b/xcm/xcm-builder/src/fee_handling.rs @@ -0,0 +1,66 @@ +// Copyright 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 core::marker::PhantomData; +use frame_support::traits::{Contains, Get}; +use xcm::prelude::*; +use xcm_executor::traits::{FeeManager, FeeReason, TransactAsset}; + +/// A `FeeManager` implementation that simply deposits the fees handled into a specific on-chain +/// `ReceiverAccount`. +/// +/// It reuses the `AssetTransactor` configured on the XCM executor to deposit fee assets, and also +/// permits specifying `WaivedLocations` for locations that are privileged to not pay for fees. If +/// the `AssetTransactor` returns an error while calling `deposit_asset`, then a warning will be +/// logged. +pub struct XcmFeesToAccount( + PhantomData<(XcmConfig, WaivedLocations, AccountId, ReceiverAccount)>, +); +impl< + XcmConfig: xcm_executor::Config, + WaivedLocations: Contains, + AccountId: Clone + Into<[u8; 32]>, + ReceiverAccount: Get>, + > FeeManager for XcmFeesToAccount +{ + fn is_waived(origin: Option<&MultiLocation>, _: FeeReason) -> bool { + #[cfg(feature = "runtime-benchmarks")] + { + let _ = origin; + true + } + #[cfg(not(feature = "runtime-benchmarks"))] + { + let Some(loc) = origin else { return false }; + WaivedLocations::contains(loc) + } + } + + fn handle_fee(fees: MultiAssets, context: Option<&XcmContext>) { + if let Some(receiver) = ReceiverAccount::get() { + let dest = AccountId32 { network: None, id: receiver.into() }.into(); + for asset in fees.into_inner() { + if let Err(e) = XcmConfig::AssetTransactor::deposit_asset(&asset, &dest, context) { + log::warn!( + target: "xcm::fees", + "`AssetTransactor::deposit_asset` returned error: {:?}, burning fees: {:?}", + e, asset, + ); + } + } + } + } +} diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs index d7fded01e2db..655f1a3557bf 100644 --- a/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/xcm/xcm-builder/src/fungibles_adapter.rs @@ -274,7 +274,11 @@ impl< } } - fn deposit_asset(what: &MultiAsset, who: &MultiLocation, _context: &XcmContext) -> XcmResult { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -371,7 +375,11 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + context: Option<&XcmContext>, + ) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index e3f910409638..d0a31ffb6497 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -67,6 +67,9 @@ pub use process_xcm_message::ProcessXcmMessage; mod currency_adapter; pub use currency_adapter::CurrencyAdapter; +mod fee_handling; +pub use fee_handling::XcmFeesToAccount; + mod fungibles_adapter; pub use fungibles_adapter::{ AssetChecking, DualMint, FungiblesAdapter, FungiblesMutateAdapter, FungiblesTransferAdapter, diff --git a/xcm/xcm-builder/src/nonfungibles_adapter.rs b/xcm/xcm-builder/src/nonfungibles_adapter.rs index 6cf5980df0e9..5caae90333c0 100644 --- a/xcm/xcm-builder/src/nonfungibles_adapter.rs +++ b/xcm/xcm-builder/src/nonfungibles_adapter.rs @@ -207,7 +207,11 @@ impl< } } - fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + context: Option<&XcmContext>, + ) -> XcmResult { log::trace!( target: LOG_TARGET, "deposit_asset what: {:?}, who: {:?}, context: {:?}", @@ -307,7 +311,11 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + context: Option<&XcmContext>, + ) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, diff --git a/xcm/xcm-builder/src/tests/mock.rs b/xcm/xcm-builder/src/tests/mock.rs index 9be034596f43..2163147e6ebc 100644 --- a/xcm/xcm-builder/src/tests/mock.rs +++ b/xcm/xcm-builder/src/tests/mock.rs @@ -252,7 +252,7 @@ impl TransactAsset for TestAssetTransactor { fn deposit_asset( what: &MultiAsset, who: &MultiLocation, - _context: &XcmContext, + _context: Option<&XcmContext>, ) -> Result<(), XcmError> { add_asset(*who, what.clone()); Ok(()) @@ -468,7 +468,7 @@ impl FeeManager for TestFeeManager { fn is_waived(_: Option<&MultiLocation>, r: FeeReason) -> bool { IS_WAIVED.with(|l| l.borrow().contains(&r)) } - fn handle_fee(_: MultiAssets) {} + fn handle_fee(_: MultiAssets, _: Option<&XcmContext>) {} } #[derive(Clone, Eq, PartialEq, Debug)] diff --git a/xcm/xcm-builder/tests/mock/mod.rs b/xcm/xcm-builder/tests/mock/mod.rs index f799be7e4013..e9dba46bacd1 100644 --- a/xcm/xcm-builder/tests/mock/mod.rs +++ b/xcm/xcm-builder/tests/mock/mod.rs @@ -169,13 +169,13 @@ pub type Barrier = ( ); parameter_types! { - pub KusamaForStatemine: (MultiAssetFilter, MultiLocation) = + pub KusamaForAssetHub: (MultiAssetFilter, MultiLocation) = (Wild(AllOf { id: Concrete(Here.into()), fun: WildFungible }), Parachain(1000).into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 4; } -pub type TrustedTeleporters = (xcm_builder::Case,); +pub type TrustedTeleporters = (xcm_builder::Case,); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { diff --git a/xcm/xcm-builder/tests/scenarios.rs b/xcm/xcm-builder/tests/scenarios.rs index 3e735720aa76..07c2f3a75b25 100644 --- a/xcm/xcm-builder/tests/scenarios.rs +++ b/xcm/xcm-builder/tests/scenarios.rs @@ -174,7 +174,7 @@ fn report_holding_works() { } /// Scenario: -/// A parachain wants to move KSM from Kusama to Statemine. +/// A parachain wants to move KSM from Kusama to Asset Hub. /// The parachain sends an XCM to withdraw funds combined with a teleport to the destination. /// /// This way of moving funds from a relay to a parachain will only work for trusted chains. @@ -182,12 +182,12 @@ fn report_holding_works() { /// /// Asserts that the balances are updated accordingly and the correct XCM is sent. #[test] -fn teleport_to_statemine_works() { +fn teleport_to_asset_hub_works() { use xcm::opaque::latest::prelude::*; let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating(); let balances = vec![(ALICE, INITIAL_BALANCE), (para_acc.clone(), INITIAL_BALANCE)]; kusama_like_with_balances(balances).execute_with(|| { - let statemine_id = 1000; + let asset_hub_id = 1000; let other_para_id = 3000; let amount = REGISTER_AMOUNT; let teleport_effects = vec![ @@ -222,13 +222,13 @@ fn teleport_to_statemine_works() { vec![(Parachain(other_para_id).into(), expected_msg, expected_hash,)] ); - // teleports are allowed from statemine to kusama. + // teleports are allowed from asset hub to kusama. let message = Xcm(vec![ WithdrawAsset((Here, amount).into()), buy_execution(), InitiateTeleport { assets: All.into(), - dest: Parachain(statemine_id).into(), + dest: Parachain(asset_hub_id).into(), xcm: Xcm(teleport_effects.clone()), }, ]); @@ -246,7 +246,7 @@ fn teleport_to_statemine_works() { mock::sent_xcm(), vec![ (Parachain(other_para_id).into(), expected_msg.clone(), expected_hash,), - (Parachain(statemine_id).into(), expected_msg, expected_hash,) + (Parachain(asset_hub_id).into(), expected_msg, expected_hash,) ] ); }); diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs index a48cd3259d67..bddfe0884dab 100644 --- a/xcm/xcm-executor/src/lib.rs +++ b/xcm/xcm-executor/src/lib.rs @@ -248,7 +248,7 @@ impl ExecuteXcm for XcmExecutor XcmExecutor { let (ticket, fee) = validate_send::(dest, msg)?; if !Config::FeeManager::is_waived(self.origin_ref(), reason) { let paid = self.holding.try_take(fee.into()).map_err(|_| XcmError::NotHoldingFees)?; - Config::FeeManager::handle_fee(paid.into()); + Config::FeeManager::handle_fee(paid.into(), Some(&self.context)); } Config::XcmSender::deliver(ticket).map_err(Into::into) } @@ -618,14 +618,18 @@ impl XcmExecutor { DepositAsset { assets, beneficiary } => { let deposited = self.holding.saturating_take(assets); for asset in deposited.into_assets_iter() { - Config::AssetTransactor::deposit_asset(&asset, &beneficiary, &self.context)?; + Config::AssetTransactor::deposit_asset( + &asset, + &beneficiary, + Some(&self.context), + )?; } Ok(()) }, DepositReserveAsset { assets, dest, xcm } => { let deposited = self.holding.saturating_take(assets); for asset in deposited.assets_iter() { - Config::AssetTransactor::deposit_asset(&asset, &dest, &self.context)?; + Config::AssetTransactor::deposit_asset(&asset, &dest, Some(&self.context))?; } // Note that we pass `None` as `maybe_failed_bin` and drop any assets which cannot // be reanchored because we have already called `deposit_asset` on all assets. @@ -953,7 +957,7 @@ impl XcmExecutor { } else { self.holding.try_take(fee.into()).map_err(|_| XcmError::NotHoldingFees)?.into() }; - Config::FeeManager::handle_fee(paid); + Config::FeeManager::handle_fee(paid, Some(&self.context)); Ok(()) } @@ -988,7 +992,7 @@ impl XcmExecutor { let (ticket, fee) = validate_send::(destination, message)?; if !Config::FeeManager::is_waived(self.origin_ref(), fee_reason) { let paid = self.holding.try_take(fee.into()).map_err(|_| XcmError::NotHoldingFees)?; - Config::FeeManager::handle_fee(paid.into()); + Config::FeeManager::handle_fee(paid.into(), Some(&self.context)); } Config::XcmSender::deliver(ticket).map_err(Into::into) } diff --git a/xcm/xcm-executor/src/traits/fee_manager.rs b/xcm/xcm-executor/src/traits/fee_manager.rs index ad2e108e7dee..588a246ce17f 100644 --- a/xcm/xcm-executor/src/traits/fee_manager.rs +++ b/xcm/xcm-executor/src/traits/fee_manager.rs @@ -23,7 +23,7 @@ pub trait FeeManager { /// Do something with the fee which has been paid. Doing nothing here silently burns the /// fees. - fn handle_fee(fee: MultiAssets); + fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>); } /// Context under which a fee is paid. @@ -55,5 +55,5 @@ impl FeeManager for () { fn is_waived(_: Option<&MultiLocation>, _: FeeReason) -> bool { true } - fn handle_fee(_: MultiAssets) {} + fn handle_fee(_: MultiAssets, _: Option<&XcmContext>) {} } diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs index 34cdb0c71413..c51befff88a6 100644 --- a/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/xcm/xcm-executor/src/traits/transact_asset.rs @@ -87,7 +87,11 @@ pub trait TransactAsset { /// 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: &XcmContext) -> XcmResult { + fn deposit_asset( + _what: &MultiAsset, + _who: &MultiLocation, + _context: Option<&XcmContext>, + ) -> XcmResult { Err(XcmError::Unimplemented) } @@ -139,7 +143,7 @@ pub trait TransactAsset { Err(XcmError::AssetNotFound | XcmError::Unimplemented) => { let assets = Self::withdraw_asset(asset, from, Some(context))?; // Not a very forgiving attitude; once we implement roll-backs then it'll be nicer. - Self::deposit_asset(asset, to, context)?; + Self::deposit_asset(asset, to, Some(context))?; Ok(assets) }, result => result, @@ -195,7 +199,11 @@ impl TransactAsset for Tuple { )* ); } - fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult { + fn deposit_asset( + what: &MultiAsset, + who: &MultiLocation, + context: Option<&XcmContext>, + ) -> XcmResult { for_tuples!( #( match Tuple::deposit_asset(what, who, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -286,7 +294,7 @@ mod tests { fn deposit_asset( _what: &MultiAsset, _who: &MultiLocation, - _context: &XcmContext, + _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::AssetNotFound) } @@ -330,7 +338,7 @@ mod tests { fn deposit_asset( _what: &MultiAsset, _who: &MultiLocation, - _context: &XcmContext, + _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::Overflow) } @@ -374,7 +382,7 @@ mod tests { fn deposit_asset( _what: &MultiAsset, _who: &MultiLocation, - _context: &XcmContext, + _context: Option<&XcmContext>, ) -> XcmResult { Ok(()) } @@ -406,7 +414,7 @@ mod tests { MultiTransactor::deposit_asset( &(Here, 1u128).into(), &Here.into(), - &XcmContext::with_message_id([0; 32]), + Some(&XcmContext::with_message_id([0; 32])), ), Err(XcmError::AssetNotFound) ); @@ -420,7 +428,7 @@ mod tests { MultiTransactor::deposit_asset( &(Here, 1u128).into(), &Here.into(), - &XcmContext::with_message_id([0; 32]), + Some(&XcmContext::with_message_id([0; 32])), ), Ok(()) ); @@ -434,7 +442,7 @@ mod tests { MultiTransactor::deposit_asset( &(Here, 1u128).into(), &Here.into(), - &XcmContext::with_message_id([0; 32]), + Some(&XcmContext::with_message_id([0; 32])), ), Err(XcmError::Overflow) ); @@ -448,7 +456,7 @@ mod tests { MultiTransactor::deposit_asset( &(Here, 1u128).into(), &Here.into(), - &XcmContext::with_message_id([0; 32]), + Some(&XcmContext::with_message_id([0; 32])), ), Ok(()), );