From 4c059c02f45370f284b0e2ba0f0ca8e02400e2d5 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre <franciscoaguirreperez@gmail.com> Date: Tue, 12 Nov 2024 14:05:52 -0300 Subject: [PATCH] XCMv5: add ExecuteWithOrigin instruction (#6304) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added `ExecuteWithOrigin` instruction according to the old XCM RFC 38: https://github.com/polkadot-fellows/xcm-format/pull/38. This instruction allows you to descend or clear while going back again. ## TODO - [x] Implementation - [x] Unit tests - [x] Integration tests - [x] Benchmarks - [x] PRDoc ## Future work Modify `WithComputedOrigin` barrier to allow, for example, fees to be paid with a descendant origin using this instruction. --------- Signed-off-by: Adrian Catangiu <adrian@parity.io> Co-authored-by: Adrian Catangiu <adrian@parity.io> Co-authored-by: Andrii <ndk@parity.io> Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: Joseph Zhao <65984904+programskillforverification@users.noreply.github.com> Co-authored-by: Nazar Mokrynskyi <nazar@mokrynskyi.com> Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: command-bot <> --- Cargo.lock | 11 +- .../tests/assets/asset-hub-westend/Cargo.toml | 1 + .../src/tests/claim_assets.rs | 82 ++++++++ .../asset-hub-rococo/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../asset-hub-westend/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../bridge-hub-rococo/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../bridge-hub-westend/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../coretime-rococo/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../coretime-westend/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../people-rococo/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../people-westend/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 7 + .../weights/pallet_xcm_benchmarks_generic.rs | 7 + .../runtime/rococo/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 137 +++++++------- .../runtime/westend/src/weights/xcm/mod.rs | 3 + .../xcm/pallet_xcm_benchmarks_generic.rs | 131 +++++++------ .../src/generic/benchmarking.rs | 17 ++ polkadot/xcm/src/v4/mod.rs | 7 +- polkadot/xcm/src/v5/mod.rs | 23 +++ polkadot/xcm/xcm-builder/src/weight.rs | 3 +- polkadot/xcm/xcm-executor/src/lib.rs | 51 +++-- .../src/tests/execute_with_origin.rs | 177 ++++++++++++++++++ polkadot/xcm/xcm-executor/src/tests/mod.rs | 1 + prdoc/pr_6304.prdoc | 45 +++++ 32 files changed, 630 insertions(+), 149 deletions(-) create mode 100644 polkadot/xcm/xcm-executor/src/tests/execute_with_origin.rs create mode 100644 prdoc/pr_6304.prdoc diff --git a/Cargo.lock b/Cargo.lock index eaa0d2667c7..c1eda1b0fb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -953,6 +953,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "asset-test-utils 7.0.0", + "assets-common 0.7.0", "cumulus-pallet-parachain-system 0.7.0", "cumulus-pallet-xcmp-queue 0.7.0", "emulated-integration-tests-common", @@ -20397,7 +20398,7 @@ checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.13.0", + "itertools 0.12.1", "log", "multimap", "once_cell", @@ -20443,7 +20444,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.12.1", "proc-macro2 1.0.86", "quote 1.0.37", "syn 2.0.87", @@ -20926,7 +20927,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -20947,9 +20948,9 @@ checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml index 71e44e5cee7..7117124b1d1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/Cargo.toml @@ -37,6 +37,7 @@ pallet-xcm = { workspace = true } xcm-runtime-apis = { workspace = true } # Cumulus +assets-common = { workspace = true } parachains-common = { workspace = true, default-features = true } asset-test-utils = { workspace = true, default-features = true } cumulus-pallet-xcmp-queue = { workspace = true } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/claim_assets.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/claim_assets.rs index 90af907654f..a7f52eb7e09 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/claim_assets.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/claim_assets.rs @@ -17,7 +17,9 @@ use crate::imports::*; +use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApiV2; use emulated_integration_tests_common::test_chain_can_claim_assets; +use frame_support::traits::fungible::Mutate; use xcm_executor::traits::DropAssets; #[test] @@ -33,3 +35,83 @@ fn assets_can_be_claimed() { amount ); } + +#[test] +fn chain_can_claim_assets_for_its_users() { + // Many Penpal users have assets trapped in AssetHubWestend. + let beneficiaries: Vec<(Location, Assets)> = vec![ + // Some WND. + ( + Location::new(1, [Parachain(2000), AccountId32 { id: [0u8; 32], network: None }]), + (Parent, 10_000_000_000_000u128).into(), + ), + // Some USDT. + ( + Location::new(1, [Parachain(2000), AccountId32 { id: [1u8; 32], network: None }]), + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(USDT_ID.into())], 100_000_000u128) + .into(), + ), + ]; + + // Start with those assets trapped. + AssetHubWestend::execute_with(|| { + for (location, assets) in &beneficiaries { + <AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::drop_assets( + location, + assets.clone().into(), + &XcmContext { origin: None, message_id: [0u8; 32], topic: None }, + ); + } + }); + + let penpal_to_asset_hub = PenpalA::sibling_location_of(AssetHubWestend::para_id()); + let mut builder = Xcm::<()>::builder() + .withdraw_asset((Parent, 1_000_000_000_000u128)) + .pay_fees((Parent, 100_000_000_000u128)); + + // Loop through all beneficiaries. + for (location, assets) in &beneficiaries { + builder = builder.execute_with_origin( + // We take only the last part, the `AccountId32` junction. + Some((*location.interior().last().unwrap()).into()), + Xcm::<()>::builder_unsafe() + .claim_asset(assets.clone(), Location::new(0, [GeneralIndex(5)])) // Means lost assets were version 5. + .deposit_asset(assets.clone(), location.clone()) + .build(), + ) + } + + // Finish assembling the message. + let message = builder.build(); + + // Fund PenpalA's sovereign account on AssetHubWestend so it can pay for fees. + AssetHubWestend::execute_with(|| { + let penpal_as_seen_by_asset_hub = AssetHubWestend::sibling_location_of(PenpalA::para_id()); + let penpal_sov_account_on_asset_hub = + AssetHubWestend::sovereign_account_id_of(penpal_as_seen_by_asset_hub); + type Balances = <AssetHubWestend as AssetHubWestendPallet>::Balances; + assert_ok!(<Balances as Mutate<_>>::mint_into( + &penpal_sov_account_on_asset_hub, + 2_000_000_000_000u128, + )); + }); + + // We can send a message from Penpal root that claims all those assets for each beneficiary. + PenpalA::execute_with(|| { + assert_ok!(<PenpalA as PenpalAPallet>::PolkadotXcm::send( + <PenpalA as Chain>::RuntimeOrigin::root(), + bx!(penpal_to_asset_hub.into()), + bx!(VersionedXcm::from(message)), + )); + }); + + // We assert beneficiaries have received their funds. + AssetHubWestend::execute_with(|| { + for (location, expected_assets) in &beneficiaries { + let sov_account = AssetHubWestend::sovereign_account_id_of(location.clone()); + let actual_assets = + <AssetHubWestend as Chain>::Runtime::query_account_balances(sov_account).unwrap(); + assert_eq!(VersionedAssets::from(expected_assets.clone()), actual_assets); + } + }); +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs index bf374fc415c..025c39bcee0 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/mod.rs @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubRococoXcmWeight<Call> { fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight { XcmGeneric::<Runtime>::unpaid_execution() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index ef08b432e5c..b69c136b29d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -373,4 +373,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 668_000 picoseconds. Weight::from_parts(726_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs index 928f1910cbd..35ff2dc367c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/mod.rs @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> { fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight { XcmGeneric::<Runtime>::unpaid_execution() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 7098f175d42..52869412311 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -373,4 +373,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 638_000 picoseconds. Weight::from_parts(708_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs index 60a0fc005ca..288aac38563 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs @@ -256,4 +256,7 @@ impl<Call> XcmWeightInfo<Call> for BridgeHubRococoXcmWeight<Call> { fn set_asset_claimer(_location: &Location) -> Weight { XcmGeneric::<Runtime>::set_asset_claimer() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index b8bd4c4e2d4..bac73e0e056 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -380,4 +380,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 707_000 picoseconds. Weight::from_parts(749_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs index 473807ea5eb..fa1304d11c6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/mod.rs @@ -257,4 +257,7 @@ impl<Call> XcmWeightInfo<Call> for BridgeHubWestendXcmWeight<Call> { fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight { XcmGeneric::<Runtime>::unpaid_execution() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 849456af925..6434f6206fb 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -380,4 +380,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 707_000 picoseconds. Weight::from_parts(749_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs index 48f1366e2c5..f69736e3145 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/mod.rs @@ -254,4 +254,7 @@ impl<Call> XcmWeightInfo<Call> for CoretimeRococoXcmWeight<Call> { fn set_asset_claimer(_location: &Location) -> Weight { XcmGeneric::<Runtime>::set_asset_claimer() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 229dafb7c5e..d207c09ffcd 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 707_000 picoseconds. Weight::from_parts(749_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs index 1f4b4aa5c5a..1640baa38c9 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/mod.rs @@ -254,4 +254,7 @@ impl<Call> XcmWeightInfo<Call> for CoretimeWestendXcmWeight<Call> { fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight { XcmGeneric::<Runtime>::unpaid_execution() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index bd70bc4f4bd..fb6e4631736 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 707_000 picoseconds. Weight::from_parts(749_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs index b82872a1cbf..631cc7b7f0b 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/mod.rs @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for PeopleRococoXcmWeight<Call> { fn set_asset_claimer(_location: &Location) -> Weight { XcmGeneric::<Runtime>::set_asset_claimer() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 30e28fac7e5..6aac6119e7e 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 707_000 picoseconds. Weight::from_parts(749_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs index 8ca9771dca4..4b51a3ba411 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/mod.rs @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for PeopleWestendXcmWeight<Call> { fn set_asset_claimer(_location: &Location) -> Weight { XcmGeneric::<Runtime>::set_asset_claimer() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 3c539902abc..36400f2c1e6 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 707_000 picoseconds. Weight::from_parts(749_000, 0) } + pub fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs index b62f36172ba..1595a6dfbe4 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs @@ -344,4 +344,11 @@ impl<T: frame_system::Config> pallet_xcm_benchmarks::generic::WeightInfo for Wei Weight::from_parts(1_354_000, 0) .saturating_add(Weight::from_parts(0, 0)) } + fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(776_000, 0) + } } diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs index 007002bf27b..a28b4680087 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/mod.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -289,6 +289,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for RococoXcmWeight<RuntimeCall> { fn set_asset_claimer(_location: &Location) -> Weight { XcmGeneric::<Runtime>::set_asset_claimer() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<RuntimeCall>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } #[test] diff --git a/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 677640b4533..e5915a7986b 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-svzsllib-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024 // Executed Command: @@ -63,8 +63,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `281` // Estimated: `3746` - // Minimum execution time: 64_284_000 picoseconds. - Weight::from_parts(65_590_000, 3746) + // Minimum execution time: 65_164_000 picoseconds. + Weight::from_parts(66_965_000, 3746) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -72,15 +72,22 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 777_000 picoseconds. - Weight::from_parts(825_000, 0) + // Minimum execution time: 675_000 picoseconds. + Weight::from_parts(745_000, 0) } pub(crate) fn pay_fees() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_543_000 picoseconds. - Weight::from_parts(1_627_000, 0) + // Minimum execution time: 2_899_000 picoseconds. + Weight::from_parts(3_090_000, 0) + } + pub(crate) fn set_asset_claimer() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 669_000 picoseconds. + Weight::from_parts(714_000, 0) } /// Storage: `XcmPallet::Queries` (r:1 w:0) /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -88,58 +95,65 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3465` - // Minimum execution time: 5_995_000 picoseconds. - Weight::from_parts(6_151_000, 3465) + // Minimum execution time: 6_004_000 picoseconds. + Weight::from_parts(6_152_000, 3465) .saturating_add(T::DbWeight::get().reads(1)) } pub(crate) fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_567_000 picoseconds. - Weight::from_parts(7_779_000, 0) + // Minimum execution time: 7_296_000 picoseconds. + Weight::from_parts(7_533_000, 0) } pub(crate) fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_226_000 picoseconds. - Weight::from_parts(1_322_000, 0) + // Minimum execution time: 1_292_000 picoseconds. + Weight::from_parts(1_414_000, 0) } pub(crate) fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 768_000 picoseconds. - Weight::from_parts(828_000, 0) + // Minimum execution time: 741_000 picoseconds. + Weight::from_parts(775_000, 0) } pub(crate) fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 765_000 picoseconds. - Weight::from_parts(814_000, 0) + // Minimum execution time: 702_000 picoseconds. + Weight::from_parts(770_000, 0) } pub(crate) fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 739_000 picoseconds. - Weight::from_parts(820_000, 0) + // Minimum execution time: 648_000 picoseconds. + Weight::from_parts(744_000, 0) } pub(crate) fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 806_000 picoseconds. - Weight::from_parts(849_000, 0) + // Minimum execution time: 731_000 picoseconds. + Weight::from_parts(772_000, 0) + } + pub(crate) fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 790_000 picoseconds. + Weight::from_parts(843_000, 0) } pub(crate) fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 782_000 picoseconds. - Weight::from_parts(820_000, 0) + // Minimum execution time: 647_000 picoseconds. + Weight::from_parts(731_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -155,8 +169,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `281` // Estimated: `3746` - // Minimum execution time: 61_410_000 picoseconds. - Weight::from_parts(62_813_000, 3746) + // Minimum execution time: 62_808_000 picoseconds. + Weight::from_parts(64_413_000, 3746) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -166,8 +180,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `23` // Estimated: `3488` - // Minimum execution time: 9_315_000 picoseconds. - Weight::from_parts(9_575_000, 3488) + // Minimum execution time: 9_298_000 picoseconds. + Weight::from_parts(9_541_000, 3488) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -175,8 +189,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 733_000 picoseconds. - Weight::from_parts(813_000, 0) + // Minimum execution time: 696_000 picoseconds. + Weight::from_parts(732_000, 0) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:1 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -192,8 +206,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3645` - // Minimum execution time: 30_641_000 picoseconds. - Weight::from_parts(31_822_000, 3645) + // Minimum execution time: 30_585_000 picoseconds. + Weight::from_parts(31_622_000, 3645) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -203,44 +217,44 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_978_000 picoseconds. - Weight::from_parts(3_260_000, 0) + // Minimum execution time: 3_036_000 picoseconds. + Weight::from_parts(3_196_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub(crate) fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_139_000 picoseconds. - Weight::from_parts(1_272_000, 0) + // Minimum execution time: 1_035_000 picoseconds. + Weight::from_parts(1_133_000, 0) } pub(crate) fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 850_000 picoseconds. - Weight::from_parts(879_000, 0) + // Minimum execution time: 764_000 picoseconds. + Weight::from_parts(802_000, 0) } pub(crate) fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 770_000 picoseconds. - Weight::from_parts(834_000, 0) + // Minimum execution time: 682_000 picoseconds. + Weight::from_parts(724_000, 0) } pub(crate) fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 756_000 picoseconds. - Weight::from_parts(797_000, 0) + // Minimum execution time: 653_000 picoseconds. + Weight::from_parts(713_000, 0) } pub(crate) fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 888_000 picoseconds. - Weight::from_parts(1_000_000, 0) + // Minimum execution time: 857_000 picoseconds. + Weight::from_parts(917_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -256,8 +270,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `281` // Estimated: `3746` - // Minimum execution time: 72_138_000 picoseconds. - Weight::from_parts(73_728_000, 3746) + // Minimum execution time: 72_331_000 picoseconds. + Weight::from_parts(74_740_000, 3746) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -265,8 +279,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_482_000 picoseconds. - Weight::from_parts(8_667_000, 0) + // Minimum execution time: 8_963_000 picoseconds. + Weight::from_parts(9_183_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,8 +296,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `281` // Estimated: `3746` - // Minimum execution time: 61_580_000 picoseconds. - Weight::from_parts(62_928_000, 3746) + // Minimum execution time: 62_555_000 picoseconds. + Weight::from_parts(64_824_000, 3746) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -291,29 +305,29 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 807_000 picoseconds. - Weight::from_parts(844_000, 0) + // Minimum execution time: 740_000 picoseconds. + Weight::from_parts(773_000, 0) } pub(crate) fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 757_000 picoseconds. - Weight::from_parts(808_000, 0) + // Minimum execution time: 678_000 picoseconds. + Weight::from_parts(714_000, 0) } pub(crate) fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 740_000 picoseconds. - Weight::from_parts(810_000, 0) + // Minimum execution time: 656_000 picoseconds. + Weight::from_parts(703_000, 0) } pub(crate) fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 752_000 picoseconds. - Weight::from_parts(786_000, 0) + // Minimum execution time: 672_000 picoseconds. + Weight::from_parts(725_000, 0) } pub(crate) fn unpaid_execution() -> Weight { // Proof Size summary in bytes: @@ -322,11 +336,4 @@ impl<T: frame_system::Config> WeightInfo<T> { // Minimum execution time: 798_000 picoseconds. Weight::from_parts(845_000, 0) } - pub(crate) fn set_asset_claimer() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(749_000, 0) - } } diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index e5f4a0d7ca8..5be9bad824d 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -294,6 +294,9 @@ impl<RuntimeCall> XcmWeightInfo<RuntimeCall> for WestendXcmWeight<RuntimeCall> { fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight { XcmGeneric::<Runtime>::unpaid_execution() } + fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<RuntimeCall>) -> Weight { + XcmGeneric::<Runtime>::execute_with_origin() + } } #[test] diff --git a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 2ad1cd6359a..076744a5975 100644 --- a/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/polkadot/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-09-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-svzsllib-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 1024 // Executed Command: @@ -63,8 +63,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 67_813_000 picoseconds. - Weight::from_parts(69_357_000, 6196) + // Minimum execution time: 69_051_000 picoseconds. + Weight::from_parts(71_282_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -72,22 +72,22 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 716_000 picoseconds. - Weight::from_parts(780_000, 0) + // Minimum execution time: 660_000 picoseconds. + Weight::from_parts(695_000, 0) } pub(crate) fn pay_fees() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_601_000 picoseconds. - Weight::from_parts(1_680_000, 0) + // Minimum execution time: 3_096_000 picoseconds. + Weight::from_parts(3_313_000, 0) } pub(crate) fn set_asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(749_000, 0) + // Minimum execution time: 661_000 picoseconds. + Weight::from_parts(707_000, 0) } /// Storage: `XcmPallet::Queries` (r:1 w:0) /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -95,58 +95,65 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3465` - // Minimum execution time: 6_574_000 picoseconds. - Weight::from_parts(6_790_000, 3465) + // Minimum execution time: 6_054_000 picoseconds. + Weight::from_parts(6_151_000, 3465) .saturating_add(T::DbWeight::get().reads(1)) } pub(crate) fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_232_000 picoseconds. - Weight::from_parts(7_422_000, 0) + // Minimum execution time: 7_462_000 picoseconds. + Weight::from_parts(7_750_000, 0) } pub(crate) fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_180_000 picoseconds. - Weight::from_parts(1_250_000, 0) + // Minimum execution time: 1_378_000 picoseconds. + Weight::from_parts(1_454_000, 0) } pub(crate) fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 702_000 picoseconds. - Weight::from_parts(766_000, 0) + // Minimum execution time: 660_000 picoseconds. + Weight::from_parts(744_000, 0) } pub(crate) fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 700_000 picoseconds. - Weight::from_parts(757_000, 0) + // Minimum execution time: 713_000 picoseconds. + Weight::from_parts(755_000, 0) } pub(crate) fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 686_000 picoseconds. - Weight::from_parts(751_000, 0) + // Minimum execution time: 632_000 picoseconds. + Weight::from_parts(703_000, 0) } pub(crate) fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 705_000 picoseconds. - Weight::from_parts(765_000, 0) + // Minimum execution time: 712_000 picoseconds. + Weight::from_parts(771_000, 0) + } + pub(crate) fn execute_with_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 740_000 picoseconds. + Weight::from_parts(826_000, 0) } pub(crate) fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 687_000 picoseconds. - Weight::from_parts(741_000, 0) + // Minimum execution time: 653_000 picoseconds. + Weight::from_parts(707_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -162,8 +169,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 65_398_000 picoseconds. - Weight::from_parts(67_140_000, 6196) + // Minimum execution time: 66_765_000 picoseconds. + Weight::from_parts(69_016_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -173,8 +180,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `23` // Estimated: `3488` - // Minimum execution time: 9_653_000 picoseconds. - Weight::from_parts(9_944_000, 3488) + // Minimum execution time: 9_545_000 picoseconds. + Weight::from_parts(9_853_000, 3488) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -182,8 +189,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 698_000 picoseconds. - Weight::from_parts(759_000, 0) + // Minimum execution time: 676_000 picoseconds. + Weight::from_parts(723_000, 0) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:1 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -199,8 +206,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `147` // Estimated: `3612` - // Minimum execution time: 31_300_000 picoseconds. - Weight::from_parts(31_989_000, 3612) + // Minimum execution time: 31_324_000 picoseconds. + Weight::from_parts(32_023_000, 3612) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -210,44 +217,44 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_863_000 picoseconds. - Weight::from_parts(3_027_000, 0) + // Minimum execution time: 3_058_000 picoseconds. + Weight::from_parts(3_199_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub(crate) fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_046_000 picoseconds. - Weight::from_parts(1_125_000, 0) + // Minimum execution time: 994_000 picoseconds. + Weight::from_parts(1_115_000, 0) } pub(crate) fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 811_000 picoseconds. - Weight::from_parts(871_000, 0) + // Minimum execution time: 763_000 picoseconds. + Weight::from_parts(824_000, 0) } pub(crate) fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(741_000, 0) + // Minimum execution time: 665_000 picoseconds. + Weight::from_parts(712_000, 0) } pub(crate) fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 687_000 picoseconds. - Weight::from_parts(741_000, 0) + // Minimum execution time: 627_000 picoseconds. + Weight::from_parts(695_000, 0) } pub(crate) fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 861_000 picoseconds. - Weight::from_parts(931_000, 0) + // Minimum execution time: 839_000 picoseconds. + Weight::from_parts(889_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -263,8 +270,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 74_622_000 picoseconds. - Weight::from_parts(77_059_000, 6196) + // Minimum execution time: 75_853_000 picoseconds. + Weight::from_parts(77_515_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -272,8 +279,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_603_000 picoseconds. - Weight::from_parts(7_871_000, 0) + // Minimum execution time: 8_183_000 picoseconds. + Weight::from_parts(8_378_000, 0) } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -289,8 +296,8 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `351` // Estimated: `6196` - // Minimum execution time: 65_617_000 picoseconds. - Weight::from_parts(66_719_000, 6196) + // Minimum execution time: 66_576_000 picoseconds. + Weight::from_parts(69_465_000, 6196) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -298,35 +305,35 @@ impl<T: frame_system::Config> WeightInfo<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 738_000 picoseconds. - Weight::from_parts(779_000, 0) + // Minimum execution time: 739_000 picoseconds. + Weight::from_parts(773_000, 0) } pub(crate) fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 688_000 picoseconds. - Weight::from_parts(755_000, 0) + // Minimum execution time: 648_000 picoseconds. + Weight::from_parts(693_000, 0) } pub(crate) fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 684_000 picoseconds. - Weight::from_parts(722_000, 0) + // Minimum execution time: 654_000 picoseconds. + Weight::from_parts(700_000, 0) } pub(crate) fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 694_000 picoseconds. - Weight::from_parts(738_000, 0) + // Minimum execution time: 646_000 picoseconds. + Weight::from_parts(702_000, 0) } pub(crate) fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 713_000 picoseconds. - Weight::from_parts(776_000, 0) + // Minimum execution time: 665_000 picoseconds. + Weight::from_parts(714_000, 0) } } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 0d80ef89a1c..87bf27e4ff1 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -229,6 +229,23 @@ benchmarks! { ); } + execute_with_origin { + let mut executor = new_executor::<T>(Default::default()); + let who: Junctions = Junctions::from([AccountId32 { id: [0u8; 32], network: None }]); + let instruction = Instruction::ExecuteWithOrigin { descendant_origin: Some(who.clone()), xcm: Xcm(vec![]) }; + let xcm = Xcm(vec![instruction]); + }: { + executor.bench_process(xcm)?; + } verify { + assert_eq!( + executor.origin(), + &Some(Location { + parents: 0, + interior: Here, + }), + ); + } + clear_origin { let mut executor = new_executor::<T>(Default::default()); let instruction = Instruction::ClearOrigin; diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs index 545b75a99ff..9baf58eacfb 100644 --- a/polkadot/xcm/src/v4/mod.rs +++ b/polkadot/xcm/src/v4/mod.rs @@ -1421,8 +1421,11 @@ impl<Call: Decode + GetDispatchInfo> TryFrom<NewInstruction<Call>> for Instructi weight_limit, check_origin: check_origin.map(|origin| origin.try_into()).transpose()?, }, - InitiateTransfer { .. } | PayFees { .. } | SetAssetClaimer { .. } => { - log::debug!(target: "xcm::v5tov4", "`{new_instruction:?}` not supported by v4"); + InitiateTransfer { .. } | + PayFees { .. } | + SetAssetClaimer { .. } | + ExecuteWithOrigin { .. } => { + log::debug!(target: "xcm::versions::v5tov4", "`{new_instruction:?}` not supported by v4"); return Err(()); }, }) diff --git a/polkadot/xcm/src/v5/mod.rs b/polkadot/xcm/src/v5/mod.rs index d455fa48ada..830b23cc44b 100644 --- a/polkadot/xcm/src/v5/mod.rs +++ b/polkadot/xcm/src/v5/mod.rs @@ -1109,6 +1109,25 @@ pub enum Instruction<Call> { assets: Vec<AssetTransferFilter>, remote_xcm: Xcm<()>, }, + + /// Executes inner `xcm` with origin set to the provided `descendant_origin`. Once the inner + /// `xcm` is executed, the original origin (the one active for this instruction) is restored. + /// + /// Parameters: + /// - `descendant_origin`: The origin that will be used during the execution of the inner + /// `xcm`. If set to `None`, the inner `xcm` is executed with no origin. If set to `Some(o)`, + /// the inner `xcm` is executed as if there was a `DescendOrigin(o)` executed before it, and + /// runs the inner xcm with origin: `original_origin.append_with(o)`. + /// - `xcm`: Inner instructions that will be executed with the origin modified according to + /// `descendant_origin`. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `BadOrigin` + ExecuteWithOrigin { descendant_origin: Option<InteriorLocation>, xcm: Xcm<Call> }, } impl<Call> Xcm<Call> { @@ -1189,6 +1208,8 @@ impl<Call> Instruction<Call> { PayFees { asset } => PayFees { asset }, InitiateTransfer { destination, remote_fees, preserve_origin, assets, remote_xcm } => InitiateTransfer { destination, remote_fees, preserve_origin, assets, remote_xcm }, + ExecuteWithOrigin { descendant_origin, xcm } => + ExecuteWithOrigin { descendant_origin, xcm: xcm.into() }, } } } @@ -1261,6 +1282,8 @@ impl<Call, W: XcmWeightInfo<Call>> GetWeight<W> for Instruction<Call> { PayFees { asset } => W::pay_fees(asset), InitiateTransfer { destination, remote_fees, preserve_origin, assets, remote_xcm } => W::initiate_transfer(destination, remote_fees, preserve_origin, assets, remote_xcm), + ExecuteWithOrigin { descendant_origin, xcm } => + W::execute_with_origin(descendant_origin, xcm), } } } diff --git a/polkadot/xcm/xcm-builder/src/weight.rs b/polkadot/xcm/xcm-builder/src/weight.rs index f8c0275d0f5..6521121f2c9 100644 --- a/polkadot/xcm/xcm-builder/src/weight.rs +++ b/polkadot/xcm/xcm-builder/src/weight.rs @@ -65,7 +65,8 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo, M> FixedWeightBounds<T, C, M> ) -> Result<Weight, ()> { let instr_weight = match instruction { Transact { ref mut call, .. } => call.ensure_decoded()?.get_dispatch_info().call_weight, - SetErrorHandler(xcm) | SetAppendix(xcm) => Self::weight_with_limit(xcm, instrs_limit)?, + SetErrorHandler(xcm) | SetAppendix(xcm) | ExecuteWithOrigin { xcm, .. } => + Self::weight_with_limit(xcm, instrs_limit)?, _ => Weight::zero(), }; T::get().checked_add(&instr_weight).ok_or(()) diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index e33f94389b2..4e051f24050 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -314,7 +314,7 @@ impl<Config: config::Config> FeeManager for XcmExecutor<Config> { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct ExecutorError { pub index: u32, pub xcm_error: XcmError, @@ -1041,19 +1041,25 @@ impl<Config: config::Config> XcmExecutor<Config> { ); Ok(()) }, - DescendOrigin(who) => self - .context - .origin - .as_mut() - .ok_or(XcmError::BadOrigin)? - .append_with(who) - .map_err(|e| { - tracing::error!(target: "xcm::process_instruction::descend_origin", ?e, "Failed to append junctions"); - XcmError::LocationFull - }), - ClearOrigin => { - self.context.origin = None; - Ok(()) + DescendOrigin(who) => self.do_descend_origin(who), + ClearOrigin => self.do_clear_origin(), + ExecuteWithOrigin { descendant_origin, xcm } => { + let previous_origin = self.context.origin.clone(); + + // Set new temporary origin. + if let Some(who) = descendant_origin { + self.do_descend_origin(who)?; + } else { + self.do_clear_origin()?; + } + // Process instructions. + let result = self.process(xcm).map_err(|error| { + tracing::error!(target: "xcm::execute", ?error, actual_origin = ?self.context.origin, original_origin = ?previous_origin, "ExecuteWithOrigin inner xcm failure"); + error.xcm_error + }); + // Reset origin to previous one. + self.context.origin = previous_origin; + result }, ReportError(response_info) => { // Report the given result by sending a QueryResponse XCM to a previously given @@ -1643,6 +1649,23 @@ impl<Config: config::Config> XcmExecutor<Config> { } } + fn do_descend_origin(&mut self, who: InteriorLocation) -> XcmResult { + self.context + .origin + .as_mut() + .ok_or(XcmError::BadOrigin)? + .append_with(who) + .map_err(|e| { + tracing::error!(target: "xcm::do_descend_origin", ?e, "Failed to append junctions"); + XcmError::LocationFull + }) + } + + fn do_clear_origin(&mut self) -> XcmResult { + self.context.origin = None; + Ok(()) + } + /// Deposit `to_deposit` assets to `beneficiary`, without giving up on the first (transient) /// error, and retrying once just in case one of the subsequently deposited assets satisfy some /// requirement. diff --git a/polkadot/xcm/xcm-executor/src/tests/execute_with_origin.rs b/polkadot/xcm/xcm-executor/src/tests/execute_with_origin.rs new file mode 100644 index 00000000000..daba8ae1c03 --- /dev/null +++ b/polkadot/xcm/xcm-executor/src/tests/execute_with_origin.rs @@ -0,0 +1,177 @@ +// Copyright (C) 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 <http://www.gnu.org/licenses/>. + +//! Unit tests for the `ExecuteWithOrigin` instruction. +//! +//! See the [XCM RFC](https://github.com/polkadot-fellows/xcm-format/pull/38) +//! and the [specification](https://github.com/polkadot-fellows/xcm-format/tree/8cef08e375c6f6d3966909ccf773ed46ac703917) for more information. +//! +//! The XCM RFCs were moved to the fellowship RFCs but this one was approved and merged before that. + +use xcm::prelude::*; + +use super::mock::*; +use crate::ExecutorError; + +// The sender and recipient we use across these tests. +const SENDER_1: [u8; 32] = [0; 32]; +const SENDER_2: [u8; 32] = [1; 32]; +const RECIPIENT: [u8; 32] = [2; 32]; + +// ===== Happy path ===== + +// In this test, root descends into one account to pay fees, pops that origin +// and descends into a second account to withdraw funds. +// These assets can now be used to perform actions as root. +#[test] +fn root_can_descend_into_more_than_one_account() { + // Make sure the sender has enough funds to withdraw. + add_asset(SENDER_1, (Here, 10u128)); + add_asset(SENDER_2, (Here, 100u128)); + + // Build xcm. + let xcm = Xcm::<TestCall>::builder_unsafe() + .execute_with_origin( + Some(SENDER_1.into()), + Xcm::<TestCall>::builder_unsafe() + .withdraw_asset((Here, 10u128)) + .pay_fees((Here, 10u128)) + .build(), + ) + .execute_with_origin( + Some(SENDER_2.into()), + Xcm::<TestCall>::builder_unsafe().withdraw_asset((Here, 100u128)).build(), + ) + .expect_origin(Some(Here.into())) + .deposit_asset(All, RECIPIENT) + .build(); + + let (mut vm, weight) = instantiate_executor(Here, xcm.clone()); + + // Program runs successfully. + assert!(vm.bench_process(xcm).is_ok()); + assert!(vm.bench_post_process(weight).ensure_complete().is_ok()); + + // RECIPIENT gets the funds. + assert_eq!(asset_list(RECIPIENT), [(Here, 100u128).into()]); +} + +// ExecuteWithOrigin works for clearing the origin as well. +#[test] +fn works_for_clearing_origin() { + // Make sure the sender has enough funds to withdraw. + add_asset(SENDER_1, (Here, 100u128)); + + // Build xcm. + let xcm = Xcm::<TestCall>::builder_unsafe() + // Root code. + .expect_origin(Some(Here.into())) + .execute_with_origin( + None, + // User code, we run it with no origin. + Xcm::<TestCall>::builder_unsafe().expect_origin(None).build(), + ) + // We go back to root code. + .build(); + + let (mut vm, weight) = instantiate_executor(Here, xcm.clone()); + + // Program runs successfully. + assert!(vm.bench_process(xcm).is_ok()); + assert!(vm.bench_post_process(weight).ensure_complete().is_ok()); +} + +// Setting the error handler or appendix inside of `ExecuteWithOrigin` +// will work as expected. +#[test] +fn set_error_handler_and_appendix_work() { + add_asset(SENDER_1, (Here, 110u128)); + + let xcm = Xcm::<TestCall>::builder_unsafe() + .execute_with_origin( + Some(SENDER_1.into()), + Xcm::<TestCall>::builder_unsafe() + .withdraw_asset((Here, 110u128)) + .pay_fees((Here, 10u128)) + .set_error_handler( + Xcm::<TestCall>::builder_unsafe() + .deposit_asset(vec![(Here, 10u128).into()], SENDER_2) + .build(), + ) + .set_appendix( + Xcm::<TestCall>::builder_unsafe().deposit_asset(All, RECIPIENT).build(), + ) + .build(), + ) + .build(); + + let (mut vm, weight) = instantiate_executor(Here, xcm.clone()); + + // Program runs successfully. + assert!(vm.bench_process(xcm).is_ok()); + + assert_eq!( + vm.error_handler(), + &Xcm::<TestCall>(vec![DepositAsset { + assets: vec![Asset { id: AssetId(Location::new(0, [])), fun: Fungible(10) }].into(), + beneficiary: Location::new(0, [AccountId32 { id: SENDER_2, network: None }]), + },]) + ); + assert_eq!( + vm.appendix(), + &Xcm::<TestCall>(vec![DepositAsset { + assets: All.into(), + beneficiary: Location::new(0, [AccountId32 { id: RECIPIENT, network: None }]), + },]) + ); + + assert!(vm.bench_post_process(weight).ensure_complete().is_ok()); +} + +// ===== Unhappy path ===== + +// Processing still can't be called recursively more than the limit. +#[test] +fn recursion_exceeds_limit() { + // Make sure the sender has enough funds to withdraw. + add_asset(SENDER_1, (Here, 10u128)); + add_asset(SENDER_2, (Here, 100u128)); + + let mut xcm = Xcm::<TestCall>::builder_unsafe() + .execute_with_origin(None, Xcm::<TestCall>::builder_unsafe().clear_origin().build()) + .build(); + + // 10 is the RECURSION_LIMIT. + for _ in 0..10 { + let clone_of_xcm = xcm.clone(); + if let ExecuteWithOrigin { xcm: ref mut inner, .. } = xcm.inner_mut()[0] { + *inner = clone_of_xcm; + } + } + + let (mut vm, weight) = instantiate_executor(Here, xcm.clone()); + + // Program errors with `ExceedsStackLimit`. + assert_eq!( + vm.bench_process(xcm), + Err(ExecutorError { + index: 0, + xcm_error: XcmError::ExceedsStackLimit, + weight: Weight::zero(), + }) + ); + assert!(vm.bench_post_process(weight).ensure_complete().is_ok()); +} diff --git a/polkadot/xcm/xcm-executor/src/tests/mod.rs b/polkadot/xcm/xcm-executor/src/tests/mod.rs index 5c133871f0b..15a0565e357 100644 --- a/polkadot/xcm/xcm-executor/src/tests/mod.rs +++ b/polkadot/xcm/xcm-executor/src/tests/mod.rs @@ -20,6 +20,7 @@ //! `xcm-emulator` based tests in the cumulus folder. //! These tests deal with internal state changes of the XCVM. +mod execute_with_origin; mod initiate_transfer; mod mock; mod pay_fees; diff --git a/prdoc/pr_6304.prdoc b/prdoc/pr_6304.prdoc new file mode 100644 index 00000000000..1c8f1bb25de --- /dev/null +++ b/prdoc/pr_6304.prdoc @@ -0,0 +1,45 @@ +# 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: XCMv5 - Add ExecuteWithOrigin instruction + +doc: + - audience: [Runtime User, Runtime Dev] + description: | + Added a new instruction to XCMv5, ExecuteWithOrigin, that allows you to specify an interior origin + and a set of instructions that will be executed using that origin. + The origins you can choose are `None` to clear it during the execution of the inner instructions, + or `Some(InteriorLocation)` to descend into an interior location. + These two options mimic the behaviour of `ClearOrigin` and `DescendOrigin` respectively. + Crucially, this instruction goes back to the previous origin once the execution of those inner + instructions end. + This allows use-cases like a parent location paying fees with one interior location, fetching funds + with another, claiming assets on behalf of many different ones, etc. + +crates: + - name: staging-xcm + bump: major + - name: staging-xcm-executor + bump: minor + - name: staging-xcm-builder + bump: minor + - name: asset-hub-rococo-runtime + bump: minor + - name: asset-hub-westend-runtime + bump: minor + - name: bridge-hub-rococo-runtime + bump: minor + - name: bridge-hub-westend-runtime + bump: minor + - name: people-rococo-runtime + bump: minor + - name: people-westend-runtime + bump: minor + - name: coretime-rococo-runtime + bump: minor + - name: coretime-westend-runtime + bump: minor + - name: rococo-runtime + bump: minor + - name: westend-runtime + bump: minor -- GitLab