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 } // 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.0.iter().any(|inst| matches!(inst, ReserveAssetDeposited { .. })) { log::warn!( target: "xcm::barrier", "Unexpected ReserveAssetDeposited from the Relay Chain", ); } // Permit everything else Ok(()) } }