diff --git a/parachain-template/runtime/src/xcm_config.rs b/parachain-template/runtime/src/xcm_config.rs index fa056fc65d3..8383e096a7d 100644 --- a/parachain-template/runtime/src/xcm_config.rs +++ b/parachain-template/runtime/src/xcm_config.rs @@ -2,7 +2,7 @@ use super::{ AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; -use core::marker::PhantomData; +use core::{marker::PhantomData, ops::ControlFlow}; use frame_support::{ log, match_types, parameter_types, traits::{ConstU32, Everything, Nothing}, @@ -11,7 +11,7 @@ use frame_support::{ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; -use xcm::latest::prelude::*; +use xcm::{latest::prelude::*, CreateMatcher, MatchXcm}; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, IsConcrete, NativeAsset, ParentIsPreset, @@ -122,32 +122,36 @@ impl ShouldExecute for DenyReserveTransferToRelayChain { _max_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { - if message.iter().any(|inst| { - matches!( - inst, + message.matcher().match_next_inst_while( + |_| true, + |inst| match 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 - } - - // An unexpected reserve transfer has arrived from the Relay Chain. Generally, `IsReserve` - // should not allow this, but we just log it here. - if matches!(origin, MultiLocation { parents: 1, interior: Here }) && - message.iter().any(|inst| matches!(inst, ReserveAssetDeposited { .. })) - { - log::warn!( - target: "xcm::barriers", - "Unexpected ReserveAssetDeposited from the Relay Chain", - ); - } + } | + DepositReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, .. + } | + TransferReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, .. + } => { + Err(()) // Deny + }, + // An unexpected reserve transfer has arrived from the Relay Chain. Generally, + // `IsReserve` should not allow this, but we just log it here. + ReserveAssetDeposited { .. } + if matches!(origin, MultiLocation { parents: 1, interior: Here }) => + { + log::warn!( + target: "xcm::barrier", + "Unexpected ReserveAssetDeposited from the Relay Chain", + ); + Ok(ControlFlow::Continue(())) + }, + _ => Ok(ControlFlow::Continue(())), + }, + )?; + // Permit everything else Ok(()) } diff --git a/parachains/common/src/xcm_config.rs b/parachains/common/src/xcm_config.rs index ac4cd8858e7..753aa97c6fe 100644 --- a/parachains/common/src/xcm_config.rs +++ b/parachains/common/src/xcm_config.rs @@ -1,12 +1,12 @@ use crate::impls::AccountIdOf; -use core::marker::PhantomData; +use core::{marker::PhantomData, ops::ControlFlow}; use frame_support::{ log, traits::{fungibles::Inspect, tokens::BalanceConversion, ContainsPair}, weights::{Weight, WeightToFee, WeightToFeePolynomial}, }; use sp_runtime::traits::Get; -use xcm::latest::prelude::*; +use xcm::{latest::prelude::*, CreateMatcher, MatchXcm}; use xcm_executor::traits::ShouldExecute; //TODO: move DenyThenTry to polkadot's xcm module. @@ -42,32 +42,38 @@ impl ShouldExecute for DenyReserveTransferToRelayChain { _max_weight: Weight, _weight_credit: &mut Weight, ) -> Result<(), ()> { - if message.iter().any(|inst| { - matches!( - inst, + message.matcher().match_next_inst_while( + |_| true, + |inst| match 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 - } + } | + DepositReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, .. + } | + TransferReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, .. + } => { + Err(()) // Deny + }, + + // An unexpected reserve transfer has arrived from the Relay Chain. Generally, + // `IsReserve` should not allow this, but we just log it here. + ReserveAssetDeposited { .. } + if matches!(origin, MultiLocation { parents: 1, interior: Here }) => + { + log::warn!( + target: "xcm::barrier", + "Unexpected ReserveAssetDeposited from the Relay Chain", + ); + Ok(ControlFlow::Continue(())) + }, + + _ => Ok(ControlFlow::Continue(())), + }, + )?; - // An unexpected reserve transfer has arrived from the Relay Chain. Generally, `IsReserve` - // should not allow this, but we just log it here. - if matches!(origin, MultiLocation { parents: 1, interior: Here }) && - message.iter().any(|inst| matches!(inst, ReserveAssetDeposited { .. })) - { - log::warn!( - target: "xcm::barriers", - "Unexpected ReserveAssetDeposited from the Relay Chain", - ); - } // Permit everything else Ok(()) }