From d968c9414a6ee4e8f95f2c011b4047c6f7779342 Mon Sep 17 00:00:00 2001 From: Adrian Catangiu Date: Sat, 5 Oct 2024 15:28:17 +0300 Subject: [PATCH] XCM paid execution barrier supports more origin altering instructions (#5917) The AllowTopLevelPaidExecutionFrom allows ClearOrigin instructions before the expected BuyExecution instruction, it also allows messages without any origin altering instructions. This commit enhances the barrier to also support messages that use AliasOrigin, or DescendOrigin. This is sometimes desired in asset transfer XCM programs that need to run the inbound assets instructions using the origin chain root origin, but then want to drop privileges for the rest of the program. Currently these programs drop privileges by clearing the origin completely, but that also unnecessarily limits the range of actions available to the rest of the program. Using DescendOrigin or AliasOrigin allows the sending chain to instruct the receiving chain what the deprivileged real origin is. See https://github.com/polkadot-fellows/RFCs/pull/109 and https://github.com/polkadot-fellows/RFCs/pull/122 for more details on how DescendOrigin and AliasOrigin could be used instead of ClearOrigin. --------- Signed-off-by: Adrian Catangiu --- polkadot/xcm/xcm-builder/src/barriers.rs | 12 +++-- .../xcm/xcm-builder/src/tests/barriers.rs | 50 +++++++++++++++++++ prdoc/pr_5917.prdoc | 14 ++++++ 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 prdoc/pr_5917.prdoc diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index 5d95005eb663..c995361ea8a3 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -57,8 +57,9 @@ const MAX_ASSETS_FOR_BUY_EXECUTION: usize = 2; /// Allows execution from `origin` if it is contained in `T` (i.e. `T::Contains(origin)`) taking /// payments into account. /// -/// Only allows for `TeleportAsset`, `WithdrawAsset`, `ClaimAsset` and `ReserveAssetDeposit` XCMs -/// because they are the only ones that place assets in the Holding Register to pay for execution. +/// Only allows for `WithdrawAsset`, `ReceiveTeleportedAsset`, `ReserveAssetDeposited` and +/// `ClaimAsset` XCMs because they are the only ones that place assets in the Holding Register to +/// pay for execution. pub struct AllowTopLevelPaidExecutionFrom(PhantomData); impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { fn should_execute( @@ -81,9 +82,9 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFrom instructions[..end] .matcher() .match_next_inst(|inst| match inst { + WithdrawAsset(ref assets) | ReceiveTeleportedAsset(ref assets) | ReserveAssetDeposited(ref assets) | - WithdrawAsset(ref assets) | ClaimAsset { ref assets, .. } => if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION { Ok(()) @@ -92,7 +93,10 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFrom }, _ => Err(ProcessMessageError::BadFormat), })? - .skip_inst_while(|inst| matches!(inst, ClearOrigin))? + .skip_inst_while(|inst| { + matches!(inst, ClearOrigin | AliasOrigin(..)) || + matches!(inst, DescendOrigin(child) if child != &Here) + })? .match_next_inst(|inst| match inst { BuyExecution { weight_limit: Limited(ref mut weight), .. } if weight.all_gte(max_weight) => diff --git a/polkadot/xcm/xcm-builder/src/tests/barriers.rs b/polkadot/xcm/xcm-builder/src/tests/barriers.rs index 665b5febc61f..cd2b6db66efc 100644 --- a/polkadot/xcm/xcm-builder/src/tests/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/tests/barriers.rs @@ -283,6 +283,56 @@ fn allow_paid_should_work() { assert_eq!(r, Ok(())) } +#[test] +fn allow_paid_should_deprivilege_origin() { + AllowPaidFrom::set(vec![Parent.into()]); + let fees = (Parent, 1).into(); + + let mut paying_message_clears_origin = Xcm::<()>(vec![ + ReserveAssetDeposited((Parent, 100).into()), + ClearOrigin, + BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, + ]); + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_clears_origin.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); + + let mut paying_message_aliases_origin = paying_message_clears_origin.clone(); + paying_message_aliases_origin.0[1] = AliasOrigin(Parachain(1).into()); + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_aliases_origin.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); + + let mut paying_message_descends_origin = paying_message_clears_origin.clone(); + paying_message_descends_origin.0[1] = DescendOrigin(Parachain(1).into()); + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_descends_origin.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Ok(())); + + let mut paying_message_fake_descends_origin = paying_message_clears_origin.clone(); + paying_message_fake_descends_origin.0[1] = DescendOrigin(Here.into()); + let r = AllowTopLevelPaidExecutionFrom::>::should_execute( + &Parent.into(), + paying_message_fake_descends_origin.inner_mut(), + Weight::from_parts(30, 30), + &mut props(Weight::zero()), + ); + assert_eq!(r, Err(ProcessMessageError::Overweight(Weight::from_parts(30, 30)))); +} + #[test] fn suspension_should_work() { TestSuspender::set_suspended(true); diff --git a/prdoc/pr_5917.prdoc b/prdoc/pr_5917.prdoc new file mode 100644 index 000000000000..54b2e42ed9c3 --- /dev/null +++ b/prdoc/pr_5917.prdoc @@ -0,0 +1,14 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "XCM paid execution barrier supports more origin altering instructions" + +doc: + - audience: Runtime Dev + description: | + Updates the `AllowTopLevelPaidExecutionFrom` barrier to also support messages that + use `DescendOrigin` or `AliasOrigin` for altering the computed origin during execution. + +crates: + - name: staging-xcm-builder + bump: patch