diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 640e9717..585241b7 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -18,6 +18,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +pub mod xcm_config; + // --- core --- use core::marker::PhantomData; // --- paritytech --- diff --git a/runtime/common/src/xcm_config.rs b/runtime/common/src/xcm_config.rs new file mode 100644 index 00000000..63b388ac --- /dev/null +++ b/runtime/common/src/xcm_config.rs @@ -0,0 +1,67 @@ +use core::marker::PhantomData; +use frame_support::{log, weights::Weight}; +use xcm::latest::prelude::*; +use xcm_executor::traits::ShouldExecute; + +//TODO: move DenyThenTry to polkadot's xcm module. +/// Deny executing the XCM if it matches any of the Deny filter regardless of anything else. +/// If it passes the Deny, and matches one of the Allow cases then it is let through. +pub struct DenyThenTry(PhantomData, PhantomData) +where + Deny: ShouldExecute, + Allow: ShouldExecute; + +impl ShouldExecute for DenyThenTry +where + Deny: ShouldExecute, + Allow: ShouldExecute, +{ + fn should_execute( + origin: &MultiLocation, + message: &mut Xcm, + max_weight: Weight, + weight_credit: &mut Weight, + ) -> Result<(), ()> { + Deny::should_execute(origin, message, max_weight, weight_credit)?; + Allow::should_execute(origin, message, max_weight, weight_credit) + } +} + +// See issue #5233 +pub struct DenyReserveTransferToRelayChain; +impl ShouldExecute for DenyReserveTransferToRelayChain { + fn should_execute( + origin: &MultiLocation, + message: &mut Xcm, + _max_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + if message.0.iter().any(|inst| { + matches!( + inst, + InitiateReserveWithdraw { + reserve: MultiLocation { parents: 1, interior: Here }, + .. + } | DepositReserveAsset { dest: MultiLocation { parents: 1, interior: Here }, .. } | + TransferReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, + .. + } + ) + }) { + return Err(()) // Deny + } + + // allow reserve transfers to arrive from relay chain + if matches!(origin, MultiLocation { parents: 1, interior: Here }) && + message.0.iter().any(|inst| matches!(inst, ReserveAssetDeposited { .. })) + { + log::info!( + target: "runtime::xcm-barier", + "Unexpected Reserve Assets Deposited on the relay chain", + ); + } + // Permit everything else + Ok(()) + } +} diff --git a/runtime/crab-parachain/src/pallets/polkadot_xcm.rs b/runtime/crab-parachain/src/pallets/polkadot_xcm.rs index 1dcb96c8..cc5a0d05 100644 --- a/runtime/crab-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/crab-parachain/src/pallets/polkadot_xcm.rs @@ -13,6 +13,7 @@ use xcm_builder::*; use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; +use dc_common_runtime::xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}; /// Converts a local signed origin into an XCM multilocation. /// Forms the basis for local origins sending/executing XCMs. @@ -41,16 +42,19 @@ pub type XcmRouter = ( XcmpQueue, ); -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - // Parent and its plurality get free execution - AllowUnpaidExecutionFrom, - // Expected responses are OK. - AllowKnownQueryResponses, - // Subscriptions for version tracking are OK. - AllowSubscriptionsFrom, -); +pub type Barrier = DenyThenTry< + DenyReserveTransferToRelayChain, + ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + // Parent and its exec plurality get free execution + AllowUnpaidExecutionFrom, + // Expected responses are OK. + AllowKnownQueryResponses, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), +>; /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM diff --git a/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs b/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs index ab2283e7..e8387e83 100644 --- a/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs @@ -13,6 +13,7 @@ use xcm_builder::*; use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; +use dc_common_runtime::xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}; /// Converts a local signed origin into an XCM multilocation. /// Forms the basis for local origins sending/executing XCMs. @@ -41,16 +42,19 @@ pub type XcmRouter = ( XcmpQueue, ); -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - // Parent and its plurality get free execution - AllowUnpaidExecutionFrom, - // Expected responses are OK. - AllowKnownQueryResponses, - // Subscriptions for version tracking are OK. - AllowSubscriptionsFrom, -); +pub type Barrier = DenyThenTry< + DenyReserveTransferToRelayChain, + ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + // Parent and its exec plurality get free execution + AllowUnpaidExecutionFrom, + // Expected responses are OK. + AllowKnownQueryResponses, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), +>; /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM diff --git a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs index 55496c35..d64213b4 100644 --- a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs @@ -13,6 +13,7 @@ use xcm_builder::*; use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; +use dc_common_runtime::xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}; /// Converts a local signed origin into an XCM multilocation. /// Forms the basis for local origins sending/executing XCMs. @@ -41,16 +42,19 @@ pub type XcmRouter = ( XcmpQueue, ); -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - // Parent and its plurality get free execution - AllowUnpaidExecutionFrom, - // Expected responses are OK. - AllowKnownQueryResponses, - // Subscriptions for version tracking are OK. - AllowSubscriptionsFrom, -); +pub type Barrier = DenyThenTry< + DenyReserveTransferToRelayChain, + ( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + // Parent and its exec plurality get free execution + AllowUnpaidExecutionFrom, + // Expected responses are OK. + AllowKnownQueryResponses, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, + ), +>; /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM