From 46090ff114a131be4139f0abf619330990194770 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Mon, 15 Jan 2024 23:30:51 +1100 Subject: [PATCH 001/283] Unbalanced and Balanced fungible conformance tests, and fungible fixes (#1296) Original PR https://github.com/paritytech/substrate/pull/14655 --- Partial https://github.com/paritytech/polkadot-sdk/issues/225 - [x] Adds conformance tests for Unbalanced - [x] Adds conformance tests for Balanced - Several minor fixes to fungible default implementations and the Balances pallet - [x] `Unbalanced::decrease_balance` can reap account when `Preservation` is `Preserve` - [x] `Balanced::pair` can return pairs of imbalances which do not cancel each other out - [x] Balances pallet `active_issuance` 'underflow' - [x] Refactors the conformance test file structure to match the fungible file structure: tests for traits in regular.rs go into a test file named regular.rs, tests for traits in freezes.rs go into a test file named freezes.rs, etc. - [x] Improve doc comments - [x] Simplify macros ## Fixes ### `Unbalanced::decrease_balance` can reap account when called with `Preservation::Preserve` There is a potential issue in the default implementation of `Unbalanced::decrease_balance`. The implementation can delete an account even when it is called with `preservation: Preservation::Preserve`. This seems to contradict the documentation of `Preservation::Preserve`: ```rust /// The account may not be killed and our provider reference must remain (in the context of /// tokens, this means that the account may not be dusted). Preserve, ``` I updated `Unbalanced::decrease_balance` to return `Err(TokenError::BelowMinimum)` when a withdrawal would cause the account to be reaped and `preservation: Preservation::Preserve`. - [ ] TODO Confirm with @gavofyork that this is correct behavior Test for this behavior: https://github.com/paritytech/polkadot-sdk/blob/e5c876dd6b59e2b7dbacaa4538cb42c802db3730/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular.rs#L912-L937 ### `Balanced::pair` returning non-canceling pairs `Balanced::pair` is supposed to create a pair of imbalances that cancel each other out. However this is not the case when the method is called with an amount greater than the total supply. In the existing default implementation, `Balanced::pair` creates a pair by first rescinding the balance, creating `Debt`, and then issuing the balance, creating `Credit`. When creating `Debt`, if the amount to create exceeds the `total_supply`, `total_supply` units of `Debt` are created *instead* of `amount` units of `Debt`. This can lead to non-canceling amount of `Credit` and `Debt` being created. To address this, I create the credit and debt directly in the method instead of calling `issue` and `rescind`. Test for this behavior: https://github.com/paritytech/polkadot-sdk/blob/e5c876dd6b59e2b7dbacaa4538cb42c802db3730/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular.rs#L1323-L1346 ### `Balances` pallet `active_issuance` 'underflow' This PR resolves an issue in the `Balances` pallet that can lead to odd behavior of `active_issuance`. Currently, the Balances pallet doesn't check if `InactiveIssuance` remains less than or equal to `TotalIssuance` when supply is deactivated. This allows `InactiveIssuance` to be greater than `TotalIssuance`, which can result in unexpected behavior from the perspective of the fungible API. `active_issuance` is derived from `TotalIssuance.saturating_sub(InactiveIssuance)`. If an `amount` is deactivated that causes `InactiveIssuance` to become greater TotalIssuance, `active_issuance` will return 0. However once in that state, reactivating an amount will not increase `active_issuance` by the reactivated `amount` as expected. Consider this test where the last assertion would fail due to this issue: https://github.com/paritytech/polkadot-sdk/blob/e5c876dd6b59e2b7dbacaa4538cb42c802db3730/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular.rs#L1036-L1071 To address this, I've modified the `deactivate` function to ensure `InactiveIssuance` never surpasses `TotalIssuance`. --------- Co-authored-by: Muharem --- prdoc/pr_1296.prdoc | 16 + substrate/frame/assets/src/tests/sets.rs | 2 +- substrate/frame/balances/src/impl_fungible.rs | 5 +- .../src/tests/fungible_conformance_tests.rs | 81 +- .../tokens/fungible/conformance_tests/mod.rs | 1 + .../conformance_tests/regular/balanced.rs | 292 +++++++ .../fungible/conformance_tests/regular/mod.rs | 20 + .../conformance_tests/regular/mutate.rs | 783 ++++++++++++++++++ .../conformance_tests/regular/unbalanced.rs | 281 +++++++ .../src/traits/tokens/fungible/item_of.rs | 8 +- .../src/traits/tokens/fungible/regular.rs | 97 ++- .../src/traits/tokens/fungible/union_of.rs | 15 +- .../src/traits/tokens/fungibles/regular.rs | 24 +- .../src/traits/tokens/fungibles/union_of.rs | 17 +- 14 files changed, 1563 insertions(+), 79 deletions(-) create mode 100644 prdoc/pr_1296.prdoc create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs create mode 100644 substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs diff --git a/prdoc/pr_1296.prdoc b/prdoc/pr_1296.prdoc new file mode 100644 index 00000000000..b7ef4288a57 --- /dev/null +++ b/prdoc/pr_1296.prdoc @@ -0,0 +1,16 @@ +title: fungible fixes and more conformance tests + +doc: + - audience: Runtime Dev + description: | + Adds conformance tests for the Balanced and Unbalanced fungible traits + Fixes Unbalanced::decrease_balance not respecting preservation + Fixes Balanced::pair possibly returning pairs of imbalances which do not cancel each other out. Method now returns a Result instead (breaking change). + Fixes Balances pallet active_issuance possible 'underflow' + Refactors the conformance test file structure to match the fungible file structure: tests for traits in regular.rs go into a test file named regular.rs, tests for traits in freezes.rs go into a test file named freezes.rs, etc. + Improve doc comments + Simplify macros + +crates: + - name: pallet-balances + - name: frame-support diff --git a/substrate/frame/assets/src/tests/sets.rs b/substrate/frame/assets/src/tests/sets.rs index bdff5175185..f85a736c083 100644 --- a/substrate/frame/assets/src/tests/sets.rs +++ b/substrate/frame/assets/src/tests/sets.rs @@ -153,7 +153,7 @@ fn pair_from_set_types_works() { assert_eq!(First::::total_issuance(()), 100); assert_eq!(First::::total_issuance(()), Assets::total_issuance(asset1)); - let (debt, credit) = First::::pair((), 100); + let (debt, credit) = First::::pair((), 100).unwrap(); assert_eq!(First::::total_issuance(()), 100); assert_eq!(debt.peek(), 100); assert_eq!(credit.peek(), 100); diff --git a/substrate/frame/balances/src/impl_fungible.rs b/substrate/frame/balances/src/impl_fungible.rs index 6737727e0a2..0f4e51f3501 100644 --- a/substrate/frame/balances/src/impl_fungible.rs +++ b/substrate/frame/balances/src/impl_fungible.rs @@ -177,7 +177,10 @@ impl, I: 'static> fungible::Unbalanced for Pallet::mutate(|b| b.saturating_accrue(amount)); + InactiveIssuance::::mutate(|b| { + // InactiveIssuance cannot be greater than TotalIssuance. + *b = b.saturating_add(amount).min(TotalIssuance::::get()); + }); } fn reactivate(amount: Self::Balance) { diff --git a/substrate/frame/balances/src/tests/fungible_conformance_tests.rs b/substrate/frame/balances/src/tests/fungible_conformance_tests.rs index 6262aa04dc0..5c0c19a554a 100644 --- a/substrate/frame/balances/src/tests/fungible_conformance_tests.rs +++ b/substrate/frame/balances/src/tests/fungible_conformance_tests.rs @@ -19,17 +19,19 @@ use super::*; use frame_support::traits::fungible::{conformance_tests, Inspect, Mutate}; use paste::paste; -macro_rules! run_tests { - ($path:path, $ext_deposit:expr, $($name:ident),*) => { +macro_rules! generate_tests { + // Handle a conformance test that requires special testing with and without a dust trap. + (dust_trap_variation, $base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { $( paste! { #[test] - fn [< $name _existential_deposit_ $ext_deposit _dust_trap_on >]() { + fn [<$trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_on >]() { + // Some random trap account. let trap_account = ::AccountId::from(65174286u64); let builder = ExtBuilder::default().existential_deposit($ext_deposit).dust_trap(trap_account); builder.build_and_execute_with(|| { Balances::set_balance(&trap_account, Balances::minimum_balance()); - $path::$name::< + $base_path::$scope::$trait::$test_name::< Balances, ::AccountId, >(Some(trap_account)); @@ -37,10 +39,10 @@ macro_rules! run_tests { } #[test] - fn [< $name _existential_deposit_ $ext_deposit _dust_trap_off >]() { + fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit _dust_trap_off >]() { let builder = ExtBuilder::default().existential_deposit($ext_deposit); builder.build_and_execute_with(|| { - $path::$name::< + $base_path::$scope::$trait::$test_name::< Balances, ::AccountId, >(None); @@ -49,9 +51,37 @@ macro_rules! run_tests { } )* }; - ($path:path, $ext_deposit:expr) => { - run_tests!( - $path, + // Regular conformance test + ($base_path:path, $scope:expr, $trait:ident, $ext_deposit:expr, $($test_name:ident),*) => { + $( + paste! { + #[test] + fn [< $trait _ $scope _ $test_name _existential_deposit_ $ext_deposit>]() { + let builder = ExtBuilder::default().existential_deposit($ext_deposit); + builder.build_and_execute_with(|| { + $base_path::$scope::$trait::$test_name::< + Balances, + ::AccountId, + >(); + }); + } + } + )* + }; + ($base_path:path, $ext_deposit:expr) => { + // regular::mutate + generate_tests!( + dust_trap_variation, + $base_path, + regular, + mutate, + $ext_deposit, + transfer_expendable_dust + ); + generate_tests!( + $base_path, + regular, + mutate, $ext_deposit, mint_into_success, mint_into_overflow, @@ -66,7 +96,6 @@ macro_rules! run_tests { shelve_insufficient_funds, transfer_success, transfer_expendable_all, - transfer_expendable_dust, transfer_protect_preserve, set_balance_mint_success, set_balance_burn_success, @@ -79,10 +108,34 @@ macro_rules! run_tests { reducible_balance_expendable, reducible_balance_protect_preserve ); + // regular::unbalanced + generate_tests!( + $base_path, + regular, + unbalanced, + $ext_deposit, + write_balance, + decrease_balance_expendable, + decrease_balance_preserve, + increase_balance, + set_total_issuance, + deactivate_and_reactivate + ); + // regular::balanced + generate_tests!( + $base_path, + regular, + balanced, + $ext_deposit, + issue_and_resolve_credit, + rescind_and_settle_debt, + deposit, + withdraw, + pair + ); }; } -run_tests!(conformance_tests::inspect_mutate, 1); -run_tests!(conformance_tests::inspect_mutate, 2); -run_tests!(conformance_tests::inspect_mutate, 5); -run_tests!(conformance_tests::inspect_mutate, 1000); +generate_tests!(conformance_tests, 1); +generate_tests!(conformance_tests, 5); +generate_tests!(conformance_tests, 1000); diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs index 56166436003..005674088dd 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/mod.rs @@ -16,3 +16,4 @@ // limitations under the License. pub mod inspect_mutate; +pub mod regular; diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs new file mode 100644 index 00000000000..d8d20543e3d --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/balanced.rs @@ -0,0 +1,292 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::traits::{ + fungible::{Balanced, Inspect}, + tokens::{imbalance::Imbalance as ImbalanceT, Fortitude, Precision, Preservation}, +}; +use core::fmt::Debug; +use frame_support::traits::tokens::fungible::imbalance::{Credit, Debt}; +use sp_arithmetic::{traits::AtLeast8BitUnsigned, ArithmeticError}; +use sp_runtime::{traits::Bounded, TokenError}; + +/// Tests issuing and resolving [`Credit`] imbalances with [`Balanced::issue`] and +/// [`Balanced::resolve`]. +pub fn issue_and_resolve_credit() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(0); + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); + + // Account that doesn't exist yet can't be credited below the minimum balance + let credit: Credit = T::issue(T::minimum_balance() - 1.into()); + // issue temporarily increases total issuance + assert_eq!(T::total_issuance(), credit.peek()); + match T::resolve(&account, credit) { + Ok(_) => panic!("Balanced::resolve should have failed"), + Err(c) => assert_eq!(c.peek(), T::minimum_balance() - 1.into()), + }; + // Credit was unused and dropped from total issuance + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); + + // Credit account with minimum balance + let credit: Credit = T::issue(T::minimum_balance()); + match T::resolve(&account, credit) { + Ok(()) => {}, + Err(_) => panic!("resolve failed"), + }; + assert_eq!(T::total_issuance(), T::minimum_balance()); + assert_eq!(T::balance(&account), T::minimum_balance()); + + // Now that account has been created, it can be credited with an amount below the minimum + // balance. + let total_issuance_before = T::total_issuance(); + let balance_before = T::balance(&account); + let amount = T::minimum_balance() - 1.into(); + let credit: Credit = T::issue(amount); + match T::resolve(&account, credit) { + Ok(()) => {}, + Err(_) => panic!("resolve failed"), + }; + assert_eq!(T::total_issuance(), total_issuance_before + amount); + assert_eq!(T::balance(&account), balance_before + amount); + + // Unhandled issuance is dropped from total issuance + // `let _ = ...` immediately drops the issuance, so everything should be unchanged when + // logic gets to the assertions. + let total_issuance_before = T::total_issuance(); + let balance_before = T::balance(&account); + let _ = T::issue(5.into()); + assert_eq!(T::total_issuance(), total_issuance_before); + assert_eq!(T::balance(&account), balance_before); +} + +/// Tests issuing and resolving [`Debt`] imbalances with [`Balanced::rescind`] and +/// [`Balanced::settle`]. +pub fn rescind_and_settle_debt() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Credit account with some balance + let account = AccountId::from(0); + let initial_bal = T::minimum_balance() + 10.into(); + let credit = T::issue(initial_bal); + match T::resolve(&account, credit) { + Ok(()) => {}, + Err(_) => panic!("resolve failed"), + }; + assert_eq!(T::total_issuance(), initial_bal); + assert_eq!(T::balance(&account), initial_bal); + + // Rescind some balance + let rescind_amount = 2.into(); + let debt: Debt = T::rescind(rescind_amount); + assert_eq!(debt.peek(), rescind_amount); + match T::settle(&account, debt, Preservation::Expendable) { + Ok(c) => { + // We settled the full debt and account was not dusted, so there is no left over + // credit. + assert_eq!(c.peek(), 0.into()); + }, + Err(_) => panic!("settle failed"), + }; + assert_eq!(T::total_issuance(), initial_bal - rescind_amount); + assert_eq!(T::balance(&account), initial_bal - rescind_amount); + + // Unhandled debt is added from total issuance + // `let _ = ...` immediately drops the debt, so everything should be unchanged when + // logic gets to the assertions. + let _ = T::rescind(T::minimum_balance()); + assert_eq!(T::total_issuance(), initial_bal - rescind_amount); + assert_eq!(T::balance(&account), initial_bal - rescind_amount); + + // Preservation::Preserve will not allow the account to be dusted on settle + let balance_before = T::balance(&account); + let total_issuance_before = T::total_issuance(); + let rescind_amount = balance_before - T::minimum_balance() + 1.into(); + let debt: Debt = T::rescind(rescind_amount); + assert_eq!(debt.peek(), rescind_amount); + // The new debt is temporarily removed from total_issuance + assert_eq!(T::total_issuance(), total_issuance_before - debt.peek().into()); + match T::settle(&account, debt, Preservation::Preserve) { + Ok(_) => panic!("Balanced::settle should have failed"), + Err(d) => assert_eq!(d.peek(), rescind_amount), + }; + // The debt is added back to total_issuance because it was dropped, leaving the operation a + // noop. + assert_eq!(T::total_issuance(), total_issuance_before); + assert_eq!(T::balance(&account), balance_before); + + // Preservation::Expendable allows the account to be dusted on settle + let debt: Debt = T::rescind(rescind_amount); + match T::settle(&account, debt, Preservation::Expendable) { + Ok(c) => { + // Dusting happens internally, there is no left over credit. + assert_eq!(c.peek(), 0.into()); + }, + Err(_) => panic!("settle failed"), + }; + // The account is dusted and debt dropped from total_issuance + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); +} + +/// Tests [`Balanced::deposit`]. +pub fn deposit() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Cannot deposit < minimum balance into non-existent account + let account = AccountId::from(0); + let amount = T::minimum_balance() - 1.into(); + match T::deposit(&account, amount, Precision::Exact) { + Ok(_) => panic!("Balanced::deposit should have failed"), + Err(e) => assert_eq!(e, TokenError::BelowMinimum.into()), + }; + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); + + // Can deposit minimum balance into non-existent account + let amount = T::minimum_balance(); + match T::deposit(&account, amount, Precision::Exact) { + Ok(d) => assert_eq!(d.peek(), amount), + Err(_) => panic!("Balanced::deposit failed"), + }; + assert_eq!(T::total_issuance(), amount); + assert_eq!(T::balance(&account), amount); + + // Depositing amount that would overflow when Precision::Exact fails and is a noop + let amount = T::Balance::max_value(); + let balance_before = T::balance(&account); + let total_issuance_before = T::total_issuance(); + match T::deposit(&account, amount, Precision::Exact) { + Ok(_) => panic!("Balanced::deposit should have failed"), + Err(e) => assert_eq!(e, ArithmeticError::Overflow.into()), + }; + assert_eq!(T::total_issuance(), total_issuance_before); + assert_eq!(T::balance(&account), balance_before); + + // Depositing amount that would overflow when Precision::BestEffort saturates + match T::deposit(&account, amount, Precision::BestEffort) { + Ok(d) => assert_eq!(d.peek(), T::Balance::max_value() - balance_before), + Err(_) => panic!("Balanced::deposit failed"), + }; + assert_eq!(T::total_issuance(), T::Balance::max_value()); + assert_eq!(T::balance(&account), T::Balance::max_value()); +} + +/// Tests [`Balanced::withdraw`]. +pub fn withdraw() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(0); + + // Init an account with some balance + let initial_balance = T::minimum_balance() + 10.into(); + match T::deposit(&account, initial_balance, Precision::Exact) { + Ok(_) => {}, + Err(_) => panic!("Balanced::deposit failed"), + }; + assert_eq!(T::total_issuance(), initial_balance); + assert_eq!(T::balance(&account), initial_balance); + + // Withdrawing an amount smaller than the balance works when Precision::Exact + let amount = 1.into(); + match T::withdraw( + &account, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ) { + Ok(c) => assert_eq!(c.peek(), amount), + Err(_) => panic!("withdraw failed"), + }; + assert_eq!(T::total_issuance(), initial_balance - amount); + assert_eq!(T::balance(&account), initial_balance - amount); + + // Withdrawing an amount greater than the balance fails when Precision::Exact + let balance_before = T::balance(&account); + let amount = balance_before + 1.into(); + match T::withdraw( + &account, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ) { + Ok(_) => panic!("should have failed"), + Err(e) => assert_eq!(e, TokenError::FundsUnavailable.into()), + }; + assert_eq!(T::total_issuance(), balance_before); + assert_eq!(T::balance(&account), balance_before); + + // Withdrawing an amount greater than the balance works when Precision::BestEffort + let balance_before = T::balance(&account); + let amount = balance_before + 1.into(); + match T::withdraw( + &account, + amount, + Precision::BestEffort, + Preservation::Expendable, + Fortitude::Polite, + ) { + Ok(c) => assert_eq!(c.peek(), balance_before), + Err(_) => panic!("withdraw failed"), + }; + assert_eq!(T::total_issuance(), 0.into()); + assert_eq!(T::balance(&account), 0.into()); +} + +/// Tests [`Balanced::pair`]. +pub fn pair() +where + T: Balanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + T::set_total_issuance(50.into()); + + // Pair zero balance works + let (credit, debt) = T::pair(0.into()).unwrap(); + assert_eq!(debt.peek(), 0.into()); + assert_eq!(credit.peek(), 0.into()); + + // Pair with non-zero balance: the credit and debt cancel each other out + let balance = 10.into(); + let (credit, debt) = T::pair(balance).unwrap(); + assert_eq!(credit.peek(), balance); + assert_eq!(debt.peek(), balance); + + // Creating a pair that could increase total_issuance beyond the max value returns an error + let max_value = T::Balance::max_value(); + let distance_from_max_value = 5.into(); + T::set_total_issuance(max_value - distance_from_max_value); + T::pair(distance_from_max_value + 5.into()).unwrap_err(); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs new file mode 100644 index 00000000000..85acbcf2fcd --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod balanced; +pub mod mutate; +pub mod unbalanced; diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs new file mode 100644 index 00000000000..95b5256bb49 --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/mutate.rs @@ -0,0 +1,783 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::traits::{ + fungible::{Inspect, Mutate}, + tokens::{ + DepositConsequence, Fortitude, Precision, Preservation, Provenance, WithdrawConsequence, + }, +}; +use core::fmt::Debug; +use sp_arithmetic::traits::AtLeast8BitUnsigned; +use sp_runtime::traits::{Bounded, Zero}; + +/// Test [`Mutate::mint_into`] for successful token minting. +/// +/// It ensures that account balances and total issuance values are updated correctly after +/// minting tokens into two distinct accounts. +pub fn mint_into_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + + // Test: Mint an amount into each account + let amount_0 = T::minimum_balance(); + let amount_1 = T::minimum_balance() + 5.into(); + T::mint_into(&account_0, amount_0).unwrap(); + T::mint_into(&account_1, amount_1).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), amount_0); + assert_eq!(T::total_balance(&account_1), amount_1); + assert_eq!(T::balance(&account_0), amount_0); + assert_eq!(T::balance(&account_1), amount_1); + + // Verify: Total issuance is updated correctly + assert_eq!(T::total_issuance(), initial_total_issuance + amount_0 + amount_1); + assert_eq!(T::active_issuance(), initial_active_issuance + amount_0 + amount_1); +} + +/// Test [`Mutate::mint_into`] for overflow prevention. +/// +/// This test ensures that minting tokens beyond the maximum balance value for an account +/// returns an error and does not change the account balance or total issuance values. +pub fn mint_into_overflow() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let amount = T::Balance::max_value() - 5.into() - initial_total_issuance; + + // Mint just below the maximum balance + T::mint_into(&account, amount).unwrap(); + + // Verify: Minting beyond the maximum balance value returns an Err + T::mint_into(&account, 10.into()).unwrap_err(); + + // Verify: The balance did not change + assert_eq!(T::total_balance(&account), amount); + assert_eq!(T::balance(&account), amount); + + // Verify: The total issuance did not change + assert_eq!(T::total_issuance(), initial_total_issuance + amount); + assert_eq!(T::active_issuance(), initial_active_issuance + amount); +} + +/// Test [`Mutate::mint_into`] for handling balances below the minimum value. +/// +/// This test verifies that minting tokens below the minimum balance for an account +/// returns an error and has no impact on the account balance or total issuance values. +pub fn mint_into_below_minimum() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Skip if there is no minimum balance + if T::minimum_balance() == T::Balance::zero() { + return + } + + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let amount = T::minimum_balance() - 1.into(); + + // Verify: Minting below the minimum balance returns Err + T::mint_into(&account, amount).unwrap_err(); + + // Verify: noop + assert_eq!(T::total_balance(&account), T::Balance::zero()); + assert_eq!(T::balance(&account), T::Balance::zero()); + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); +} + +/// Test [`Mutate::burn_from`] for successfully burning an exact amount of tokens. +/// +/// This test checks that burning tokens with [`Precision::Exact`] correctly reduces the account +/// balance and total issuance values by the burned amount. +pub fn burn_from_exact_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Setup account + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: Burn an exact amount from the account + let amount_to_burn = T::Balance::from(5); + let precision = Precision::Exact; + let force = Fortitude::Polite; + T::burn_from(&account, amount_to_burn, precision, force).unwrap(); + + // Verify: The balance and total issuance should be reduced by the burned amount + assert_eq!(T::balance(&account), initial_balance - amount_to_burn); + assert_eq!(T::total_balance(&account), initial_balance - amount_to_burn); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - amount_to_burn); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - amount_to_burn); +} + +/// Test [`Mutate::burn_from`] for successfully burning tokens with [`Precision::BestEffort`]. +/// +/// This test verifies that the burning tokens with best-effort precision correctly reduces the +/// account balance and total issuance values by the reducible balance when attempting to burn +/// an amount greater than the reducible balance. +pub fn burn_from_best_effort_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Setup account + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Get reducible balance + let force = Fortitude::Polite; + let reducible_balance = T::reducible_balance(&account, Preservation::Expendable, force); + + // Test: Burn a best effort amount from the account that is greater than the reducible + // balance + let amount_to_burn = reducible_balance + 5.into(); + let precision = Precision::BestEffort; + assert!(amount_to_burn > reducible_balance); + assert!(amount_to_burn > T::balance(&account)); + T::burn_from(&account, amount_to_burn, precision, force).unwrap(); + + // Verify: The balance and total issuance should be reduced by the reducible_balance + assert_eq!(T::balance(&account), initial_balance - reducible_balance); + assert_eq!(T::total_balance(&account), initial_balance - reducible_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - reducible_balance); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - reducible_balance); +} + +/// Test [`Mutate::burn_from`] handling of insufficient funds when called with +/// [`Precision::Exact`]. +/// +/// This test verifies that burning an amount greater than the account's balance with exact +/// precision returns an error and does not change the account balance or total issuance values. +pub fn burn_from_exact_insufficient_funds() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Set up the initial conditions and parameters for the test + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Verify: Burn an amount greater than the account's balance with Exact precision returns + // Err + let amount_to_burn = initial_balance + 10.into(); + let precision = Precision::Exact; + let force = Fortitude::Polite; + T::burn_from(&account, amount_to_burn, precision, force).unwrap_err(); + + // Verify: The balance and total issuance should remain unchanged + assert_eq!(T::balance(&account), initial_balance); + assert_eq!(T::total_balance(&account), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); +} + +/// Test [`Mutate::restore`] for successful restoration. +/// +/// This test verifies that restoring an amount into each account updates their balances and the +/// total issuance values correctly. +pub fn restore_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + + // Test: Restore an amount into each account + let amount_0 = T::minimum_balance(); + let amount_1 = T::minimum_balance() + 5.into(); + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + T::restore(&account_0, amount_0).unwrap(); + T::restore(&account_1, amount_1).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), amount_0); + assert_eq!(T::total_balance(&account_1), amount_1); + assert_eq!(T::balance(&account_0), amount_0); + assert_eq!(T::balance(&account_1), amount_1); + + // Verify: Total issuance is updated correctly + assert_eq!(T::total_issuance(), initial_total_issuance + amount_0 + amount_1); + assert_eq!(T::active_issuance(), initial_active_issuance + amount_0 + amount_1); +} + +/// Test [`Mutate::restore`] handles balance overflow. +/// +/// This test verifies that restoring an amount beyond the maximum balance returns an error and +/// does not change the account balance or total issuance values. +pub fn restore_overflow() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let amount = T::Balance::max_value() - 5.into() - initial_total_issuance; + + // Restore just below the maximum balance + T::restore(&account, amount).unwrap(); + + // Verify: Restoring beyond the maximum balance returns an Err + T::restore(&account, 10.into()).unwrap_err(); + + // Verify: The balance and total issuance did not change + assert_eq!(T::total_balance(&account), amount); + assert_eq!(T::balance(&account), amount); + assert_eq!(T::total_issuance(), initial_total_issuance + amount); + assert_eq!(T::active_issuance(), initial_active_issuance + amount); +} + +/// Test [`Mutate::restore`] handles restoration below the minimum balance. +/// +/// This test verifies that restoring an amount below the minimum balance returns an error and +/// does not change the account balance or total issuance values. +pub fn restore_below_minimum() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Skip if there is no minimum balance + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account = AccountId::from(10); + let amount = T::minimum_balance() - 1.into(); + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Verify: Restoring below the minimum balance returns Err + T::restore(&account, amount).unwrap_err(); + + // Verify: noop + assert_eq!(T::total_balance(&account), T::Balance::zero()); + assert_eq!(T::balance(&account), T::Balance::zero()); + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); +} + +/// Test [`Mutate::shelve`] for successful shelving. +/// +/// This test verifies that shelving an amount from an account reduces the account balance and +/// total issuance values by the shelved amount. +pub fn shelve_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Setup account + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + + T::restore(&account, initial_balance).unwrap(); + + // Test: Shelve an amount from the account + let amount_to_shelve = T::Balance::from(5); + T::shelve(&account, amount_to_shelve).unwrap(); + + // Verify: The balance and total issuance should be reduced by the shelved amount + assert_eq!(T::balance(&account), initial_balance - amount_to_shelve); + assert_eq!(T::total_balance(&account), initial_balance - amount_to_shelve); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - amount_to_shelve); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - amount_to_shelve); +} + +/// Test [`Mutate::shelve`] handles insufficient funds correctly. +/// +/// This test verifies that attempting to shelve an amount greater than the account's balance +/// returns an error and does not change the account balance or total issuance values. +pub fn shelve_insufficient_funds() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + + // Set up the initial conditions and parameters for the test + let account = AccountId::from(5); + let initial_balance = T::minimum_balance() + 10.into(); + T::restore(&account, initial_balance).unwrap(); + + // Verify: Shelving greater than the balance with Exact precision returns Err + let amount_to_shelve = initial_balance + 10.into(); + T::shelve(&account, amount_to_shelve).unwrap_err(); + + // Verify: The balance and total issuance should remain unchanged + assert_eq!(T::balance(&account), initial_balance); + assert_eq!(T::total_balance(&account), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance); +} + +/// Test [`Mutate::transfer`] for a successful transfer. +/// +/// This test verifies that transferring an amount between two accounts with updates the account +/// balances and maintains correct total issuance and active issuance values. +pub fn transfer_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + // Test: Transfer an amount from account_0 to account_1 + let transfer_amount = T::Balance::from(3); + T::transfer(&account_0, &account_1, transfer_amount, Preservation::Expendable).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), initial_balance - transfer_amount); + assert_eq!(T::total_balance(&account_1), initial_balance + transfer_amount); + assert_eq!(T::balance(&account_0), initial_balance - transfer_amount); + assert_eq!(T::balance(&account_1), initial_balance + transfer_amount); + + // Verify: Total issuance doesn't change + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); +} + +/// Test calling [`Mutate::transfer`] with [`Preservation::Expendable`] correctly transfers the +/// entire balance. +/// +/// This test verifies that transferring the entire balance from one account to another with +/// when preservation is expendable updates the account balances and maintains the total +/// issuance and active issuance values. +pub fn transfer_expendable_all() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + // Test: Transfer entire balance from account_0 to account_1 + let preservation = Preservation::Expendable; + let transfer_amount = initial_balance; + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), T::Balance::zero()); + assert_eq!(T::total_balance(&account_1), initial_balance * 2.into()); + assert_eq!(T::balance(&account_0), T::Balance::zero()); + assert_eq!(T::balance(&account_1), initial_balance * 2.into()); + + // Verify: Total issuance doesn't change + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); +} + +/// Test calling [`Mutate::transfer`] function with [`Preservation::Expendable`] and an amount +/// that results in some dust. +/// +/// This test verifies that dust is handled correctly when an account is reaped, with and +/// without a dust trap. +/// +/// # Parameters +/// +/// - dust_trap: An optional account identifier to which dust will be collected. If `None`, dust is +/// expected to be removed from the total and active issuance. +pub fn transfer_expendable_dust(dust_trap: Option) +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account_0 = AccountId::from(10); + let account_1 = AccountId::from(20); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let initial_dust_trap_balance = match dust_trap.clone() { + Some(dust_trap) => T::total_balance(&dust_trap), + None => T::Balance::zero(), + }; + + // Test: Transfer balance + let preservation = Preservation::Expendable; + let transfer_amount = T::Balance::from(11); + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap(); + + // Verify: Account balances are updated correctly + assert_eq!(T::total_balance(&account_0), T::Balance::zero()); + assert_eq!(T::total_balance(&account_1), initial_balance + transfer_amount); + assert_eq!(T::balance(&account_0), T::Balance::zero()); + assert_eq!(T::balance(&account_1), initial_balance + transfer_amount); + + match dust_trap { + Some(dust_trap) => { + // Verify: Total issuance and active issuance don't change + assert_eq!(T::total_issuance(), initial_total_issuance); + assert_eq!(T::active_issuance(), initial_active_issuance); + // Verify: Dust is collected into dust trap + assert_eq!( + T::total_balance(&dust_trap), + initial_dust_trap_balance + T::minimum_balance() - 1.into() + ); + assert_eq!( + T::balance(&dust_trap), + initial_dust_trap_balance + T::minimum_balance() - 1.into() + ); + }, + None => { + // Verify: Total issuance and active issuance are reduced by the dust amount + assert_eq!( + T::total_issuance(), + initial_total_issuance - T::minimum_balance() + 1.into() + ); + assert_eq!( + T::active_issuance(), + initial_active_issuance - T::minimum_balance() + 1.into() + ); + }, + } +} + +/// Test [`Mutate::transfer`] with [`Preservation::Protect`] and [`Preservation::Preserve`] +/// transferring the entire balance. +/// +/// This test verifies that attempting to transfer the entire balance with returns an error when +/// preservation should not allow it, and the account balances, total issuance, and active +/// issuance values remain unchanged. +pub fn transfer_protect_preserve() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // This test means nothing if there is no minimum balance + if T::minimum_balance() == T::Balance::zero() { + return + } + + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account_0 = AccountId::from(0); + let account_1 = AccountId::from(1); + let initial_balance = T::minimum_balance() + 10.into(); + T::set_balance(&account_0, initial_balance); + T::set_balance(&account_1, initial_balance); + + // Verify: Transfer Protect entire balance from account_0 to account_1 should Err + let preservation = Preservation::Protect; + let transfer_amount = initial_balance; + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap_err(); + + // Verify: Noop + assert_eq!(T::total_balance(&account_0), initial_balance); + assert_eq!(T::total_balance(&account_1), initial_balance); + assert_eq!(T::balance(&account_0), initial_balance); + assert_eq!(T::balance(&account_1), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); + + // Verify: Transfer Preserve entire balance from account_0 to account_1 should Err + let preservation = Preservation::Preserve; + T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap_err(); + + // Verify: Noop + assert_eq!(T::total_balance(&account_0), initial_balance); + assert_eq!(T::total_balance(&account_1), initial_balance); + assert_eq!(T::balance(&account_0), initial_balance); + assert_eq!(T::balance(&account_1), initial_balance); + assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into()); + assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into()); +} + +/// Test [`Mutate::set_balance`] mints balances correctly. +/// +/// This test verifies that minting a balance using `set_balance` updates the account balance, +/// total issuance, and active issuance correctly. +pub fn set_balance_mint_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: Increase the account balance with set_balance + let increase_amount: T::Balance = 5.into(); + let new = T::set_balance(&account, initial_balance + increase_amount); + + // Verify: set_balance returned the new balance + let expected_new = initial_balance + increase_amount; + assert_eq!(new, expected_new); + + // Verify: Balance and issuance is updated correctly + assert_eq!(T::total_balance(&account), expected_new); + assert_eq!(T::balance(&account), expected_new); + assert_eq!(T::total_issuance(), initial_total_issuance + expected_new); + assert_eq!(T::active_issuance(), initial_active_issuance + expected_new); +} + +/// Test [`Mutate::set_balance`] burns balances correctly. +/// +/// This test verifies that burning a balance using `set_balance` updates the account balance, +/// total issuance, and active issuance correctly. +pub fn set_balance_burn_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let initial_total_issuance = T::total_issuance(); + let initial_active_issuance = T::active_issuance(); + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: Increase the account balance with set_balance + let burn_amount: T::Balance = 5.into(); + let new = T::set_balance(&account, initial_balance - burn_amount); + + // Verify: set_balance returned the new balance + let expected_new = initial_balance - burn_amount; + assert_eq!(new, expected_new); + + // Verify: Balance and issuance is updated correctly + assert_eq!(T::total_balance(&account), expected_new); + assert_eq!(T::balance(&account), expected_new); + assert_eq!(T::total_issuance(), initial_total_issuance + expected_new); + assert_eq!(T::active_issuance(), initial_active_issuance + expected_new); +} + +/// Test [`Inspect::can_deposit`] works correctly returns [`DepositConsequence::Success`] +/// when depositing an amount that should succeed. +pub fn can_deposit_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: can_deposit a reasonable amount + let ret = T::can_deposit(&account, 5.into(), Provenance::Minted); + + // Verify: Returns success + assert_eq!(ret, DepositConsequence::Success); +} + +/// Test [`Inspect::can_deposit`] returns [`DepositConsequence::BelowMinimum`] when depositing +/// below the minimum balance. +pub fn can_deposit_below_minimum() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // can_deposit always returns Success for amount 0 + if T::minimum_balance() < 2.into() { + return + } + + let account = AccountId::from(10); + + // Test: can_deposit below the minimum + let ret = T::can_deposit(&account, T::minimum_balance() - 1.into(), Provenance::Minted); + + // Verify: Returns success + assert_eq!(ret, DepositConsequence::BelowMinimum); +} + +/// Test [`Inspect::can_deposit`] returns [`DepositConsequence::Overflow`] when +/// depositing an amount that would overflow. +pub fn can_deposit_overflow() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + + // Test: Try deposit over the max balance + let initial_balance = T::Balance::max_value() - 5.into() - T::total_issuance(); + T::mint_into(&account, initial_balance).unwrap(); + let ret = T::can_deposit(&account, 10.into(), Provenance::Minted); + + // Verify: Returns success + assert_eq!(ret, DepositConsequence::Overflow); +} + +/// Test [`Inspect::can_withdraw`] returns [`WithdrawConsequence::Success`] when withdrawing an +/// amount that should succeed. +pub fn can_withdraw_success() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Test: can_withdraw a reasonable amount + let ret = T::can_withdraw(&account, 5.into()); + + // Verify: Returns success + assert_eq!(ret, WithdrawConsequence::Success); +} + +/// Test [`Inspect::can_withdraw`] returns [`WithdrawConsequence::ReducedToZero`] when +/// withdrawing an amount that would reduce the account balance below the minimum balance. +pub fn can_withdraw_reduced_to_zero() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account = AccountId::from(10); + let initial_balance = T::minimum_balance(); + T::mint_into(&account, initial_balance).unwrap(); + + // Verify: can_withdraw below the minimum balance returns ReducedToZero + let ret = T::can_withdraw(&account, 1.into()); + assert_eq!(ret, WithdrawConsequence::ReducedToZero(T::minimum_balance() - 1.into())); +} + +/// Test [`Inspect::can_withdraw`] returns [`WithdrawConsequence::BalanceLow`] when withdrawing +/// an amount that would result in an account balance below the current balance. +pub fn can_withdraw_balance_low() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + if T::minimum_balance() == T::Balance::zero() { + return + } + + let account = AccountId::from(10); + let other_account = AccountId::from(100); + let initial_balance = T::minimum_balance() + 5.into(); + T::mint_into(&account, initial_balance).unwrap(); + T::mint_into(&other_account, initial_balance * 2.into()).unwrap(); + + // Verify: can_withdraw below the account balance returns BalanceLow + let ret = T::can_withdraw(&account, initial_balance + 1.into()); + assert_eq!(ret, WithdrawConsequence::BalanceLow); +} + +/// Test [`Inspect::reducible_balance`] returns the full account balance when called with +/// [`Preservation::Expendable`]. +pub fn reducible_balance_expendable() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Verify: reducible_balance returns the full balance + let ret = T::reducible_balance(&account, Preservation::Expendable, Fortitude::Polite); + assert_eq!(ret, initial_balance); +} + +/// Tests [`Inspect::reducible_balance`] returns [`Inspect::balance`] - +/// [`Inspect::minimum_balance`] when called with either [`Preservation::Protect`] or +/// [`Preservation::Preserve`]. +pub fn reducible_balance_protect_preserve() +where + T: Mutate, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account = AccountId::from(10); + let initial_balance = T::minimum_balance() + 10.into(); + T::mint_into(&account, initial_balance).unwrap(); + + // Verify: reducible_balance returns the full balance - min balance + let ret = T::reducible_balance(&account, Preservation::Protect, Fortitude::Polite); + assert_eq!(ret, initial_balance - T::minimum_balance()); + let ret = T::reducible_balance(&account, Preservation::Preserve, Fortitude::Polite); + assert_eq!(ret, initial_balance - T::minimum_balance()); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs new file mode 100644 index 00000000000..e7fcc15472e --- /dev/null +++ b/substrate/frame/support/src/traits/tokens/fungible/conformance_tests/regular/unbalanced.rs @@ -0,0 +1,281 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::traits::{ + fungible::{Inspect, Unbalanced}, + tokens::{Fortitude, Precision, Preservation}, +}; +use core::fmt::Debug; +use sp_arithmetic::{traits::AtLeast8BitUnsigned, ArithmeticError}; +use sp_runtime::{traits::Bounded, TokenError}; + +/// Tests [`Unbalanced::write_balance`]. +/// +/// We don't need to test the Error case for this function, because the trait makes no +/// assumptions about the ways it can fail. That is completely an implementation detail. +pub fn write_balance() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Setup some accounts to test varying initial balances + let account_0_ed = AccountId::from(0); + let account_1_gt_ed = AccountId::from(1); + let account_2_empty = AccountId::from(2); + T::increase_balance(&account_0_ed, T::minimum_balance(), Precision::Exact).unwrap(); + T::increase_balance(&account_1_gt_ed, T::minimum_balance() + 5.into(), Precision::Exact) + .unwrap(); + + // Test setting the balances of each account by gt the minimum balance succeeds with no + // dust. + let amount = T::minimum_balance() + 10.into(); + assert_eq!(T::write_balance(&account_0_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_1_gt_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_2_empty, amount), Ok(None)); + assert_eq!(T::balance(&account_0_ed), amount); + assert_eq!(T::balance(&account_1_gt_ed), amount); + assert_eq!(T::balance(&account_2_empty), amount); + + // Test setting the balances of each account to below the minimum balance succeeds with + // the expected dust. + // If the minimum balance is 1, then the dust is 0, represented as None. + // If the minimum balance is >1, then the dust is the remaining balance that will be wiped + // as the account is reaped. + let amount = T::minimum_balance() - 1.into(); + if T::minimum_balance() == 1.into() { + assert_eq!(T::write_balance(&account_0_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_1_gt_ed, amount), Ok(None)); + assert_eq!(T::write_balance(&account_2_empty, amount), Ok(None)); + } else if T::minimum_balance() > 1.into() { + assert_eq!(T::write_balance(&account_0_ed, amount), Ok(Some(amount))); + assert_eq!(T::write_balance(&account_1_gt_ed, amount), Ok(Some(amount))); + assert_eq!(T::write_balance(&account_2_empty, amount), Ok(Some(amount))); + } +} + +/// Tests [`Unbalanced::decrease_balance`] called with [`Preservation::Expendable`]. +pub fn decrease_balance_expendable() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Setup account with some balance + let account_0 = AccountId::from(0); + let account_0_initial_balance = T::minimum_balance() + 10.into(); + T::increase_balance(&account_0, account_0_initial_balance, Precision::Exact).unwrap(); + + // Decreasing the balance still above the minimum balance should not reap the account. + let amount = 1.into(); + assert_eq!( + T::decrease_balance( + &account_0, + amount, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ), + Ok(amount), + ); + assert_eq!(T::balance(&account_0), account_0_initial_balance - amount); + + // Decreasing the balance below funds avalibale should fail when Precision::Exact + let balance_before = T::balance(&account_0); + assert_eq!( + T::decrease_balance( + &account_0, + account_0_initial_balance, + Precision::Exact, + Preservation::Expendable, + Fortitude::Polite, + ), + Err(TokenError::FundsUnavailable.into()) + ); + // Balance unchanged + assert_eq!(T::balance(&account_0), balance_before); + + // And reap the account when Precision::BestEffort + assert_eq!( + T::decrease_balance( + &account_0, + account_0_initial_balance, + Precision::BestEffort, + Preservation::Expendable, + Fortitude::Polite, + ), + Ok(balance_before), + ); + // Account reaped + assert_eq!(T::balance(&account_0), 0.into()); +} + +/// Tests [`Unbalanced::decrease_balance`] called with [`Preservation::Preserve`]. +pub fn decrease_balance_preserve() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + // Setup account with some balance + let account_0 = AccountId::from(0); + let account_0_initial_balance = T::minimum_balance() + 10.into(); + T::increase_balance(&account_0, account_0_initial_balance, Precision::Exact).unwrap(); + + // Decreasing the balance below the minimum when Precision::Exact should fail. + let amount = 11.into(); + assert_eq!( + T::decrease_balance( + &account_0, + amount, + Precision::Exact, + Preservation::Preserve, + Fortitude::Polite, + ), + Err(TokenError::FundsUnavailable.into()), + ); + // Balance should not have changed. + assert_eq!(T::balance(&account_0), account_0_initial_balance); + + // Decreasing the balance below the minimum when Precision::BestEffort should reduce to + // minimum balance. + let amount = 11.into(); + assert_eq!( + T::decrease_balance( + &account_0, + amount, + Precision::BestEffort, + Preservation::Preserve, + Fortitude::Polite, + ), + Ok(account_0_initial_balance - T::minimum_balance()), + ); + assert_eq!(T::balance(&account_0), T::minimum_balance()); +} + +/// Tests [`Unbalanced::increase_balance`]. +pub fn increase_balance() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + let account_0 = AccountId::from(0); + assert_eq!(T::balance(&account_0), 0.into()); + + // Increasing the bal below the ED errors when precision is Exact + if T::minimum_balance() > 0.into() { + assert_eq!( + T::increase_balance(&account_0, T::minimum_balance() - 1.into(), Precision::Exact), + Err(TokenError::BelowMinimum.into()), + ); + } + assert_eq!(T::balance(&account_0), 0.into()); + + // Increasing the bal below the ED leaves the balance at zero when precision is BestEffort + if T::minimum_balance() > 0.into() { + assert_eq!( + T::increase_balance(&account_0, T::minimum_balance() - 1.into(), Precision::BestEffort), + Ok(0.into()), + ); + } + assert_eq!(T::balance(&account_0), 0.into()); + + // Can increase if new bal is >= ED + assert_eq!( + T::increase_balance(&account_0, T::minimum_balance(), Precision::Exact), + Ok(T::minimum_balance()), + ); + assert_eq!(T::balance(&account_0), T::minimum_balance()); + assert_eq!(T::increase_balance(&account_0, 5.into(), Precision::Exact), Ok(5.into()),); + assert_eq!(T::balance(&account_0), T::minimum_balance() + 5.into()); + + // Increasing by amount that would overflow fails when precision is Exact + assert_eq!( + T::increase_balance(&account_0, T::Balance::max_value(), Precision::Exact), + Err(ArithmeticError::Overflow.into()), + ); + + // Increasing by amount that would overflow saturates when precision is BestEffort + let balance_before = T::balance(&account_0); + assert_eq!( + T::increase_balance(&account_0, T::Balance::max_value(), Precision::BestEffort), + Ok(T::Balance::max_value() - balance_before), + ); + assert_eq!(T::balance(&account_0), T::Balance::max_value()); +} + +/// Tests [`Unbalanced::set_total_issuance`]. +pub fn set_total_issuance() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + T::set_total_issuance(1.into()); + assert_eq!(T::total_issuance(), 1.into()); + + T::set_total_issuance(0.into()); + assert_eq!(T::total_issuance(), 0.into()); + + T::set_total_issuance(T::minimum_balance()); + assert_eq!(T::total_issuance(), T::minimum_balance()); + + T::set_total_issuance(T::minimum_balance() + 5.into()); + assert_eq!(T::total_issuance(), T::minimum_balance() + 5.into()); + + if T::minimum_balance() > 0.into() { + T::set_total_issuance(T::minimum_balance() - 1.into()); + assert_eq!(T::total_issuance(), T::minimum_balance() - 1.into()); + } +} + +/// Tests [`Unbalanced::deactivate`] and [`Unbalanced::reactivate`]. +pub fn deactivate_and_reactivate() +where + T: Unbalanced, + >::Balance: AtLeast8BitUnsigned + Debug, + AccountId: AtLeast8BitUnsigned, +{ + T::set_total_issuance(10.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 10.into()); + + T::deactivate(2.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 8.into()); + + // Saturates at total_issuance + T::reactivate(4.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 10.into()); + + // Decrements correctly after saturating at total_issuance + T::deactivate(1.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 9.into()); + + // Saturates at zero + T::deactivate(15.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 0.into()); + + // Increments correctly after saturating at zero + T::reactivate(1.into()); + assert_eq!(T::total_issuance(), 10.into()); + assert_eq!(T::active_issuance(), 1.into()); +} diff --git a/substrate/frame/support/src/traits/tokens/fungible/item_of.rs b/substrate/frame/support/src/traits/tokens/fungible/item_of.rs index fe252c6b089..37749d39600 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/item_of.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/item_of.rs @@ -389,9 +389,11 @@ impl< let credit = >::issue(A::get(), amount); imbalance::from_fungibles(credit) } - fn pair(amount: Self::Balance) -> (Debt, Credit) { - let (a, b) = >::pair(A::get(), amount); - (imbalance::from_fungibles(a), imbalance::from_fungibles(b)) + fn pair( + amount: Self::Balance, + ) -> Result<(Debt, Credit), DispatchError> { + let (a, b) = >::pair(A::get(), amount)?; + Ok((imbalance::from_fungibles(a), imbalance::from_fungibles(b))) } fn rescind(amount: Self::Balance) -> Debt { let debt = >::rescind(A::get(), amount); diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs index 87c6ef68d77..f15c3418d0a 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs @@ -64,7 +64,7 @@ pub trait Inspect: Sized { /// indefinitely. /// /// For the amount of the balance which is currently free to be removed from the account without - /// error, use `reducible_balance`. + /// error, use [`Inspect::reducible_balance`]. /// /// For the amount of the balance which may eventually be free to be removed from the account, /// use `balance()`. @@ -74,7 +74,7 @@ pub trait Inspect: Sized { /// subsystems of the chain ("on hold" or "reserved"). /// /// In general this isn't especially useful outside of tests, and for practical purposes, you'll - /// want to use `reducible_balance()`. + /// want to use [`Inspect::reducible_balance`]. fn balance(who: &AccountId) -> Self::Balance; /// Get the maximum amount that `who` can withdraw/transfer successfully based on whether the @@ -82,7 +82,7 @@ pub trait Inspect: Sized { /// reduction and potentially go below user-level restrictions on the minimum amount of the /// account. /// - /// Always less than or equal to `balance()`. + /// Always less than or equal to [`Inspect::balance`]. fn reducible_balance( who: &AccountId, preservation: Preservation, @@ -106,7 +106,7 @@ pub trait Inspect: Sized { fn can_withdraw(who: &AccountId, amount: Self::Balance) -> WithdrawConsequence; } -/// Special dust type which can be type-safely converted into a `Credit`. +/// Special dust type which can be type-safely converted into a [`Credit`]. #[must_use] pub struct Dust>(pub T::Balance); @@ -123,20 +123,20 @@ impl> Dust { /// Do not use this directly unless you want trouble, since it allows you to alter account balances /// without keeping the issuance up to date. It has no safeguards against accidentally creating /// token imbalances in your system leading to accidental inflation or deflation. It's really just -/// for the underlying datatype to implement so the user gets the much safer `Balanced` trait to +/// for the underlying datatype to implement so the user gets the much safer [`Balanced`] trait to /// use. pub trait Unbalanced: Inspect { - /// Create some dust and handle it with `Self::handle_dust`. This is an unbalanced operation - /// and it must only be used when an account is modified in a raw fashion, outside of the entire - /// fungibles API. The `amount` is capped at `Self::minimum_balance() - 1`. + /// Create some dust and handle it with [`Unbalanced::handle_dust`]. This is an unbalanced + /// operation and it must only be used when an account is modified in a raw fashion, outside of + /// the entire fungibles API. The `amount` is capped at [`Inspect::minimum_balance()`] - 1`. /// /// This should not be reimplemented. fn handle_raw_dust(amount: Self::Balance) { Self::handle_dust(Dust(amount.min(Self::minimum_balance().saturating_sub(One::one())))) } - /// Do something with the dust which has been destroyed from the system. `Dust` can be converted - /// into a `Credit` with the `Balanced` trait impl. + /// Do something with the dust which has been destroyed from the system. [`Dust`] can be + /// converted into a [`Credit`] with the [`Balanced`] trait impl. fn handle_dust(dust: Dust); /// Forcefully set the balance of `who` to `amount`. @@ -151,9 +151,10 @@ pub trait Unbalanced: Inspect { /// If this cannot be done for some reason (e.g. because the account cannot be created, deleted /// or would overflow) then an `Err` is returned. /// - /// If `Ok` is returned then its inner, if `Some` is the amount which was discarded as dust due - /// to existential deposit requirements. The default implementation of `decrease_balance` and - /// `increase_balance` converts this into an `Imbalance` and then passes it into `handle_dust`. + /// If `Ok` is returned then its inner, then `Some` is the amount which was discarded as dust + /// due to existential deposit requirements. The default implementation of + /// [`Unbalanced::decrease_balance`] and [`Unbalanced::increase_balance`] converts this into an + /// [`Imbalance`] and then passes it into [`Unbalanced::handle_dust`]. fn write_balance( who: &AccountId, amount: Self::Balance, @@ -164,14 +165,14 @@ pub trait Unbalanced: Inspect { /// Reduce the balance of `who` by `amount`. /// - /// If `precision` is `Exact` and it cannot be reduced by that amount for - /// some reason, return `Err` and don't reduce it at all. If `precision` is `BestEffort`, then + /// If `precision` is [`Exact`] and it cannot be reduced by that amount for + /// some reason, return `Err` and don't reduce it at all. If `precision` is [`BestEffort`], then /// reduce the balance of `who` by the most that is possible, up to `amount`. /// /// In either case, if `Ok` is returned then the inner is the amount by which is was reduced. /// Minimum balance will be respected and thus the returned amount may be up to - /// `Self::minimum_balance() - 1` greater than `amount` in the case that the reduction caused - /// the account to be deleted. + /// [`Inspect::minimum_balance()`] - 1` greater than `amount` in the case that the reduction + /// caused the account to be deleted. fn decrease_balance( who: &AccountId, mut amount: Self::Balance, @@ -180,15 +181,10 @@ pub trait Unbalanced: Inspect { force: Fortitude, ) -> Result { let old_balance = Self::balance(who); - let free = Self::reducible_balance(who, preservation, force); + let reducible = Self::reducible_balance(who, preservation, force); match precision { - BestEffort => { - amount = amount.min(free); - }, - Exact => - if free < amount { - return Err(TokenError::FundsUnavailable.into()) - }, + BestEffort => amount = amount.min(reducible), + Exact => ensure!(reducible >= amount, TokenError::FundsUnavailable), } let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; @@ -203,7 +199,7 @@ pub trait Unbalanced: Inspect { /// If it cannot be increased by that amount for some reason, return `Err` and don't increase /// it at all. If Ok, return the imbalance. /// Minimum balance will be respected and an error will be returned if - /// `amount < Self::minimum_balance()` when the account of `who` is zero. + /// amount < [`Inspect::minimum_balance()`] when the account of `who` is zero. fn increase_balance( who: &AccountId, amount: Self::Balance, @@ -276,8 +272,8 @@ where /// Attempt to decrease the `asset` balance of `who` by `amount`. /// - /// Equivalent to `burn_from`, except with an expectation that within the bounds of some - /// universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The + /// Equivalent to [`Mutate::burn_from`], except with an expectation that within the bounds of + /// some universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The /// implementation may be configured such that the total assets suspended may never be less than /// the total assets resumed (which is the invariant for an issuing system), or the reverse /// (which the invariant in a non-issuing system). @@ -296,8 +292,8 @@ where /// Attempt to increase the `asset` balance of `who` by `amount`. /// - /// Equivalent to `mint_into`, except with an expectation that within the bounds of some - /// universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The + /// Equivalent to [`Mutate::mint_into`], except with an expectation that within the bounds of + /// some universal issuance, the total assets `suspend`ed and `resume`d will be equivalent. The /// implementation may be configured such that the total assets suspended may never be less than /// the total assets resumed (which is the invariant for an issuing system), or the reverse /// (which the invariant in a non-issuing system). @@ -325,7 +321,7 @@ where let _extra = Self::can_withdraw(source, amount).into_result(preservation != Expendable)?; Self::can_deposit(dest, amount, Extant).into_result()?; if source == dest { - return Ok(amount) + return Ok(amount); } Self::decrease_balance(source, amount, BestEffort, preservation, Polite)?; @@ -383,7 +379,7 @@ impl> HandleImbalanceDrop /// A fungible token class where any creation and deletion of tokens is semi-explicit and where the /// total supply is maintained automatically. /// -/// This is auto-implemented when a token class has `Unbalanced` implemented. +/// This is auto-implemented when a token class has [`Unbalanced`] implemented. pub trait Balanced: Inspect + Unbalanced { /// The type for managing what happens when an instance of `Debt` is dropped without being used. type OnDropDebt: HandleImbalanceDrop; @@ -392,7 +388,7 @@ pub trait Balanced: Inspect + Unbalanced { type OnDropCredit: HandleImbalanceDrop; /// Reduce the total issuance by `amount` and return the according imbalance. The imbalance will - /// typically be used to reduce an account by the same amount with e.g. `settle`. + /// typically be used to reduce an account by the same amount with e.g. [`Balanced::settle`]. /// /// This is infallible, but doesn't guarantee that the entire `amount` is burnt, for example /// in the case of underflow. @@ -407,7 +403,7 @@ pub trait Balanced: Inspect + Unbalanced { /// Increase the total issuance by `amount` and return the according imbalance. The imbalance /// will typically be used to increase an account by the same amount with e.g. - /// `resolve_into_existing` or `resolve_creating`. + /// [`Balanced::resolve`]. /// /// This is infallible, but doesn't guarantee that the entire `amount` is issued, for example /// in the case of overflow. @@ -424,18 +420,33 @@ pub trait Balanced: Inspect + Unbalanced { /// /// This is just the same as burning and issuing the same amount and has no effect on the /// total issuance. - fn pair(amount: Self::Balance) -> (Debt, Credit) { - (Self::rescind(amount), Self::issue(amount)) + /// + /// This could fail when we cannot issue and redeem the entire `amount`, for example in the + /// case where the amount would cause overflow or underflow in [`Balanced::issue`] or + /// [`Balanced::rescind`]. + fn pair( + amount: Self::Balance, + ) -> Result<(Debt, Credit), DispatchError> { + let issued = Self::issue(amount); + let rescinded = Self::rescind(amount); + // Need to check amount in case by some edge case both issued and rescinded are below + // `amount` by the exact same value + if issued.peek() != rescinded.peek() || issued.peek() != amount { + // Issued and rescinded will be dropped automatically + Err("Failed to issue and rescind equal amounts".into()) + } else { + Ok((rescinded, issued)) + } } /// Mints `value` into the account of `who`, creating it as needed. /// /// If `precision` is `BestEffort` and `value` in full could not be minted (e.g. due to - /// overflow), then the maximum is minted, up to `value`. If `precision` is `Exact`, then + /// overflow), then the maximum is minted, up to `value`. If `precision` is [`Exact`], then /// exactly `value` must be minted into the account of `who` or the operation will fail with an /// `Err` and nothing will change. /// - /// If the operation is successful, this will return `Ok` with a `Debt` of the total value + /// If the operation is successful, this will return `Ok` with a [`Debt`] of the total value /// added to the account. fn deposit( who: &AccountId, @@ -449,8 +460,8 @@ pub trait Balanced: Inspect + Unbalanced { /// Removes `value` balance from `who` account if possible. /// - /// If `precision` is `BestEffort` and `value` in full could not be removed (e.g. due to - /// underflow), then the maximum is removed, up to `value`. If `precision` is `Exact`, then + /// If `precision` is [`BestEffort`] and `value` in full could not be removed (e.g. due to + /// underflow), then the maximum is removed, up to `value`. If `precision` is [`Exact`], then /// exactly `value` must be removed from the account of `who` or the operation will fail with an /// `Err` and nothing will change. /// @@ -458,7 +469,7 @@ pub trait Balanced: Inspect + Unbalanced { /// If the account needed to be deleted, then slightly more than `value` may be removed from the /// account owning since up to (but not including) minimum balance may also need to be removed. /// - /// If the operation is successful, this will return `Ok` with a `Credit` of the total value + /// If the operation is successful, this will return `Ok` with a [`Credit`] of the total value /// removed from the account. fn withdraw( who: &AccountId, @@ -476,7 +487,7 @@ pub trait Balanced: Inspect + Unbalanced { /// cannot be countered, then nothing is changed and the original `credit` is returned in an /// `Err`. /// - /// Please note: If `credit.peek()` is less than `Self::minimum_balance()`, then `who` must + /// Please note: If `credit.peek()` is less than [`Inspect::minimum_balance()`], then `who` must /// already exist for this to succeed. fn resolve( who: &AccountId, @@ -503,7 +514,7 @@ pub trait Balanced: Inspect + Unbalanced { let amount = debt.peek(); let credit = match Self::withdraw(who, amount, Exact, preservation, Polite) { Err(_) => return Err(debt), - Ok(d) => d, + Ok(c) => c, }; match credit.offset(debt) { diff --git a/substrate/frame/support/src/traits/tokens/fungible/union_of.rs b/substrate/frame/support/src/traits/tokens/fungible/union_of.rs index 86505befc05..33711d7a16c 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/union_of.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/union_of.rs @@ -727,21 +727,22 @@ impl< fn pair( asset: Self::AssetId, amount: Self::Balance, - ) -> (fungibles::Debt, fungibles::Credit) { + ) -> Result<(fungibles::Debt, fungibles::Credit), DispatchError> + { match Criterion::convert(asset.clone()) { Left(()) => { - let (a, b) = >::pair(amount); - ( + let (a, b) = >::pair(amount)?; + Ok(( fungibles::imbalance::from_fungible(a, asset.clone()), fungibles::imbalance::from_fungible(b, asset), - ) + )) }, Right(a) => { - let (a, b) = >::pair(a, amount); - ( + let (a, b) = >::pair(a, amount)?; + Ok(( fungibles::imbalance::from_fungibles(a, asset.clone()), fungibles::imbalance::from_fungibles(b, asset), - ) + )) }, } } diff --git a/substrate/frame/support/src/traits/tokens/fungibles/regular.rs b/substrate/frame/support/src/traits/tokens/fungibles/regular.rs index 41ef4b40c75..8cc97802da6 100644 --- a/substrate/frame/support/src/traits/tokens/fungibles/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungibles/regular.rs @@ -194,9 +194,10 @@ pub trait Unbalanced: Inspect { force: Fortitude, ) -> Result { let old_balance = Self::balance(asset.clone(), who); - let free = Self::reducible_balance(asset.clone(), who, preservation, force); - if let BestEffort = precision { - amount = amount.min(free); + let reducible = Self::reducible_balance(asset.clone(), who, preservation, force); + match precision { + BestEffort => amount = amount.min(reducible), + Exact => ensure!(reducible >= amount, TokenError::FundsUnavailable), } let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?; if let Some(dust) = Self::write_balance(asset.clone(), who, new_balance)? { @@ -478,11 +479,24 @@ pub trait Balanced: Inspect + Unbalanced { /// /// This is just the same as burning and issuing the same amount and has no effect on the /// total issuance. + /// + /// This is infallible, but doesn't guarantee that the entire `amount` is used to create the + /// pair, for example in the case where the amounts would cause overflow or underflow in + /// [`Balanced::issue`] or [`Balanced::rescind`]. fn pair( asset: Self::AssetId, amount: Self::Balance, - ) -> (Debt, Credit) { - (Self::rescind(asset.clone(), amount), Self::issue(asset, amount)) + ) -> Result<(Debt, Credit), DispatchError> { + let issued = Self::issue(asset.clone(), amount); + let rescinded = Self::rescind(asset, amount); + // Need to check amount in case by some edge case both issued and rescinded are below + // `amount` by the exact same value + if issued.peek() != rescinded.peek() || issued.peek() != amount { + // Issued and rescinded will be dropped automatically + Err("Failed to issue and rescind equal amounts".into()) + } else { + Ok((rescinded, issued)) + } } /// Mints `value` into the account of `who`, creating it as needed. diff --git a/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs b/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs index 3619db3a37b..9d2a783df2a 100644 --- a/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs +++ b/substrate/frame/support/src/traits/tokens/fungibles/union_of.rs @@ -706,15 +706,22 @@ impl< fn pair( asset: Self::AssetId, amount: Self::Balance, - ) -> (fungibles::Debt, fungibles::Credit) { + ) -> Result<(fungibles::Debt, fungibles::Credit), DispatchError> + { match Criterion::convert(asset.clone()) { Left(a) => { - let (a, b) = >::pair(a, amount); - (imbalance::from_fungibles(a, asset.clone()), imbalance::from_fungibles(b, asset)) + let (a, b) = >::pair(a, amount)?; + Ok(( + imbalance::from_fungibles(a, asset.clone()), + imbalance::from_fungibles(b, asset), + )) }, Right(a) => { - let (a, b) = >::pair(a, amount); - (imbalance::from_fungibles(a, asset.clone()), imbalance::from_fungibles(b, asset)) + let (a, b) = >::pair(a, amount)?; + Ok(( + imbalance::from_fungibles(a, asset.clone()), + imbalance::from_fungibles(b, asset), + )) }, } } -- GitLab From 53bcbb15f1de62661671ad8099b9dc3f8b623efd Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:03:32 +0200 Subject: [PATCH 002/283] archive: Implement archive_unstable_storage (#1846) This PR implements the `archive_unstable_storage` method that offers support for: - fetching values - fetching hashes - iterating over keys and values - iterating over keys and hashes - fetching merkle values from the trie-db A common component dedicated to RPC-V2 storage queries is created to bridge the gap between `chainHead/storage` and `archive/storage`. Query pagination is supported by `paginationStartKey`, similar to the old APIs. Similarly to the `chainHead/storage`, the `archive/storage` method accepts a maximum number of queried items. The design builds upon: https://github.com/paritytech/json-rpc-interface-spec/pull/94. Closes https://github.com/paritytech/polkadot-sdk/issues/1512. cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile Co-authored-by: Niklas Adolfsson --- .../client/rpc-spec-v2/src/archive/api.rs | 18 +- .../client/rpc-spec-v2/src/archive/archive.rs | 70 ++- .../src/archive/archive_storage.rs | 125 ++++ .../client/rpc-spec-v2/src/archive/mod.rs | 2 + .../client/rpc-spec-v2/src/archive/tests.rs | 547 +++++++++++++++++- .../client/rpc-spec-v2/src/chain_head/api.rs | 5 +- .../rpc-spec-v2/src/chain_head/chain_head.rs | 6 +- .../src/chain_head/chain_head_storage.rs | 210 +------ .../rpc-spec-v2/src/chain_head/event.rs | 146 +---- .../client/rpc-spec-v2/src/chain_head/mod.rs | 7 - .../rpc-spec-v2/src/chain_head/tests.rs | 7 +- .../client/rpc-spec-v2/src/common/events.rs | 273 +++++++++ .../client/rpc-spec-v2/src/common/mod.rs | 17 + .../client/rpc-spec-v2/src/common/storage.rs | 198 +++++++ substrate/client/rpc-spec-v2/src/lib.rs | 10 +- 15 files changed, 1278 insertions(+), 363 deletions(-) create mode 100644 substrate/client/rpc-spec-v2/src/archive/archive_storage.rs create mode 100644 substrate/client/rpc-spec-v2/src/common/events.rs create mode 100644 substrate/client/rpc-spec-v2/src/common/mod.rs create mode 100644 substrate/client/rpc-spec-v2/src/common/storage.rs diff --git a/substrate/client/rpc-spec-v2/src/archive/api.rs b/substrate/client/rpc-spec-v2/src/archive/api.rs index 0583111cb48..b1973830400 100644 --- a/substrate/client/rpc-spec-v2/src/archive/api.rs +++ b/substrate/client/rpc-spec-v2/src/archive/api.rs @@ -18,7 +18,10 @@ //! API trait of the archive methods. -use crate::MethodResult; +use crate::{ + common::events::{ArchiveStorageResult, PaginatedStorageQuery}, + MethodResult, +}; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; #[rpc(client, server)] @@ -88,4 +91,17 @@ pub trait ArchiveApi { function: String, call_parameters: String, ) -> RpcResult; + + /// Returns storage entries at a specific block's state. + /// + /// # Unstable + /// + /// This method is unstable and subject to change in the future. + #[method(name = "archive_unstable_storage", blocking)] + fn archive_unstable_storage( + &self, + hash: Hash, + items: Vec>, + child_trie: Option, + ) -> RpcResult; } diff --git a/substrate/client/rpc-spec-v2/src/archive/archive.rs b/substrate/client/rpc-spec-v2/src/archive/archive.rs index 269962cfd74..c01afb5d779 100644 --- a/substrate/client/rpc-spec-v2/src/archive/archive.rs +++ b/substrate/client/rpc-spec-v2/src/archive/archive.rs @@ -20,14 +20,15 @@ use crate::{ archive::{error::Error as ArchiveError, ArchiveApiServer}, - chain_head::hex_string, - MethodResult, + common::events::{ArchiveStorageResult, PaginatedStorageQuery}, + hex_string, MethodResult, }; use codec::Encode; use jsonrpsee::core::{async_trait, RpcResult}; use sc_client_api::{ - Backend, BlockBackend, BlockchainEvents, CallExecutor, ExecutorProvider, StorageProvider, + Backend, BlockBackend, BlockchainEvents, CallExecutor, ChildInfo, ExecutorProvider, StorageKey, + StorageProvider, }; use sp_api::{CallApiAt, CallContext}; use sp_blockchain::{ @@ -40,6 +41,8 @@ use sp_runtime::{ }; use std::{collections::HashSet, marker::PhantomData, sync::Arc}; +use super::archive_storage::ArchiveStorage; + /// An API for archive RPC calls. pub struct Archive, Block: BlockT, Client> { /// Substrate client. @@ -48,8 +51,12 @@ pub struct Archive, Block: BlockT, Client> { backend: Arc, /// The hexadecimal encoded hash of the genesis block. genesis_hash: String, + /// The maximum number of reported items by the `archive_storage` at a time. + storage_max_reported_items: usize, + /// The maximum number of queried items allowed for the `archive_storage` at a time. + storage_max_queried_items: usize, /// Phantom member to pin the block type. - _phantom: PhantomData<(Block, BE)>, + _phantom: PhantomData, } impl, Block: BlockT, Client> Archive { @@ -58,9 +65,18 @@ impl, Block: BlockT, Client> Archive { client: Arc, backend: Arc, genesis_hash: GenesisHash, + storage_max_reported_items: usize, + storage_max_queried_items: usize, ) -> Self { let genesis_hash = hex_string(&genesis_hash.as_ref()); - Self { client, backend, genesis_hash, _phantom: PhantomData } + Self { + client, + backend, + genesis_hash, + storage_max_reported_items, + storage_max_queried_items, + _phantom: PhantomData, + } } } @@ -185,4 +201,48 @@ where Err(error) => MethodResult::err(error.to_string()), }) } + + fn archive_unstable_storage( + &self, + hash: Block::Hash, + items: Vec>, + child_trie: Option, + ) -> RpcResult { + let items = items + .into_iter() + .map(|query| { + let key = StorageKey(parse_hex_param(query.key)?); + let pagination_start_key = query + .pagination_start_key + .map(|key| parse_hex_param(key).map(|key| StorageKey(key))) + .transpose()?; + + // Paginated start key is only supported + if pagination_start_key.is_some() && !query.query_type.is_descendant_query() { + return Err(ArchiveError::InvalidParam( + "Pagination start key is only supported for descendants queries" + .to_string(), + )) + } + + Ok(PaginatedStorageQuery { + key, + query_type: query.query_type, + pagination_start_key, + }) + }) + .collect::, ArchiveError>>()?; + + let child_trie = child_trie + .map(|child_trie| parse_hex_param(child_trie)) + .transpose()? + .map(ChildInfo::new_default_from_vec); + + let storage_client = ArchiveStorage::new( + self.client.clone(), + self.storage_max_reported_items, + self.storage_max_queried_items, + ); + Ok(storage_client.handle_query(hash, items, child_trie)) + } } diff --git a/substrate/client/rpc-spec-v2/src/archive/archive_storage.rs b/substrate/client/rpc-spec-v2/src/archive/archive_storage.rs new file mode 100644 index 00000000000..09415af1ca1 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/archive/archive_storage.rs @@ -0,0 +1,125 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Implementation of the `archive_storage` method. + +use std::sync::Arc; + +use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider}; +use sp_runtime::traits::Block as BlockT; + +use crate::common::{ + events::{ArchiveStorageResult, PaginatedStorageQuery, StorageQueryType}, + storage::{IterQueryType, QueryIter, Storage}, +}; + +/// Generates the events of the `chainHead_storage` method. +pub struct ArchiveStorage { + /// Storage client. + client: Storage, + /// The maximum number of reported items by the `archive_storage` at a time. + storage_max_reported_items: usize, + /// The maximum number of queried items allowed for the `archive_storage` at a time. + storage_max_queried_items: usize, +} + +impl ArchiveStorage { + /// Constructs a new [`ArchiveStorage`]. + pub fn new( + client: Arc, + storage_max_reported_items: usize, + storage_max_queried_items: usize, + ) -> Self { + Self { client: Storage::new(client), storage_max_reported_items, storage_max_queried_items } + } +} + +impl ArchiveStorage +where + Block: BlockT + 'static, + BE: Backend + 'static, + Client: StorageProvider + 'static, +{ + /// Generate the response of the `archive_storage` method. + pub fn handle_query( + &self, + hash: Block::Hash, + mut items: Vec>, + child_key: Option, + ) -> ArchiveStorageResult { + let discarded_items = items.len().saturating_sub(self.storage_max_queried_items); + items.truncate(self.storage_max_queried_items); + + let mut storage_results = Vec::with_capacity(items.len()); + for item in items { + match item.query_type { + StorageQueryType::Value => { + match self.client.query_value(hash, &item.key, child_key.as_ref()) { + Ok(Some(value)) => storage_results.push(value), + Ok(None) => continue, + Err(error) => return ArchiveStorageResult::err(error), + } + }, + StorageQueryType::Hash => + match self.client.query_hash(hash, &item.key, child_key.as_ref()) { + Ok(Some(value)) => storage_results.push(value), + Ok(None) => continue, + Err(error) => return ArchiveStorageResult::err(error), + }, + StorageQueryType::ClosestDescendantMerkleValue => + match self.client.query_merkle_value(hash, &item.key, child_key.as_ref()) { + Ok(Some(value)) => storage_results.push(value), + Ok(None) => continue, + Err(error) => return ArchiveStorageResult::err(error), + }, + StorageQueryType::DescendantsValues => { + match self.client.query_iter_pagination( + QueryIter { + query_key: item.key, + ty: IterQueryType::Value, + pagination_start_key: item.pagination_start_key, + }, + hash, + child_key.as_ref(), + self.storage_max_reported_items, + ) { + Ok((results, _)) => storage_results.extend(results), + Err(error) => return ArchiveStorageResult::err(error), + } + }, + StorageQueryType::DescendantsHashes => { + match self.client.query_iter_pagination( + QueryIter { + query_key: item.key, + ty: IterQueryType::Hash, + pagination_start_key: item.pagination_start_key, + }, + hash, + child_key.as_ref(), + self.storage_max_reported_items, + ) { + Ok((results, _)) => storage_results.extend(results), + Err(error) => return ArchiveStorageResult::err(error), + } + }, + }; + } + + ArchiveStorageResult::ok(storage_results, discarded_items) + } +} diff --git a/substrate/client/rpc-spec-v2/src/archive/mod.rs b/substrate/client/rpc-spec-v2/src/archive/mod.rs index eb7d71d702f..e1f45e19a62 100644 --- a/substrate/client/rpc-spec-v2/src/archive/mod.rs +++ b/substrate/client/rpc-spec-v2/src/archive/mod.rs @@ -25,6 +25,8 @@ #[cfg(test)] mod tests; +mod archive_storage; + pub mod api; pub mod archive; pub mod error; diff --git a/substrate/client/rpc-spec-v2/src/archive/tests.rs b/substrate/client/rpc-spec-v2/src/archive/tests.rs index 6b288c2c954..45da8e588e6 100644 --- a/substrate/client/rpc-spec-v2/src/archive/tests.rs +++ b/substrate/client/rpc-spec-v2/src/archive/tests.rs @@ -16,7 +16,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::{chain_head::hex_string, MethodResult}; +use crate::{ + common::events::{ + ArchiveStorageMethodOk, ArchiveStorageResult, PaginatedStorageQuery, StorageQueryType, + StorageResultType, + }, + hex_string, MethodResult, +}; use super::{archive::Archive, *}; @@ -24,17 +30,20 @@ use assert_matches::assert_matches; use codec::{Decode, Encode}; use jsonrpsee::{ core::error::Error, + rpc_params, types::{error::CallError, EmptyServerParams as EmptyParams}, RpcModule, }; use sc_block_builder::BlockBuilderBuilder; +use sc_client_api::ChildInfo; use sp_blockchain::HeaderBackend; use sp_consensus::BlockOrigin; +use sp_core::{Blake2Hasher, Hasher}; use sp_runtime::{ traits::{Block as BlockT, Header as HeaderT}, SaturatedConversion, }; -use std::sync::Arc; +use std::{collections::HashMap, sync::Arc}; use substrate_test_runtime::Transfer; use substrate_test_runtime_client::{ prelude::*, runtime, Backend, BlockBuilderExt, Client, ClientBlockImportExt, @@ -42,23 +51,39 @@ use substrate_test_runtime_client::{ const CHAIN_GENESIS: [u8; 32] = [0; 32]; const INVALID_HASH: [u8; 32] = [1; 32]; +const MAX_PAGINATION_LIMIT: usize = 5; +const MAX_QUERIED_LIMIT: usize = 5; +const KEY: &[u8] = b":mock"; +const VALUE: &[u8] = b"hello world"; +const CHILD_STORAGE_KEY: &[u8] = b"child"; +const CHILD_VALUE: &[u8] = b"child value"; type Header = substrate_test_runtime_client::runtime::Header; type Block = substrate_test_runtime_client::runtime::Block; -fn setup_api() -> (Arc>, RpcModule>>) { - let builder = TestClientBuilder::new(); +fn setup_api( + max_returned_items: usize, + max_queried_items: usize, +) -> (Arc>, RpcModule>>) { + let child_info = ChildInfo::new_default(CHILD_STORAGE_KEY); + let builder = TestClientBuilder::new().add_extra_child_storage( + &child_info, + KEY.to_vec(), + CHILD_VALUE.to_vec(), + ); let backend = builder.backend(); let client = Arc::new(builder.build()); - let api = Archive::new(client.clone(), backend, CHAIN_GENESIS).into_rpc(); + let api = + Archive::new(client.clone(), backend, CHAIN_GENESIS, max_returned_items, max_queried_items) + .into_rpc(); (client, api) } #[tokio::test] async fn archive_genesis() { - let (_client, api) = setup_api(); + let (_client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); let genesis: String = api.call("archive_unstable_genesisHash", EmptyParams::new()).await.unwrap(); @@ -67,7 +92,7 @@ async fn archive_genesis() { #[tokio::test] async fn archive_body() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); // Invalid block hash. let invalid_hash = hex_string(&INVALID_HASH); @@ -101,7 +126,7 @@ async fn archive_body() { #[tokio::test] async fn archive_header() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); // Invalid block hash. let invalid_hash = hex_string(&INVALID_HASH); @@ -135,7 +160,7 @@ async fn archive_header() { #[tokio::test] async fn archive_finalized_height() { - let (client, api) = setup_api(); + let (client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); let client_height: u32 = client.info().finalized_number.saturated_into(); @@ -147,7 +172,7 @@ async fn archive_finalized_height() { #[tokio::test] async fn archive_hash_by_height() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); // Genesis height. let hashes: Vec = api.call("archive_unstable_hashByHeight", [0]).await.unwrap(); @@ -253,7 +278,7 @@ async fn archive_hash_by_height() { #[tokio::test] async fn archive_call() { - let (mut client, api) = setup_api(); + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); let invalid_hash = hex_string(&INVALID_HASH); // Invalid parameter (non-hex). @@ -309,3 +334,503 @@ async fn archive_call() { let expected = MethodResult::ok("0x0000000000000000"); assert_eq!(result, expected); } + +#[tokio::test] +async fn archive_storage_hashes_values() { + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); + + let block = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap() + .build() + .unwrap() + .block; + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + let block_hash = format!("{:?}", block.header.hash()); + let key = hex_string(&KEY); + + let items: Vec> = vec![ + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::DescendantsHashes, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::Hash, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: key.clone(), + query_type: StorageQueryType::Value, + pagination_start_key: None, + }, + ]; + + let result: ArchiveStorageResult = api + .call("archive_unstable_storage", rpc_params![&block_hash, items.clone()]) + .await + .unwrap(); + + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + // Key has not been imported yet. + assert_eq!(result.len(), 0); + assert_eq!(discarded_items, 0); + }, + _ => panic!("Unexpected result"), + }; + + // Import a block with the given key value pair. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(block.hash()) + .with_parent_block_number(1) + .build() + .unwrap(); + builder.push_storage_change(KEY.to_vec(), Some(VALUE.to_vec())).unwrap(); + let block = builder.build().unwrap().block; + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + let block_hash = format!("{:?}", block.header.hash()); + let expected_hash = format!("{:?}", Blake2Hasher::hash(&VALUE)); + let expected_value = hex_string(&VALUE); + + let result: ArchiveStorageResult = api + .call("archive_unstable_storage", rpc_params![&block_hash, items]) + .await + .unwrap(); + + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 4); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, key); + assert_eq!(result[0].result, StorageResultType::Hash(expected_hash.clone())); + assert_eq!(result[1].key, key); + assert_eq!(result[1].result, StorageResultType::Value(expected_value.clone())); + assert_eq!(result[2].key, key); + assert_eq!(result[2].result, StorageResultType::Hash(expected_hash)); + assert_eq!(result[3].key, key); + assert_eq!(result[3].result, StorageResultType::Value(expected_value)); + }, + _ => panic!("Unexpected result"), + }; +} + +#[tokio::test] +async fn archive_storage_closest_merkle_value() { + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, MAX_QUERIED_LIMIT); + + /// The core of this test. + /// + /// Checks keys that are exact match, keys with descedant and keys that should not return + /// values. + /// + /// Returns (key, merkle value) pairs. + async fn expect_merkle_request( + api: &RpcModule>>, + block_hash: String, + ) -> HashMap { + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![ + PaginatedStorageQuery { + key: hex_string(b":AAAA"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AAAB"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + // Key with descedent. + PaginatedStorageQuery { + key: hex_string(b":A"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AA"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + // Keys below this comment do not produce a result. + // Key that exceed the keyspace of the trie. + PaginatedStorageQuery { + key: hex_string(b":AAAAX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AAABX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + // Key that are not part of the trie. + PaginatedStorageQuery { + key: hex_string(b":AAX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":AAAX"), + query_type: StorageQueryType::ClosestDescendantMerkleValue, + pagination_start_key: None, + }, + ] + ], + ) + .await + .unwrap(); + + let merkle_values: HashMap<_, _> = match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, .. }) => result + .into_iter() + .map(|res| { + let value = match res.result { + StorageResultType::ClosestDescendantMerkleValue(value) => value, + _ => panic!("Unexpected StorageResultType"), + }; + (res.key, value) + }) + .collect(), + _ => panic!("Unexpected result"), + }; + + // Response for AAAA, AAAB, A and AA. + assert_eq!(merkle_values.len(), 4); + + // While checking for expected merkle values to align, + // the following will check that the returned keys are + // expected. + + // Values for AAAA and AAAB are different. + assert_ne!( + merkle_values.get(&hex_string(b":AAAA")).unwrap(), + merkle_values.get(&hex_string(b":AAAB")).unwrap() + ); + + // Values for A and AA should be on the same branch node. + assert_eq!( + merkle_values.get(&hex_string(b":A")).unwrap(), + merkle_values.get(&hex_string(b":AA")).unwrap() + ); + // The branch node value must be different than the leaf of either + // AAAA and AAAB. + assert_ne!( + merkle_values.get(&hex_string(b":A")).unwrap(), + merkle_values.get(&hex_string(b":AAAA")).unwrap() + ); + assert_ne!( + merkle_values.get(&hex_string(b":A")).unwrap(), + merkle_values.get(&hex_string(b":AAAB")).unwrap() + ); + + merkle_values + } + + // Import a new block with storage changes. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap(); + builder.push_storage_change(b":AAAA".to_vec(), Some(vec![1; 64])).unwrap(); + builder.push_storage_change(b":AAAB".to_vec(), Some(vec![2; 64])).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + let merkle_values_lhs = expect_merkle_request(&api, block_hash).await; + + // Import a new block with and change AAAB value. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(block.hash()) + .with_parent_block_number(1) + .build() + .unwrap(); + builder.push_storage_change(b":AAAA".to_vec(), Some(vec![1; 64])).unwrap(); + builder.push_storage_change(b":AAAB".to_vec(), Some(vec![3; 64])).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + let merkle_values_rhs = expect_merkle_request(&api, block_hash).await; + + // Change propagated to the root. + assert_ne!( + merkle_values_lhs.get(&hex_string(b":A")).unwrap(), + merkle_values_rhs.get(&hex_string(b":A")).unwrap() + ); + assert_ne!( + merkle_values_lhs.get(&hex_string(b":AAAB")).unwrap(), + merkle_values_rhs.get(&hex_string(b":AAAB")).unwrap() + ); + // However the AAAA branch leaf remains unchanged. + assert_eq!( + merkle_values_lhs.get(&hex_string(b":AAAA")).unwrap(), + merkle_values_rhs.get(&hex_string(b":AAAA")).unwrap() + ); +} + +#[tokio::test] +async fn archive_storage_paginate_iterations() { + // 1 iteration allowed before pagination kicks in. + let (mut client, api) = setup_api(1, MAX_QUERIED_LIMIT); + + // Import a new block with storage changes. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap(); + builder.push_storage_change(b":m".to_vec(), Some(b"a".to_vec())).unwrap(); + builder.push_storage_change(b":mo".to_vec(), Some(b"ab".to_vec())).unwrap(); + builder.push_storage_change(b":moc".to_vec(), Some(b"abc".to_vec())).unwrap(); + builder.push_storage_change(b":moD".to_vec(), Some(b"abcmoD".to_vec())).unwrap(); + builder.push_storage_change(b":mock".to_vec(), Some(b"abcd".to_vec())).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + // Calling with an invalid hash. + let invalid_hash = hex_string(&INVALID_HASH); + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &invalid_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: None, + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Err(_) => (), + _ => panic!("Unexpected result"), + }; + + // Valid call with storage at the key. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: None, + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":m")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"a"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":m")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":mo")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"ab"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":mo")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":moD")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"abcmoD"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":moD")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":moc")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"abc"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":moc")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 0); + + assert_eq!(result[0].key, hex_string(b":mock")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"abcd"))); + }, + _ => panic!("Unexpected result"), + }; + + // Continue with pagination until no keys are returned. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::DescendantsValues, + pagination_start_key: Some(hex_string(b":mock")), + }] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 0); + assert_eq!(discarded_items, 0); + }, + _ => panic!("Unexpected result"), + }; +} + +#[tokio::test] +async fn archive_storage_discarded_items() { + // One query at a time + let (mut client, api) = setup_api(MAX_PAGINATION_LIMIT, 1); + + // Import a new block with storage changes. + let mut builder = BlockBuilderBuilder::new(&*client) + .on_parent_block(client.chain_info().genesis_hash) + .with_parent_block_number(0) + .build() + .unwrap(); + builder.push_storage_change(b":m".to_vec(), Some(b"a".to_vec())).unwrap(); + let block = builder.build().unwrap().block; + let block_hash = format!("{:?}", block.header.hash()); + client.import(BlockOrigin::Own, block.clone()).await.unwrap(); + + // Valid call with storage at the key. + let result: ArchiveStorageResult = api + .call( + "archive_unstable_storage", + rpc_params![ + &block_hash, + vec![ + PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::Value, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::Hash, + pagination_start_key: None, + }, + PaginatedStorageQuery { + key: hex_string(b":m"), + query_type: StorageQueryType::Hash, + pagination_start_key: None, + } + ] + ], + ) + .await + .unwrap(); + match result { + ArchiveStorageResult::Ok(ArchiveStorageMethodOk { result, discarded_items }) => { + assert_eq!(result.len(), 1); + assert_eq!(discarded_items, 2); + + assert_eq!(result[0].key, hex_string(b":m")); + assert_eq!(result[0].result, StorageResultType::Value(hex_string(b"a"))); + }, + _ => panic!("Unexpected result"), + }; +} diff --git a/substrate/client/rpc-spec-v2/src/chain_head/api.rs b/substrate/client/rpc-spec-v2/src/chain_head/api.rs index 9ae80137955..3d6091b91bd 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/api.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/api.rs @@ -19,7 +19,10 @@ #![allow(non_snake_case)] //! API trait of the chain head. -use crate::chain_head::event::{FollowEvent, MethodResponse, StorageQuery}; +use crate::{ + chain_head::event::{FollowEvent, MethodResponse}, + common::events::StorageQuery, +}; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use sp_rpc::list::ListOrValue; diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs index 8e04ac7b177..6e4d6ade965 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head.rs @@ -27,11 +27,11 @@ use crate::{ api::ChainHeadApiServer, chain_head_follow::ChainHeadFollower, error::Error as ChainHeadRpcError, - event::{FollowEvent, MethodResponse, OperationError, StorageQuery}, - hex_string, + event::{FollowEvent, MethodResponse, OperationError}, subscription::{SubscriptionManagement, SubscriptionManagementError}, }, - SubscriptionTaskExecutor, + common::events::StorageQuery, + hex_string, SubscriptionTaskExecutor, }; use codec::Encode; use futures::future::FutureExt; diff --git a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs index c23489a050e..ee39ec253a3 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/chain_head_storage.rs @@ -22,33 +22,24 @@ use std::{collections::VecDeque, marker::PhantomData, sync::Arc}; use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider}; use sc_utils::mpsc::TracingUnboundedSender; -use sp_core::storage::well_known_keys; use sp_runtime::traits::Block as BlockT; -use crate::chain_head::event::OperationStorageItems; - -use super::{ - event::{ - OperationError, OperationId, StorageQuery, StorageQueryType, StorageResult, - StorageResultType, +use crate::{ + chain_head::{ + event::{OperationError, OperationId, OperationStorageItems}, + subscription::BlockGuard, + FollowEvent, + }, + common::{ + events::{StorageQuery, StorageQueryType}, + storage::{IterQueryType, QueryIter, QueryIterResult, Storage}, }, - hex_string, - subscription::BlockGuard, - FollowEvent, }; -/// The query type of an interation. -enum IterQueryType { - /// Iterating over (key, value) pairs. - Value, - /// Iterating over (key, hash) pairs. - Hash, -} - /// Generates the events of the `chainHead_storage` method. pub struct ChainHeadStorage { - /// Substrate client. - client: Arc, + /// Storage client. + client: Storage, /// Queue of operations that may require pagination. iter_operations: VecDeque, /// The maximum number of items reported by the `chainHead_storage` before @@ -61,7 +52,7 @@ impl ChainHeadStorage { /// Constructs a new [`ChainHeadStorage`]. pub fn new(client: Arc, operation_max_storage_items: usize) -> Self { Self { - client, + client: Storage::new(client), iter_operations: VecDeque::new(), operation_max_storage_items, _phandom: PhantomData, @@ -69,163 +60,12 @@ impl ChainHeadStorage { } } -/// Query to iterate over storage. -struct QueryIter { - /// The key from which the iteration was started. - query_key: StorageKey, - /// The key after which pagination should resume. - pagination_start_key: Option, - /// The type of the query (either value or hash). - ty: IterQueryType, -} - -/// Checks if the provided key (main or child key) is valid -/// for queries. -/// -/// Keys that are identical to `:child_storage:` or `:child_storage:default:` -/// are not queryable. -fn is_key_queryable(key: &[u8]) -> bool { - !well_known_keys::is_default_child_storage_key(key) && - !well_known_keys::is_child_storage_key(key) -} - -/// The result of making a query call. -type QueryResult = Result, String>; - -/// The result of iterating over keys. -type QueryIterResult = Result<(Vec, Option), String>; - impl ChainHeadStorage where Block: BlockT + 'static, BE: Backend + 'static, Client: StorageProvider + 'static, { - /// Fetch the value from storage. - fn query_storage_value( - &self, - hash: Block::Hash, - key: &StorageKey, - child_key: Option<&ChildInfo>, - ) -> QueryResult { - let result = if let Some(child_key) = child_key { - self.client.child_storage(hash, child_key, key) - } else { - self.client.storage(hash, key) - }; - - result - .map(|opt| { - QueryResult::Ok(opt.map(|storage_data| StorageResult { - key: hex_string(&key.0), - result: StorageResultType::Value(hex_string(&storage_data.0)), - })) - }) - .unwrap_or_else(|error| QueryResult::Err(error.to_string())) - } - - /// Fetch the hash of a value from storage. - fn query_storage_hash( - &self, - hash: Block::Hash, - key: &StorageKey, - child_key: Option<&ChildInfo>, - ) -> QueryResult { - let result = if let Some(child_key) = child_key { - self.client.child_storage_hash(hash, child_key, key) - } else { - self.client.storage_hash(hash, key) - }; - - result - .map(|opt| { - QueryResult::Ok(opt.map(|storage_data| StorageResult { - key: hex_string(&key.0), - result: StorageResultType::Hash(hex_string(&storage_data.as_ref())), - })) - }) - .unwrap_or_else(|error| QueryResult::Err(error.to_string())) - } - - /// Fetch the closest merkle value. - fn query_storage_merkle_value( - &self, - hash: Block::Hash, - key: &StorageKey, - child_key: Option<&ChildInfo>, - ) -> QueryResult { - let result = if let Some(child_key) = child_key { - self.client.child_closest_merkle_value(hash, child_key, key) - } else { - self.client.closest_merkle_value(hash, key) - }; - - result - .map(|opt| { - QueryResult::Ok(opt.map(|storage_data| { - let result = match &storage_data { - sc_client_api::MerkleValue::Node(data) => hex_string(&data.as_slice()), - sc_client_api::MerkleValue::Hash(hash) => hex_string(&hash.as_ref()), - }; - - StorageResult { - key: hex_string(&key.0), - result: StorageResultType::ClosestDescendantMerkleValue(result), - } - })) - }) - .unwrap_or_else(|error| QueryResult::Err(error.to_string())) - } - - /// Iterate over at most `operation_max_storage_items` keys. - /// - /// Returns the storage result with a potential next key to resume iteration. - fn query_storage_iter_pagination( - &self, - query: QueryIter, - hash: Block::Hash, - child_key: Option<&ChildInfo>, - ) -> QueryIterResult { - let QueryIter { ty, query_key, pagination_start_key } = query; - - let mut keys_iter = if let Some(child_key) = child_key { - self.client.child_storage_keys( - hash, - child_key.to_owned(), - Some(&query_key), - pagination_start_key.as_ref(), - ) - } else { - self.client.storage_keys(hash, Some(&query_key), pagination_start_key.as_ref()) - } - .map_err(|err| err.to_string())?; - - let mut ret = Vec::with_capacity(self.operation_max_storage_items); - let mut next_pagination_key = None; - for _ in 0..self.operation_max_storage_items { - let Some(key) = keys_iter.next() else { break }; - - next_pagination_key = Some(key.clone()); - - let result = match ty { - IterQueryType::Value => self.query_storage_value(hash, &key, child_key), - IterQueryType::Hash => self.query_storage_hash(hash, &key, child_key), - }?; - - if let Some(value) = result { - ret.push(value); - } - } - - // Save the next key if any to continue the iteration. - let maybe_next_query = keys_iter.next().map(|_| QueryIter { - ty, - query_key, - pagination_start_key: next_pagination_key, - }); - Ok((ret, maybe_next_query)) - } - /// Iterate over (key, hash) and (key, value) generating the `WaitingForContinue` event if /// necessary. async fn generate_storage_iter_events( @@ -242,7 +82,12 @@ where return } - let result = self.query_storage_iter_pagination(query, hash, child_key.as_ref()); + let result = self.client.query_iter_pagination( + query, + hash, + child_key.as_ref(), + self.operation_max_storage_items, + ); let (events, maybe_next_query) = match result { QueryIterResult::Ok(result) => result, QueryIterResult::Err(error) => { @@ -294,24 +139,11 @@ where let sender = block_guard.response_sender(); let operation = block_guard.operation(); - if let Some(child_key) = child_key.as_ref() { - if !is_key_queryable(child_key.storage_key()) { - let _ = sender.unbounded_send(FollowEvent::::OperationStorageDone( - OperationId { operation_id: operation.operation_id() }, - )); - return - } - } - let mut storage_results = Vec::with_capacity(items.len()); for item in items { - if !is_key_queryable(&item.key.0) { - continue - } - match item.query_type { StorageQueryType::Value => { - match self.query_storage_value(hash, &item.key, child_key.as_ref()) { + match self.client.query_value(hash, &item.key, child_key.as_ref()) { Ok(Some(value)) => storage_results.push(value), Ok(None) => continue, Err(error) => { @@ -321,7 +153,7 @@ where } }, StorageQueryType::Hash => - match self.query_storage_hash(hash, &item.key, child_key.as_ref()) { + match self.client.query_hash(hash, &item.key, child_key.as_ref()) { Ok(Some(value)) => storage_results.push(value), Ok(None) => continue, Err(error) => { @@ -330,7 +162,7 @@ where }, }, StorageQueryType::ClosestDescendantMerkleValue => - match self.query_storage_merkle_value(hash, &item.key, child_key.as_ref()) { + match self.client.query_merkle_value(hash, &item.key, child_key.as_ref()) { Ok(Some(value)) => storage_results.push(value), Ok(None) => continue, Err(error) => { diff --git a/substrate/client/rpc-spec-v2/src/chain_head/event.rs b/substrate/client/rpc-spec-v2/src/chain_head/event.rs index b5f9d6cc2ff..560ab87eab4 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/event.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/event.rs @@ -23,6 +23,8 @@ use sp_api::ApiError; use sp_version::RuntimeVersion; use std::collections::BTreeMap; +use crate::common::events::StorageResult; + /// The operation could not be processed due to an error. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -313,56 +315,6 @@ pub enum FollowEvent { Stop, } -/// The storage item received as paramter. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StorageQuery { - /// The provided key. - pub key: Key, - /// The type of the storage query. - #[serde(rename = "type")] - pub query_type: StorageQueryType, -} - -/// The type of the storage query. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum StorageQueryType { - /// Fetch the value of the provided key. - Value, - /// Fetch the hash of the value of the provided key. - Hash, - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue, - /// Fetch the values of all descendants of they provided key. - DescendantsValues, - /// Fetch the hashes of the values of all descendants of they provided key. - DescendantsHashes, -} - -/// The storage result. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct StorageResult { - /// The hex-encoded key of the result. - pub key: String, - /// The result of the query. - #[serde(flatten)] - pub result: StorageResultType, -} - -/// The type of the storage query. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum StorageResultType { - /// Fetch the value of the provided key. - Value(String), - /// Fetch the hash of the value of the provided key. - Hash(String), - /// Fetch the closest descendant merkle value. - ClosestDescendantMerkleValue(String), -} - /// The method respose of `chainHead_body`, `chainHead_call` and `chainHead_storage`. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -388,6 +340,8 @@ pub struct MethodResponseStarted { #[cfg(test)] mod tests { + use crate::common::events::StorageResultType; + use super::*; #[test] @@ -697,96 +651,4 @@ mod tests { let event_dec: MethodResponse = serde_json::from_str(exp).unwrap(); assert_eq!(event_dec, event); } - - #[test] - fn chain_head_storage_query() { - // Item with Value. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Value }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"value"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with Hash. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Hash }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"hash"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with DescendantsValues. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"descendantsValues"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with DescendantsHashes. - let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with Merkle. - let item = - StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - } - - #[test] - fn chain_head_storage_result() { - // Item with Value. - let item = - StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","value":"res"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageResult = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with Hash. - let item = - StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","hash":"res"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageResult = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - - // Item with DescendantsValues. - let item = StorageResult { - key: "0x1".into(), - result: StorageResultType::ClosestDescendantMerkleValue("res".into()), - }; - // Encode - let ser = serde_json::to_string(&item).unwrap(); - let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#; - assert_eq!(ser, exp); - // Decode - let dec: StorageResult = serde_json::from_str(exp).unwrap(); - assert_eq!(dec, item); - } } diff --git a/substrate/client/rpc-spec-v2/src/chain_head/mod.rs b/substrate/client/rpc-spec-v2/src/chain_head/mod.rs index 1bd22885780..4cbbd00f64f 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/mod.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/mod.rs @@ -42,10 +42,3 @@ pub use event::{ BestBlockChanged, ErrorEvent, Finalized, FollowEvent, Initialized, NewBlock, RuntimeEvent, RuntimeVersionEvent, }; - -use sp_core::hexdisplay::{AsBytesRef, HexDisplay}; - -/// Util function to print the results of `chianHead` as hex string -pub(crate) fn hex_string(data: &Data) -> String { - format!("0x{:?}", HexDisplay::from(data)) -} diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index c8f2362b9eb..4859793a8e2 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -16,9 +16,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::chain_head::{ - event::{MethodResponse, StorageQuery, StorageQueryType, StorageResultType}, - test_utils::ChainHeadMockClient, +use crate::{ + chain_head::{event::MethodResponse, test_utils::ChainHeadMockClient}, + common::events::{StorageQuery, StorageQueryType, StorageResultType}, + hex_string, }; use super::*; diff --git a/substrate/client/rpc-spec-v2/src/common/events.rs b/substrate/client/rpc-spec-v2/src/common/events.rs new file mode 100644 index 00000000000..b1627d74c84 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/common/events.rs @@ -0,0 +1,273 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Common events for RPC-V2 spec. + +use serde::{Deserialize, Serialize}; + +/// The storage item to query. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageQuery { + /// The provided key. + pub key: Key, + /// The type of the storage query. + #[serde(rename = "type")] + pub query_type: StorageQueryType, +} + +/// The storage item to query with pagination. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PaginatedStorageQuery { + /// The provided key. + pub key: Key, + /// The type of the storage query. + #[serde(rename = "type")] + pub query_type: StorageQueryType, + /// The pagination key from which the iteration should resume. + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(default)] + pub pagination_start_key: Option, +} + +/// The type of the storage query. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum StorageQueryType { + /// Fetch the value of the provided key. + Value, + /// Fetch the hash of the value of the provided key. + Hash, + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue, + /// Fetch the values of all descendants of they provided key. + DescendantsValues, + /// Fetch the hashes of the values of all descendants of they provided key. + DescendantsHashes, +} + +impl StorageQueryType { + /// Returns `true` if the query is a descendant query. + pub fn is_descendant_query(&self) -> bool { + matches!(self, Self::DescendantsValues | Self::DescendantsHashes) + } +} + +/// The storage result. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageResult { + /// The hex-encoded key of the result. + pub key: String, + /// The result of the query. + #[serde(flatten)] + pub result: StorageResultType, +} + +/// The type of the storage query. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum StorageResultType { + /// Fetch the value of the provided key. + Value(String), + /// Fetch the hash of the value of the provided key. + Hash(String), + /// Fetch the closest descendant merkle value. + ClosestDescendantMerkleValue(String), +} + +/// The error of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageResultErr { + /// The hex-encoded key of the result. + pub key: String, + /// The result of the query. + #[serde(flatten)] + pub error: StorageResultType, +} + +/// The result of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ArchiveStorageResult { + /// Query generated a result. + Ok(ArchiveStorageMethodOk), + /// Query encountered an error. + Err(ArchiveStorageMethodErr), +} + +impl ArchiveStorageResult { + /// Create a new `ArchiveStorageResult::Ok` result. + pub fn ok(result: Vec, discarded_items: usize) -> Self { + Self::Ok(ArchiveStorageMethodOk { result, discarded_items }) + } + + /// Create a new `ArchiveStorageResult::Err` result. + pub fn err(error: String) -> Self { + Self::Err(ArchiveStorageMethodErr { error }) + } +} + +/// The result of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ArchiveStorageMethodOk { + /// Reported results. + pub result: Vec, + /// Number of discarded items. + pub discarded_items: usize, +} + +/// The error of a storage call. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ArchiveStorageMethodErr { + /// Reported error. + pub error: String, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn storage_result() { + // Item with Value. + let item = + StorageResult { key: "0x1".into(), result: StorageResultType::Value("res".into()) }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","value":"res"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageResult = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with Hash. + let item = + StorageResult { key: "0x1".into(), result: StorageResultType::Hash("res".into()) }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","hash":"res"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageResult = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with DescendantsValues. + let item = StorageResult { + key: "0x1".into(), + result: StorageResultType::ClosestDescendantMerkleValue("res".into()), + }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","closestDescendantMerkleValue":"res"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageResult = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + } + + #[test] + fn storage_query() { + // Item with Value. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Value }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"value"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with Hash. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::Hash }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"hash"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with DescendantsValues. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsValues }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"descendantsValues"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with DescendantsHashes. + let item = StorageQuery { key: "0x1", query_type: StorageQueryType::DescendantsHashes }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"descendantsHashes"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + // Item with Merkle. + let item = + StorageQuery { key: "0x1", query_type: StorageQueryType::ClosestDescendantMerkleValue }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"closestDescendantMerkleValue"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + } + + #[test] + fn storage_query_paginated() { + let item = PaginatedStorageQuery { + key: "0x1", + query_type: StorageQueryType::Value, + pagination_start_key: None, + }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"value"}"#; + assert_eq!(ser, exp); + // Decode + let dec: StorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec.key, item.key); + assert_eq!(dec.query_type, item.query_type); + let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + + let item = PaginatedStorageQuery { + key: "0x1", + query_type: StorageQueryType::Value, + pagination_start_key: Some("0x2"), + }; + // Encode + let ser = serde_json::to_string(&item).unwrap(); + let exp = r#"{"key":"0x1","type":"value","paginationStartKey":"0x2"}"#; + assert_eq!(ser, exp); + // Decode + let dec: PaginatedStorageQuery<&str> = serde_json::from_str(exp).unwrap(); + assert_eq!(dec, item); + } +} diff --git a/substrate/client/rpc-spec-v2/src/common/mod.rs b/substrate/client/rpc-spec-v2/src/common/mod.rs new file mode 100644 index 00000000000..ac1af8fce3c --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/common/mod.rs @@ -0,0 +1,17 @@ +// This program 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. + +// This program 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 this program. If not, see . + +//! Common types and functionality for the RPC-V2 spec. + +pub mod events; +pub mod storage; diff --git a/substrate/client/rpc-spec-v2/src/common/storage.rs b/substrate/client/rpc-spec-v2/src/common/storage.rs new file mode 100644 index 00000000000..bd249e033f8 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/common/storage.rs @@ -0,0 +1,198 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +//! Storage queries for the RPC-V2 spec. + +use std::{marker::PhantomData, sync::Arc}; + +use sc_client_api::{Backend, ChildInfo, StorageKey, StorageProvider}; +use sp_runtime::traits::Block as BlockT; + +use super::events::{StorageResult, StorageResultType}; +use crate::hex_string; + +/// Call into the storage of blocks. +pub struct Storage { + /// Substrate client. + client: Arc, + _phandom: PhantomData<(BE, Block)>, +} + +impl Storage { + /// Constructs a new [`Storage`]. + pub fn new(client: Arc) -> Self { + Self { client, _phandom: PhantomData } + } +} + +/// Query to iterate over storage. +pub struct QueryIter { + /// The key from which the iteration was started. + pub query_key: StorageKey, + /// The key after which pagination should resume. + pub pagination_start_key: Option, + /// The type of the query (either value or hash). + pub ty: IterQueryType, +} + +/// The query type of an iteration. +pub enum IterQueryType { + /// Iterating over (key, value) pairs. + Value, + /// Iterating over (key, hash) pairs. + Hash, +} + +/// The result of making a query call. +pub type QueryResult = Result, String>; + +/// The result of iterating over keys. +pub type QueryIterResult = Result<(Vec, Option), String>; + +impl Storage +where + Block: BlockT + 'static, + BE: Backend + 'static, + Client: StorageProvider + 'static, +{ + /// Fetch the value from storage. + pub fn query_value( + &self, + hash: Block::Hash, + key: &StorageKey, + child_key: Option<&ChildInfo>, + ) -> QueryResult { + let result = if let Some(child_key) = child_key { + self.client.child_storage(hash, child_key, key) + } else { + self.client.storage(hash, key) + }; + + result + .map(|opt| { + QueryResult::Ok(opt.map(|storage_data| StorageResult { + key: hex_string(&key.0), + result: StorageResultType::Value(hex_string(&storage_data.0)), + })) + }) + .unwrap_or_else(|error| QueryResult::Err(error.to_string())) + } + + /// Fetch the hash of a value from storage. + pub fn query_hash( + &self, + hash: Block::Hash, + key: &StorageKey, + child_key: Option<&ChildInfo>, + ) -> QueryResult { + let result = if let Some(child_key) = child_key { + self.client.child_storage_hash(hash, child_key, key) + } else { + self.client.storage_hash(hash, key) + }; + + result + .map(|opt| { + QueryResult::Ok(opt.map(|storage_data| StorageResult { + key: hex_string(&key.0), + result: StorageResultType::Hash(hex_string(&storage_data.as_ref())), + })) + }) + .unwrap_or_else(|error| QueryResult::Err(error.to_string())) + } + + /// Fetch the closest merkle value. + pub fn query_merkle_value( + &self, + hash: Block::Hash, + key: &StorageKey, + child_key: Option<&ChildInfo>, + ) -> QueryResult { + let result = if let Some(child_key) = child_key { + self.client.child_closest_merkle_value(hash, child_key, key) + } else { + self.client.closest_merkle_value(hash, key) + }; + + result + .map(|opt| { + QueryResult::Ok(opt.map(|storage_data| { + let result = match &storage_data { + sc_client_api::MerkleValue::Node(data) => hex_string(&data.as_slice()), + sc_client_api::MerkleValue::Hash(hash) => hex_string(&hash.as_ref()), + }; + + StorageResult { + key: hex_string(&key.0), + result: StorageResultType::ClosestDescendantMerkleValue(result), + } + })) + }) + .unwrap_or_else(|error| QueryResult::Err(error.to_string())) + } + + /// Iterate over at most the provided number of keys. + /// + /// Returns the storage result with a potential next key to resume iteration. + pub fn query_iter_pagination( + &self, + query: QueryIter, + hash: Block::Hash, + child_key: Option<&ChildInfo>, + count: usize, + ) -> QueryIterResult { + let QueryIter { ty, query_key, pagination_start_key } = query; + + let mut keys_iter = if let Some(child_key) = child_key { + self.client.child_storage_keys( + hash, + child_key.to_owned(), + Some(&query_key), + pagination_start_key.as_ref(), + ) + } else { + self.client.storage_keys(hash, Some(&query_key), pagination_start_key.as_ref()) + } + .map_err(|err| err.to_string())?; + + let mut ret = Vec::with_capacity(count); + let mut next_pagination_key = None; + for _ in 0..count { + let Some(key) = keys_iter.next() else { break }; + + next_pagination_key = Some(key.clone()); + + let result = match ty { + IterQueryType::Value => self.query_value(hash, &key, child_key), + IterQueryType::Hash => self.query_hash(hash, &key, child_key), + }?; + + if let Some(value) = result { + ret.push(value); + } + } + + // Save the next key if any to continue the iteration. + let maybe_next_query = keys_iter.next().map(|_| QueryIter { + ty, + query_key, + pagination_start_key: next_pagination_key, + }); + Ok((ret, maybe_next_query)) + } +} diff --git a/substrate/client/rpc-spec-v2/src/lib.rs b/substrate/client/rpc-spec-v2/src/lib.rs index d202bfef4a7..23ed422cff1 100644 --- a/substrate/client/rpc-spec-v2/src/lib.rs +++ b/substrate/client/rpc-spec-v2/src/lib.rs @@ -24,6 +24,9 @@ #![deny(unused_crate_dependencies)] use serde::{Deserialize, Serialize}; +use sp_core::hexdisplay::{AsBytesRef, HexDisplay}; + +mod common; pub mod archive; pub mod chain_head; @@ -39,7 +42,7 @@ pub type SubscriptionTaskExecutor = std::sync::Arc(data: &Data) -> String { + format!("0x{:?}", HexDisplay::from(data)) +} + #[cfg(test)] mod tests { use super::*; -- GitLab From ac303406ffc0b1478b53d236a7983c31755717bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:56:22 +0100 Subject: [PATCH 003/283] Bump the known_good_semver group with 1 update (#2926) Bumps the known_good_semver group with 1 update: [clap](https://github.com/clap-rs/clap). Updates `clap` from 4.4.14 to 4.4.16
Release notes

Sourced from clap's releases.

v4.4.16

[4.4.16] - 2024-01-12

Fixes

  • Ensure invalid escape sequences in user-defined strings are correctly stripped when terminal doesn't support color

v4.4.15

[4.4.15] - 2024-01-11

Fixes

  • Improve error for args_conflicts_with_subcommands
  • Ensure we error for args_conflicts_with_subcommands when using subcommand short and long flags
Changelog

Sourced from clap's changelog.

[4.4.16] - 2024-01-12

Fixes

  • Ensure invalid escape sequences in user-defined strings are correctly stripped when terminal doesn't support color

[4.4.15] - 2024-01-11

Fixes

  • Improve error for args_conflicts_with_subcommands
  • Ensure we error for args_conflicts_with_subcommands when using subcommand short and long flags
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=clap&package-manager=cargo&previous-version=4.4.14&new-version=4.4.16)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 70 +++++++++---------- cumulus/client/cli/Cargo.toml | 2 +- cumulus/parachain-template/node/Cargo.toml | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- cumulus/test/service/Cargo.toml | 2 +- polkadot/cli/Cargo.toml | 2 +- polkadot/node/malus/Cargo.toml | 2 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../test-parachains/adder/collator/Cargo.toml | 2 +- .../undying/collator/Cargo.toml | 2 +- polkadot/utils/generate-bags/Cargo.toml | 2 +- .../remote-ext-tests/bags-list/Cargo.toml | 2 +- substrate/bin/minimal/node/Cargo.toml | 2 +- substrate/bin/node-template/node/Cargo.toml | 2 +- substrate/bin/node/bench/Cargo.toml | 2 +- substrate/bin/node/cli/Cargo.toml | 4 +- substrate/bin/node/inspect/Cargo.toml | 2 +- .../bin/utils/chain-spec-builder/Cargo.toml | 2 +- substrate/bin/utils/subkey/Cargo.toml | 2 +- substrate/client/cli/Cargo.toml | 2 +- substrate/client/storage-monitor/Cargo.toml | 2 +- .../solution-type/fuzzer/Cargo.toml | 2 +- .../npos-elections/fuzzer/Cargo.toml | 2 +- .../ci/node-template-release/Cargo.toml | 2 +- .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- .../frame/frame-utilities-cli/Cargo.toml | 2 +- .../generate-bags/node-runtime/Cargo.toml | 2 +- .../utils/frame/try-runtime/cli/Cargo.toml | 2 +- 28 files changed, 63 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b20adebf963..aa773aa104a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,9 +270,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" dependencies = [ "anstyle", "anstyle-parse", @@ -2637,9 +2637,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.14" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" +checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" dependencies = [ "clap_builder", "clap_derive 4.4.7", @@ -2656,9 +2656,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.14" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" +checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" dependencies = [ "anstream", "anstyle", @@ -2673,7 +2673,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", ] [[package]] @@ -3411,7 +3411,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.14", + "clap 4.4.16", "criterion-plot", "futures", "is-terminal", @@ -3574,7 +3574,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -4313,7 +4313,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.4.14", + "clap 4.4.16", "criterion 0.5.1", "cumulus-client-cli", "cumulus-client-consensus-common", @@ -5497,7 +5497,7 @@ dependencies = [ "Inflector", "array-bytes 6.1.0", "chrono", - "clap 4.4.14", + "clap 4.4.16", "comfy-table", "frame-benchmarking", "frame-support", @@ -5589,7 +5589,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -8105,7 +8105,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "minimal-node" version = "4.0.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame", "futures", "futures-timer", @@ -8569,7 +8569,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes 6.1.0", - "clap 4.4.14", + "clap 4.4.16", "derive_more", "fs_extra", "futures", @@ -8646,7 +8646,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "generate-bags", "kitchensink-runtime", ] @@ -8655,7 +8655,7 @@ dependencies = [ name = "node-template" version = "4.0.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -8699,7 +8699,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "flate2", "fs_extra", "glob", @@ -11243,7 +11243,7 @@ dependencies = [ name = "parachain-template-node" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -12201,7 +12201,7 @@ name = "polkadot-cli" version = "1.1.0" dependencies = [ "cfg-if", - "clap 4.4.14", + "clap 4.4.16", "frame-benchmarking-cli", "futures", "log", @@ -13042,7 +13042,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.4.14", + "clap 4.4.16", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -13553,7 +13553,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.14", + "clap 4.4.16", "clap-num", "color-eyre", "colored", @@ -13630,7 +13630,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.14", + "clap 4.4.16", "color-eyre", "futures", "futures-timer", @@ -13777,7 +13777,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "generate-bags", "sp-io", "westend-runtime", @@ -14647,7 +14647,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -15437,7 +15437,7 @@ dependencies = [ "array-bytes 6.1.0", "bip39", "chrono", - "clap 4.4.14", + "clap 4.4.16", "fdlimit", "futures", "futures-timer", @@ -16581,7 +16581,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "fs4", "log", "sp-core", @@ -18531,7 +18531,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "honggfuzz", "rand 0.8.5", "sp-npos-elections", @@ -19052,7 +19052,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "log", "sc-chain-spec", "serde_json", @@ -19065,7 +19065,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes 6.1.0", "assert_cmd", - "clap 4.4.14", + "clap 4.4.16", "clap_complete", "criterion 0.4.0", "frame-benchmarking", @@ -19174,7 +19174,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.9.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -19379,7 +19379,7 @@ dependencies = [ name = "subkey" version = "3.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "sc-cli", ] @@ -19421,7 +19421,7 @@ dependencies = [ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "frame-support", "frame-system", "sc-cli", @@ -19899,7 +19899,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "futures", "futures-timer", "log", @@ -19947,7 +19947,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.4.14", + "clap 4.4.16", "futures", "futures-timer", "log", @@ -20598,7 +20598,7 @@ version = "0.10.0-dev" dependencies = [ "assert_cmd", "async-trait", - "clap 4.4.14", + "clap 4.4.16", "frame-remote-externalities", "frame-try-runtime", "hex", diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 736cb02b94b..4048c3eaecb 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } url = "2.4.0" diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index 7edb4b454c0..b34478ab3dd 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -14,7 +14,7 @@ publish = false workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.20" codec = { package = "parity-scale-codec", version = "3.0.0" } serde = { version = "1.0.195", features = ["derive"] } diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 50fc48b3f2f..9f42a265f39 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } futures = "0.3.28" hex-literal = "0.4.1" diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index f4dde7d2945..387d65c4931 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } criterion = { version = "0.5.1", features = ["async_tokio"] } jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index 1b331c5ed42..cc96422abbc 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] cfg-if = "1.0" -clap = { version = "4.4.14", features = ["derive"], optional = true } +clap = { version = "4.4.16", features = ["derive"], optional = true } log = "0.4.17" thiserror = "1.0.48" futures = "0.3.21" diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml index 56d377648bb..7793abfd69b 100644 --- a/polkadot/node/malus/Cargo.toml +++ b/polkadot/node/malus/Cargo.toml @@ -43,7 +43,7 @@ assert_matches = "1.5" async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index dc1179b7762..ab3de33fe2c 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -31,7 +31,7 @@ async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sc-keystore = { path = "../../../substrate/client/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml index c2cea979b97..4ebeb767905 100644 --- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml index 4d7c7391d82..1d851218bed 100644 --- a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index 5435baa6151..a16ee8de496 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -10,7 +10,7 @@ description = "CLI to generate voter bags for Polkadot runtimes" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } generate-bags = { path = "../../../substrate/utils/frame/generate-bags" } sp-io = { path = "../../../substrate/primitives/io" } diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml index aeb62e87941..75bfdd9d1a0 100644 --- a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -18,6 +18,6 @@ sp-tracing = { path = "../../../../substrate/primitives/tracing" } frame-system = { path = "../../../../substrate/frame/system" } sp-core = { path = "../../../../substrate/primitives/core" } -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.17" tokio = { version = "1.24.2", features = ["macros"] } diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml index 07138eb0c55..5a2427fd4d8 100644 --- a/substrate/bin/minimal/node/Cargo.toml +++ b/substrate/bin/minimal/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "minimal-node" [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index aac24a83096..f91db97985b 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } serde_json = "1.0.111" diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index e2b68b2a0e8..926cdc3bfb0 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] array-bytes = "6.1" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.17" node-primitives = { path = "../primitives" } node-testing = { path = "../testing" } diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 4bf5efd7cd1..64b61288391 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -41,7 +41,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies array-bytes = "6.1" -clap = { version = "4.4.14", features = ["derive"], optional = true } +clap = { version = "4.4.16", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } @@ -164,7 +164,7 @@ sp-trie = { path = "../../../primitives/trie" } sp-state-machine = { path = "../../../primitives/state-machine" } [build-dependencies] -clap = { version = "4.4.14", optional = true } +clap = { version = "4.4.16", optional = true } clap_complete = { version = "4.0.2", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml index 29c0917440e..ef82f16be2a 100644 --- a/substrate/bin/node/inspect/Cargo.toml +++ b/substrate/bin/node/inspect/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } thiserror = "1.0" sc-cli = { path = "../../../client/cli" } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index e9dc4d83b6b..a9ea0ad40b3 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -23,7 +23,7 @@ name = "chain-spec-builder" crate-type = ["rlib"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } log = "0.4.17" sc-chain-spec = { path = "../../../client/chain-spec" } serde_json = "1.0.111" diff --git a/substrate/bin/utils/subkey/Cargo.toml b/substrate/bin/utils/subkey/Cargo.toml index 822068f6614..19eba2f1969 100644 --- a/substrate/bin/utils/subkey/Cargo.toml +++ b/substrate/bin/utils/subkey/Cargo.toml @@ -20,5 +20,5 @@ path = "src/main.rs" name = "subkey" [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index caaa96b904c..ce9b1781686 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4.31" -clap = { version = "4.4.14", features = ["derive", "string", "wrap_help"] } +clap = { version = "4.4.16", features = ["derive", "string", "wrap_help"] } fdlimit = "0.3.0" futures = "0.3.21" itertools = "0.10.3" diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 7185c62e276..17f1c42bccb 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://substrate.io" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive", "string"] } +clap = { version = "4.4.16", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" sp-core = { path = "../../primitives/core" } diff --git a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml index d64498de087..62316b27290 100644 --- a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index e7cfb75e54b..f98e41ae77a 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -17,7 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } sp-npos-elections = { path = ".." } diff --git a/substrate/scripts/ci/node-template-release/Cargo.toml b/substrate/scripts/ci/node-template-release/Cargo.toml index b02f941811c..40ba629fb05 100644 --- a/substrate/scripts/ci/node-template-release/Cargo.toml +++ b/substrate/scripts/ci/node-template-release/Cargo.toml @@ -14,7 +14,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } flate2 = "1.0" fs_extra = "1.3" glob = "0.3" diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index 21c5701b518..f7210cf768f 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.0.1", default-features = false } handlebars = "4.2.2" diff --git a/substrate/utils/frame/frame-utilities-cli/Cargo.toml b/substrate/utils/frame/frame-utilities-cli/Cargo.toml index 886e17280b1..899f86f3cb4 100644 --- a/substrate/utils/frame/frame-utilities-cli/Cargo.toml +++ b/substrate/utils/frame/frame-utilities-cli/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" workspace = true [dependencies] -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } frame-support = { path = "../../../frame/support" } frame-system = { path = "../../../frame/system" } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml index d2aaaff9a69..ba11fce18f8 100644 --- a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml +++ b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml @@ -17,4 +17,4 @@ kitchensink-runtime = { path = "../../../../bin/node/runtime" } generate-bags = { path = ".." } # third-party -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml index b5bce36e3b7..ac515315bbe 100644 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ b/substrate/utils/frame/try-runtime/cli/Cargo.toml @@ -38,7 +38,7 @@ frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } substrate-rpc-client = { path = "../../rpc/client" } async-trait = "0.1.74" -clap = { version = "4.4.14", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } hex = { version = "0.4.3", default-features = false } log = "0.4.17" parity-scale-codec = "3.6.1" -- GitLab From 36a83186376707e551e43966265fbcc3f1c4afcc Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Mon, 15 Jan 2024 15:53:35 +0100 Subject: [PATCH 004/283] Add missing crates to the workspace (#2932) Changes: - add missing member to the workspace - add CI script after the last attempt to merge it upstream failed https://github.com/paritytech/pipeline-scripts/pull/105 Two crates are excluded from the check since they are templates `substrate/frame/contracts/fixtures/build` and `substrate/frame/contracts/fixtures/contracts/common`. Hopefully this is the last time that some crates need to be added manually. ![meme](https://github.com/paritytech/polkadot-sdk/assets/10380170/984843ee-1c76-4126-a4fc-ff2ba1d47377) --------- Signed-off-by: Oliver Tale-Yazdi --- .github/scripts/check-workspace.py | 162 ++++++++++++++++++++++++++ .github/workflows/check-workspace.yml | 23 ++++ Cargo.toml | 1 + 3 files changed, 186 insertions(+) create mode 100644 .github/scripts/check-workspace.py create mode 100644 .github/workflows/check-workspace.yml diff --git a/.github/scripts/check-workspace.py b/.github/scripts/check-workspace.py new file mode 100644 index 00000000000..fb3b53acb0c --- /dev/null +++ b/.github/scripts/check-workspace.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 + +# Ensures that: +# - all crates are added to the root workspace +# - local dependencies are resolved via `path` +# +# It does not check that the local paths resolve to the correct crate. This is already done by cargo. +# +# Must be called with a folder containing a `Cargo.toml` workspace file. + +import os +import sys +import toml +import argparse + +def parse_args(): + parser = argparse.ArgumentParser(description='Check Rust workspace integrity.') + + parser.add_argument('workspace_dir', help='The directory to check', metavar='workspace_dir', type=str, nargs=1) + parser.add_argument('--exclude', help='Exclude crate paths from the check', metavar='exclude', type=str, nargs='*', default=[]) + + args = parser.parse_args() + return (args.workspace_dir[0], args.exclude) + +def main(root, exclude): + workspace_crates = get_members(root, exclude) + all_crates = get_crates(root, exclude) + print(f'📦 Found {len(all_crates)} crates in total') + + check_missing(workspace_crates, all_crates) + check_links(all_crates) + +# Extract all members from a workspace. +# Return: list of all workspace paths +def get_members(workspace_dir, exclude): + print(f'🔎 Indexing workspace {os.path.abspath(workspace_dir)}') + + root_manifest_path = os.path.join(workspace_dir, "Cargo.toml") + if not os.path.exists(root_manifest_path): + print(f'❌ No root manifest found at {root_manifest}') + sys.exit(1) + + root_manifest = toml.load(root_manifest_path) + if not 'workspace' in root_manifest: + print(f'❌ No workspace found in root {root_manifest_path}') + sys.exit(1) + + if not 'members' in root_manifest['workspace']: + return [] + + members = [] + for member in root_manifest['workspace']['members']: + if member in exclude: + print(f'❌ Excluded member should not appear in the workspace {member}') + sys.exit(1) + members.append(member) + + return members + +# List all members of the workspace. +# Return: Map name -> (path, manifest) +def get_crates(workspace_dir, exclude_crates) -> dict: + crates = {} + + for root, dirs, files in os.walk(workspace_dir): + if "target" in root: + continue + for file in files: + if file != "Cargo.toml": + continue + + path = os.path.join(root, file) + with open(path, "r") as f: + content = f.read() + manifest = toml.loads(content) + + if 'workspace' in manifest: + if root != workspace_dir: + print("⏩ Excluded recursive workspace at %s" % path) + continue + + # Cut off the root path and the trailing /Cargo.toml. + path = path[len(workspace_dir)+1:-11] + name = manifest['package']['name'] + if path in exclude_crates: + print("⏩ Excluded crate %s at %s" % (name, path)) + continue + crates[name] = (path, manifest) + + return crates + +# Check that all crates are in the workspace. +def check_missing(workspace_crates, all_crates): + print(f'🔎 Checking for missing crates') + if len(workspace_crates) == len(all_crates): + print(f'✅ All {len(all_crates)} crates are in the workspace') + return + + missing = [] + # Find out which ones are missing. + for name, (path, manifest) in all_crates.items(): + if not path in workspace_crates: + missing.append([name, path, manifest]) + missing.sort() + + for name, path, _manifest in missing: + print("❌ %s in %s" % (name, path)) + print(f'😱 {len(all_crates) - len(workspace_crates)} crates are missing from the workspace') + sys.exit(1) + +# Check that all local dependencies are good. +def check_links(all_crates): + print(f'🔎 Checking for broken dependency links') + links = [] + broken = [] + + for name, (path, manifest) in all_crates.items(): + def check_deps(deps): + for dep in deps: + # Could be renamed: + dep_name = dep + if 'package' in deps[dep]: + dep_name = deps[dep]['package'] + if dep_name in all_crates: + links.append((name, dep_name)) + + if not 'path' in deps[dep]: + broken.append((name, dep_name, "crate must be linked via `path`")) + return + + def check_crate(deps): + to_checks = ['dependencies', 'dev-dependencies', 'build-dependencies'] + + for to_check in to_checks: + if to_check in deps: + check_deps(deps[to_check]) + + # There could possibly target dependant deps: + if 'target' in manifest: + # Target dependant deps can only have one level of nesting: + for _, target in manifest['target'].items(): + check_crate(target) + + check_crate(manifest) + + + + links.sort() + broken.sort() + + if len(broken) > 0: + for (l, r, reason) in broken: + print(f'❌ {l} -> {r} ({reason})') + + print("💥 %d out of %d links are broken" % (len(broken), len(links))) + sys.exit(1) + else: + print("✅ All %d internal dependency links are correct" % len(links)) + +if __name__ == "__main__": + args = parse_args() + main(args[0], args[1]) diff --git a/.github/workflows/check-workspace.yml b/.github/workflows/check-workspace.yml new file mode 100644 index 00000000000..3dd812d7d9b --- /dev/null +++ b/.github/workflows/check-workspace.yml @@ -0,0 +1,23 @@ +name: Check workspace + +on: + pull_request: + paths: + - "*.toml" + merge_group: + +jobs: + check-workspace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.0 (22. Sep 2023) + + - name: install python deps + run: pip3 install toml + + - name: check integrity + run: > + python3 .github/scripts/check-workspace.py . + --exclude + "substrate/frame/contracts/fixtures/build" + "substrate/frame/contracts/fixtures/contracts/common" diff --git a/Cargo.toml b/Cargo.toml index 38cae6f640c..3afccc24992 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,6 +105,7 @@ members = [ "cumulus/parachains/runtimes/assets/test-utils", "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo", "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend", + "cumulus/parachains/runtimes/bridge-hubs/common", "cumulus/parachains/runtimes/bridge-hubs/test-utils", "cumulus/parachains/runtimes/collectives/collectives-westend", "cumulus/parachains/runtimes/contracts/contracts-rococo", -- GitLab From f2fbba3be1d7deaf7cfc731cea00552c212ddfcf Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Mon, 15 Jan 2024 17:21:31 +0100 Subject: [PATCH 005/283] Contracts: stabilize sr25519 (#2920) Integration tests in ink!: https://github.com/paritytech/ink/tree/master/integration-tests/sr25519-verification --- prdoc/pr_2920.prdoc | 11 +++++++++++ substrate/frame/contracts/src/wasm/runtime.rs | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 prdoc/pr_2920.prdoc diff --git a/prdoc/pr_2920.prdoc b/prdoc/pr_2920.prdoc new file mode 100644 index 00000000000..7745838ab5c --- /dev/null +++ b/prdoc/pr_2920.prdoc @@ -0,0 +1,11 @@ +# 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: Contracts: Stabilize sr25519_verify host function + +doc: + - audience: Runtime Dev + description: | + Removed the `#[unstable]` attrribute on `sr25519_verify` host function. + +crates: ["pallet-contracts"] diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index 7b1e35ee1ad..a7f329005f9 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -2229,7 +2229,6 @@ pub mod env { /// Verify a sr25519 signature /// See [`pallet_contracts_uapi::HostFn::sr25519_verify`]. - #[unstable] fn sr25519_verify( ctx: _, memory: _, -- GitLab From 0c166ae0194b7337f1c151434483b78b31235549 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:07:09 +0100 Subject: [PATCH 006/283] Bump lycheeverse/lychee-action (#2900) Bumps [lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action) from fdea7032675810093199f485fe075f057cc37b3e to c3089c702fbb949e3f7a8122be0c33c017904f9b.
Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Signed-off-by: Oliver Tale-Yazdi Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sergejs Kostjucenko <85877331+sergejparity@users.noreply.github.com> Co-authored-by: Oliver Tale-Yazdi --- .config/lychee.toml | 4 ++++ .github/workflows/check-links.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.config/lychee.toml b/.config/lychee.toml index 70869465d67..200521ac41e 100644 --- a/.config/lychee.toml +++ b/.config/lychee.toml @@ -47,4 +47,8 @@ exclude = [ "https://w3f.github.io/parachain-implementers-guide/node/index.html", "https://w3f.github.io/parachain-implementers-guide/protocol-chain-selection.html", "https://w3f.github.io/parachain-implementers-guide/runtime/session_info.html", + + # Behind a captcha (code 403): + "https://iohk.io/en/blog/posts/2023/11/03/partner-chains-are-coming-to-cardano/", + "https://www.reddit.com/r/rust/comments/3spfh1/does_collect_allocate_more_than_once_while/", ] diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index d3865335c09..903d7a3fcb3 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.0 (22. Sep 2023) - name: Lychee link checker - uses: lycheeverse/lychee-action@fdea7032675810093199f485fe075f057cc37b3e # for v1.9.0 (5. Jan 2024) + uses: lycheeverse/lychee-action@c3089c702fbb949e3f7a8122be0c33c017904f9b # for v1.9.1 (10. Jan 2024) with: args: >- --config .config/lychee.toml -- GitLab From 1c2db1747e72a0d953a69e88569fa822eb94622a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 16 Jan 2024 01:19:17 +0100 Subject: [PATCH 007/283] Some random fixes (#2936) - Do not disable `std` feature in the integration tests - `contracts-fixtures` test should only check for `riscv` build when the feature is enabled --- .../emulated/common/Cargo.toml | 28 +++++++++---------- substrate/frame/contracts/fixtures/src/lib.rs | 1 + 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml index 8277b3d734f..2ee91e83585 100644 --- a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml @@ -16,29 +16,29 @@ serde_json = "1.0.111" # Substrate grandpa = { package = "sc-consensus-grandpa", path = "../../../../../substrate/client/consensus/grandpa" } -sp-authority-discovery = { path = "../../../../../substrate/primitives/authority-discovery", default-features = false } -sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-features = false } -frame-support = { path = "../../../../../substrate/frame/support", default-features = false } -sp-core = { path = "../../../../../substrate/primitives/core", default-features = false } -sp-consensus-babe = { path = "../../../../../substrate/primitives/consensus/babe", default-features = false } -pallet-assets = { path = "../../../../../substrate/frame/assets", default-features = false } -pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false } -pallet-message-queue = { path = "../../../../../substrate/frame/message-queue", default-features = false } -pallet-im-online = { path = "../../../../../substrate/frame/im-online", default-features = false } +sp-authority-discovery = { path = "../../../../../substrate/primitives/authority-discovery" } +sp-runtime = { path = "../../../../../substrate/primitives/runtime" } +frame-support = { path = "../../../../../substrate/frame/support" } +sp-core = { path = "../../../../../substrate/primitives/core" } +sp-consensus-babe = { path = "../../../../../substrate/primitives/consensus/babe" } +pallet-assets = { path = "../../../../../substrate/frame/assets" } +pallet-balances = { path = "../../../../../substrate/frame/balances" } +pallet-message-queue = { path = "../../../../../substrate/frame/message-queue" } +pallet-im-online = { path = "../../../../../substrate/frame/im-online" } beefy-primitives = { package = "sp-consensus-beefy", path = "../../../../../substrate/primitives/consensus/beefy" } # Polkadot polkadot-service = { path = "../../../../../polkadot/node/service", default-features = false, features = ["full-node"] } -polkadot-primitives = { path = "../../../../../polkadot/primitives", default-features = false } +polkadot-primitives = { path = "../../../../../polkadot/primitives" } polkadot-runtime-parachains = { path = "../../../../../polkadot/runtime/parachains" } -xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false } -pallet-xcm = { path = "../../../../../polkadot/xcm/pallet-xcm", default-features = false } +xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm" } +pallet-xcm = { path = "../../../../../polkadot/xcm/pallet-xcm" } # Cumulus parachains-common = { path = "../../../common" } cumulus-primitives-core = { path = "../../../../primitives/core" } -xcm-emulator = { path = "../../../../xcm/xcm-emulator", default-features = false } -cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false } +xcm-emulator = { path = "../../../../xcm/xcm-emulator" } +cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue" } cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system" } asset-test-utils = { path = "../../../runtimes/assets/test-utils" } diff --git a/substrate/frame/contracts/fixtures/src/lib.rs b/substrate/frame/contracts/fixtures/src/lib.rs index 4d850d75624..e0d9d4f8bd5 100644 --- a/substrate/frame/contracts/fixtures/src/lib.rs +++ b/substrate/frame/contracts/fixtures/src/lib.rs @@ -70,6 +70,7 @@ mod test { fn out_dir_should_have_compiled_mocks() { let out_dir: std::path::PathBuf = env!("OUT_DIR").into(); assert!(out_dir.join("dummy.wasm").exists()); + #[cfg(feature = "riscv")] assert!(out_dir.join("dummy.polkavm").exists()); } } -- GitLab From 4c4963a1929b59cce2c81d755b440403019e836d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 01:19:37 +0100 Subject: [PATCH 008/283] Bump Swatinem/rust-cache from 2.7.2 to 2.7.3 (#2925) Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.7.2 to 2.7.3.
Release notes

Sourced from Swatinem/rust-cache's releases.

v2.7.3

  • Work around upstream problem that causes cache saving to hang for minutes.

Full Changelog: https://github.com/Swatinem/rust-cache/compare/v2.7.2...v2.7.3

Changelog

Sourced from Swatinem/rust-cache's changelog.

Changelog

2.7.3

  • Work around upstream problem that causes cache saving to hang for minutes.

2.7.2

  • Only key by Cargo.toml and Cargo.lock files of workspace members.

2.7.1

  • Update toml parser to fix parsing errors.

2.7.0

  • Properly cache trybuild tests.

2.6.2

  • Fix toml parsing.

2.6.1

  • Fix hash contributions of Cargo.lock/Cargo.toml files.

2.6.0

  • Add "buildjet" as a second cache-provider backend.
  • Clean up sparse registry index.
  • Do not clean up src of -sys crates.
  • Remove .cargo/credentials.toml before saving.

2.5.1

  • Fix hash contribution of Cargo.lock.

2.5.0

  • feat: Rm workspace crates version before caching.
  • feat: Add hash of .cargo/config.toml to key.

2.4.0

  • Fix cache key stability.
  • Use 8 character hash components to reduce the key length, making it more readable.

2.3.0

  • Add cache-all-crates option, which enables caching of crates installed by workflows.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Swatinem/rust-cache&package-manager=github_actions&previous-version=2.7.2&new-version=2.7.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-publish.yml | 2 +- .github/workflows/claim-crates.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-publish.yml b/.github/workflows/check-publish.yml index 398cb732585..b16b3d4e5c5 100644 --- a/.github/workflows/check-publish.yml +++ b/.github/workflows/check-publish.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Rust Cache - uses: Swatinem/rust-cache@a22603398250b864f7190077025cf752307154dc # v2.7.2 + uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 with: cache-on-failure: true diff --git a/.github/workflows/claim-crates.yml b/.github/workflows/claim-crates.yml index 038ea213123..f3df0bce72d 100644 --- a/.github/workflows/claim-crates.yml +++ b/.github/workflows/claim-crates.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Rust Cache - uses: Swatinem/rust-cache@a22603398250b864f7190077025cf752307154dc # v2.7.2 + uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 with: cache-on-failure: true -- GitLab From 2cb39f8dc90f3431bd011084862ffa14e618b987 Mon Sep 17 00:00:00 2001 From: Muharem Date: Tue, 16 Jan 2024 15:34:48 +0800 Subject: [PATCH 009/283] XCM WeightTrader: Swap Fee Asset for Native Asset (#1845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements an XCM executor `WeightTrader`, facilitating fee payments in any asset that can be exchanged for a native asset. A few constraints need to be observed: - `buy_weight` and `refund` operations must be atomic, as another weight trader implementation might be attempted in case of failure. - swap credit must be utilized since there isn’t an account to which an asset of some class can be deposited with a guarantee to meet the existential deposit requirement. Also, operating with credits enhances the efficiency of the weight trader - https://github.com/paritytech/polkadot-sdk/pull/1677 related PRs: - (depends) https://github.com/paritytech/polkadot-sdk/pull/2031 - (depends) https://github.com/paritytech/polkadot-sdk/pull/1677 - (caused) https://github.com/paritytech/polkadot-sdk/pull/1847 - (caused) https://github.com/paritytech/polkadot-sdk/pull/1876 // DONE: impl `OnUnbalanced` for a `fungible/s` credit // DONE: make the trader free from a concept of a native currency and drop few fallible conversions. related issue - https://github.com/paritytech/polkadot-sdk/issues/1842 // DONE: tests --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Liam Aharon --- Cargo.lock | 4 + .../assets/asset-hub-rococo/src/tests/send.rs | 75 --- .../assets/asset-hub-rococo/src/tests/swap.rs | 127 ++++ .../asset-hub-westend/src/tests/send.rs | 75 --- .../asset-hub-westend/src/tests/swap.rs | 127 ++++ .../bridges/bridge-hub-rococo/Cargo.toml | 1 + .../bridges/bridge-hub-rococo/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 45 +- .../bridges/bridge-hub-westend/Cargo.toml | 1 + .../bridges/bridge-hub-westend/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 43 ++ .../assets/asset-hub-rococo/src/lib.rs | 19 +- .../assets/asset-hub-rococo/src/xcm_config.rs | 47 +- .../assets/asset-hub-rococo/tests/tests.rs | 497 +++++++--------- .../assets/asset-hub-westend/src/lib.rs | 19 +- .../asset-hub-westend/src/xcm_config.rs | 47 +- .../assets/asset-hub-westend/tests/tests.rs | 491 +++++++--------- .../runtimes/assets/common/src/lib.rs | 10 + .../runtimes/assets/test-utils/Cargo.toml | 2 + .../test-utils/src/test_cases_over_bridge.rs | 77 ++- cumulus/primitives/utility/Cargo.toml | 3 + cumulus/primitives/utility/src/lib.rs | 270 ++++++++- cumulus/primitives/utility/src/tests/mod.rs | 17 + .../utility/src/tests/swap_first.rs | 551 ++++++++++++++++++ prdoc/pr_1845.prdoc | 16 + 25 files changed, 1739 insertions(+), 831 deletions(-) create mode 100644 cumulus/primitives/utility/src/tests/mod.rs create mode 100644 cumulus/primitives/utility/src/tests/swap_first.rs create mode 100644 prdoc/pr_1845.prdoc diff --git a/Cargo.lock b/Cargo.lock index aa773aa104a..6299bbfe51c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1066,6 +1066,7 @@ dependencies = [ "frame-support", "frame-system", "hex-literal", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-collator-selection", @@ -1973,6 +1974,7 @@ dependencies = [ "frame-support", "hex", "hex-literal", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-bridge-messages", @@ -2165,6 +2167,7 @@ dependencies = [ "cumulus-pallet-xcmp-queue", "emulated-integration-tests-common", "frame-support", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-bridge-messages", @@ -4095,6 +4098,7 @@ dependencies = [ "cumulus-primitives-core", "frame-support", "log", + "pallet-asset-conversion", "pallet-xcm-benchmarks", "parity-scale-codec", "polkadot-runtime-common", diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs index 7be0463d2ec..fcf4513859e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs @@ -27,78 +27,3 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } - -/// Parachain should be able to send XCM paying its fee with sufficient asset -/// in the System Parachain -#[test] -fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { - let para_sovereign_account = AssetHubRococo::sovereign_account_id_of( - AssetHubRococo::sibling_location_of(PenpalA::para_id()), - ); - - // Force create and mint assets for Parachain's sovereign account - AssetHubRococo::force_create_and_mint_asset( - ASSET_ID, - ASSET_MIN_BALANCE, - true, - para_sovereign_account.clone(), - Some(Weight::from_parts(1_019_445_000, 200_000)), - ASSET_MIN_BALANCE * 1000000000, - ); - - // We just need a call that can pass the `SafeCallFilter` - // Call values are not relevant - let call = AssetHubRococo::force_create_asset_call( - ASSET_ID, - para_sovereign_account.clone(), - true, - ASSET_MIN_BALANCE, - ); - - let origin_kind = OriginKind::SovereignAccount; - let fee_amount = ASSET_MIN_BALANCE * 1000000; - let native_asset = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount).into(); - - let root_origin = ::RuntimeOrigin::root(); - let system_para_destination = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); - let xcm = xcm_transact_paid_execution( - call, - origin_kind, - native_asset, - para_sovereign_account.clone(), - ); - - PenpalA::execute_with(|| { - assert_ok!(::PolkadotXcm::send( - root_origin, - bx!(system_para_destination), - bx!(xcm), - )); - - PenpalA::assert_xcm_pallet_sent(); - }); - - AssetHubRococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - AssetHubRococo::assert_xcmp_queue_success(Some(Weight::from_parts( - 15_594_564_000, - 562_893, - ))); - - assert_expected_events!( - AssetHubRococo, - vec![ - RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == ASSET_ID, - owner: *owner == para_sovereign_account, - balance: *balance == fee_amount, - }, - RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { - asset_id: *asset_id == ASSET_ID, - }, - ] - ); - }); -} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs index 3dcc51b75cc..b1af69a1cd1 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs @@ -270,3 +270,130 @@ fn cannot_create_pool_from_pool_assets() { ); }); } + +#[test] +fn pay_xcm_fee_with_some_asset_swapped_for_native() { + let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); + let asset_one = MultiLocation { + parents: 0, + interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + }; + let penpal = AssetHubRococo::sovereign_account_id_of(AssetHubRococo::sibling_location_of( + PenpalA::para_id(), + )); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // set up pool with ASSET_ID <> NATIVE pair + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + AssetHubRococoSender::get().into(), + ASSET_MIN_BALANCE, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + AssetHubRococoSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(asset_native), + Box::new(asset_one), + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(asset_native), + Box::new(asset_one), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubRococoSender::get().into() + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + // ensure `penpal` sovereign account has no native tokens and mint some `ASSET_ID` + assert_eq!( + ::Balances::free_balance(penpal.clone()), + 0 + ); + + assert_ok!(::Assets::touch_other( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + )); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + 10_000_000_000_000, + )); + }); + + PenpalA::execute_with(|| { + // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // `AssetHubRococo` + let call = AssetHubRococo::force_create_asset_call( + ASSET_ID + 1000, + penpal.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let penpal_root = ::RuntimeOrigin::root(); + let fee_amount = 4_000_000_000_000u128; + let asset_one = + (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) + .into(); + let asset_hub_location = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + OriginKind::SovereignAccount, + asset_one, + penpal.clone(), + ); + + assert_ok!(::PolkadotXcm::send( + penpal_root, + bx!(asset_hub_location), + bx!(xcm), + )); + + PenpalA::assert_xcm_pallet_sent(); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubRococo::assert_xcmp_queue_success(None); + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapCreditExecuted { .. },) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true,.. }) => {}, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs index 4b98eeb0ed3..d943bafc379 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs @@ -27,78 +27,3 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } - -/// Parachain should be able to send XCM paying its fee with sufficient asset -/// in the System Parachain -#[test] -fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { - let para_sovereign_account = AssetHubWestend::sovereign_account_id_of( - AssetHubWestend::sibling_location_of(PenpalB::para_id()), - ); - - // Force create and mint assets for Parachain's sovereign account - AssetHubWestend::force_create_and_mint_asset( - ASSET_ID, - ASSET_MIN_BALANCE, - true, - para_sovereign_account.clone(), - Some(Weight::from_parts(1_019_445_000, 200_000)), - ASSET_MIN_BALANCE * 1000000000, - ); - - // We just need a call that can pass the `SafeCallFilter` - // Call values are not relevant - let call = AssetHubWestend::force_create_asset_call( - ASSET_ID, - para_sovereign_account.clone(), - true, - ASSET_MIN_BALANCE, - ); - - let origin_kind = OriginKind::SovereignAccount; - let fee_amount = ASSET_MIN_BALANCE * 1000000; - let native_asset = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount).into(); - - let root_origin = ::RuntimeOrigin::root(); - let system_para_destination = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); - let xcm = xcm_transact_paid_execution( - call, - origin_kind, - native_asset, - para_sovereign_account.clone(), - ); - - PenpalB::execute_with(|| { - assert_ok!(::PolkadotXcm::send( - root_origin, - bx!(system_para_destination), - bx!(xcm), - )); - - PenpalB::assert_xcm_pallet_sent(); - }); - - AssetHubWestend::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts( - 16_290_336_000, - 562_893, - ))); - - assert_expected_events!( - AssetHubWestend, - vec![ - RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == ASSET_ID, - owner: *owner == para_sovereign_account, - balance: *balance == fee_amount, - }, - RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { - asset_id: *asset_id == ASSET_ID, - }, - ] - ); - }); -} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs index 47b6ab01e8f..c768a1366fa 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs @@ -264,3 +264,130 @@ fn cannot_create_pool_from_pool_assets() { ); }); } + +#[test] +fn pay_xcm_fee_with_some_asset_swapped_for_native() { + let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); + let asset_one = MultiLocation { + parents: 0, + interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + }; + let penpal = AssetHubWestend::sovereign_account_id_of(AssetHubWestend::sibling_location_of( + PenpalB::para_id(), + )); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // set up pool with ASSET_ID <> NATIVE pair + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + AssetHubWestendSender::get().into(), + ASSET_MIN_BALANCE, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + AssetHubWestendSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(asset_native), + Box::new(asset_one), + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(asset_native), + Box::new(asset_one), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubWestendSender::get().into() + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + // ensure `penpal` sovereign account has no native tokens and mint some `ASSET_ID` + assert_eq!( + ::Balances::free_balance(penpal.clone()), + 0 + ); + + assert_ok!(::Assets::touch_other( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + )); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + 10_000_000_000_000, + )); + }); + + PenpalB::execute_with(|| { + // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // `AssetHubWestend` + let call = AssetHubWestend::force_create_asset_call( + ASSET_ID + 1000, + penpal.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let penpal_root = ::RuntimeOrigin::root(); + let fee_amount = 4_000_000_000_000u128; + let asset_one = + (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) + .into(); + let asset_hub_location = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + OriginKind::SovereignAccount, + asset_one, + penpal.clone(), + ); + + assert_ok!(::PolkadotXcm::send( + penpal_root, + bx!(asset_hub_location), + bx!(xcm), + )); + + PenpalB::assert_xcm_pallet_sent(); + }); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubWestend::assert_xcmp_queue_success(None); + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapCreditExecuted { .. },) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true,.. }) => {}, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml index 0904578b156..da09c674a03 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml @@ -20,6 +20,7 @@ hex-literal = "0.4.1" sp-core = { path = "../../../../../../../substrate/primitives/core", default-features = false } frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false } pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false } +pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false } pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false } pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" } sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index 5127bd759dc..608aa388ce8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -61,7 +61,8 @@ pub use rococo_westend_system_emulated_network::{ rococo_emulated_chain::{genesis::ED as ROCOCO_ED, RococoRelayPallet as RococoPallet}, AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver, AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend, - AssetHubWestendParaReceiver as AssetHubWestendReceiver, BridgeHubRococoPara as BridgeHubRococo, + AssetHubWestendParaReceiver as AssetHubWestendReceiver, + AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo, BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWestendPara as BridgeHubWestend, RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs index 5a2111a9be9..8b5a72a8e62 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs @@ -49,6 +49,49 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { AssetHubWestend::para_id(), ); + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `roc_at_asset_hub_westend` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + roc_at_asset_hub_westend.into(), + AssetHubWestendSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(Parent.into()), + Box::new(roc_at_asset_hub_westend), + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubWestendSender::get()), + Box::new(Parent.into()), + Box::new(roc_at_asset_hub_westend), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + AssetHubWestendSender::get().into() + )); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + let rocs_in_reserve_on_ahr_before = ::account_data_of(sov_ahw_on_ahr.clone()).free; let sender_rocs_before = @@ -58,7 +101,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { >::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get()) }); - let amount = ASSET_HUB_ROCOCO_ED * 1_000; + let amount = ASSET_HUB_ROCOCO_ED * 1_000_000; send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml index 6dcb57f4161..e9b4f8fb180 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml @@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "3.4.0", default-features = # Substrate frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false } pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false } +pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false } pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false } pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" } sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs index 90a11d38f77..17255320f1d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs @@ -55,7 +55,8 @@ pub use rococo_westend_system_emulated_network::{ }, westend_emulated_chain::WestendRelayPallet as WestendPallet, AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver, - AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver, + AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend, + AssetHubWestendParaReceiver as AssetHubWestendReceiver, AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo, BridgeHubWestendPara as BridgeHubWestend, BridgeHubWestendParaSender as BridgeHubWestendSender, WestendRelay as Westend, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs index 21f4b4ee235..a4b2719e9fd 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs @@ -48,6 +48,49 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { AssetHubRococo::para_id(), ); + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `wnd_at_asset_hub_rococo` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + wnd_at_asset_hub_rococo.into(), + AssetHubRococoSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(Parent.into()), + Box::new(wnd_at_asset_hub_rococo), + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubRococoSender::get()), + Box::new(Parent.into()), + Box::new(wnd_at_asset_hub_rococo), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + AssetHubRococoSender::get().into() + )); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + let wnds_in_reserve_on_ahw_before = ::account_data_of(sov_ahr_on_ahw.clone()).free; let sender_wnds_before = diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 3010cbc69fa..8cfa4565187 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -312,7 +312,7 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } -/// Union fungibles implementation for `Assets`` and `ForeignAssets`. +/// Union fungibles implementation for `Assets` and `ForeignAssets`. pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, @@ -324,18 +324,21 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< AccountId, >; +/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`. +pub type NativeAndAssets = fungible::UnionOf< + Balances, + LocalAndForeignAssets, + TargetFromLeft, + MultiLocation, + AccountId, +>; + impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; type AssetKind = MultiLocation; - type Assets = fungible::UnionOf< - Balances, - LocalAndForeignAssets, - TargetFromLeft, - Self::AssetKind, - Self::AccountId, - >; + type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = pallet_asset_conversion::WithFirstAsset; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 121e213b57f..f88d1066488 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -15,17 +15,21 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, - FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, - PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToWestendXcmRouter, - TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, + ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, matching::{FromNetwork, FromSiblingParachain, IsForeignConcreteAsset}, + TrustBackedAssetsAsMultiLocation, }; use frame_support::{ match_types, parameter_types, - traits::{ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess}, + traits::{ + tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, + PalletInfoAccess, + }, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -73,6 +77,7 @@ parameter_types! { pub PoolAssetsPalletLocation: MultiLocation = PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub StakingPot: AccountId = CollatorSelection::account_id(); pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); @@ -550,31 +555,17 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, - // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated - // `pallet_assets` instance - `Assets`. - cumulus_primitives_utility::TakeFirstAssetTrader< + cumulus_primitives_utility::SwapFirstAssetTrader< + TokenLocation, + crate::AssetConversion, + WeightToFee, + crate::NativeAndAssets, + ( + TrustBackedAssetsAsMultiLocation, + ForeignAssetsConvertedConcreteId, + ), + ResolveAssetTo, AccountId, - AssetFeeAsExistentialDepositMultiplierFeeCharger, - TrustBackedAssetsConvertedConcreteId, - Assets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - FungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, - >, - // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated - // `pallet_assets` instance - `ForeignAssets`. - cumulus_primitives_utility::TakeFirstAssetTrader< - AccountId, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, - ForeignAssetsConvertedConcreteId, - ForeignAssets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - ForeignFungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, >, ); type ResponseHandler = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index 42c91cc8ea6..c67374126d3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -17,34 +17,38 @@ //! Tests for the Rococo Assets Hub chain. -use asset_hub_rococo_runtime::xcm_config::{ - AssetFeeAsExistentialDepositMultiplierFeeCharger, TokenLocation, - TrustBackedAssetsPalletLocation, +use asset_hub_rococo_runtime::{ + xcm_config, + xcm_config::{bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation}, + AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, + RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, }; pub use asset_hub_rococo_runtime::{ - xcm_config::{ - self, bridging, CheckingAccount, ForeignCreatorsSovereignAccountOf, LocationToAccountId, - XcmConfig, - }, - AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, - RuntimeCall, RuntimeEvent, SessionKeys, System, ToWestendXcmRouterInstance, - TrustBackedAssetsInstance, XcmpQueue, + xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, + ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, + TrustBackedAssetsInstance, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; -use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, - traits::fungibles::InspectEnumerable, + assert_ok, + traits::{ + fungible::{Inspect, Mutate}, + fungibles::{ + Create, Inspect as FungiblesInspect, InspectEnumerable, Mutate as FungiblesMutate, + }, + }, weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - rococo::fee::WeightToFee, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + rococo::{currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; use sp_runtime::traits::MaybeEquivalence; +use std::convert::Into; use xcm::latest::prelude::*; use xcm_executor::traits::{Identity, JustTry, WeightTrader}; @@ -69,7 +73,7 @@ fn collator_session_keys() -> CollatorSessionKeys { } #[test] -fn test_asset_xcm_trader() { +fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -79,77 +83,55 @@ fn test_asset_xcm_trader() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - let minimum_asset_balance = 3333333_u128; - let local_asset_id = 1; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - local_asset_id.into(), - AccountId::from(ALICE).into(), - true, - minimum_asset_balance - )); + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = TokenLocation::get(); + let initial_balance = 200 * UNITS; - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - local_asset_id.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - // get asset id as multilocation - let asset_multilocation = - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(); - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - // Lets calculate amount needed - let asset_amount_needed = - AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( - local_asset_id, - bought, - ) - .expect("failed to compute"); - - // Lets pay with: asset_amount_needed + asset_amount_extra - let asset_amount_extra = 100_u128; - let asset: MultiAsset = - (asset_multilocation, asset_amount_needed + asset_amount_extra).into(); + // keep initial total issuance to assert later. + let total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (native_location, fee + extra_amount).into(); - // Lets buy_weight and make sure buy_weight does not return an error - let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); - // Check whether a correct amount of unused assets is returned - assert_ok!( - unused_assets.ensure_contains(&(asset_multilocation, asset_amount_extra).into()) - ); - - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Balances::total_issuance(), total_issuance); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (native_location, refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!( - Assets::balance(local_asset_id, AccountId::from(ALICE)), - minimum_asset_balance + asset_amount_needed - ); - - // We also need to ensure the total supply increased - assert_eq!( - Assets::total_supply(local_asset_id), - minimum_asset_balance + asset_amount_needed - ); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!(Balances::total_issuance(), total_issuance + fee - refund); + }) } #[test] -fn test_asset_xcm_trader_with_refund() { +fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -159,77 +141,93 @@ fn test_asset_xcm_trader_with_refund() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let asset_1: u32 = 1; + let native_location = TokenLocation::get(); + let asset_1_location = + AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create(asset_1, bob.clone(), true, 10)); + + assert_ok!(Assets::mint_into(asset_1, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location) )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - ExistentialDeposit::get() + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - // lets calculate amount needed - let amount_bought = WeightToFee::weight_to_fee(&bought); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - - // Make sure buy_weight does not return an error - assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); - - // Make sure again buy_weight does return an error - // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` - // tuple chain, which cannot be called twice - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // We actually use half of the weight - let weight_used = bought / 2; + // keep initial total issuance to assert later. + let asset_total_issuance = Assets::total_issuance(asset_1); + let native_total_issuance = Balances::total_issuance(); - // Make sure refurnd works. - let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); - - assert_eq!( - trader.refund_weight(bought - weight_used, &ctx), - Some((asset_multilocation, amount_refunded).into()) - ); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, asset_1_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // We only should have paid for half of the bought weight - let fees_paid = WeightToFee::weight_to_fee(&weight_used); - + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); assert_eq!( - Assets::balance(1, AccountId::from(ALICE)), - ExistentialDeposit::get() + fees_paid + Assets::total_issuance(asset_1), + asset_total_issuance + asset_fee - asset_refund ); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); - }); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] -fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { +fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -239,169 +237,96 @@ fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = TokenLocation::get(); + let foreign_location = + MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create( + foreign_location, + bob.clone(), true, - ExistentialDeposit::get() + 10 )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy small amount - let bought = Weight::from_parts(500_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); + assert_ok!(ForeignAssets::mint_into(foreign_location, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - - // Buy weight should return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // not credited since the ED is higher than this value - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); - - // We also need to ensure the total supply did not increase - assert_eq!(Assets::total_supply(1), 0); - }); -} - -#[test] -fn test_that_buying_ed_refund_does_not_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location) )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are gonna buy ED - let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - // We know we will have to buy at least ED, so lets make sure first it will - // fail with a payment of less than ED - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Now lets buy ED at least - let asset: MultiAsset = (asset_multilocation, ExistentialDeposit::get()).into(); - - // Buy weight should work - assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); - - // Should return None. We have a specific check making sure we dont go below ED for - // drop payment - assert_eq!(trader.refund_weight(bought, &ctx), None); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); - }); -} - -#[test] -fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // Create a non-sufficient asset with specific existential deposit - let minimum_asset_balance = 1_000_000_u128; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - false, - minimum_asset_balance + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); + // keep initial total issuance to assert later. + let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); + let native_total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // lets calculate amount needed - let asset_amount_needed = WeightToFee::weight_to_fee(&bought); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let asset: MultiAsset = (asset_multilocation, asset_amount_needed).into(); + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); - // Make sure again buy_weight does return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + // assert. + let unused_amount = + unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee + ); - // Drop trader + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, foreign_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has NOT received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); - - // We also need to ensure the total supply NOT increased - assert_eq!(Assets::total_supply(1), minimum_asset_balance); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index e0dff0c4516..8543500fa23 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -295,7 +295,7 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } -/// Union fungibles implementation for `Assets`` and `ForeignAssets`. +/// Union fungibles implementation for `Assets` and `ForeignAssets`. pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, @@ -307,18 +307,21 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< AccountId, >; +/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`. +pub type NativeAndAssets = fungible::UnionOf< + Balances, + LocalAndForeignAssets, + TargetFromLeft, + MultiLocation, + AccountId, +>; + impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; type AssetKind = MultiLocation; - type Assets = fungible::UnionOf< - Balances, - LocalAndForeignAssets, - TargetFromLeft, - Self::AssetKind, - Self::AccountId, - >; + type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = pallet_asset_conversion::WithFirstAsset; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index cb2fedeb146..28876d1d454 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -15,17 +15,21 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, - FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, - PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToRococoXcmRouter, - TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, + ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, matching::{FromSiblingParachain, IsForeignConcreteAsset}, + TrustBackedAssetsAsMultiLocation, }; use frame_support::{ match_types, parameter_types, - traits::{ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess}, + traits::{ + tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, + PalletInfoAccess, + }, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -70,6 +74,7 @@ parameter_types! { pub PoolAssetsPalletLocation: MultiLocation = PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub StakingPot: AccountId = CollatorSelection::account_id(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -567,31 +572,17 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, - // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated - // `pallet_assets` instance - `Assets`. - cumulus_primitives_utility::TakeFirstAssetTrader< + cumulus_primitives_utility::SwapFirstAssetTrader< + WestendLocation, + crate::AssetConversion, + WeightToFee, + crate::NativeAndAssets, + ( + TrustBackedAssetsAsMultiLocation, + ForeignAssetsConvertedConcreteId, + ), + ResolveAssetTo, AccountId, - AssetFeeAsExistentialDepositMultiplierFeeCharger, - TrustBackedAssetsConvertedConcreteId, - Assets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - FungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, - >, - // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated - // `pallet_assets` instance - `ForeignAssets`. - cumulus_primitives_utility::TakeFirstAssetTrader< - AccountId, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, - ForeignAssetsConvertedConcreteId, - ForeignAssets, - cumulus_primitives_utility::XcmFeesTo32ByteAccount< - ForeignFungiblesTransactor, - AccountId, - XcmAssetFeesReceiver, - >, >, ); type ResponseHandler = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 0aaf1d91879..c50a8f3661d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -18,28 +18,36 @@ //! Tests for the Westmint (Westend Assets Hub) chain. use asset_hub_westend_runtime::{ + xcm_config, xcm_config::{ - self, bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignCreatorsSovereignAccountOf, LocationToAccountId, TrustBackedAssetsPalletLocation, - WestendLocation, XcmConfig, + bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, }, - AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, - PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, - ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, + AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, + RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, +}; +pub use asset_hub_westend_runtime::{ + xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, + ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, + TrustBackedAssetsInstance, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; -use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, - traits::fungibles::InspectEnumerable, + assert_ok, + traits::{ + fungible::{Inspect, Mutate}, + fungibles::{ + Create, Inspect as FungiblesInspect, InspectEnumerable, Mutate as FungiblesMutate, + }, + }, weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - westend::fee::WeightToFee, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + westend::{currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; @@ -67,7 +75,7 @@ fn collator_session_keys() -> CollatorSessionKeys { } #[test] -fn test_asset_xcm_trader() { +fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -77,77 +85,55 @@ fn test_asset_xcm_trader() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - let minimum_asset_balance = 3333333_u128; - let local_asset_id = 1; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - local_asset_id.into(), - AccountId::from(ALICE).into(), - true, - minimum_asset_balance - )); + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = WestendLocation::get(); + let initial_balance = 200 * UNITS; - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - local_asset_id.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - // get asset id as multilocation - let asset_multilocation = - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(); - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // Lets calculate amount needed - let asset_amount_needed = - AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( - local_asset_id, - bought, - ) - .expect("failed to compute"); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - // Lets pay with: asset_amount_needed + asset_amount_extra - let asset_amount_extra = 100_u128; - let asset: MultiAsset = - (asset_multilocation, asset_amount_needed + asset_amount_extra).into(); + // keep initial total issuance to assert later. + let total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (native_location, fee + extra_amount).into(); - // Lets buy_weight and make sure buy_weight does not return an error - let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); - // Check whether a correct amount of unused assets is returned - assert_ok!( - unused_assets.ensure_contains(&(asset_multilocation, asset_amount_extra).into()) - ); - - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Balances::total_issuance(), total_issuance); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (native_location, refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!( - Assets::balance(local_asset_id, AccountId::from(ALICE)), - minimum_asset_balance + asset_amount_needed - ); - - // We also need to ensure the total supply increased - assert_eq!( - Assets::total_supply(local_asset_id), - minimum_asset_balance + asset_amount_needed - ); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!(Balances::total_issuance(), total_issuance + fee - refund); + }) } #[test] -fn test_asset_xcm_trader_with_refund() { +fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -157,76 +143,93 @@ fn test_asset_xcm_trader_with_refund() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let asset_1: u32 = 1; + let native_location = WestendLocation::get(); + let asset_1_location = + AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create(asset_1, bob.clone(), true, 10)); + + assert_ok!(Assets::mint_into(asset_1, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location) )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - ExistentialDeposit::get() + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - // lets calculate amount needed - let amount_bought = WeightToFee::weight_to_fee(&bought); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); + // keep initial total issuance to assert later. + let asset_total_issuance = Assets::total_issuance(asset_1); + let native_total_issuance = Balances::total_issuance(); - // Make sure buy_weight does not return an error - assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); - - // Make sure again buy_weight does return an error - // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` - // tuple chain, which cannot be called twice - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // We actually use half of the weight - let weight_used = bought / 2; - - // Make sure refurnd works. - let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); - - assert_eq!( - trader.refund_weight(bought - weight_used, &ctx), - Some((asset_multilocation, amount_refunded).into()) - ); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); - // Drop trader + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, asset_1_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // We only should have paid for half of the bought weight - let fees_paid = WeightToFee::weight_to_fee(&weight_used); - + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); assert_eq!( - Assets::balance(1, AccountId::from(ALICE)), - ExistentialDeposit::get() + fees_paid + Assets::total_issuance(asset_1), + asset_total_issuance + asset_fee - asset_refund ); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); - }); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] -fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { +fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { ExtBuilder::::default() .with_collators(vec![AccountId::from(ALICE)]) .with_session_keys(vec![( @@ -236,168 +239,96 @@ fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { )]) .build() .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = CollatorSelection::account_id(); + let native_location = WestendLocation::get(); + let foreign_location = + MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create( + foreign_location, + bob.clone(), true, - ExistentialDeposit::get() + 10 )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy small amount - let bought = Weight::from_parts(500_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); + assert_ok!(ForeignAssets::mint_into(foreign_location, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - - // Buy weight should return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // not credited since the ED is higher than this value - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); - - // We also need to ensure the total supply did not increase - assert_eq!(Assets::total_supply(1), 0); - }); -} - -#[test] -fn test_that_buying_ed_refund_does_not_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location) )); - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - let bought = Weight::from_parts(500_000_000u64, 0); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - // We know we will have to buy at least ED, so lets make sure first it will - // fail with a payment of less than ED - let asset: MultiAsset = (asset_multilocation, amount_bought).into(); - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Now lets buy ED at least - let asset: MultiAsset = (asset_multilocation, ExistentialDeposit::get()).into(); - - // Buy weight should work - assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); - - // Should return None. We have a specific check making sure we dont go below ED for - // drop payment - assert_eq!(trader.refund_weight(bought, &ctx), None); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); - }); -} - -#[test] -fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // Create a non-sufficient asset with specific existential deposit - let minimum_asset_balance = 1_000_000_u128; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - false, - minimum_asset_balance + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, )); - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); + // keep initial total issuance to assert later. + let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); + let native_total_issuance = Balances::total_issuance(); - let mut trader = ::Trader::new(); + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // lets calculate amount needed - let asset_amount_needed = WeightToFee::weight_to_fee(&bought); - - let asset_multilocation = AssetIdForTrustBackedAssetsConvert::convert_back(&1).unwrap(); - - let asset: MultiAsset = (asset_multilocation, asset_amount_needed).into(); + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); - // Make sure again buy_weight does return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + // assert. + let unused_amount = + unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee + ); - // Drop trader + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, foreign_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. drop(trader); - - // Make sure author(Alice) has NOT received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); - - // We also need to ensure the total supply NOT increased - assert_eq!(Assets::total_supply(1), minimum_asset_balance); - }); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) } #[test] diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index 15327f51b2a..b0e47143929 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -47,6 +47,16 @@ pub type TrustBackedAssetsConvertedConcreteId = + MatchedConvertedConcreteId< + MultiLocationForAssetId, + Balance, + StartsWith, + Identity, + JustTry, + >; + /// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `MultiLocation`. pub type MultiLocationConvertedConcreteId = MatchedConvertedConcreteId< diff --git a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml index a3ed3759600..1b863499f04 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/test-utils/Cargo.toml @@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = frame-support = { path = "../../../../../substrate/frame/support", default-features = false } frame-system = { path = "../../../../../substrate/frame/system", default-features = false } pallet-assets = { path = "../../../../../substrate/frame/assets", default-features = false } +pallet-asset-conversion = { path = "../../../../../substrate/frame/asset-conversion", default-features = false } pallet-balances = { path = "../../../../../substrate/frame/balances", default-features = false } pallet-session = { path = "../../../../../substrate/frame/session", default-features = false } sp-consensus-aura = { path = "../../../../../substrate/primitives/consensus/aura", default-features = false } @@ -64,6 +65,7 @@ std = [ "cumulus-test-relay-sproof-builder/std", "frame-support/std", "frame-system/std", + "pallet-asset-conversion/std", "pallet-assets/std", "pallet-balances/std", "pallet-collator-selection/std", diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 8007b275cb5..d7441880426 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -30,6 +30,7 @@ use parachains_runtimes_test_utils::{ ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{traits::StaticLookup, Saturating}; +use sp_std::ops::Mul; use xcm::{latest::prelude::*, VersionedMultiAssets}; use xcm_builder::{CreateMatcher, MatchXcm}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; @@ -336,12 +337,13 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< + pallet_collator_selection::Config + cumulus_pallet_parachain_system::Config + cumulus_pallet_xcmp_queue::Config - + pallet_assets::Config, + + pallet_assets::Config + + pallet_asset_conversion::Config, AllPalletsWithoutSystem: OnInitialize> + OnFinalize>, - AccountIdOf: Into<[u8; 32]>, + AccountIdOf: Into<[u8; 32]> + From<[u8; 32]>, ValidatorIdOf: From>, - BalanceOf: From, + BalanceOf: From + Into, XcmConfig: xcm_executor::Config, LocationToAccountId: ConvertLocation>, >::AssetId: @@ -354,6 +356,9 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< + Into, <::Lookup as StaticLookup>::Source: From<::AccountId>, + ::AssetKind: + From + Into, + ::Balance: From, ForeignAssetsPalletInstance: 'static, { ExtBuilder::::default() @@ -400,6 +405,43 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ) ); + // setup a pool to pay fees with `foreign_asset_id_multilocation` tokens + let pool_owner: AccountIdOf = [1u8; 32].into(); + let native_asset = MultiLocation::parent(); + let pool_liquidity: u128 = + existential_deposit.into().max(foreign_asset_id_minimum_balance).mul(100_000); + + let _ = >::deposit_creating( + &pool_owner, + (existential_deposit.into() + pool_liquidity).mul(2).into(), + ); + + assert_ok!(>::mint( + RuntimeHelper::::origin_of( + sovereign_account_as_owner_of_foreign_asset + ), + foreign_asset_id_multilocation.into(), + pool_owner.clone().into(), + (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), + )); + + assert_ok!(>::create_pool( + RuntimeHelper::::origin_of(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_multilocation.into()) + )); + + assert_ok!(>::add_liquidity( + RuntimeHelper::::origin_of(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_multilocation.into()), + pool_liquidity.into(), + pool_liquidity.into(), + 1.into(), + 1.into(), + pool_owner, + )); + // Balances before assert_eq!( >::free_balance(&target_account), @@ -485,14 +527,12 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ); assert_ok!(outcome.ensure_complete()); - // author actual balance after (received fees from Trader for ForeignAssets) - let author_received_fees = - >::balance( - foreign_asset_id_multilocation.into(), - &block_author_account, - ); - - // Balances after (untouched) + // Balances after + // staking pot receives xcm fees in dot + assert!( + >::free_balance(&staking_pot) != + existential_deposit + ); assert_eq!( >::free_balance(&target_account), existential_deposit.clone() @@ -501,30 +541,25 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< >::free_balance(&block_author_account), 0.into() ); - assert_eq!( - >::free_balance(&staking_pot), - existential_deposit.clone() - ); // ForeignAssets balances after - assert_eq!( + assert!( >::balance( foreign_asset_id_multilocation.into(), &target_account - ), - (transfered_foreign_asset_id_amount - author_received_fees.into()).into() + ) > 0.into() ); assert_eq!( >::balance( foreign_asset_id_multilocation.into(), - &block_author_account + &staking_pot ), - author_received_fees + 0.into() ); assert_eq!( >::balance( foreign_asset_id_multilocation.into(), - &staking_pot + &block_author_account ), 0.into() ); diff --git a/cumulus/primitives/utility/Cargo.toml b/cumulus/primitives/utility/Cargo.toml index 56b6b928417..1558295b936 100644 --- a/cumulus/primitives/utility/Cargo.toml +++ b/cumulus/primitives/utility/Cargo.toml @@ -18,6 +18,7 @@ frame-support = { path = "../../../substrate/frame/support", default-features = sp-io = { path = "../../../substrate/primitives/io", default-features = false } sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false } sp-std = { path = "../../../substrate/primitives/std", default-features = false } +pallet-asset-conversion = { path = "../../../substrate/frame/asset-conversion", default-features = false } # Polkadot polkadot-runtime-common = { path = "../../../polkadot/runtime/common", default-features = false } @@ -37,6 +38,7 @@ std = [ "cumulus-primitives-core/std", "frame-support/std", "log/std", + "pallet-asset-conversion/std", "pallet-xcm-benchmarks/std", "polkadot-runtime-common/std", "polkadot-runtime-parachains/std", @@ -51,6 +53,7 @@ std = [ runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", "frame-support/runtime-benchmarks", + "pallet-asset-conversion/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", diff --git a/cumulus/primitives/utility/src/lib.rs b/cumulus/primitives/utility/src/lib.rs index 03f827d7ee2..7216000cb45 100644 --- a/cumulus/primitives/utility/src/lib.rs +++ b/cumulus/primitives/utility/src/lib.rs @@ -22,19 +22,24 @@ use codec::Encode; use cumulus_primitives_core::{MessageSendError, UpwardMessageSender}; use frame_support::{ - traits::{ - tokens::{fungibles, fungibles::Inspect}, - Get, - }, - weights::Weight, + defensive, + traits::{tokens::fungibles, Get, OnUnbalanced as OnUnbalancedT}, + weights::{Weight, WeightToFee as WeightToFeeT}, }; +use pallet_asset_conversion::SwapCredit as SwapCreditT; use polkadot_runtime_common::xcm_sender::PriceForMessageDelivery; -use sp_runtime::{traits::Saturating, SaturatedConversion}; +use sp_runtime::{ + traits::{Saturating, Zero}, + SaturatedConversion, +}; use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, WrapVersion}; use xcm_builder::TakeRevenue; use xcm_executor::traits::{MatchesFungibles, TransactAsset, WeightTrader}; +#[cfg(test)] +mod tests; + /// Xcm router which recognises the `Parent` destination and handles it by sending the message into /// the given UMP `UpwardMessageSender` implementation. Thus this essentially adapts an /// `UpwardMessageSender` trait impl into a `SendXcm` trait impl. @@ -286,23 +291,238 @@ impl< /// in such assetId for that amount of weight pub trait ChargeWeightInFungibles> { fn charge_weight_in_fungibles( - asset_id: >::AssetId, + asset_id: >::AssetId, weight: Weight, - ) -> Result<>::Balance, XcmError>; + ) -> Result<>::Balance, XcmError>; +} + +/// Provides an implementation of [`WeightTrader`] to charge for weight using the first asset +/// specified in the `payment` argument. +/// +/// The asset used to pay for the weight must differ from the `Target` asset and be exchangeable for +/// the same `Target` asset through `SwapCredit`. +/// +/// ### Parameters: +/// - `Target`: the asset into which the user's payment will be exchanged using `SwapCredit`. +/// - `SwapCredit`: mechanism used for the exchange of the user's payment asset into the `Target`. +/// - `WeightToFee`: weight to the `Target` asset fee calculator. +/// - `Fungibles`: registry of fungible assets. +/// - `FungiblesAssetMatcher`: utility for mapping [`MultiAsset`] to `Fungibles::AssetId` and +/// `Fungibles::Balance`. +/// - `OnUnbalanced`: handler for the fee payment. +/// - `AccountId`: the account identifier type. +pub struct SwapFirstAssetTrader< + Target: Get, + SwapCredit: SwapCreditT< + AccountId, + Balance = Fungibles::Balance, + AssetKind = Fungibles::AssetId, + Credit = fungibles::Credit, + >, + WeightToFee: WeightToFeeT, + Fungibles: fungibles::Balanced, + FungiblesAssetMatcher: MatchesFungibles, + OnUnbalanced: OnUnbalancedT>, + AccountId, +> where + Fungibles::Balance: Into, +{ + /// Accumulated fee paid for XCM execution. + total_fee: fungibles::Credit, + /// Last asset utilized by a client to settle a fee. + last_fee_asset: Option, + _phantom_data: PhantomData<( + Target, + SwapCredit, + WeightToFee, + Fungibles, + FungiblesAssetMatcher, + OnUnbalanced, + AccountId, + )>, +} + +impl< + Target: Get, + SwapCredit: SwapCreditT< + AccountId, + Balance = Fungibles::Balance, + AssetKind = Fungibles::AssetId, + Credit = fungibles::Credit, + >, + WeightToFee: WeightToFeeT, + Fungibles: fungibles::Balanced, + FungiblesAssetMatcher: MatchesFungibles, + OnUnbalanced: OnUnbalancedT>, + AccountId, + > WeightTrader + for SwapFirstAssetTrader< + Target, + SwapCredit, + WeightToFee, + Fungibles, + FungiblesAssetMatcher, + OnUnbalanced, + AccountId, + > where + Fungibles::Balance: Into, +{ + fn new() -> Self { + Self { + total_fee: fungibles::Credit::::zero(Target::get()), + last_fee_asset: None, + _phantom_data: PhantomData, + } + } + + fn buy_weight( + &mut self, + weight: Weight, + mut payment: xcm_executor::Assets, + _context: &XcmContext, + ) -> Result { + log::trace!( + target: "xcm::weight", + "SwapFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}", + weight, + payment, + ); + let first_asset: MultiAsset = + payment.fungible.pop_first().ok_or(XcmError::AssetNotFound)?.into(); + let (fungibles_asset, balance) = FungiblesAssetMatcher::matches_fungibles(&first_asset) + .map_err(|_| XcmError::AssetNotFound)?; + + let swap_asset = fungibles_asset.clone().into(); + if Target::get().eq(&swap_asset) { + // current trader is not applicable. + return Err(XcmError::FeesNotMet) + } + + let credit_in = Fungibles::issue(fungibles_asset, balance); + let fee = WeightToFee::weight_to_fee(&weight); + + // swap the user's asset for the `Target` asset. + let (credit_out, credit_change) = SwapCredit::swap_tokens_for_exact_tokens( + vec![swap_asset, Target::get()], + credit_in, + fee, + ) + .map_err(|(credit_in, _)| { + drop(credit_in); + XcmError::FeesNotMet + })?; + + match self.total_fee.subsume(credit_out) { + Err(credit_out) => { + // error may occur if `total_fee.asset` differs from `credit_out.asset`, which does + // not apply in this context. + defensive!( + "`total_fee.asset` must be equal to `credit_out.asset`", + (self.total_fee.asset(), credit_out.asset()) + ); + return Err(XcmError::FeesNotMet) + }, + _ => (), + }; + self.last_fee_asset = Some(first_asset.id); + + payment.fungible.insert(first_asset.id, credit_change.peek().into()); + drop(credit_change); + Ok(payment) + } + + fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { + log::trace!( + target: "xcm::weight", + "SwapFirstAssetTrader::refund_weight weight: {:?}, self.total_fee: {:?}", + weight, + self.total_fee, + ); + if self.total_fee.peek().is_zero() { + // noting yet paid to refund. + return None + } + let mut refund_asset = if let Some(asset) = &self.last_fee_asset { + // create an initial zero refund in the asset used in the last `buy_weight`. + (*asset, Fungible(0)).into() + } else { + return None + }; + let refund_amount = WeightToFee::weight_to_fee(&weight); + if refund_amount >= self.total_fee.peek() { + // not enough was paid to refund the `weight`. + return None + } + + let refund_swap_asset = FungiblesAssetMatcher::matches_fungibles(&refund_asset) + .map(|(a, _)| a.into()) + .ok()?; + + let refund = self.total_fee.extract(refund_amount); + let refund = match SwapCredit::swap_exact_tokens_for_tokens( + vec![Target::get(), refund_swap_asset], + refund, + None, + ) { + Ok(refund_in_target) => refund_in_target, + Err((refund, _)) => { + // return an attempted refund back to the `total_fee`. + let _ = self.total_fee.subsume(refund).map_err(|refund| { + // error may occur if `total_fee.asset` differs from `refund.asset`, which does + // not apply in this context. + defensive!( + "`total_fee.asset` must be equal to `refund.asset`", + (self.total_fee.asset(), refund.asset()) + ); + }); + return None + }, + }; + + refund_asset.fun = refund.peek().into().into(); + drop(refund); + Some(refund_asset) + } +} + +impl< + Target: Get, + SwapCredit: SwapCreditT< + AccountId, + Balance = Fungibles::Balance, + AssetKind = Fungibles::AssetId, + Credit = fungibles::Credit, + >, + WeightToFee: WeightToFeeT, + Fungibles: fungibles::Balanced, + FungiblesAssetMatcher: MatchesFungibles, + OnUnbalanced: OnUnbalancedT>, + AccountId, + > Drop + for SwapFirstAssetTrader< + Target, + SwapCredit, + WeightToFee, + Fungibles, + FungiblesAssetMatcher, + OnUnbalanced, + AccountId, + > where + Fungibles::Balance: Into, +{ + fn drop(&mut self) { + if self.total_fee.peek().is_zero() { + return + } + let total_fee = self.total_fee.extract(self.total_fee.peek()); + OnUnbalanced::on_unbalanced(total_fee); + } } #[cfg(test)] -mod tests { +mod test_xcm_router { use super::*; use cumulus_primitives_core::UpwardMessage; - use frame_support::{ - assert_ok, - traits::tokens::{ - DepositConsequence, Fortitude, Preservation, Provenance, WithdrawConsequence, - }, - }; - use sp_runtime::DispatchError; - use xcm_executor::{traits::Error, Assets}; /// Validates [`validate`] for required Some(destination) and Some(message) struct OkFixedXcmHashWithAssertingRequiredInputsSender; @@ -398,6 +618,18 @@ mod tests { )>(dest.into(), message) ); } +} +#[cfg(test)] +mod test_trader { + use super::*; + use frame_support::{ + assert_ok, + traits::tokens::{ + DepositConsequence, Fortitude, Preservation, Provenance, WithdrawConsequence, + }, + }; + use sp_runtime::DispatchError; + use xcm_executor::{traits::Error, Assets}; #[test] fn take_first_asset_trader_buy_weight_called_twice_throws_error() { @@ -491,9 +723,9 @@ mod tests { struct FeeChargerAssetsHandleRefund; impl ChargeWeightInFungibles for FeeChargerAssetsHandleRefund { fn charge_weight_in_fungibles( - _: >::AssetId, + _: >::AssetId, _: Weight, - ) -> Result<>::Balance, XcmError> { + ) -> Result<>::Balance, XcmError> { Ok(AMOUNT) } } diff --git a/cumulus/primitives/utility/src/tests/mod.rs b/cumulus/primitives/utility/src/tests/mod.rs new file mode 100644 index 00000000000..e0ad8718b89 --- /dev/null +++ b/cumulus/primitives/utility/src/tests/mod.rs @@ -0,0 +1,17 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Substrate 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. + +// Substrate 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 Cumulus. If not, see . + +mod swap_first; diff --git a/cumulus/primitives/utility/src/tests/swap_first.rs b/cumulus/primitives/utility/src/tests/swap_first.rs new file mode 100644 index 00000000000..222cd005b12 --- /dev/null +++ b/cumulus/primitives/utility/src/tests/swap_first.rs @@ -0,0 +1,551 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Substrate 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. + +// Substrate 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 Cumulus. If not, see . + +use crate::*; +use frame_support::{parameter_types, traits::fungibles::Inspect}; +use mock::{setup_pool, AccountId, AssetId, Balance, Fungibles}; +use xcm::latest::AssetId as XcmAssetId; +use xcm_executor::Assets as HoldingAsset; + +fn create_holding_asset(asset_id: AssetId, amount: Balance) -> HoldingAsset { + create_asset(asset_id, amount).into() +} + +fn create_asset(asset_id: AssetId, amount: Balance) -> MultiAsset { + MultiAsset { id: create_asset_id(asset_id), fun: Fungible(amount) } +} + +fn create_asset_id(asset_id: AssetId) -> XcmAssetId { + Concrete(MultiLocation::new(0, X1(GeneralIndex(asset_id.into())))) +} + +fn xcm_context() -> XcmContext { + XcmContext { origin: None, message_id: [0u8; 32], topic: None } +} + +fn weight_worth_of(fee: Balance) -> Weight { + Weight::from_parts(fee.try_into().unwrap(), 0) +} + +const TARGET_ASSET: AssetId = 1; +const CLIENT_ASSET: AssetId = 2; +const CLIENT_ASSET_2: AssetId = 3; + +parameter_types! { + pub const TargetAsset: AssetId = TARGET_ASSET; +} + +pub type Trader = SwapFirstAssetTrader< + TargetAsset, + mock::Swap, + mock::WeightToFee, + mock::Fungibles, + mock::FungiblesMatcher, + (), + AccountId, +>; + +#[test] +fn holding_asset_swap_for_target() { + let client_asset_total = 15; + let fee = 5; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee); +} + +#[test] +fn holding_asset_swap_for_target_twice() { + let client_asset_total = 20; + let fee1 = 5; + let fee2 = 6; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change1 = create_holding_asset(CLIENT_ASSET, client_asset_total - fee1); + let holding_change2 = create_holding_asset(CLIENT_ASSET, client_asset_total - fee1 - fee2); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee1), holding_asset, &xcm_context()).unwrap(), + holding_change1 + ); + assert_eq!( + trader + .buy_weight(weight_worth_of(fee2), holding_change1, &xcm_context()) + .unwrap(), + holding_change2 + ); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee1 + fee2); +} + +#[test] +fn buy_and_refund_twice_for_target() { + let client_asset_total = 15; + let fee = 5; + let refund1 = 4; + let refund2 = 2; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + // create pool for refund swap. + setup_pool(TARGET_ASSET, 1000, CLIENT_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + let refund_asset = create_asset(CLIENT_ASSET, refund1); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund1), &xcm_context()), Some(refund_asset)); + + assert_eq!(trader.total_fee.peek(), fee - refund1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund2), &xcm_context()), None); + + assert_eq!(trader.total_fee.peek(), fee - refund1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee - refund1); +} + +#[test] +fn buy_with_various_assets_and_refund_for_target() { + let client_asset_total = 10; + let client_asset_2_total = 15; + let fee1 = 5; + let fee2 = 6; + let refund1 = 6; + let refund2 = 4; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + setup_pool(CLIENT_ASSET_2, 1000, TARGET_ASSET, 1000); + // create pool for refund swap. + setup_pool(TARGET_ASSET, 1000, CLIENT_ASSET_2, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_asset_2 = create_holding_asset(CLIENT_ASSET_2, client_asset_2_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee1); + let holding_change_2 = create_holding_asset(CLIENT_ASSET_2, client_asset_2_total - fee2); + // both refunds in the latest buy asset (`CLIENT_ASSET_2`). + let refund_asset = create_asset(CLIENT_ASSET_2, refund1); + let refund_asset_2 = create_asset(CLIENT_ASSET_2, refund2); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + let client_total_2 = Fungibles::total_issuance(CLIENT_ASSET_2); + + let mut trader = Trader::new(); + // first purchase with `CLIENT_ASSET`. + assert_eq!( + trader.buy_weight(weight_worth_of(fee1), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + // second purchase with `CLIENT_ASSET_2`. + assert_eq!( + trader + .buy_weight(weight_worth_of(fee2), holding_asset_2, &xcm_context()) + .unwrap(), + holding_change_2 + ); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET_2))); + + // first refund in the last asset used with `buy_weight`. + assert_eq!(trader.refund_weight(weight_worth_of(refund1), &xcm_context()), Some(refund_asset)); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2 - refund1); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET_2))); + + // second refund in the last asset used with `buy_weight`. + assert_eq!( + trader.refund_weight(weight_worth_of(refund2), &xcm_context()), + Some(refund_asset_2) + ); + + assert_eq!(trader.total_fee.peek(), fee1 + fee2 - refund1 - refund2); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET_2))); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee1); + assert_eq!( + Fungibles::total_issuance(CLIENT_ASSET_2), + client_total_2 + fee2 - refund1 - refund2 + ); +} + +#[test] +fn not_enough_to_refund() { + let client_asset_total = 15; + let fee = 5; + let refund = 6; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund), &xcm_context()), None); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee); +} + +#[test] +fn not_exchangeable_to_refund() { + let client_asset_total = 15; + let fee = 5; + let refund = 1; + + setup_pool(CLIENT_ASSET, 1000, TARGET_ASSET, 1000); + + let holding_asset = create_holding_asset(CLIENT_ASSET, client_asset_total); + let holding_change = create_holding_asset(CLIENT_ASSET, client_asset_total - fee); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader.buy_weight(weight_worth_of(fee), holding_asset, &xcm_context()).unwrap(), + holding_change + ); + + assert_eq!(trader.total_fee.peek(), fee); + assert_eq!(trader.last_fee_asset, Some(create_asset_id(CLIENT_ASSET))); + + assert_eq!(trader.refund_weight(weight_worth_of(refund), &xcm_context()), None); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total + fee); +} + +#[test] +fn nothing_to_refund() { + let fee = 5; + + let mut trader = Trader::new(); + assert_eq!(trader.refund_weight(weight_worth_of(fee), &xcm_context()), None); +} + +#[test] +fn holding_asset_not_exchangeable_for_target() { + let holding_asset = create_holding_asset(CLIENT_ASSET, 10); + + let target_total = Fungibles::total_issuance(TARGET_ASSET); + let client_total = Fungibles::total_issuance(CLIENT_ASSET); + + let mut trader = Trader::new(); + assert_eq!( + trader + .buy_weight(Weight::from_all(10), holding_asset, &xcm_context()) + .unwrap_err(), + XcmError::FeesNotMet + ); + + assert_eq!(Fungibles::total_issuance(TARGET_ASSET), target_total); + assert_eq!(Fungibles::total_issuance(CLIENT_ASSET), client_total); +} + +#[test] +fn empty_holding_asset() { + let mut trader = Trader::new(); + assert_eq!( + trader + .buy_weight(Weight::from_all(10), HoldingAsset::new(), &xcm_context()) + .unwrap_err(), + XcmError::AssetNotFound + ); +} + +#[test] +fn fails_to_match_holding_asset() { + let mut trader = Trader::new(); + let holding_asset = + MultiAsset { id: Concrete(MultiLocation::new(1, X1(Parachain(1)))), fun: Fungible(10) }; + assert_eq!( + trader + .buy_weight(Weight::from_all(10), holding_asset.into(), &xcm_context()) + .unwrap_err(), + XcmError::AssetNotFound + ); +} + +#[test] +fn holding_asset_equal_to_target_asset() { + let mut trader = Trader::new(); + let holding_asset = create_holding_asset(TargetAsset::get(), 10); + assert_eq!( + trader + .buy_weight(Weight::from_all(10), holding_asset, &xcm_context()) + .unwrap_err(), + XcmError::FeesNotMet + ); +} + +pub mod mock { + use crate::*; + use core::cell::RefCell; + use frame_support::{ + ensure, + traits::{ + fungibles::{Balanced, DecreaseIssuance, Dust, IncreaseIssuance, Inspect, Unbalanced}, + tokens::{ + DepositConsequence, Fortitude, Fortitude::Polite, Precision::Exact, Preservation, + Preservation::Preserve, Provenance, WithdrawConsequence, + }, + }, + }; + use sp_runtime::{traits::One, DispatchError}; + use std::collections::HashMap; + use xcm::latest::Junction; + + pub type AccountId = u64; + pub type AssetId = u32; + pub type Balance = u128; + pub type Credit = fungibles::Credit; + + thread_local! { + pub static TOTAL_ISSUANCE: RefCell> = RefCell::new(HashMap::new()); + pub static ACCOUNT: RefCell> = RefCell::new(HashMap::new()); + pub static SWAP: RefCell> = RefCell::new(HashMap::new()); + } + + pub struct Swap {} + impl SwapCreditT for Swap { + type Balance = Balance; + type AssetKind = AssetId; + type Credit = Credit; + fn max_path_len() -> u32 { + 2 + } + fn swap_exact_tokens_for_tokens( + path: Vec, + credit_in: Self::Credit, + amount_out_min: Option, + ) -> Result { + ensure!(2 == path.len(), (credit_in, DispatchError::Unavailable)); + ensure!( + credit_in.peek() >= amount_out_min.unwrap_or(Self::Balance::zero()), + (credit_in, DispatchError::Unavailable) + ); + let swap_res = SWAP.with(|b| b.borrow().get(&(path[0], path[1])).map(|v| *v)); + let pool_account = match swap_res { + Some(a) => a, + None => return Err((credit_in, DispatchError::Unavailable)), + }; + let credit_out = match Fungibles::withdraw( + path[1], + &pool_account, + credit_in.peek(), + Exact, + Preserve, + Polite, + ) { + Ok(c) => c, + Err(_) => return Err((credit_in, DispatchError::Unavailable)), + }; + let _ = Fungibles::resolve(&pool_account, credit_in) + .map_err(|c| (c, DispatchError::Unavailable))?; + Ok(credit_out) + } + fn swap_tokens_for_exact_tokens( + path: Vec, + credit_in: Self::Credit, + amount_out: Self::Balance, + ) -> Result<(Self::Credit, Self::Credit), (Self::Credit, DispatchError)> { + ensure!(2 == path.len(), (credit_in, DispatchError::Unavailable)); + ensure!(credit_in.peek() >= amount_out, (credit_in, DispatchError::Unavailable)); + let swap_res = SWAP.with(|b| b.borrow().get(&(path[0], path[1])).map(|v| *v)); + let pool_account = match swap_res { + Some(a) => a, + None => return Err((credit_in, DispatchError::Unavailable)), + }; + let credit_out = match Fungibles::withdraw( + path[1], + &pool_account, + amount_out, + Exact, + Preserve, + Polite, + ) { + Ok(c) => c, + Err(_) => return Err((credit_in, DispatchError::Unavailable)), + }; + let (credit_in, change) = credit_in.split(amount_out); + let _ = Fungibles::resolve(&pool_account, credit_in) + .map_err(|c| (c, DispatchError::Unavailable))?; + Ok((credit_out, change)) + } + } + + pub fn pool_account(asset1: AssetId, asset2: AssetId) -> AccountId { + (1000 + asset1 * 10 + asset2 * 100).into() + } + + pub fn setup_pool(asset1: AssetId, liquidity1: Balance, asset2: AssetId, liquidity2: Balance) { + let account = pool_account(asset1, asset2); + SWAP.with(|b| b.borrow_mut().insert((asset1, asset2), account)); + let debt1 = Fungibles::deposit(asset1, &account, liquidity1, Exact); + let debt2 = Fungibles::deposit(asset2, &account, liquidity2, Exact); + drop(debt1); + drop(debt2); + } + + pub struct WeightToFee; + impl WeightToFeeT for WeightToFee { + type Balance = Balance; + fn weight_to_fee(weight: &Weight) -> Self::Balance { + (weight.ref_time() + weight.proof_size()).into() + } + } + + pub struct Fungibles {} + impl Inspect for Fungibles { + type AssetId = AssetId; + type Balance = Balance; + fn total_issuance(asset: Self::AssetId) -> Self::Balance { + TOTAL_ISSUANCE.with(|b| b.borrow().get(&asset).map_or(Self::Balance::zero(), |b| *b)) + } + fn minimum_balance(_: Self::AssetId) -> Self::Balance { + Self::Balance::one() + } + fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + ACCOUNT.with(|b| b.borrow().get(&(asset, *who)).map_or(Self::Balance::zero(), |b| *b)) + } + fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + ACCOUNT.with(|b| b.borrow().get(&(asset, *who)).map_or(Self::Balance::zero(), |b| *b)) + } + fn reducible_balance( + asset: Self::AssetId, + who: &AccountId, + _: Preservation, + _: Fortitude, + ) -> Self::Balance { + ACCOUNT.with(|b| b.borrow().get(&(asset, *who)).map_or(Self::Balance::zero(), |b| *b)) + } + fn can_deposit( + _: Self::AssetId, + _: &AccountId, + _: Self::Balance, + _: Provenance, + ) -> DepositConsequence { + unimplemented!() + } + fn can_withdraw( + _: Self::AssetId, + _: &AccountId, + _: Self::Balance, + ) -> WithdrawConsequence { + unimplemented!() + } + fn asset_exists(_: Self::AssetId) -> bool { + unimplemented!() + } + } + + impl Unbalanced for Fungibles { + fn set_total_issuance(asset: Self::AssetId, amount: Self::Balance) { + TOTAL_ISSUANCE.with(|b| b.borrow_mut().insert(asset, amount)); + } + fn handle_dust(_: Dust) { + unimplemented!() + } + fn write_balance( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> Result, DispatchError> { + let _ = ACCOUNT.with(|b| b.borrow_mut().insert((asset, *who), amount)); + Ok(None) + } + } + + impl Balanced for Fungibles { + type OnDropCredit = DecreaseIssuance; + type OnDropDebt = IncreaseIssuance; + } + + pub struct FungiblesMatcher; + impl MatchesFungibles for FungiblesMatcher { + fn matches_fungibles( + a: &MultiAsset, + ) -> core::result::Result<(AssetId, Balance), xcm_executor::traits::Error> { + match a { + MultiAsset { + fun: Fungible(amount), + id: + Concrete(MultiLocation { parents: 0, interior: X1(Junction::GeneralIndex(id)) }), + } => Ok(((*id).try_into().unwrap(), *amount)), + _ => Err(xcm_executor::traits::Error::AssetNotHandled), + } + } + } +} diff --git a/prdoc/pr_1845.prdoc b/prdoc/pr_1845.prdoc new file mode 100644 index 00000000000..cf6cd1feadf --- /dev/null +++ b/prdoc/pr_1845.prdoc @@ -0,0 +1,16 @@ +# 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 WeightTrader: Swap Fee Asset for Native Asset" + +doc: + - audience: Runtime Dev + description: | + Implements an XCM executor `WeightTrader`, facilitating fee payments in any asset that can be exchanged for a native asset. + + A few constraints need to be observed: + - `buy_weight` and `refund` operations must be atomic, as another weight trader implementation might be attempted in case of failure. + - swap credit must be utilized since there isn’t an account to which an asset of some class can be deposited with a guarantee to meet the existential deposit requirement. + +crates: + - name: cumulus-primitives-utility -- GitLab From a42a47f81d91ccf2f885ff01749185cd4c793278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal=20Murray?= Date: Tue, 16 Jan 2024 08:24:13 +0000 Subject: [PATCH 010/283] Bump rococo relay and coretime-rococo to 1.6 (#2913) Co-authored-by: command-bot <> --- .../coretime/coretime-rococo/src/lib.rs | 2 +- .../cumulus_pallet_parachain_system.rs | 26 ++- .../src/weights/cumulus_pallet_xcmp_queue.rs | 41 ++-- .../src/weights/frame_system.rs | 110 ++++++---- .../src/weights/pallet_balances.rs | 62 +++--- .../src/weights/pallet_broker.rs | 161 +++++++------- .../src/weights/pallet_collator_selection.rs | 154 +++++++------ .../src/weights/pallet_message_queue.rs | 58 ++--- .../src/weights/pallet_multisig.rs | 89 ++++---- .../src/weights/pallet_session.rs | 33 +-- .../src/weights/pallet_timestamp.rs | 23 +- .../src/weights/pallet_utility.rs | 45 ++-- .../coretime-rococo/src/weights/pallet_xcm.rs | 77 +++---- .../xcm/pallet_xcm_benchmarks_fungible.rs | 117 +++++----- .../xcm/pallet_xcm_benchmarks_generic.rs | 202 ++++++++---------- polkadot/runtime/rococo/src/lib.rs | 2 +- 16 files changed, 640 insertions(+), 562 deletions(-) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 0f01c2d7416..c381d78b57f 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-rococo"), impl_name: create_runtime_str!("coretime-rococo"), authoring_version: 1, - spec_version: 1_005_004, + spec_version: 1_006_001, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs index f7a1486ed58..139e37c5448 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_parachain_system.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `cumulus_pallet_parachain_system` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=cumulus_pallet_parachain_system +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -58,14 +61,17 @@ impl cumulus_pallet_parachain_system::WeightInfo for We /// Storage: `MessageQueue::Pages` (r:0 w:1000) /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn enqueue_inbound_downward_messages(_n: u32, ) -> Weight { + fn enqueue_inbound_downward_messages(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `42` + // Measured: `48` // Estimated: `3517` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(144_747_000_000, 0) + // Minimum execution time: 2_067_000 picoseconds. + Weight::from_parts(2_151_000, 0) .saturating_add(Weight::from_parts(0, 3517)) + // Standard Error: 32_757 + .saturating_add(Weight::from_parts(204_001_420, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1004)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs index f5683f747a3..efbe7980de2 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/cumulus_pallet_xcmp_queue.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `cumulus_pallet_xcmp_queue` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=cumulus_pallet_xcmp_queue +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,8 +56,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `76` // Estimated: `1561` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 0) + // Minimum execution time: 3_935_000 picoseconds. + Weight::from_parts(4_188_000, 0) .saturating_add(Weight::from_parts(0, 1561)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -73,8 +76,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `82` // Estimated: `3517` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) + // Minimum execution time: 10_252_000 picoseconds. + Weight::from_parts(10_551_000, 0) .saturating_add(Weight::from_parts(0, 3517)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -85,8 +88,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `76` // Estimated: `1561` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Minimum execution time: 2_294_000 picoseconds. + Weight::from_parts(2_477_000, 0) .saturating_add(Weight::from_parts(0, 1561)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -97,8 +100,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `111` // Estimated: `1596` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 3_068_000 picoseconds. + Weight::from_parts(3_204_000, 0) .saturating_add(Weight::from_parts(0, 1596)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -107,8 +110,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 42_000_000 picoseconds. - Weight::from_parts(42_000_000, 0) + // Minimum execution time: 68_610_000 picoseconds. + Weight::from_parts(68_800_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: UNKNOWN KEY `0x7b3237373ffdfeb1cab4222e3b520d6b345d8e88afa015075c945637c07e8f20` (r:1 w:1) @@ -129,8 +132,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `65711` // Estimated: `69176` - // Minimum execution time: 86_000_000 picoseconds. - Weight::from_parts(86_000_000, 0) + // Minimum execution time: 125_878_000 picoseconds. + Weight::from_parts(127_632_000, 0) .saturating_add(Weight::from_parts(0, 69176)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) @@ -143,8 +146,8 @@ impl cumulus_pallet_xcmp_queue::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `65710` // Estimated: `69175` - // Minimum execution time: 79_000_000 picoseconds. - Weight::from_parts(79_000_000, 0) + // Minimum execution time: 54_918_000 picoseconds. + Weight::from_parts(56_246_000, 0) .saturating_add(Weight::from_parts(0, 69175)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs index 7c41112152f..428976e3e03 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `frame_system` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=frame_system +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -48,22 +51,26 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl frame_system::WeightInfo for WeightInfo { /// The range of component `b` is `[0, 3932160]`. - fn remark(_b: u32, ) -> Weight { + fn remark(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(775_000_000, 0) + // Minimum execution time: 1_760_000 picoseconds. + Weight::from_parts(6_086_623, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 0 + .saturating_add(Weight::from_parts(430, 0).saturating_mul(b.into())) } /// The range of component `b` is `[0, 3932160]`. - fn remark_with_event(_b: u32, ) -> Weight { + fn remark_with_event(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(4_700_000_000, 0) + // Minimum execution time: 5_315_000 picoseconds. + Weight::from_parts(20_446_491, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_725, 0).saturating_mul(b.into())) } /// Storage: `System::Digest` (r:1 w:1) /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -73,8 +80,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 5_000_000 picoseconds. - Weight::from_parts(5_000_000, 0) + // Minimum execution time: 3_046_000 picoseconds. + Weight::from_parts(3_249_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -95,8 +102,8 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `164` // Estimated: `1649` - // Minimum execution time: 79_510_000_000 picoseconds. - Weight::from_parts(79_510_000_000, 0) + // Minimum execution time: 108_366_941_000 picoseconds. + Weight::from_parts(111_101_742_000, 0) .saturating_add(Weight::from_parts(0, 1649)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -104,39 +111,46 @@ impl frame_system::WeightInfo for WeightInfo { /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. - fn set_storage(_i: u32, ) -> Weight { + fn set_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(816_000_000, 0) + // Minimum execution time: 1_877_000 picoseconds. + Weight::from_parts(1_947_000, 0) .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Standard Error: 2_035 + .saturating_add(Weight::from_parts(763_800, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `i` is `[0, 1000]`. - fn kill_storage(_i: u32, ) -> Weight { + fn kill_storage(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(598_000_000, 0) + // Minimum execution time: 1_847_000 picoseconds. + Weight::from_parts(1_931_000, 0) .saturating_add(Weight::from_parts(0, 0)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Standard Error: 932 + .saturating_add(Weight::from_parts(565_066, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into()))) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[0, 1000]`. - fn kill_prefix(_p: u32, ) -> Weight { + fn kill_prefix(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `55 + p * (69 ±0)` - // Estimated: `69609` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(1_091_000_000, 0) - .saturating_add(Weight::from_parts(0, 69609)) - .saturating_add(T::DbWeight::get().reads(1000)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Measured: `71 + p * (69 ±0)` + // Estimated: `72 + p * (70 ±0)` + // Minimum execution time: 3_587_000 picoseconds. + Weight::from_parts(3_654_000, 0) + .saturating_add(Weight::from_parts(0, 72)) + // Standard Error: 1_468 + .saturating_add(Weight::from_parts(1_170_655, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into())) } /// Storage: `System::AuthorizedUpgrade` (r:0 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) @@ -144,25 +158,33 @@ impl frame_system::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 33_027_000 picoseconds. - Weight::from_parts(33_027_000, 0) + // Minimum execution time: 9_701_000 picoseconds. + Weight::from_parts(10_142_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `System::AuthorizedUpgrade` (r:1 w:1) /// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) - /// Storage: `System::Digest` (r:1 w:1) - /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) - /// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1) + /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) + /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::UpgradeRestrictionSignal` (r:1 w:0) + /// Proof: `ParachainSystem::UpgradeRestrictionSignal` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingValidationCode` (r:1 w:1) + /// Proof: `ParachainSystem::PendingValidationCode` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::NewValidationCode` (r:0 w:1) + /// Proof: `ParachainSystem::NewValidationCode` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::DidSetValidationCode` (r:0 w:1) + /// Proof: `ParachainSystem::DidSetValidationCode` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn apply_authorized_upgrade() -> Weight { // Proof Size summary in bytes: - // Measured: `22` - // Estimated: `1518` - // Minimum execution time: 118_101_992_000 picoseconds. - Weight::from_parts(118_101_992_000, 0) - .saturating_add(Weight::from_parts(0, 1518)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `186` + // Estimated: `1671` + // Minimum execution time: 113_812_980_000 picoseconds. + Weight::from_parts(115_758_263_000, 0) + .saturating_add(Weight::from_parts(0, 1671)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs index ee12da7c436..bb9d7b3fe8a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_balances` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_balances +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,8 +56,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 55_000_000 picoseconds. - Weight::from_parts(55_000_000, 0) + // Minimum execution time: 45_258_000 picoseconds. + Weight::from_parts(46_265_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -65,8 +68,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 42_000_000 picoseconds. - Weight::from_parts(42_000_000, 0) + // Minimum execution time: 35_639_000 picoseconds. + Weight::from_parts(36_170_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -77,8 +80,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 15_000_000 picoseconds. - Weight::from_parts(15_000_000, 0) + // Minimum execution time: 12_342_000 picoseconds. + Weight::from_parts(12_736_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -89,8 +92,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(21_000_000, 0) + // Minimum execution time: 17_150_000 picoseconds. + Weight::from_parts(17_764_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -101,8 +104,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 66_000_000 picoseconds. - Weight::from_parts(66_000_000, 0) + // Minimum execution time: 46_745_000 picoseconds. + Weight::from_parts(47_693_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -113,8 +116,8 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 53_000_000 picoseconds. - Weight::from_parts(53_000_000, 0) + // Minimum execution time: 44_553_000 picoseconds. + Weight::from_parts(45_113_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -125,23 +128,26 @@ impl pallet_balances::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 15_439_000 picoseconds. + Weight::from_parts(15_832_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `System::Account` (r:1000 w:1000) + /// Storage: `System::Account` (r:999 w:999) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `u` is `[1, 1000]`. - fn upgrade_accounts(_u: u32, ) -> Weight { + fn upgrade_accounts(u: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + u * (135 ±0)` - // Estimated: `2603990` - // Minimum execution time: 20_000_000 picoseconds. - Weight::from_parts(14_684_000_000, 0) - .saturating_add(Weight::from_parts(0, 2603990)) - .saturating_add(T::DbWeight::get().reads(1000)) - .saturating_add(T::DbWeight::get().writes(1000)) + // Measured: `0 + u * (136 ±0)` + // Estimated: `990 + u * (2603 ±0)` + // Minimum execution time: 15_017_000 picoseconds. + Weight::from_parts(15_286_000, 0) + .saturating_add(Weight::from_parts(0, 990)) + // Standard Error: 11_887 + .saturating_add(Weight::from_parts(13_536_178, 0).saturating_mul(u.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into()))) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into())) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs index 665b84e32cc..2d30ddc612c 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs @@ -17,23 +17,25 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-q7z7ruxr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/production/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 -// --extrinsic=* +// --chain=coretime-rococo-dev // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_broker -// --chain=coretime-rococo-dev +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -54,8 +56,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_403_000 picoseconds. - Weight::from_parts(2_504_000, 0) + // Minimum execution time: 2_462_000 picoseconds. + Weight::from_parts(2_552_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -65,8 +67,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `10888` // Estimated: `13506` - // Minimum execution time: 22_025_000 picoseconds. - Weight::from_parts(22_799_000, 0) + // Minimum execution time: 25_494_000 picoseconds. + Weight::from_parts(26_063_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -77,8 +79,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12090` // Estimated: `13506` - // Minimum execution time: 21_012_000 picoseconds. - Weight::from_parts(21_567_000, 0) + // Minimum execution time: 22_299_000 picoseconds. + Weight::from_parts(22_911_000, 0) .saturating_add(Weight::from_parts(0, 13506)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -87,20 +89,24 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(401), added: 896, mode: `MaxEncodedLen`) /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn set_lease() -> Weight { // Proof Size summary in bytes: // Measured: `466` // Estimated: `1951` - // Minimum execution time: 10_767_000 picoseconds. - Weight::from_parts(11_364_000, 0) + // Minimum execution time: 11_590_000 picoseconds. + Weight::from_parts(12_007_000, 0) .saturating_add(Weight::from_parts(0, 1951)) - .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `ParachainSystem::ValidationData` (r:1 w:0) /// Proof: `ParachainSystem::ValidationData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::LastRelayChainBlockNumber` (r:1 w:0) + /// Proof: `ParachainSystem::LastRelayChainBlockNumber` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) /// Storage: `Broker::Reservations` (r:1 w:0) @@ -118,12 +124,12 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `12567` // Estimated: `14052` - // Minimum execution time: 112_187_000 picoseconds. - Weight::from_parts(115_233_014, 0) + // Minimum execution time: 120_928_000 picoseconds. + Weight::from_parts(124_947_252, 0) .saturating_add(Weight::from_parts(0, 14052)) - // Standard Error: 162 - .saturating_add(Weight::from_parts(539, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(7)) + // Standard Error: 435 + .saturating_add(Weight::from_parts(1_246, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(66)) } /// Storage: `Broker::Status` (r:1 w:0) @@ -138,8 +144,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `316` // Estimated: `3593` - // Minimum execution time: 32_469_000 picoseconds. - Weight::from_parts(33_443_000, 0) + // Minimum execution time: 32_826_000 picoseconds. + Weight::from_parts(33_889_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -160,8 +166,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `434` // Estimated: `4698` - // Minimum execution time: 59_488_000 picoseconds. - Weight::from_parts(64_711_000, 0) + // Minimum execution time: 57_362_000 picoseconds. + Weight::from_parts(58_994_000, 0) .saturating_add(Weight::from_parts(0, 4698)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) @@ -172,8 +178,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3550` - // Minimum execution time: 13_370_000 picoseconds. - Weight::from_parts(13_938_000, 0) + // Minimum execution time: 13_982_000 picoseconds. + Weight::from_parts(14_447_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -184,23 +190,23 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3550` - // Minimum execution time: 14_592_000 picoseconds. - Weight::from_parts(15_235_000, 0) + // Minimum execution time: 15_070_000 picoseconds. + Weight::from_parts(15_735_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `Broker::Regions` (r:1 w:2) + /// Storage: `Broker::Regions` (r:1 w:3) /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) fn interlace() -> Weight { // Proof Size summary in bytes: // Measured: `357` // Estimated: `3550` - // Minimum execution time: 14_880_000 picoseconds. - Weight::from_parts(15_274_000, 0) + // Minimum execution time: 16_527_000 picoseconds. + Weight::from_parts(16_894_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().writes(3)) } /// Storage: `Broker::Configuration` (r:1 w:0) /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) @@ -214,8 +220,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `936` // Estimated: `4681` - // Minimum execution time: 24_786_000 picoseconds. - Weight::from_parts(26_047_000, 0) + // Minimum execution time: 25_493_000 picoseconds. + Weight::from_parts(26_091_000, 0) .saturating_add(Weight::from_parts(0, 4681)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -234,8 +240,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1002` // Estimated: `5996` - // Minimum execution time: 31_159_000 picoseconds. - Weight::from_parts(31_770_000, 0) + // Minimum execution time: 31_498_000 picoseconds. + Weight::from_parts(32_560_000, 0) .saturating_add(Weight::from_parts(0, 5996)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(5)) @@ -251,11 +257,11 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `652` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 56_524_000 picoseconds. - Weight::from_parts(58_065_019, 0) + // Minimum execution time: 57_183_000 picoseconds. + Weight::from_parts(58_024_898, 0) .saturating_add(Weight::from_parts(0, 6196)) - // Standard Error: 41_840 - .saturating_add(Weight::from_parts(1_322_201, 0).saturating_mul(m.into())) + // Standard Error: 35_831 + .saturating_add(Weight::from_parts(1_384_446, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5)) @@ -277,8 +283,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `215` // Estimated: `3680` - // Minimum execution time: 60_923_000 picoseconds. - Weight::from_parts(62_721_000, 0) + // Minimum execution time: 59_762_000 picoseconds. + Weight::from_parts(61_114_000, 0) .saturating_add(Weight::from_parts(0, 3680)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -291,8 +297,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `465` // Estimated: `3550` - // Minimum execution time: 39_683_000 picoseconds. - Weight::from_parts(55_799_000, 0) + // Minimum execution time: 41_473_000 picoseconds. + Weight::from_parts(44_155_000, 0) .saturating_add(Weight::from_parts(0, 3550)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -307,8 +313,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `463` // Estimated: `3533` - // Minimum execution time: 90_833_000 picoseconds. - Weight::from_parts(97_249_000, 0) + // Minimum execution time: 56_672_000 picoseconds. + Weight::from_parts(58_086_000, 0) .saturating_add(Weight::from_parts(0, 3533)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -325,8 +331,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `857` // Estimated: `3593` - // Minimum execution time: 93_311_000 picoseconds. - Weight::from_parts(105_496_000, 0) + // Minimum execution time: 64_460_000 picoseconds. + Weight::from_parts(65_894_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)) @@ -339,8 +345,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `957` // Estimated: `4698` - // Minimum execution time: 44_597_000 picoseconds. - Weight::from_parts(48_739_000, 0) + // Minimum execution time: 37_447_000 picoseconds. + Weight::from_parts(42_318_000, 0) .saturating_add(Weight::from_parts(0, 4698)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -356,28 +362,28 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 22_114_000 picoseconds. - Weight::from_parts(23_031_633, 0) + // Minimum execution time: 21_219_000 picoseconds. + Weight::from_parts(22_084_648, 0) .saturating_add(Weight::from_parts(0, 3539)) - // Standard Error: 60 - .saturating_add(Weight::from_parts(60, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn process_core_count(_n: u32, ) -> Weight { + fn process_core_count(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `266` // Estimated: `1487` - // Minimum execution time: 6_020_000 picoseconds. - Weight::from_parts(6_540_421, 0) + // Minimum execution time: 5_792_000 picoseconds. + Weight::from_parts(6_358_588, 0) .saturating_add(Weight::from_parts(0, 1487)) + // Standard Error: 20 + .saturating_add(Weight::from_parts(26, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -391,8 +397,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `447` // Estimated: `6196` - // Minimum execution time: 38_744_000 picoseconds. - Weight::from_parts(40_572_000, 0) + // Minimum execution time: 38_690_000 picoseconds. + Weight::from_parts(39_706_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) @@ -408,13 +414,15 @@ impl pallet_broker::WeightInfo for WeightInfo { /// Storage: `Broker::Workplan` (r:0 w:60) /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. - fn rotate_sale(_n: u32, ) -> Weight { + fn rotate_sale(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `12514` // Estimated: `13506` - // Minimum execution time: 94_727_000 picoseconds. - Weight::from_parts(97_766_746, 0) + // Minimum execution time: 93_531_000 picoseconds. + Weight::from_parts(95_836_318, 0) .saturating_add(Weight::from_parts(0, 13506)) + // Standard Error: 113 + .saturating_add(Weight::from_parts(329, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(65)) } @@ -426,8 +434,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `42` // Estimated: `3493` - // Minimum execution time: 6_496_000 picoseconds. - Weight::from_parts(6_757_000, 0) + // Minimum execution time: 6_506_000 picoseconds. + Weight::from_parts(6_783_000, 0) .saturating_add(Weight::from_parts(0, 3493)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -450,8 +458,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `1321` // Estimated: `4786` - // Minimum execution time: 33_164_000 picoseconds. - Weight::from_parts(33_800_000, 0) + // Minimum execution time: 31_927_000 picoseconds. + Weight::from_parts(32_748_000, 0) .saturating_add(Weight::from_parts(0, 4786)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -470,21 +478,20 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 16_884_000 picoseconds. - Weight::from_parts(17_315_000, 0) + // Minimum execution time: 15_682_000 picoseconds. + Weight::from_parts(16_012_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Broker::CoreCountInbox` (r:0 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// The range of component `n` is `[0, 1000]`. fn notify_core_count() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_017_000 picoseconds. - Weight::from_parts(2_210_693, 0) + // Minimum execution time: 2_147_000 picoseconds. + Weight::from_parts(2_281_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -502,8 +509,8 @@ impl pallet_broker::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `398` // Estimated: `3863` - // Minimum execution time: 12_118_000 picoseconds. - Weight::from_parts(12_541_000, 0) + // Minimum execution time: 12_015_000 picoseconds. + Weight::from_parts(12_619_000, 0) .saturating_add(Weight::from_parts(0, 3863)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs index ca740bc3550..b62a6c2fce5 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_collator_selection.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_collator_selection` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_collator_selection +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -52,15 +55,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::Invulnerables` (r:0 w:1) /// Proof: `CollatorSelection::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) /// The range of component `b` is `[1, 20]`. - fn set_invulnerables(_b: u32, ) -> Weight { + fn set_invulnerables(b: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `162 + b * (79 ±0)` - // Estimated: `52242` - // Minimum execution time: 14_000_000 picoseconds. - Weight::from_parts(74_000_000, 0) - .saturating_add(Weight::from_parts(0, 52242)) - .saturating_add(T::DbWeight::get().reads(20)) + // Measured: `164 + b * (79 ±0)` + // Estimated: `1155 + b * (2555 ±0)` + // Minimum execution time: 11_551_000 picoseconds. + Weight::from_parts(8_982_740, 0) + .saturating_add(Weight::from_parts(0, 1155)) + // Standard Error: 6_117 + .saturating_add(Weight::from_parts(3_093_494, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 2555).saturating_mul(b.into())) } /// Storage: `Session::NextKeys` (r:1 w:0) /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -74,18 +80,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// The range of component `c` is `[1, 99]`. fn add_invulnerable(b: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `796 + b * (32 ±0) + c * (52 ±0)` - // Estimated: `6287 + b * (32 ±0) + c * (53 ±0)` - // Minimum execution time: 39_000_000 picoseconds. - Weight::from_parts(37_903_628, 0) + // Measured: `720 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 38_580_000 picoseconds. + Weight::from_parts(39_137_598, 0) .saturating_add(Weight::from_parts(0, 6287)) - // Standard Error: 96_225 - .saturating_add(Weight::from_parts(55_555, 0).saturating_mul(b.into())) - // Standard Error: 17_673 - .saturating_add(Weight::from_parts(40_816, 0).saturating_mul(c.into())) + // Standard Error: 6_413 + .saturating_add(Weight::from_parts(119_463, 0).saturating_mul(b.into())) + // Standard Error: 1_215 + .saturating_add(Weight::from_parts(120_116, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(Weight::from_parts(0, 32).saturating_mul(b.into())) + .saturating_add(Weight::from_parts(0, 37).saturating_mul(b.into())) .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) } /// Storage: `CollatorSelection::CandidateList` (r:1 w:0) @@ -93,13 +99,15 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::Invulnerables` (r:1 w:1) /// Proof: `CollatorSelection::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) /// The range of component `b` is `[5, 20]`. - fn remove_invulnerable(_b: u32, ) -> Weight { + fn remove_invulnerable(b: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `82 + b * (32 ±0)` // Estimated: `6287` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 11_347_000 picoseconds. + Weight::from_parts(11_332_550, 0) .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_287 + .saturating_add(Weight::from_parts(134_624, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -109,8 +117,8 @@ impl pallet_collator_selection::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 0) + // Minimum execution time: 4_883_000 picoseconds. + Weight::from_parts(5_141_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -126,32 +134,36 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// The range of component `k` is `[0, 100]`. fn set_candidacy_bond(c: u32, k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `0 + c * (179 ±0) + k * (130 ±0)` - // Estimated: `261290` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(11_000_000, 0) - .saturating_add(Weight::from_parts(0, 261290)) - // Standard Error: 5_514_936 - .saturating_add(Weight::from_parts(6_438_000, 0).saturating_mul(c.into())) - // Standard Error: 5_514_936 - .saturating_add(Weight::from_parts(6_368_000, 0).saturating_mul(k.into())) + // Measured: `0 + c * (180 ±0) + k * (112 ±0)` + // Estimated: `6287 + c * (901 ±29) + k * (901 ±29)` + // Minimum execution time: 8_661_000 picoseconds. + Weight::from_parts(8_852_000, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 159_154 + .saturating_add(Weight::from_parts(5_352_946, 0).saturating_mul(c.into())) + // Standard Error: 159_154 + .saturating_add(Weight::from_parts(5_075_906, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) + .saturating_add(Weight::from_parts(0, 901).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 901).saturating_mul(k.into())) } /// Storage: `CollatorSelection::CandidacyBond` (r:1 w:0) /// Proof: `CollatorSelection::CandidacyBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `CollatorSelection::CandidateList` (r:1 w:1) /// Proof: `CollatorSelection::CandidateList` (`max_values`: Some(1), `max_size`: Some(4802), added: 5297, mode: `MaxEncodedLen`) /// The range of component `c` is `[4, 100]`. - fn update_bond(_c: u32, ) -> Weight { + fn update_bond(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `243 + c * (50 ±0)` + // Measured: `250 + c * (50 ±0)` // Estimated: `6287` - // Minimum execution time: 26_000_000 picoseconds. - Weight::from_parts(36_000_000, 0) + // Minimum execution time: 23_840_000 picoseconds. + Weight::from_parts(26_343_302, 0) .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 1_743 + .saturating_add(Weight::from_parts(118_295, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -166,15 +178,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::LastAuthoredBlock` (r:0 w:1) /// Proof: `CollatorSelection::LastAuthoredBlock` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 99]`. - fn register_as_candidate(_c: u32, ) -> Weight { + fn register_as_candidate(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `441 + c * (54 ±0)` - // Estimated: `9299` - // Minimum execution time: 39_000_000 picoseconds. - Weight::from_parts(40_000_000, 0) - .saturating_add(Weight::from_parts(0, 9299)) + // Measured: `687 + c * (52 ±0)` + // Estimated: `6287 + c * (54 ±0)` + // Minimum execution time: 31_637_000 picoseconds. + Weight::from_parts(35_792_418, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_274 + .saturating_add(Weight::from_parts(146_163, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_parts(0, 54).saturating_mul(c.into())) } /// Storage: `CollatorSelection::Invulnerables` (r:1 w:0) /// Proof: `CollatorSelection::Invulnerables` (`max_values`: Some(1), `max_size`: Some(641), added: 1136, mode: `MaxEncodedLen`) @@ -189,15 +204,18 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::LastAuthoredBlock` (r:0 w:2) /// Proof: `CollatorSelection::LastAuthoredBlock` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `c` is `[4, 100]`. - fn take_candidate_slot(_c: u32, ) -> Weight { + fn take_candidate_slot(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `589 + c * (54 ±0)` - // Estimated: `9521` - // Minimum execution time: 54_000_000 picoseconds. - Weight::from_parts(59_000_000, 0) - .saturating_add(Weight::from_parts(0, 9521)) + // Measured: `855 + c * (52 ±0)` + // Estimated: `6287 + c * (55 ±0)` + // Minimum execution time: 47_931_000 picoseconds. + Weight::from_parts(52_506_905, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_696 + .saturating_add(Weight::from_parts(149_395, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 55).saturating_mul(c.into())) } /// Storage: `CollatorSelection::CandidateList` (r:1 w:1) /// Proof: `CollatorSelection::CandidateList` (`max_values`: Some(1), `max_size`: Some(4802), added: 5297, mode: `MaxEncodedLen`) @@ -206,13 +224,15 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Storage: `CollatorSelection::LastAuthoredBlock` (r:0 w:1) /// Proof: `CollatorSelection::LastAuthoredBlock` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `c` is `[4, 100]`. - fn leave_intent(_c: u32, ) -> Weight { + fn leave_intent(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `268 + c * (48 ±0)` + // Measured: `277 + c * (48 ±0)` // Estimated: `6287` - // Minimum execution time: 31_000_000 picoseconds. - Weight::from_parts(38_000_000, 0) + // Minimum execution time: 27_658_000 picoseconds. + Weight::from_parts(30_896_953, 0) .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_038 + .saturating_add(Weight::from_parts(120_980, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -226,8 +246,8 @@ impl pallet_collator_selection::WeightInfo for WeightIn // Proof Size summary in bytes: // Measured: `103` // Estimated: `6196` - // Minimum execution time: 49_000_000 picoseconds. - Weight::from_parts(49_000_000, 0) + // Minimum execution time: 37_700_000 picoseconds. + Weight::from_parts(38_497_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(4)) @@ -242,24 +262,24 @@ impl pallet_collator_selection::WeightInfo for WeightIn /// Proof: `CollatorSelection::DesiredCandidates` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `System::BlockWeight` (r:1 w:1) /// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:97 w:97) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `r` is `[1, 100]`. /// The range of component `c` is `[1, 100]`. fn new_session(r: u32, c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `340 + c * (97 ±0)` - // Estimated: `6287 + c * (2519 ±0)` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(11_136_363, 0) + // Measured: `2143 + c * (97 ±0) + r * (112 ±0)` + // Estimated: `6287 + c * (2519 ±0) + r * (2603 ±0)` + // Minimum execution time: 16_077_000 picoseconds. + Weight::from_parts(16_274_000, 0) .saturating_add(Weight::from_parts(0, 6287)) - // Standard Error: 323_666 - .saturating_add(Weight::from_parts(35_353, 0).saturating_mul(r.into())) - // Standard Error: 323_666 - .saturating_add(Weight::from_parts(4_328_282, 0).saturating_mul(c.into())) + // Standard Error: 283_859 + .saturating_add(Weight::from_parts(12_293_155, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) - .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) .saturating_add(Weight::from_parts(0, 2519).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 2603).saturating_mul(r.into())) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs index e0e8c79ca17..934ab627bc8 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_message_queue.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_message_queue` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_message_queue +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -55,8 +58,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `223` // Estimated: `6044` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) + // Minimum execution time: 11_120_000 picoseconds. + Weight::from_parts(11_605_000, 0) .saturating_add(Weight::from_parts(0, 6044)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(2)) @@ -69,8 +72,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `218` // Estimated: `6044` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 9_795_000 picoseconds. + Weight::from_parts(10_300_000, 0) .saturating_add(Weight::from_parts(0, 6044)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -81,8 +84,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `6` // Estimated: `3517` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 3_277_000 picoseconds. + Weight::from_parts(3_426_000, 0) .saturating_add(Weight::from_parts(0, 3517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -93,8 +96,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `72` // Estimated: `69050` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 5_016_000 picoseconds. + Weight::from_parts(5_237_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) @@ -105,19 +108,24 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `72` // Estimated: `69050` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 5_118_000 picoseconds. + Weight::from_parts(5_347_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `MessageQueue::BookStateFor` (r:0 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(65585), added: 68060, mode: `MaxEncodedLen`) fn service_page_item() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 65_000_000 picoseconds. - Weight::from_parts(65_000_000, 0) + // Minimum execution time: 175_756_000 picoseconds. + Weight::from_parts(177_423_000, 0) .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`) @@ -127,8 +135,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `171` // Estimated: `3517` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(8_000_000, 0) + // Minimum execution time: 6_515_000 picoseconds. + Weight::from_parts(6_953_000, 0) .saturating_add(Weight::from_parts(0, 3517)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -141,8 +149,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `65667` // Estimated: `69050` - // Minimum execution time: 73_000_000 picoseconds. - Weight::from_parts(73_000_000, 0) + // Minimum execution time: 57_649_000 picoseconds. + Weight::from_parts(59_093_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -155,8 +163,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `65667` // Estimated: `69050` - // Minimum execution time: 74_000_000 picoseconds. - Weight::from_parts(74_000_000, 0) + // Minimum execution time: 73_366_000 picoseconds. + Weight::from_parts(74_402_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) @@ -169,8 +177,8 @@ impl pallet_message_queue::WeightInfo for WeightInfo // Proof Size summary in bytes: // Measured: `65667` // Estimated: `69050` - // Minimum execution time: 109_000_000 picoseconds. - Weight::from_parts(109_000_000, 0) + // Minimum execution time: 116_063_000 picoseconds. + Weight::from_parts(117_532_000, 0) .saturating_add(Weight::from_parts(0, 69050)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs index 421fc033e7c..8e010d768f6 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_multisig.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_multisig` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_multisig +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -48,27 +51,31 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_multisig::WeightInfo for WeightInfo { /// The range of component `z` is `[0, 10000]`. - fn as_multi_threshold_1(_z: u32, ) -> Weight { + fn as_multi_threshold_1(z: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(16_000_000, 0) + // Minimum execution time: 12_905_000 picoseconds. + Weight::from_parts(13_544_225, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 2 + .saturating_add(Weight::from_parts(596, 0).saturating_mul(z.into())) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. - fn as_multi_create(_s: u32, z: u32, ) -> Weight { + fn as_multi_create(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `172 + s * (3 ±0)` + // Measured: `262 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 35_000_000 picoseconds. - Weight::from_parts(36_530_612, 0) + // Minimum execution time: 38_729_000 picoseconds. + Weight::from_parts(27_942_442, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 259 - .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(z.into())) + // Standard Error: 648 + .saturating_add(Weight::from_parts(120_340, 0).saturating_mul(s.into())) + // Standard Error: 6 + .saturating_add(Weight::from_parts(1_578, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -80,13 +87,13 @@ impl pallet_multisig::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `282` // Estimated: `6811` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(18_422_680, 0) + // Minimum execution time: 25_936_000 picoseconds. + Weight::from_parts(16_537_903, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 8_928 - .saturating_add(Weight::from_parts(25_773, 0).saturating_mul(s.into())) - // Standard Error: 86 - .saturating_add(Weight::from_parts(1_250, 0).saturating_mul(z.into())) + // Standard Error: 412 + .saturating_add(Weight::from_parts(105_835, 0).saturating_mul(s.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(1_534, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -96,54 +103,62 @@ impl pallet_multisig::WeightInfo for WeightInfo { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. /// The range of component `z` is `[0, 10000]`. - fn as_multi_complete(_s: u32, z: u32, ) -> Weight { + fn as_multi_complete(s: u32, z: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `315 + s * (34 ±0)` + // Measured: `385 + s * (33 ±0)` // Estimated: `6811` - // Minimum execution time: 53_000_000 picoseconds. - Weight::from_parts(56_571_428, 0) + // Minimum execution time: 45_291_000 picoseconds. + Weight::from_parts(31_294_385, 0) .saturating_add(Weight::from_parts(0, 6811)) - // Standard Error: 86 - .saturating_add(Weight::from_parts(150, 0).saturating_mul(z.into())) + // Standard Error: 816 + .saturating_add(Weight::from_parts(152_838, 0).saturating_mul(s.into())) + // Standard Error: 8 + .saturating_add(Weight::from_parts(1_638, 0).saturating_mul(z.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. - fn approve_as_multi_create(_s: u32, ) -> Weight { + fn approve_as_multi_create(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `172 + s * (3 ±0)` + // Measured: `263 + s * (2 ±0)` // Estimated: `6811` - // Minimum execution time: 32_000_000 picoseconds. - Weight::from_parts(35_000_000, 0) + // Minimum execution time: 26_585_000 picoseconds. + Weight::from_parts(27_424_168, 0) .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 732 + .saturating_add(Weight::from_parts(123_460, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. - fn approve_as_multi_approve(_s: u32, ) -> Weight { + fn approve_as_multi_approve(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `282` // Estimated: `6811` - // Minimum execution time: 17_000_000 picoseconds. - Weight::from_parts(21_000_000, 0) + // Minimum execution time: 15_228_000 picoseconds. + Weight::from_parts(15_568_631, 0) .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 441 + .saturating_add(Weight::from_parts(107_463, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Multisig::Multisigs` (r:1 w:1) /// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`) /// The range of component `s` is `[2, 100]`. - fn cancel_as_multi(_s: u32, ) -> Weight { + fn cancel_as_multi(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `379 + s * (2 ±0)` + // Measured: `454 + s * (1 ±0)` // Estimated: `6811` - // Minimum execution time: 31_000_000 picoseconds. - Weight::from_parts(40_000_000, 0) + // Minimum execution time: 28_033_000 picoseconds. + Weight::from_parts(29_228_827, 0) .saturating_add(Weight::from_parts(0, 6811)) + // Standard Error: 748 + .saturating_add(Weight::from_parts(117_495, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs index 5151bcaa9e4..409d92be4fc 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_session.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_session` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_session +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,11 +56,11 @@ impl pallet_session::WeightInfo for WeightInfo { /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn set_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `270` - // Estimated: `3735` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) - .saturating_add(Weight::from_parts(0, 3735)) + // Measured: `271` + // Estimated: `3736` + // Minimum execution time: 15_924_000 picoseconds. + Weight::from_parts(16_586_000, 0) + .saturating_add(Weight::from_parts(0, 3736)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -67,11 +70,11 @@ impl pallet_session::WeightInfo for WeightInfo { /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) fn purge_keys() -> Weight { // Proof Size summary in bytes: - // Measured: `242` - // Estimated: `3707` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) - .saturating_add(Weight::from_parts(0, 3707)) + // Measured: `243` + // Estimated: `3708` + // Minimum execution time: 11_218_000 picoseconds. + Weight::from_parts(11_587_000, 0) + .saturating_add(Weight::from_parts(0, 3708)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs index c2a23bf2a73..c171353404e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_timestamp.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_timestamp` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_timestamp +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -53,10 +56,10 @@ impl pallet_timestamp::WeightInfo for WeightInfo { /// Proof: `Aura::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) fn set() -> Weight { // Proof Size summary in bytes: - // Measured: `49` + // Measured: `86` // Estimated: `1493` - // Minimum execution time: 8_000_000 picoseconds. - Weight::from_parts(8_000_000, 0) + // Minimum execution time: 5_979_000 picoseconds. + Weight::from_parts(6_115_000, 0) .saturating_add(Weight::from_parts(0, 1493)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -65,8 +68,8 @@ impl pallet_timestamp::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `57` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) + // Minimum execution time: 2_830_000 picoseconds. + Weight::from_parts(2_988_000, 0) .saturating_add(Weight::from_parts(0, 0)) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs index cf3cc98b593..84eb9783868 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_utility.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_utility` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_utility +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -48,46 +51,52 @@ use core::marker::PhantomData; pub struct WeightInfo(PhantomData); impl pallet_utility::WeightInfo for WeightInfo { /// The range of component `c` is `[0, 1000]`. - fn batch(_c: u32, ) -> Weight { + fn batch(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(4_117_000_000, 0) + // Minimum execution time: 4_434_000 picoseconds. + Weight::from_parts(2_232_360, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_409 + .saturating_add(Weight::from_parts(3_308_287, 0).saturating_mul(c.into())) } fn as_derivative() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_000_000, 0) + // Minimum execution time: 4_455_000 picoseconds. + Weight::from_parts(4_561_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. - fn batch_all(_c: u32, ) -> Weight { + fn batch_all(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(4_519_000_000, 0) + // Minimum execution time: 4_304_000 picoseconds. + Weight::from_parts(4_146_029, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 3_128 + .saturating_add(Weight::from_parts(3_581_489, 0).saturating_mul(c.into())) } fn dispatch_as() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_000_000 picoseconds. - Weight::from_parts(9_000_000, 0) + // Minimum execution time: 6_531_000 picoseconds. + Weight::from_parts(6_805_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// The range of component `c` is `[0, 1000]`. - fn force_batch(_c: u32, ) -> Weight { + fn force_batch(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(4_114_000_000, 0) + // Minimum execution time: 4_412_000 picoseconds. + Weight::from_parts(4_498_000, 0) .saturating_add(Weight::from_parts(0, 0)) + // Standard Error: 1_621 + .saturating_add(Weight::from_parts(3_312_302, 0).saturating_mul(c.into())) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs index 538401ef2c5..0e34cba4aaf 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs @@ -17,21 +17,24 @@ //! Autogenerated weights for `pallet_xcm` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `dagda.local`, CPU: `` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// target/release/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet // --chain=coretime-rococo-dev // --wasm-execution=compiled // --pallet=pallet_xcm +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* -// --steps=2 -// --repeat=1 +// --steps=50 +// --repeat=20 // --json // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -61,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 37_000_000 picoseconds. - Weight::from_parts(37_000_000, 0) + // Minimum execution time: 22_669_000 picoseconds. + Weight::from_parts(23_227_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -83,8 +86,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 86_000_000 picoseconds. - Weight::from_parts(86_000_000, 0) + // Minimum execution time: 64_486_000 picoseconds. + Weight::from_parts(65_247_000, 0) .saturating_add(Weight::from_parts(0, 3571)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -125,8 +128,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) + // Minimum execution time: 7_020_000 picoseconds. + Weight::from_parts(7_300_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -136,8 +139,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 2_022_000 picoseconds. + Weight::from_parts(2_141_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -161,8 +164,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 37_000_000 picoseconds. - Weight::from_parts(37_000_000, 0) + // Minimum execution time: 26_893_000 picoseconds. + Weight::from_parts(27_497_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) @@ -185,8 +188,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292` // Estimated: `3757` - // Minimum execution time: 72_000_000 picoseconds. - Weight::from_parts(72_000_000, 0) + // Minimum execution time: 29_673_000 picoseconds. + Weight::from_parts(30_693_000, 0) .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) @@ -197,8 +200,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 0) + // Minimum execution time: 1_990_000 picoseconds. + Weight::from_parts(2_105_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -208,8 +211,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `95` // Estimated: `10985` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) + // Minimum execution time: 14_819_000 picoseconds. + Weight::from_parts(15_180_000, 0) .saturating_add(Weight::from_parts(0, 10985)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -220,8 +223,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `99` // Estimated: `10989` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) + // Minimum execution time: 14_935_000 picoseconds. + Weight::from_parts(15_335_000, 0) .saturating_add(Weight::from_parts(0, 10989)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -232,8 +235,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `13471` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(22_000_000, 0) + // Minimum execution time: 16_278_000 picoseconds. + Weight::from_parts(16_553_000, 0) .saturating_add(Weight::from_parts(0, 13471)) .saturating_add(T::DbWeight::get().reads(5)) } @@ -253,8 +256,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `6082` - // Minimum execution time: 32_000_000 picoseconds. - Weight::from_parts(32_000_000, 0) + // Minimum execution time: 26_360_000 picoseconds. + Weight::from_parts(26_868_000, 0) .saturating_add(Weight::from_parts(0, 6082)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -265,8 +268,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `136` // Estimated: `8551` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 0) + // Minimum execution time: 8_615_000 picoseconds. + Weight::from_parts(8_903_000, 0) .saturating_add(Weight::from_parts(0, 8551)) .saturating_add(T::DbWeight::get().reads(3)) } @@ -276,8 +279,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `10996` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 0) + // Minimum execution time: 15_284_000 picoseconds. + Weight::from_parts(15_504_000, 0) .saturating_add(Weight::from_parts(0, 10996)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) @@ -298,8 +301,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `148` // Estimated: `11038` - // Minimum execution time: 39_000_000 picoseconds. - Weight::from_parts(39_000_000, 0) + // Minimum execution time: 32_675_000 picoseconds. + Weight::from_parts(33_816_000, 0) .saturating_add(Weight::from_parts(0, 11038)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) @@ -312,8 +315,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 5_000_000 picoseconds. - Weight::from_parts(5_000_000, 0) + // Minimum execution time: 4_058_000 picoseconds. + Weight::from_parts(4_170_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -324,8 +327,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 31_000_000 picoseconds. - Weight::from_parts(31_000_000, 0) + // Minimum execution time: 25_375_000 picoseconds. + Weight::from_parts(26_026_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs index 7fab3584250..ec71a87b5a7 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::fungible` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("coretime-rococo-dev"), DB CACHE: 1024 // Executed Command: -// target/production/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 -// --extrinsic=* +// --template=./cumulus/templates/xcm-bench-template.hbs +// --chain=coretime-rococo-dev // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_xcm_benchmarks::fungible -// --chain=asset-hub-rococo-dev +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json // --header=./cumulus/file_header.txt -// --template=./cumulus/templates/xcm-bench-template.hbs -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/ +// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -54,8 +56,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `101` // Estimated: `3593` - // Minimum execution time: 21_643_000 picoseconds. - Weight::from_parts(22_410_000, 3593) + // Minimum execution time: 19_199_000 picoseconds. + Weight::from_parts(19_784_000, 3593) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -65,17 +67,15 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `101` // Estimated: `6196` - // Minimum execution time: 43_758_000 picoseconds. - Weight::from_parts(44_654_000, 6196) + // Minimum execution time: 42_601_000 picoseconds. + Weight::from_parts(43_296_000, 6196) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } - // Storage: `System::Account` (r:3 w:3) + // Storage: `System::Account` (r:2 w:2) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -88,54 +88,49 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn transfer_reserve_asset() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `8799` - // Minimum execution time: 87_978_000 picoseconds. - Weight::from_parts(88_517_000, 8799) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(5)) + // Measured: `207` + // Estimated: `6196` + // Minimum execution time: 62_463_000 picoseconds. + Weight::from_parts(64_142_000, 6196) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(4)) } - // Storage: `ParachainInfo::ParachainId` (r:1 w:0) - // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `Benchmark::Override` (r:0 w:0) + // Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) pub fn reserve_asset_deposited() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `1489` - // Minimum execution time: 6_883_000 picoseconds. - Weight::from_parts(6_979_000, 1489) - .saturating_add(T::DbWeight::get().reads(1)) + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn initiate_reserve_withdraw() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 198_882_000 picoseconds. - Weight::from_parts(199_930_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 31_417_000 picoseconds. + Weight::from_parts(32_153_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn receive_teleported_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_343_000 picoseconds. - Weight::from_parts(3_487_000, 0) + // Minimum execution time: 3_235_000 picoseconds. + Weight::from_parts(3_331_000, 0) } // Storage: `System::Account` (r:1 w:1) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) @@ -143,17 +138,15 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 19_399_000 picoseconds. - Weight::from_parts(19_659_000, 3593) + // Minimum execution time: 17_701_000 picoseconds. + Weight::from_parts(18_219_000, 3593) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } - // Storage: `System::Account` (r:2 w:2) + // Storage: `System::Account` (r:1 w:1) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -166,36 +159,32 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn deposit_reserve_asset() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `6196` - // Minimum execution time: 59_017_000 picoseconds. - Weight::from_parts(60_543_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3593` + // Minimum execution time: 41_748_000 picoseconds. + Weight::from_parts(42_401_000, 3593) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:1 w:1) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn initiate_teleport() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3610` - // Minimum execution time: 45_409_000 picoseconds. - Weight::from_parts(47_041_000, 3610) - .saturating_add(T::DbWeight::get().reads(8)) - .saturating_add(T::DbWeight::get().writes(3)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 27_455_000 picoseconds. + Weight::from_parts(27_976_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } } 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 4454494badc..a11d049a3fc 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 @@ -17,26 +17,28 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-rococo-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("coretime-rococo-dev"), DB CACHE: 1024 // Executed Command: -// target/production/polkadot-parachain +// ./target/production/polkadot-parachain // benchmark // pallet -// --steps=50 -// --repeat=20 -// --extrinsic=* +// --template=./cumulus/templates/xcm-bench-template.hbs +// --chain=coretime-rococo-dev // --wasm-execution=compiled -// --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json // --pallet=pallet_xcm_benchmarks::generic -// --chain=asset-hub-rococo-dev +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json // --header=./cumulus/file_header.txt -// --template=./cumulus/templates/xcm-bench-template.hbs -// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/xcm/ +// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,128 +52,120 @@ pub struct WeightInfo(PhantomData); impl WeightInfo { // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 440_298_000 picoseconds. - Weight::from_parts(446_508_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 35_477_000 picoseconds. + Weight::from_parts(36_129_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn buy_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_313_000 picoseconds. - Weight::from_parts(3_422_000, 0) + // Minimum execution time: 2_243_000 picoseconds. + Weight::from_parts(2_329_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) pub fn query_response() -> Weight { // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `3568` - // Minimum execution time: 9_691_000 picoseconds. - Weight::from_parts(9_948_000, 3568) + // Measured: `32` + // Estimated: `3497` + // Minimum execution time: 8_112_000 picoseconds. + Weight::from_parts(8_275_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_384_000 picoseconds. - Weight::from_parts(11_085_000, 0) + // Minimum execution time: 8_960_000 picoseconds. + Weight::from_parts(9_253_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_438_000 picoseconds. - Weight::from_parts(3_577_000, 0) + // Minimum execution time: 2_332_000 picoseconds. + Weight::from_parts(2_438_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_126_000 picoseconds. - Weight::from_parts(2_243_000, 0) + // Minimum execution time: 2_054_000 picoseconds. + Weight::from_parts(2_119_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_126_000 picoseconds. - Weight::from_parts(2_207_000, 0) + // Minimum execution time: 2_061_000 picoseconds. + Weight::from_parts(2_133_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_105_000 picoseconds. - Weight::from_parts(2_193_000, 0) + // Minimum execution time: 2_054_000 picoseconds. + Weight::from_parts(2_128_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_999_000 picoseconds. - Weight::from_parts(3_056_000, 0) + // Minimum execution time: 2_791_000 picoseconds. + Weight::from_parts(2_903_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_091_000 picoseconds. - Weight::from_parts(2_176_000, 0) + // Minimum execution time: 2_088_000 picoseconds. + Weight::from_parts(2_153_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 55_728_000 picoseconds. - Weight::from_parts(56_704_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 27_721_000 picoseconds. + Weight::from_parts(28_602_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } // Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) // Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) pub fn claim_asset() -> Weight { // Proof Size summary in bytes: - // Measured: `160` - // Estimated: `3625` - // Minimum execution time: 12_839_000 picoseconds. - Weight::from_parts(13_457_000, 3625) + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 11_468_000 picoseconds. + Weight::from_parts(11_866_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -179,13 +173,11 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_116_000 picoseconds. - Weight::from_parts(2_219_000, 0) + // Minimum execution time: 2_125_000 picoseconds. + Weight::from_parts(2_167_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -198,11 +190,11 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn subscribe_version() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `3610` - // Minimum execution time: 24_891_000 picoseconds. - Weight::from_parts(25_583_000, 3610) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `74` + // Estimated: `3539` + // Minimum execution time: 22_422_000 picoseconds. + Weight::from_parts(22_924_000, 3539) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1) @@ -211,122 +203,114 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_968_000 picoseconds. - Weight::from_parts(4_122_000, 0) + // Minimum execution time: 3_880_000 picoseconds. + Weight::from_parts(4_050_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 136_220_000 picoseconds. - Weight::from_parts(137_194_000, 0) + // Minimum execution time: 3_432_000 picoseconds. + Weight::from_parts(3_536_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 12_343_000 picoseconds. - Weight::from_parts(12_635_000, 0) + // Minimum execution time: 2_213_000 picoseconds. + Weight::from_parts(2_286_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_237_000 picoseconds. - Weight::from_parts(2_315_000, 0) + // Minimum execution time: 2_155_000 picoseconds. + Weight::from_parts(2_239_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_094_000 picoseconds. - Weight::from_parts(2_231_000, 0) + // Minimum execution time: 2_093_000 picoseconds. + Weight::from_parts(2_139_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_379_000 picoseconds. - Weight::from_parts(2_455_000, 0) + // Minimum execution time: 2_345_000 picoseconds. + Weight::from_parts(2_378_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 60_734_000 picoseconds. - Weight::from_parts(61_964_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 31_543_000 picoseconds. + Weight::from_parts(32_075_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn expect_pallet() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_500_000 picoseconds. - Weight::from_parts(5_720_000, 0) + // Minimum execution time: 4_416_000 picoseconds. + Weight::from_parts(4_613_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) // Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) // Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - // Storage: `System::Account` (r:2 w:2) - // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) // Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `246` - // Estimated: `6196` - // Minimum execution time: 55_767_000 picoseconds. - Weight::from_parts(56_790_000, 6196) - .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(4)) + // Measured: `106` + // Estimated: `3571` + // Minimum execution time: 28_050_000 picoseconds. + Weight::from_parts(28_755_000, 3571) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn clear_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_201_000 picoseconds. - Weight::from_parts(2_291_000, 0) + // Minimum execution time: 2_073_000 picoseconds. + Weight::from_parts(2_181_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_164_000 picoseconds. - Weight::from_parts(2_241_000, 0) + // Minimum execution time: 2_049_000 picoseconds. + Weight::from_parts(2_137_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_127_000 picoseconds. - Weight::from_parts(2_236_000, 0) + // Minimum execution time: 2_082_000 picoseconds. + Weight::from_parts(2_144_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -342,14 +326,14 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_132_000 picoseconds. - Weight::from_parts(2_216_000, 0) + // Minimum execution time: 2_043_000 picoseconds. + Weight::from_parts(2_151_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_265_000 picoseconds. - Weight::from_parts(2_332_000, 0) + // Minimum execution time: 2_197_000 picoseconds. + Weight::from_parts(2_293_000, 0) } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 3fd3f2bc635..e492caddc8f 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -153,7 +153,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("rococo"), impl_name: create_runtime_str!("parity-rococo-v2.0"), authoring_version: 0, - spec_version: 1_005_001, + spec_version: 1_006_001, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, -- GitLab From 05cfb02bec116349fe6e0428f06837a9290662ac Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 16 Jan 2024 20:47:35 +0800 Subject: [PATCH 011/283] CI check features (#1708) To resolve issue #1136. This is a cross verification against zepter. - [cargo-featalign](https://github.com/hack-ink/cargo-featalign): Verifies the proper propagation of all features. - [zepter](https://github.com/ggwpez/zepter): Checks for accidentally enabled features. cc @ggwpez --- Switch to a new branch. Original PR #1537. --------- Signed-off-by: Xavier Lau Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Oliver Tale-Yazdi Co-authored-by: Chevdor --- .github/workflows/check-features.yml | 19 +++++++++++++++++++ substrate/frame/support/procedural/Cargo.toml | 4 ++-- substrate/primitives/api/Cargo.toml | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/check-features.yml diff --git a/.github/workflows/check-features.yml b/.github/workflows/check-features.yml new file mode 100644 index 00000000000..53d6ac6b4db --- /dev/null +++ b/.github/workflows/check-features.yml @@ -0,0 +1,19 @@ +name: Check Features + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + check-features: + runs-on: ubuntu-latest + steps: + - name: Fetch latest code + uses: actions/checkout@v4 + - name: Check + uses: hack-ink/cargo-featalign-action@bea88a864d6ca7d0c53c26f1391ce1d431dc7f34 # v0.1.1 + with: + crate: substrate/bin/node/runtime + features: std,runtime-benchmarks,try-runtime + ignore: sc-executor + default-std: true diff --git a/substrate/frame/support/procedural/Cargo.toml b/substrate/frame/support/procedural/Cargo.toml index 5e47f0dfeb0..25debb7fc2b 100644 --- a/substrate/frame/support/procedural/Cargo.toml +++ b/substrate/frame/support/procedural/Cargo.toml @@ -29,14 +29,14 @@ frame-support-procedural-tools = { path = "tools" } macro_magic = { version = "0.5.0", features = ["proc_support"] } proc-macro-warning = { version = "1.0.0", default-features = false } expander = "2.0.0" -sp-core-hashing = { path = "../../../primitives/core/hashing" } +sp-core-hashing = { path = "../../../primitives/core/hashing", default-features = false } [dev-dependencies] regex = "1" [features] default = ["std"] -std = [] +std = ["sp-core-hashing/std"] no-metadata-docs = [] # Generate impl-trait for tuples with the given number of tuples. Will be needed as the number of # pallets in a runtime grows. Does increase the compile time! diff --git a/substrate/primitives/api/Cargo.toml b/substrate/primitives/api/Cargo.toml index 345647cec25..346b9c35fa8 100644 --- a/substrate/primitives/api/Cargo.toml +++ b/substrate/primitives/api/Cargo.toml @@ -17,7 +17,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } -sp-api-proc-macro = { path = "proc-macro" } +sp-api-proc-macro = { path = "proc-macro", default-features = false } sp-core = { path = "../core", default-features = false } sp-std = { path = "../std", default-features = false } sp-runtime = { path = "../runtime", default-features = false } -- GitLab From 82c057ee78ca941d86a4455793fc9076f7ab00af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 17:03:54 +0000 Subject: [PATCH 012/283] Bump walkdir from 2.3.3 to 2.4.0 (#2910) Bumps [walkdir](https://github.com/BurntSushi/walkdir) from 2.3.3 to 2.4.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=walkdir&package-manager=cargo&previous-version=2.3.3&new-version=2.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- substrate/utils/wasm-builder/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6299bbfe51c..31347261151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20933,9 +20933,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", diff --git a/substrate/utils/wasm-builder/Cargo.toml b/substrate/utils/wasm-builder/Cargo.toml index ffe95994c65..f882b85e473 100644 --- a/substrate/utils/wasm-builder/Cargo.toml +++ b/substrate/utils/wasm-builder/Cargo.toml @@ -21,7 +21,7 @@ console = "0.15.8" strum = { version = "0.24.1", features = ["derive"] } tempfile = "3.1.0" toml = "0.8.8" -walkdir = "2.3.2" +walkdir = "2.4.0" sp-maybe-compressed-blob = { path = "../../primitives/maybe-compressed-blob" } filetime = "0.2.16" wasm-opt = "0.116" -- GitLab From ec7bfae00a0ec0ce0841274acc707ad9b8d5b1c0 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Tue, 16 Jan 2024 18:14:29 +0100 Subject: [PATCH 013/283] subsystem-bench: cache misses profiling (#2893) ## Why we need it To provide another level of understanding to why polkadot's subsystems may perform slower than expected. Cache misses occur when processing large amounts of data, such as during availability recovery. ## Why Cachegrind Cachegrind has many drawbacks: it is slow, it uses its own cache simulation, which is very basic. But unlike `perf`, which is a great tool, Cachegrind can run in a virtual machine. This means we can easily run it in remote installations and even use it in CI/CD to catch possible regressions. Why Cachegrind and not Callgrind, another part of Valgrind? It is simply empirically proven that profiling runs faster with Cachegrind. ## First results First results have been obtained while testing of the approach. Here is an example. ``` $ target/testnet/subsystem-bench --n-cores 10 --cache-misses data-availability-read $ cat cachegrind_report.txt I refs: 64,622,081,485 I1 misses: 3,018,168 LLi misses: 437,654 I1 miss rate: 0.00% LLi miss rate: 0.00% D refs: 12,161,833,115 (9,868,356,364 rd + 2,293,476,751 wr) D1 misses: 167,940,701 ( 71,060,073 rd + 96,880,628 wr) LLd misses: 33,550,018 ( 16,685,853 rd + 16,864,165 wr) D1 miss rate: 1.4% ( 0.7% + 4.2% ) LLd miss rate: 0.3% ( 0.2% + 0.7% ) LL refs: 170,958,869 ( 74,078,241 rd + 96,880,628 wr) LL misses: 33,987,672 ( 17,123,507 rd + 16,864,165 wr) LL miss rate: 0.0% ( 0.0% + 0.7% ) ``` The CLI output shows that 1.4% of the L1 data cache missed, which is not so bad, given that the last-level cache had that data most of the time missing only 0.3%. Instruction data of the L1 has 0.00% misses of the time. Looking at an output file with `cg_annotate` shows that most of the misses occur during reed-solomon, which is expected. --- polkadot/node/subsystem-bench/README.md | 77 +++++++++++++++---- .../subsystem-bench/src/subsystem-bench.rs | 13 +++- polkadot/node/subsystem-bench/src/valgrind.rs | 49 ++++++++++++ 3 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 polkadot/node/subsystem-bench/src/valgrind.rs diff --git a/polkadot/node/subsystem-bench/README.md b/polkadot/node/subsystem-bench/README.md index b1476db2754..1ff5b129e1e 100644 --- a/polkadot/node/subsystem-bench/README.md +++ b/polkadot/node/subsystem-bench/README.md @@ -117,23 +117,24 @@ used to run a suite of tests defined in a `yaml` file like in this [example](exa ``` Options: - --network The type of network to be emulated [default: ideal] [possible values: - ideal, healthy, degraded] - --n-cores Number of cores to fetch availability for [default: 100] - --n-validators Number of validators to fetch chunks from [default: 500] - --min-pov-size The minimum pov size in KiB [default: 5120] - --max-pov-size The maximum pov size bytes [default: 5120] - -n, --num-blocks The number of blocks the test is going to run [default: 1] - -p, --peer-bandwidth The bandwidth of simulated remote peers in KiB - -b, --bandwidth The bandwidth of our simulated node in KiB - --peer-error Simulated conection error ratio [0-100] - --peer-min-latency Minimum remote peer latency in milliseconds [0-5000] - --peer-max-latency Maximum remote peer latency in milliseconds [0-5000] - --profile Enable CPU Profiling with Pyroscope - --pyroscope-url Pyroscope Server URL [default: http://localhost:4040] - --pyroscope-sample-rate Pyroscope Sample Rate [default: 113] - -h, --help Print help - -V, --version Print version + --network The type of network to be emulated [default: ideal] [possible + values: ideal, healthy, degraded] + --n-cores Number of cores to fetch availability for [default: 100] + --n-validators Number of validators to fetch chunks from [default: 500] + --min-pov-size The minimum pov size in KiB [default: 5120] + --max-pov-size The maximum pov size bytes [default: 5120] +-n, --num-blocks The number of blocks the test is going to run [default: 1] +-p, --peer-bandwidth The bandwidth of simulated remote peers in KiB +-b, --bandwidth The bandwidth of our simulated node in KiB + --peer-error Simulated conection error ratio [0-100] + --peer-min-latency Minimum remote peer latency in milliseconds [0-5000] + --peer-max-latency Maximum remote peer latency in milliseconds [0-5000] + --profile Enable CPU Profiling with Pyroscope + --pyroscope-url Pyroscope Server URL [default: http://localhost:4040] + --pyroscope-sample-rate Pyroscope Sample Rate [default: 113] + --cache-misses Enable Cache Misses Profiling with Valgrind. Linux only, Valgrind + must be in the PATH +-h, --help Print help ``` These apply to all test objectives, except `test-sequence` which relies on the values being specified in a file. @@ -221,6 +222,48 @@ view the test progress in real time by accessing [this link](http://localhost:30 Now run `target/testnet/subsystem-bench test-sequence --path polkadot/node/subsystem-bench/examples/availability_read.yaml` and view the metrics in real time and spot differences between different `n_validators` values. + +### Profiling cache misses + +Cache misses are profiled using Cachegrind, part of Valgrind. Cachegrind runs slowly, and its cache simulation is basic +and unlikely to reflect the behavior of a modern machine. However, it still represents the general situation with cache +usage, and more importantly it doesn't require a bare-metal machine to run on, which means it could be run in CI or in +a remote virtual installation. + +To profile cache misses use the `--cache-misses` flag. Cache simulation of current runs tuned for Intel Ice Lake CPU. +Since the execution will be very slow, it's recommended not to run it together with other profiling and not to take +benchmark results into account. A report is saved in a file `cachegrind_report.txt`. + +Example run results: +``` +$ target/testnet/subsystem-bench --n-cores 10 --cache-misses data-availability-read +$ cat cachegrind_report.txt +I refs: 64,622,081,485 +I1 misses: 3,018,168 +LLi misses: 437,654 +I1 miss rate: 0.00% +LLi miss rate: 0.00% + +D refs: 12,161,833,115 (9,868,356,364 rd + 2,293,476,751 wr) +D1 misses: 167,940,701 ( 71,060,073 rd + 96,880,628 wr) +LLd misses: 33,550,018 ( 16,685,853 rd + 16,864,165 wr) +D1 miss rate: 1.4% ( 0.7% + 4.2% ) +LLd miss rate: 0.3% ( 0.2% + 0.7% ) + +LL refs: 170,958,869 ( 74,078,241 rd + 96,880,628 wr) +LL misses: 33,987,672 ( 17,123,507 rd + 16,864,165 wr) +LL miss rate: 0.0% ( 0.0% + 0.7% ) +``` + +The results show that 1.4% of the L1 data cache missed, but the last level cache only missed 0.3% of the time. +Instruction data of the L1 has 0.00%. + +Cachegrind writes line-by-line cache profiling information to a file named `cachegrind.out.`. +This file is best interpreted with `cg_annotate --auto=yes cachegrind.out.`. For more information see the +[cachegrind manual](https://www.cs.cmu.edu/afs/cs.cmu.edu/project/cmt-40/Nice/RuleRefinement/bin/valgrind-3.2.0/docs/html/cg-manual.html). + +For finer profiling of cache misses, better use `perf` on a bare-metal machine. + ## Create new test objectives This tool is intended to make it easy to write new test objectives that focus individual subsystems, diff --git a/polkadot/node/subsystem-bench/src/subsystem-bench.rs b/polkadot/node/subsystem-bench/src/subsystem-bench.rs index 29b62b27855..8669ee4e8b1 100644 --- a/polkadot/node/subsystem-bench/src/subsystem-bench.rs +++ b/polkadot/node/subsystem-bench/src/subsystem-bench.rs @@ -16,6 +16,7 @@ //! A tool for running subsystem benchmark tests designed for development and //! CI regression testing. + use clap::Parser; use color_eyre::eyre; use pyroscope::PyroscopeAgent; @@ -27,6 +28,7 @@ use std::{path::Path, time::Duration}; pub(crate) mod availability; pub(crate) mod cli; pub(crate) mod core; +mod valgrind; use availability::{prepare_test, NetworkEmulation, TestState}; use cli::TestObjective; @@ -90,12 +92,21 @@ struct BenchCli { /// Pyroscope Sample Rate pub pyroscope_sample_rate: u32, + #[clap(long, default_value_t = false)] + /// Enable Cache Misses Profiling with Valgrind. Linux only, Valgrind must be in the PATH + pub cache_misses: bool, + #[command(subcommand)] pub objective: cli::TestObjective, } impl BenchCli { fn launch(self) -> eyre::Result<()> { + let is_valgrind_running = valgrind::is_valgrind_running(); + if !is_valgrind_running && self.cache_misses { + return valgrind::relaunch_in_valgrind_mode() + } + let agent_running = if self.profile { let agent = PyroscopeAgent::builder(self.pyroscope_url.as_str(), "subsystem-bench") .backend(pprof_backend(PprofConfig::new().sample_rate(self.pyroscope_sample_rate))) @@ -185,7 +196,7 @@ impl BenchCli { let mut state = TestState::new(&test_config); let (mut env, _protocol_config) = prepare_test(test_config, &mut state); - // test_config.write_to_disk(); + env.runtime() .block_on(availability::benchmark_availability_read(&mut env, state)); diff --git a/polkadot/node/subsystem-bench/src/valgrind.rs b/polkadot/node/subsystem-bench/src/valgrind.rs new file mode 100644 index 00000000000..3d0c488355b --- /dev/null +++ b/polkadot/node/subsystem-bench/src/valgrind.rs @@ -0,0 +1,49 @@ +// 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 . + +use color_eyre::eyre; + +/// Show if the app is running under Valgrind +pub(crate) fn is_valgrind_running() -> bool { + match std::env::var("LD_PRELOAD") { + Ok(v) => v.contains("valgrind"), + Err(_) => false, + } +} + +/// Stop execution and relaunch the app under valgrind +/// Cache configuration used to emulate Intel Ice Lake (size, associativity, line size): +/// L1 instruction: 32,768 B, 8-way, 64 B lines +/// L1 data: 49,152 B, 12-way, 64 B lines +/// Last-level: 2,097,152 B, 16-way, 64 B lines +pub(crate) fn relaunch_in_valgrind_mode() -> eyre::Result<()> { + use std::os::unix::process::CommandExt; + let err = std::process::Command::new("valgrind") + .arg("--tool=cachegrind") + .arg("--cache-sim=yes") + .arg("--log-file=cachegrind_report.txt") + .arg("--I1=32768,8,64") + .arg("--D1=49152,12,64") + .arg("--LL=2097152,16,64") + .arg("--verbose") + .args(std::env::args()) + .exec(); + + Err(eyre::eyre!( + "Сannot run Valgrind, check that it is installed and available in the PATH\n{}", + err + )) +} -- GitLab From 8428f678fe5179399f6854e194f1c8b30a9102f9 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Tue, 16 Jan 2024 19:18:04 +0100 Subject: [PATCH 014/283] XCMv4 (#1230) # Note for reviewer Most changes are just syntax changes necessary for the new version. Most important files should be the ones under the `xcm` folder. # Description Added XCMv4. ## Removed `Multi` prefix The following types have been renamed: - MultiLocation -> Location - MultiAsset -> Asset - MultiAssets -> Assets - InteriorMultiLocation -> InteriorLocation - MultiAssetFilter -> AssetFilter - VersionedMultiAsset -> VersionedAsset - WildMultiAsset -> WildAsset - VersionedMultiLocation -> VersionedLocation In order to fix a name conflict, the `Assets` in `xcm-executor` were renamed to `HoldingAssets`, as they represent assets in holding. ## Removed `Abstract` asset id It was not being used anywhere and this simplifies the code. Now assets are just constructed as follows: ```rust let asset: Asset = (AssetId(Location::new(1, Here)), 100u128).into(); ``` No need for specifying `Concrete` anymore. ## Outcome is now a named fields struct Instead of ```rust pub enum Outcome { Complete(Weight), Incomplete(Weight, Error), Error(Error), } ``` we now have ```rust pub enum Outcome { Complete { used: Weight }, Incomplete { used: Weight, error: Error }, Error { error: Error }, } ``` ## Added Reanchorable trait Now both locations and assets implement this trait, making it easier to reanchor both. ## New syntax for building locations and junctions Now junctions are built using the following methods: ```rust let location = Location { parents: 1, interior: [Parachain(1000), PalletInstance(50), GeneralIndex(1984)].into() }; ``` or ```rust let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]); ``` And they are matched like so: ```rust match location.unpack() { (1, [Parachain(id)]) => ... (0, Here) => ..., (1, [_]) => ..., } ``` This syntax is mandatory in v4, and has been also implemented for v2 and v3 for easier migration. This was needed to make all sizes smaller. # TODO - [x] Scaffold v4 - [x] Port github.com/paritytech/polkadot/pull/7236 - [x] Remove `Multi` prefix - [x] Remove `Abstract` asset id --------- Co-authored-by: command-bot <> Co-authored-by: Keith Yeung --- .../src/messages_benchmarking.rs | 12 +- .../src/messages_xcm_extension.rs | 22 +- .../xcm-bridge-hub-router/src/benchmarking.rs | 6 +- .../modules/xcm-bridge-hub-router/src/lib.rs | 33 +- .../modules/xcm-bridge-hub-router/src/mock.rs | 18 +- .../modules/xcm-bridge-hub/src/exporter.rs | 12 +- bridges/modules/xcm-bridge-hub/src/lib.rs | 14 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 17 +- .../pallets/inbound-queue/src/lib.rs | 10 +- .../pallets/inbound-queue/src/mock.rs | 59 +- .../pallets/inbound-queue/src/test.rs | 4 +- .../pallets/system/runtime-api/src/lib.rs | 4 +- .../parachain/pallets/system/src/api.rs | 6 +- .../pallets/system/src/benchmarking.rs | 16 +- .../parachain/pallets/system/src/lib.rs | 44 +- .../parachain/pallets/system/src/mock.rs | 26 +- .../parachain/pallets/system/src/tests.rs | 107 +- .../parachain/primitives/core/src/lib.rs | 22 +- .../parachain/primitives/core/tests/mod.rs | 6 +- .../primitives/router/src/inbound/mod.rs | 60 +- .../primitives/router/src/inbound/tests.rs | 7 +- .../primitives/router/src/outbound/mod.rs | 39 +- .../primitives/router/src/outbound/tests.rs | 283 ++-- .../runtime/runtime-common/src/lib.rs | 47 +- .../parachain/runtime/test-common/src/lib.rs | 69 +- cumulus/pallets/xcmp-queue/src/lib.rs | 8 +- cumulus/pallets/xcmp-queue/src/mock.rs | 19 +- cumulus/pallets/xcmp-queue/src/tests.rs | 54 +- .../runtime/src/xcm_config.rs | 22 +- cumulus/parachains/common/src/impls.rs | 18 +- cumulus/parachains/common/src/xcm_config.rs | 88 +- .../parachains/testing/penpal/src/lib.rs | 4 +- .../emulated/common/src/impls.rs | 57 +- .../emulated/common/src/lib.rs | 1 + .../emulated/common/src/macros.rs | 18 +- .../emulated/common/src/xcm_helpers.rs | 16 +- .../tests/assets/asset-hub-rococo/src/lib.rs | 2 +- .../src/tests/reserve_transfer.rs | 18 +- .../src/tests/set_xcm_versions.rs | 7 +- .../assets/asset-hub-rococo/src/tests/swap.rs | 68 +- .../asset-hub-rococo/src/tests/teleport.rs | 31 +- .../tests/assets/asset-hub-westend/src/lib.rs | 2 +- .../src/tests/fellowship_treasury.rs | 14 +- .../src/tests/reserve_transfer.rs | 18 +- .../src/tests/set_xcm_versions.rs | 7 +- .../asset-hub-westend/src/tests/swap.rs | 67 +- .../asset-hub-westend/src/tests/teleport.rs | 31 +- .../asset-hub-westend/src/tests/treasury.rs | 10 +- .../bridges/bridge-hub-rococo/src/lib.rs | 2 +- .../src/tests/asset_transfers.rs | 23 +- .../bridge-hub-rococo/src/tests/mod.rs | 34 +- .../bridge-hub-rococo/src/tests/send_xcm.rs | 24 +- .../bridge-hub-rococo/src/tests/snowbridge.rs | 63 +- .../bridge-hub-rococo/src/tests/teleport.rs | 2 +- .../bridges/bridge-hub-westend/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 20 +- .../bridge-hub-westend/src/tests/mod.rs | 34 +- .../bridge-hub-westend/src/tests/send_xcm.rs | 22 +- .../bridge-hub-westend/src/tests/teleport.rs | 2 +- cumulus/parachains/pallets/ping/src/lib.rs | 4 +- .../assets/asset-hub-rococo/src/lib.rs | 148 +- .../asset-hub-rococo/src/weights/xcm/mod.rs | 96 +- .../assets/asset-hub-rococo/src/xcm_config.rs | 140 +- .../assets/asset-hub-rococo/tests/tests.rs | 103 +- .../assets/asset-hub-westend/src/lib.rs | 146 +- .../asset-hub-westend/src/weights/xcm/mod.rs | 96 +- .../asset-hub-westend/src/xcm_config.rs | 153 +- .../assets/asset-hub-westend/tests/tests.rs | 104 +- .../runtimes/assets/common/src/benchmarks.rs | 21 +- .../assets/common/src/foreign_creators.rs | 25 +- .../assets/common/src/fungible_conversion.rs | 103 +- .../runtimes/assets/common/src/lib.rs | 224 +-- .../common/src/local_and_foreign_assets.rs | 32 +- .../runtimes/assets/common/src/matching.rs | 118 +- .../runtimes/assets/common/src/runtime_api.rs | 12 +- .../runtimes/assets/test-utils/src/lib.rs | 6 +- .../assets/test-utils/src/test_cases.rs | 290 ++-- .../test-utils/src/test_cases_over_bridge.rs | 114 +- .../assets/test-utils/src/xcm_helpers.rs | 28 +- .../src/bridge_to_bulletin_config.rs | 30 +- .../src/bridge_to_westend_config.rs | 40 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 78 +- .../bridge-hub-rococo/src/weights/xcm/mod.rs | 96 +- .../bridge-hub-rococo/src/xcm_config.rs | 48 +- .../bridge-hub-rococo/tests/tests.rs | 2 +- .../src/bridge_to_rococo_config.rs | 32 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 66 +- .../bridge-hub-westend/src/weights/xcm/mod.rs | 96 +- .../bridge-hub-westend/src/xcm_config.rs | 26 +- .../bridge-hub-westend/tests/tests.rs | 2 +- .../bridge-hubs/common/src/message_queue.rs | 12 +- .../src/test_cases/from_grandpa_chain.rs | 4 +- .../src/test_cases/from_parachain.rs | 4 +- .../test-utils/src/test_cases/helpers.rs | 12 +- .../test-utils/src/test_cases/mod.rs | 63 +- .../test-utils/src/test_data/mod.rs | 12 +- .../collectives-westend/src/ambassador/mod.rs | 2 +- .../collectives-westend/src/fellowship/mod.rs | 12 +- .../collectives-westend/src/lib.rs | 14 +- .../collectives-westend/src/xcm_config.rs | 34 +- .../contracts/contracts-rococo/src/lib.rs | 12 +- .../contracts-rococo/src/xcm_config.rs | 28 +- .../coretime/coretime-rococo/src/coretime.rs | 8 +- .../coretime/coretime-rococo/src/lib.rs | 58 +- .../coretime-rococo/src/weights/xcm/mod.rs | 96 +- .../coretime-rococo/src/xcm_config.rs | 30 +- .../coretime/coretime-westend/src/lib.rs | 58 +- .../coretime-westend/src/weights/xcm/mod.rs | 96 +- .../coretime-westend/src/xcm_config.rs | 40 +- .../glutton/glutton-westend/src/xcm_config.rs | 15 +- .../runtimes/people/people-rococo/src/lib.rs | 56 +- .../people-rococo/src/weights/xcm/mod.rs | 94 +- .../people/people-rococo/src/xcm_config.rs | 55 +- .../runtimes/people/people-westend/src/lib.rs | 56 +- .../people-westend/src/weights/xcm/mod.rs | 94 +- .../people/people-westend/src/xcm_config.rs | 65 +- .../runtimes/starters/shell/src/xcm_config.rs | 15 +- .../parachains/runtimes/test-utils/src/lib.rs | 41 +- .../runtimes/testing/penpal/src/lib.rs | 5 +- .../runtimes/testing/penpal/src/xcm_config.rs | 85 +- .../testing/rococo-parachain/src/lib.rs | 46 +- cumulus/primitives/core/src/lib.rs | 9 +- cumulus/primitives/utility/src/lib.rs | 101 +- .../utility/src/tests/swap_first.rs | 28 +- cumulus/xcm/xcm-emulator/src/lib.rs | 33 +- polkadot/runtime/common/src/impls.rs | 69 +- polkadot/runtime/common/src/xcm_sender.rs | 30 +- .../parachains/src/coretime/migration.rs | 17 +- .../runtime/parachains/src/coretime/mod.rs | 10 +- polkadot/runtime/parachains/src/mock.rs | 9 +- polkadot/runtime/rococo/src/impls.rs | 18 +- polkadot/runtime/rococo/src/lib.rs | 77 +- .../runtime/rococo/src/weights/xcm/mod.rs | 108 +- polkadot/runtime/rococo/src/xcm_config.rs | 85 +- polkadot/runtime/test-runtime/src/lib.rs | 2 +- .../runtime/test-runtime/src/xcm_config.rs | 30 +- polkadot/runtime/westend/src/impls.rs | 18 +- polkadot/runtime/westend/src/lib.rs | 79 +- .../runtime/westend/src/weights/xcm/mod.rs | 108 +- polkadot/runtime/westend/src/xcm_config.rs | 87 +- polkadot/xcm/Cargo.toml | 2 +- .../src/fungible/benchmarking.rs | 24 +- .../src/fungible/mock.rs | 33 +- .../pallet-xcm-benchmarks/src/fungible/mod.rs | 6 +- .../src/generic/benchmarking.rs | 40 +- .../pallet-xcm-benchmarks/src/generic/mock.rs | 68 +- .../pallet-xcm-benchmarks/src/generic/mod.rs | 31 +- polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs | 42 +- .../xcm/pallet-xcm-benchmarks/src/mock.rs | 24 +- polkadot/xcm/pallet-xcm/src/benchmarking.rs | 77 +- polkadot/xcm/pallet-xcm/src/lib.rs | 670 ++++---- polkadot/xcm/pallet-xcm/src/mock.rs | 220 +-- .../pallet-xcm/src/tests/assets_transfer.rs | 835 ++++++---- polkadot/xcm/pallet-xcm/src/tests/mod.rs | 321 ++-- polkadot/xcm/procedural/src/lib.rs | 22 + polkadot/xcm/procedural/src/v2.rs | 49 +- polkadot/xcm/procedural/src/v3.rs | 49 +- polkadot/xcm/procedural/src/v4.rs | 196 +++ .../xcm/procedural/tests/builder_pattern.rs | 16 +- .../procedural/tests/conversion_functions.rs | 24 + polkadot/xcm/src/lib.rs | 256 ++- polkadot/xcm/src/tests.rs | 36 +- polkadot/xcm/src/v2/multilocation.rs | 29 +- polkadot/xcm/src/v2/traits.rs | 5 +- polkadot/xcm/src/v3/junction.rs | 55 +- polkadot/xcm/src/v3/junctions.rs | 21 + polkadot/xcm/src/v3/mod.rs | 234 ++- polkadot/xcm/src/v3/multiasset.rs | 105 +- polkadot/xcm/src/v3/multilocation.rs | 30 +- polkadot/xcm/src/v3/traits.rs | 50 - polkadot/xcm/src/v4/asset.rs | 915 +++++++++++ polkadot/xcm/src/v4/junction.rs | 317 ++++ polkadot/xcm/src/v4/junctions.rs | 723 ++++++++ polkadot/xcm/src/v4/location.rs | 746 +++++++++ polkadot/xcm/src/v4/mod.rs | 1457 +++++++++++++++++ polkadot/xcm/src/v4/traits.rs | 312 ++++ .../xcm/xcm-builder/src/asset_conversion.rs | 168 +- polkadot/xcm/xcm-builder/src/barriers.rs | 64 +- polkadot/xcm/xcm-builder/src/controller.rs | 12 +- .../xcm/xcm-builder/src/currency_adapter.rs | 36 +- polkadot/xcm/xcm-builder/src/fee_handling.rs | 31 +- .../xcm-builder/src/filter_asset_location.rs | 66 +- .../xcm/xcm-builder/src/fungible_adapter.rs | 65 +- .../xcm/xcm-builder/src/fungibles_adapter.rs | 64 +- polkadot/xcm/xcm-builder/src/lib.rs | 8 +- .../xcm-builder/src/location_conversion.rs | 372 ++--- polkadot/xcm/xcm-builder/src/matcher.rs | 6 +- .../xcm/xcm-builder/src/matches_location.rs | 46 +- polkadot/xcm/xcm-builder/src/matches_token.rs | 67 +- .../xcm-builder/src/nonfungibles_adapter.rs | 56 +- .../xcm/xcm-builder/src/origin_aliases.rs | 12 +- .../xcm/xcm-builder/src/origin_conversion.rs | 123 +- polkadot/xcm/xcm-builder/src/pay.rs | 21 +- .../xcm-builder/src/process_xcm_message.rs | 20 +- polkadot/xcm/xcm-builder/src/routing.rs | 4 +- polkadot/xcm/xcm-builder/src/test_utils.rs | 74 +- polkadot/xcm/xcm-builder/src/tests/aliases.rs | 19 +- polkadot/xcm/xcm-builder/src/tests/assets.rs | 358 ++-- polkadot/xcm/xcm-builder/src/tests/basic.rs | 40 +- .../src/tests/bridging/local_para_para.rs | 6 +- .../src/tests/bridging/local_relay_relay.rs | 6 +- .../xcm/xcm-builder/src/tests/bridging/mod.rs | 54 +- .../tests/bridging/paid_remote_relay_relay.rs | 26 +- .../src/tests/bridging/remote_para_para.rs | 20 +- .../bridging/remote_para_para_via_relay.rs | 20 +- .../src/tests/bridging/remote_relay_relay.rs | 18 +- .../xcm/xcm-builder/src/tests/expecting.rs | 130 +- polkadot/xcm/xcm-builder/src/tests/locking.rs | 130 +- polkadot/xcm/xcm-builder/src/tests/mock.rs | 315 ++-- polkadot/xcm/xcm-builder/src/tests/origins.rs | 76 +- .../xcm/xcm-builder/src/tests/pay/mock.rs | 54 +- polkadot/xcm/xcm-builder/src/tests/pay/pay.rs | 28 +- .../xcm/xcm-builder/src/tests/pay/salary.rs | 14 +- .../xcm/xcm-builder/src/tests/querying.rs | 44 +- .../xcm/xcm-builder/src/tests/transacting.rs | 147 +- .../src/tests/version_subscriptions.rs | 110 +- polkadot/xcm/xcm-builder/src/tests/weight.rs | 67 +- .../xcm/xcm-builder/src/universal_exports.rs | 133 +- polkadot/xcm/xcm-builder/src/weight.rs | 38 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 22 +- polkadot/xcm/xcm-builder/tests/scenarios.rs | 88 +- .../xcm-executor/integration-tests/src/lib.rs | 12 +- polkadot/xcm/xcm-executor/src/assets.rs | 353 ++-- polkadot/xcm/xcm-executor/src/config.rs | 10 +- polkadot/xcm/xcm-executor/src/lib.rs | 168 +- .../xcm-executor/src/traits/asset_exchange.rs | 18 +- .../xcm/xcm-executor/src/traits/asset_lock.rs | 44 +- .../xcm-executor/src/traits/asset_transfer.rs | 19 +- .../xcm/xcm-executor/src/traits/conversion.rs | 35 +- .../xcm-executor/src/traits/drop_assets.rs | 32 +- .../xcm/xcm-executor/src/traits/export.rs | 20 +- .../xcm-executor/src/traits/fee_manager.rs | 12 +- .../src/traits/filter_asset_location.rs | 10 +- .../xcm-executor/src/traits/on_response.rs | 52 +- .../xcm-executor/src/traits/should_execute.rs | 10 +- .../xcm-executor/src/traits/token_matching.rs | 20 +- .../xcm-executor/src/traits/transact_asset.rs | 172 +- .../xcm/xcm-executor/src/traits/weight.rs | 16 +- polkadot/xcm/xcm-simulator/example/src/lib.rs | 4 +- .../xcm-simulator/example/src/parachain.rs | 65 +- .../xcm-simulator/example/src/relay_chain.rs | 6 +- polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs | 4 +- .../xcm/xcm-simulator/fuzzer/src/parachain.rs | 35 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 6 +- polkadot/xcm/xcm-simulator/src/lib.rs | 44 +- prdoc/pr_1230.prdoc | 20 + substrate/frame/assets/src/benchmarking.rs | 121 +- substrate/frame/assets/src/lib.rs | 6 +- .../frame/contracts/mock-network/src/lib.rs | 8 +- .../mock-network/src/mocks/msg_queue.rs | 27 +- .../contracts/mock-network/src/parachain.rs | 62 +- .../contracts/mock-network/src/relay_chain.rs | 12 +- .../frame/contracts/mock-network/src/tests.rs | 25 +- substrate/frame/contracts/src/wasm/runtime.rs | 4 +- .../frame/support/src/traits/tokens/pay.rs | 2 +- 255 files changed, 12421 insertions(+), 6722 deletions(-) create mode 100644 polkadot/xcm/procedural/src/v4.rs create mode 100644 polkadot/xcm/procedural/tests/conversion_functions.rs create mode 100644 polkadot/xcm/src/v4/asset.rs create mode 100644 polkadot/xcm/src/v4/junction.rs create mode 100644 polkadot/xcm/src/v4/junctions.rs create mode 100644 polkadot/xcm/src/v4/location.rs create mode 100644 polkadot/xcm/src/v4/mod.rs create mode 100644 polkadot/xcm/src/v4/traits.rs create mode 100644 prdoc/pr_1230.prdoc diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index e7e7891461b..0c7a9ad1a83 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -38,7 +38,7 @@ use frame_support::weights::Weight; use pallet_bridge_messages::benchmarking::{MessageDeliveryProofParams, MessageProofParams}; use sp_runtime::traits::{Header, Zero}; use sp_std::prelude::*; -use xcm::v3::prelude::*; +use xcm::latest::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. fn prepare_inbound_message( @@ -266,19 +266,19 @@ where /// Returns callback which generates `BridgeMessage` from Polkadot XCM builder based on /// `expected_message_size` for benchmark. pub fn generate_xcm_builder_bridge_message_sample( - destination: InteriorMultiLocation, + destination: InteriorLocation, ) -> impl Fn(usize) -> MessagePayload { move |expected_message_size| -> MessagePayload { // For XCM bridge hubs, it is the message that // will be pushed further to some XCM queue (XCMP/UMP) - let location = xcm::VersionedInteriorMultiLocation::V3(destination); + let location = xcm::VersionedInteriorLocation::V4(destination.clone()); let location_encoded_size = location.encoded_size(); // we don't need to be super-precise with `expected_size` here let xcm_size = expected_message_size.saturating_sub(location_encoded_size); let xcm_data_size = xcm_size.saturating_sub( // minus empty instruction size - xcm::v3::Instruction::<()>::ExpectPallet { + Instruction::<()>::ExpectPallet { index: 0, name: vec![], module_name: vec![], @@ -294,8 +294,8 @@ pub fn generate_xcm_builder_bridge_message_sample( expected_message_size, location_encoded_size, xcm_size, xcm_data_size, ); - let xcm = xcm::VersionedXcm::<()>::V3( - vec![xcm::v3::Instruction::<()>::ExpectPallet { + let xcm = xcm::VersionedXcm::<()>::V4( + vec![Instruction::<()>::ExpectPallet { index: 0, name: vec![42; xcm_data_size], module_name: vec![], diff --git a/bridges/bin/runtime-common/src/messages_xcm_extension.rs b/bridges/bin/runtime-common/src/messages_xcm_extension.rs index 53c0579c4cd..fd2c20af72a 100644 --- a/bridges/bin/runtime-common/src/messages_xcm_extension.rs +++ b/bridges/bin/runtime-common/src/messages_xcm_extension.rs @@ -123,14 +123,14 @@ impl< #[cfg_attr(feature = "std", derive(Debug, Eq, PartialEq))] pub struct SenderAndLane { /// Sending chain relative location. - pub location: MultiLocation, + pub location: Location, /// Message lane, used by the sending chain. pub lane: LaneId, } impl SenderAndLane { /// Create new object using provided location and lane. - pub fn new(location: MultiLocation, lane: LaneId) -> Self { + pub fn new(location: Location, lane: LaneId) -> Self { SenderAndLane { location, lane } } } @@ -168,7 +168,7 @@ pub struct XcmBlobHaulerAdapter( impl< H: XcmBlobHauler, - Lanes: Get>, + Lanes: Get>, > OnMessagesDelivered for XcmBlobHaulerAdapter { fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce) { @@ -288,7 +288,7 @@ impl LocalXcmQueueManager { /// Send congested signal to the `sending_chain_location`. fn send_congested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> { if let Some(msg) = H::CongestedMessage::get() { - send_xcm::(sender_and_lane.location, msg)?; + send_xcm::(sender_and_lane.location.clone(), msg)?; OutboundLanesCongestedSignals::::insert( sender_and_lane.lane, true, @@ -300,7 +300,7 @@ impl LocalXcmQueueManager { /// Send `uncongested` signal to the `sending_chain_location`. fn send_uncongested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> { if let Some(msg) = H::UncongestedMessage::get() { - send_xcm::(sender_and_lane.location, msg)?; + send_xcm::(sender_and_lane.location.clone(), msg)?; OutboundLanesCongestedSignals::::remove( sender_and_lane.lane, ); @@ -315,10 +315,10 @@ impl LocalXcmQueueManager { pub struct XcmVersionOfDestAndRemoteBridge( sp_std::marker::PhantomData<(Version, RemoteBridge)>, ); -impl> GetVersion +impl> GetVersion for XcmVersionOfDestAndRemoteBridge { - fn get_version_for(dest: &MultiLocation) -> Option { + fn get_version_for(dest: &Location) -> Option { let dest_version = Version::get_version_for(dest); let bridge_hub_version = Version::get_version_for(&RemoteBridge::get()); @@ -342,11 +342,11 @@ mod tests { parameter_types! { pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: MultiLocation::new(1, X1(Parachain(1000))), + location: Location::new(1, [Parachain(1000)]), lane: TEST_LANE_ID, }; - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ - (TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorMultiLocation::Here)) + pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ + (TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorLocation::Here)) ]; pub DummyXcmMessage: Xcm<()> = Xcm::new(); } @@ -363,7 +363,7 @@ mod tests { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { Ok(((), Default::default())) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 922e4bf94ba..c4f9f534c1a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -37,10 +37,10 @@ pub trait Config: crate::Config { /// Returns destination which is valid for this router instance. /// (Needs to pass `T::Bridges`) /// Make sure that `SendXcm` will pass. - fn ensure_bridged_target_destination() -> Result { - Ok(MultiLocation::new( + fn ensure_bridged_target_destination() -> Result { + Ok(Location::new( Self::UniversalLocation::get().len() as u8, - X1(GlobalConsensus(Self::BridgedNetworkId::get().unwrap())), + [GlobalConsensus(Self::BridgedNetworkId::get().unwrap())], )) } } diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 229628aedcb..f219be78f9e 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -80,7 +80,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// Universal location of this runtime. - type UniversalLocation: Get; + type UniversalLocation: Get; /// The bridged network that this config is for if specified. /// Also used for filtering `Bridges` by `BridgedNetworkId`. /// If not specified, allows all networks pass through. @@ -235,9 +235,9 @@ type ViaBridgeHubExporter = SovereignPaidRemoteExporter< impl, I: 'static> ExporterFor for Pallet { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { // ensure that the message is sent to the expected bridged network (if specified). if let Some(bridged_network) = T::BridgedNetworkId::get() { if *network != bridged_network { @@ -268,7 +268,7 @@ impl, I: 'static> ExporterFor for Pallet { // take `base_fee` from `T::Brides`, but it has to be the same `T::FeeAsset` let base_fee = match maybe_payment { Some(payment) => match payment { - MultiAsset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, + Asset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, invalid_asset => { log::error!( target: LOG_TARGET, @@ -318,7 +318,7 @@ impl, I: 'static> SendXcm for Pallet { type Ticket = (u32, ::Ticket); fn validate( - dest: &mut Option, + dest: &mut Option, xcm: &mut Option>, ) -> SendResult { // `dest` and `xcm` are required here @@ -446,7 +446,7 @@ mod tests { run_test(|| { assert_eq!( send_xcm::( - MultiLocation::new(2, X2(GlobalConsensus(Rococo), Parachain(1000))), + Location::new(2, [GlobalConsensus(Rococo), Parachain(1000)]), vec![].into(), ), Err(SendError::NotApplicable), @@ -459,7 +459,7 @@ mod tests { run_test(|| { assert_eq!( send_xcm::( - MultiLocation::new(2, X2(GlobalConsensus(Rococo), Parachain(1000))), + Location::new(2, [GlobalConsensus(Rococo), Parachain(1000)]), vec![ClearOrigin; HARD_MESSAGE_SIZE_LIMIT as usize].into(), ), Err(SendError::ExceedsMaxMessageSize), @@ -483,14 +483,14 @@ mod tests { #[test] fn returns_proper_delivery_price() { run_test(|| { - let dest = MultiLocation::new(2, X1(GlobalConsensus(BridgedNetworkId::get()))); + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); let xcm: Xcm<()> = vec![ClearOrigin].into(); let msg_size = xcm.encoded_size(); // initially the base fee is used: `BASE_FEE + BYTE_FEE * msg_size + HRMP_FEE` let expected_fee = BASE_FEE + BYTE_FEE * (msg_size as u128) + HRMP_FEE; assert_eq!( - XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm.clone())) + XcmBridgeHubRouter::validate(&mut Some(dest.clone()), &mut Some(xcm.clone())) .unwrap() .1 .get(0), @@ -518,10 +518,7 @@ mod tests { run_test(|| { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); @@ -538,10 +535,7 @@ mod tests { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); @@ -560,10 +554,7 @@ mod tests { let old_bridge = XcmBridgeHubRouter::bridge(); assert_ok!(send_xcm::( - MultiLocation::new( - 2, - X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)) - ), + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), vec![ClearOrigin].into(), ) .map(drop)); diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 9079f4b9c4c..6dbfba5f6fd 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -49,9 +49,9 @@ construct_runtime! { parameter_types! { pub ThisNetworkId: NetworkId = Polkadot; pub BridgedNetworkId: NetworkId = Kusama; - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ThisNetworkId::get()), Parachain(1000)); - pub SiblingBridgeHubLocation: MultiLocation = ParentThen(X1(Parachain(1002))).into(); - pub BridgeFeeAsset: AssetId = MultiLocation::parent().into(); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetworkId::get()), Parachain(1000)].into(); + pub SiblingBridgeHubLocation: Location = ParentThen([Parachain(1002)].into()).into(); + pub BridgeFeeAsset: AssetId = Location::parent().into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( @@ -61,7 +61,7 @@ parameter_types! { Some((BridgeFeeAsset::get(), BASE_FEE).into()) ) ]; - pub UnknownXcmVersionLocation: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(BridgedNetworkId::get()), Parachain(9999))); + pub UnknownXcmVersionLocation: Location = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(9999)]); } #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] @@ -87,11 +87,11 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { } pub struct LatestOrNoneForLocationVersionChecker(sp_std::marker::PhantomData); -impl> GetVersion - for LatestOrNoneForLocationVersionChecker +impl> GetVersion + for LatestOrNoneForLocationVersionChecker { - fn get_version_for(dest: &MultiLocation) -> Option { - if Location::contains(dest) { + fn get_version_for(dest: &Location) -> Option { + if LocationValue::contains(dest) { return None } Some(XCM_VERSION) @@ -110,7 +110,7 @@ impl SendXcm for TestToBridgeHubSender { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { Ok(((), (BridgeFeeAsset::get(), HRMP_FEE).into())) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 5318b222c54..3dd7459d30f 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -52,10 +52,10 @@ where fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, - ) -> Result<(Self::Ticket, MultiAssets), SendError> { + ) -> Result<(Self::Ticket, Assets), SendError> { // Find supported lane_id. let sender_and_lane = Self::lane_for( universal_source.as_ref().ok_or(SendError::MissingArgument)?, @@ -137,11 +137,11 @@ mod tests { use frame_support::assert_ok; use xcm_executor::traits::export_xcm; - fn universal_source() -> InteriorMultiLocation { - X2(GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)) + fn universal_source() -> InteriorLocation { + [GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)].into() } - fn universal_destination() -> InteriorMultiLocation { + fn universal_destination() -> InteriorLocation { BridgedDestination::get() } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 44f6903b018..60b988497fc 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -45,25 +45,25 @@ pub mod pallet { BridgeMessagesConfig { /// Runtime's universal location. - type UniversalLocation: Get; + type UniversalLocation: Get; // TODO: https://github.com/paritytech/parity-bridges-common/issues/1666 remove `ChainId` and // replace it with the `NetworkId` - then we'll be able to use // `T as pallet_bridge_messages::Config::BridgedChain::NetworkId` /// Bridged network as relative location of bridged `GlobalConsensus`. #[pallet::constant] - type BridgedNetwork: Get; + type BridgedNetwork: Get; /// Associated messages pallet instance that bridges us with the /// `BridgedNetworkId` consensus. type BridgeMessagesPalletInstance: 'static; /// Price of single message export to the bridged consensus (`Self::BridgedNetworkId`). - type MessageExportPrice: Get; + type MessageExportPrice: Get; /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; /// Get point-to-point links with bridged consensus (`Self::BridgedNetworkId`). /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) - type Lanes: Get>; + type Lanes: Get>; /// Support for point-to-point links /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) type LanesSupport: XcmBlobHauler; @@ -86,10 +86,10 @@ pub mod pallet { impl, I: 'static> Pallet { /// Returns dedicated/configured lane identifier. pub(crate) fn lane_for( - source: &InteriorMultiLocation, - dest: (&NetworkId, &InteriorMultiLocation), + source: &InteriorLocation, + dest: (&NetworkId, &InteriorLocation), ) -> Option { - let source = source.relative_to(&T::UniversalLocation::get()); + let source = source.clone().relative_to(&T::UniversalLocation::get()); // Check that we have configured a point-to-point lane for 'source' and `dest`. T::Lanes::get() diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 8edd4b1f7aa..6708d4b789a 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -170,16 +170,13 @@ impl pallet_bridge_messages::WeightInfoExt for TestMessagesWeights { parameter_types! { pub const RelayNetwork: NetworkId = NetworkId::Kusama; pub const BridgedRelayNetwork: NetworkId = NetworkId::Polkadot; - pub const BridgedRelayNetworkLocation: MultiLocation = MultiLocation { - parents: 1, - interior: X1(GlobalConsensus(BridgedRelayNetwork::get())) - }; + pub BridgedRelayNetworkLocation: Location = (Parent, GlobalConsensus(BridgedRelayNetwork::get())).into(); pub const NonBridgedRelayNetwork: NetworkId = NetworkId::Rococo; pub const BridgeReserve: Balance = 100_000; - pub UniversalLocation: InteriorMultiLocation = X2( + pub UniversalLocation: InteriorLocation = [ GlobalConsensus(RelayNetwork::get()), Parachain(THIS_BRIDGE_HUB_ID), - ); + ].into(); pub const Penalty: Balance = 1_000; } @@ -197,13 +194,13 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { parameter_types! { pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: MultiLocation::new(1, X1(Parachain(SIBLING_ASSET_HUB_ID))), + location: Location::new(1, [Parachain(SIBLING_ASSET_HUB_ID)]), lane: TEST_LANE_ID, }; - pub const BridgedDestination: InteriorMultiLocation = X1( + pub BridgedDestination: InteriorLocation = [ Parachain(BRIDGED_ASSET_HUB_ID) - ); - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + ].into(); + pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ (TestSenderAndLane::get(), (BridgedRelayNetwork::get(), BridgedDestination::get())) ]; } diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs index f7eea0aadfa..bdc21fcf037 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/lib.rs @@ -54,8 +54,8 @@ use scale_info::TypeInfo; use sp_core::{H160, H256}; use sp_std::{convert::TryFrom, vec}; use xcm::prelude::{ - send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, - SendError as XcmpSendError, SendXcm, Xcm, XcmContext, XcmHash, + send_xcm, Instruction::SetTopic, Junction::*, Location, SendError as XcmpSendError, SendXcm, + Xcm, XcmContext, XcmHash, }; use xcm_executor::traits::TransactAsset; @@ -324,7 +324,7 @@ pub mod pallet { } pub fn send_xcm(xcm: Xcm<()>, dest: ParaId) -> Result> { - let dest = MultiLocation { parents: 1, interior: X1(Parachain(dest.into())) }; + let dest = Location::new(1, [Parachain(dest.into())]); let (xcm_hash, _) = send_xcm::(dest, xcm).map_err(Error::::from)?; Ok(xcm_hash) } @@ -341,8 +341,8 @@ pub mod pallet { pub fn burn_fees(para_id: ParaId, fee: BalanceOf) -> DispatchResult { let dummy_context = XcmContext { origin: None, message_id: Default::default(), topic: None }; - let dest = MultiLocation { parents: 1, interior: X1(Parachain(para_id.into())) }; - let fees = (MultiLocation::parent(), fee.saturated_into::()).into(); + let dest = Location::new(1, [Parachain(para_id.into())]); + let fees = (Location::parent(), fee.saturated_into::()).into(); T::AssetTransactor::can_check_out(&dest, &fees, &dummy_context).map_err(|error| { log::error!( target: LOG_TARGET, diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs index b031a46e219..39374aa3d71 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs @@ -21,8 +21,8 @@ use sp_runtime::{ BuildStorage, FixedU128, MultiSignature, }; use sp_std::convert::From; -use xcm::v3::{prelude::*, MultiAssets, SendXcm}; -use xcm_executor::Assets; +use xcm::v4::{prelude::*, SendXcm}; +use xcm_executor::AssetsInHolding; use crate::{self as inbound_queue}; @@ -155,17 +155,16 @@ impl SendXcm for MockXcmSender { type Ticket = Xcm<()>; fn validate( - dest: &mut Option, - xcm: &mut Option>, + dest: &mut Option, + xcm: &mut Option>, ) -> SendResult { - match dest { - Some(MultiLocation { interior, .. }) => { - if let X1(Parachain(1001)) = interior { - return Err(XcmpSendError::NotApplicable) - } - Ok((xcm.clone().unwrap(), MultiAssets::default())) - }, - _ => Ok((xcm.clone().unwrap(), MultiAssets::default())), + if let Some(location) = dest { + match location.unpack() { + (_, [Parachain(1001)]) => return Err(XcmpSendError::NotApplicable), + _ => Ok((xcm.clone().unwrap(), Assets::default())), + } + } else { + Ok((xcm.clone().unwrap(), Assets::default())) } } @@ -203,45 +202,33 @@ impl StaticLookup for MockChannelLookup { pub struct SuccessfulTransactor; impl TransactAsset for SuccessfulTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs index 17ebeb39446..9a47e475b8c 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/test.rs @@ -41,8 +41,8 @@ fn test_submit_happy_path() { .into(), nonce: 1, message_id: [ - 27, 217, 88, 127, 46, 143, 199, 70, 236, 66, 212, 244, 85, 221, 153, 104, 175, 37, - 224, 20, 140, 95, 140, 7, 27, 74, 182, 199, 77, 12, 194, 236, + 57, 61, 232, 3, 66, 61, 25, 190, 234, 188, 193, 174, 13, 186, 1, 64, 237, 94, 73, + 83, 14, 18, 209, 213, 78, 121, 43, 108, 251, 245, 107, 67, ], fee_burned: 110000000000, } diff --git a/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs index d99b456c848..7f119809546 100644 --- a/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/runtime-api/src/lib.rs @@ -3,11 +3,11 @@ #![cfg_attr(not(feature = "std"), no_std)] use snowbridge_core::AgentId; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; sp_api::decl_runtime_apis! { pub trait ControlApi { - fn agent_id(location: VersionedMultiLocation) -> Option; + fn agent_id(location: VersionedLocation) -> Option; } } diff --git a/bridges/snowbridge/parachain/pallets/system/src/api.rs b/bridges/snowbridge/parachain/pallets/system/src/api.rs index 245e6eea1c1..ef12b03e1d7 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/api.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/api.rs @@ -3,14 +3,14 @@ //! Helpers for implementing runtime api use snowbridge_core::AgentId; -use xcm::{prelude::*, VersionedMultiLocation}; +use xcm::{prelude::*, VersionedLocation}; use crate::{agent_id_of, Config}; -pub fn agent_id(location: VersionedMultiLocation) -> Option +pub fn agent_id(location: VersionedLocation) -> Option where Runtime: Config, { - let location: MultiLocation = location.try_into().ok()?; + let location: Location = location.try_into().ok()?; agent_id_of::(&location).ok() } diff --git a/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs b/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs index 8d26408b38e..ef908ad6a3f 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/benchmarking.rs @@ -63,7 +63,7 @@ mod benchmarks { #[benchmark] fn create_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; @@ -76,7 +76,7 @@ mod benchmarks { #[benchmark] fn create_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; @@ -91,7 +91,7 @@ mod benchmarks { #[benchmark] fn update_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; @@ -106,7 +106,7 @@ mod benchmarks { #[benchmark] fn force_update_channel() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); let channel_id: ChannelId = ParaId::from(origin_para_id).into(); @@ -123,7 +123,7 @@ mod benchmarks { #[benchmark] fn transfer_native_from_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let origin = T::Helper::make_xcm_origin(origin_location); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; @@ -138,12 +138,12 @@ mod benchmarks { #[benchmark] fn force_transfer_native_from_agent() -> Result<(), BenchmarkError> { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; - let origin = T::Helper::make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(origin_para_id)]); + let origin = T::Helper::make_xcm_origin(origin_location.clone()); fund_sovereign_account::(origin_para_id.into())?; SnowbridgeControl::::create_agent(origin.clone())?; - let versioned_location: VersionedMultiLocation = origin_location.into(); + let versioned_location: VersionedLocation = origin_location.into(); #[extrinsic_call] _(RawOrigin::Root, Box::new(versioned_location), H160::default(), 1); diff --git a/bridges/snowbridge/parachain/pallets/system/src/lib.rs b/bridges/snowbridge/parachain/pallets/system/src/lib.rs index 0042093ee66..e742bd8e110 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/lib.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/lib.rs @@ -87,12 +87,12 @@ pub type AccountIdOf = ::AccountId; pub type PricingParametersOf = PricingParametersRecord>; /// Ensure origin location is a sibling -fn ensure_sibling(location: &MultiLocation) -> Result<(ParaId, H256), DispatchError> +fn ensure_sibling(location: &Location) -> Result<(ParaId, H256), DispatchError> where T: Config, { - match location { - MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } => { + match location.unpack() { + (1, [Parachain(para_id)]) => { let agent_id = agent_id_of::(location)?; Ok(((*para_id).into(), agent_id)) }, @@ -101,7 +101,7 @@ where } /// Hash the location to produce an agent id -fn agent_id_of(location: &MultiLocation) -> Result { +fn agent_id_of(location: &Location) -> Result { T::AgentIdOf::convert_location(location).ok_or(Error::::LocationConversionFailed.into()) } @@ -110,7 +110,7 @@ pub trait BenchmarkHelper where O: OriginTrait, { - fn make_xcm_origin(location: MultiLocation) -> O; + fn make_xcm_origin(location: Location) -> O; } /// Whether a fee should be withdrawn to an account for sending an outbound message @@ -145,9 +145,9 @@ pub mod pallet { type OutboundQueue: SendMessage>; /// Origin check for XCM locations that can create agents - type SiblingOrigin: EnsureOrigin; + type SiblingOrigin: EnsureOrigin; - /// Converts MultiLocation to AgentId + /// Converts Location to AgentId type AgentIdOf: ConvertLocation; /// Token reserved for control operations @@ -180,7 +180,7 @@ pub mod pallet { }, /// An CreateAgent message was sent to the Gateway CreateAgent { - location: Box, + location: Box, agent_id: AgentId, }, /// An CreateChannel message was sent to the Gateway @@ -299,7 +299,7 @@ pub mod pallet { /// /// Fee required: No /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` #[pallet::call_index(1)] #[pallet::weight((T::WeightInfo::set_operating_mode(), DispatchClass::Operational))] pub fn set_operating_mode(origin: OriginFor, mode: OperatingMode) -> DispatchResult { @@ -342,11 +342,11 @@ pub mod pallet { /// /// Fee required: Yes /// - /// - `origin`: Must be `MultiLocation` of a sibling parachain + /// - `origin`: Must be `Location` of a sibling parachain #[pallet::call_index(3)] #[pallet::weight(T::WeightInfo::create_agent())] pub fn create_agent(origin: OriginFor) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is some consensus system on a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -375,12 +375,12 @@ pub mod pallet { /// /// The message is sent over the bridge on BridgeHub's own channel to the Gateway. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` /// - `mode`: Initial operating mode of the channel #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::create_channel())] pub fn create_channel(origin: OriginFor, mode: OperatingMode) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -407,12 +407,12 @@ pub mod pallet { /// /// A partial fee will be charged for local processing only. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` /// - `mode`: Initial operating mode of the channel #[pallet::call_index(5)] #[pallet::weight(T::WeightInfo::update_channel())] pub fn update_channel(origin: OriginFor, mode: OperatingMode) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is a sibling parachain let (para_id, _) = ensure_sibling::(&origin_location)?; @@ -461,7 +461,7 @@ pub mod pallet { /// /// A partial fee will be charged for local processing only. /// - /// - `origin`: Must be `MultiLocation` + /// - `origin`: Must be `Location` #[pallet::call_index(7)] #[pallet::weight(T::WeightInfo::transfer_native_from_agent())] pub fn transfer_native_from_agent( @@ -469,7 +469,7 @@ pub mod pallet { recipient: H160, amount: u128, ) -> DispatchResult { - let origin_location: MultiLocation = T::SiblingOrigin::ensure_origin(origin)?; + let origin_location: Location = T::SiblingOrigin::ensure_origin(origin)?; // Ensure that origin location is some consensus system on a sibling parachain let (para_id, agent_id) = ensure_sibling::(&origin_location)?; @@ -501,14 +501,14 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_transfer_native_from_agent())] pub fn force_transfer_native_from_agent( origin: OriginFor, - location: Box, + location: Box, recipient: H160, amount: u128, ) -> DispatchResult { ensure_root(origin)?; // Ensure that location is some consensus system on a sibling parachain - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|_| Error::::UnsupportedLocationVersion)?; let (_, agent_id) = ensure_sibling::(&location).map_err(|_| Error::::InvalidLocation)?; @@ -621,8 +621,8 @@ pub mod pallet { /// Initializes agents and channels. pub fn initialize(para_id: ParaId, asset_hub_para_id: ParaId) -> Result<(), DispatchError> { // Asset Hub - let asset_hub_location: MultiLocation = - ParentThen(X1(Parachain(asset_hub_para_id.into()))).into(); + let asset_hub_location: Location = + ParentThen(Parachain(asset_hub_para_id.into()).into()).into(); let asset_hub_agent_id = agent_id_of::(&asset_hub_location)?; let asset_hub_channel_id: ChannelId = asset_hub_para_id.into(); Agents::::insert(asset_hub_agent_id, ()); @@ -632,7 +632,7 @@ pub mod pallet { ); // Governance channels - let bridge_hub_agent_id = agent_id_of::(&MultiLocation::here())?; + let bridge_hub_agent_id = agent_id_of::(&Location::here())?; // Agent for BridgeHub Agents::::insert(bridge_hub_agent_id, ()); diff --git a/bridges/snowbridge/parachain/pallets/system/src/mock.rs b/bridges/snowbridge/parachain/pallets/system/src/mock.rs index bb9bae6b56d..bc229578132 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/mock.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/mock.rs @@ -49,22 +49,22 @@ mod pallet_xcm_origin { // Insert this custom Origin into the aggregate RuntimeOrigin #[pallet::origin] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct Origin(pub MultiLocation); + pub struct Origin(pub Location); - impl From for Origin { - fn from(location: MultiLocation) -> Origin { + impl From for Origin { + fn from(location: Location) -> Origin { Origin(location) } } - /// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and + /// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and /// filter the contained location pub struct EnsureXcm(PhantomData); - impl, F: Contains> EnsureOrigin for EnsureXcm + impl, F: Contains> EnsureOrigin for EnsureXcm where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = Location; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { @@ -77,7 +77,7 @@ mod pallet_xcm_origin { #[cfg(feature = "runtime-benchmarks")] fn try_successful_origin() -> Result { - Ok(O::from(Origin(MultiLocation { parents: 1, interior: X1(Parachain(2000)) }))) + Ok(O::from(Origin(Location::new(1, [Parachain(2000)])))) } } } @@ -186,9 +186,9 @@ parameter_types! { pub const SS58Prefix: u8 = 42; pub const AnyNetwork: Option = None; pub const RelayNetwork: Option = Some(NetworkId::Kusama); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)); + pub const RelayLocation: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)].into(); } pub const DOT: u128 = 10_000_000_000; @@ -211,7 +211,7 @@ parameter_types! { #[cfg(feature = "runtime-benchmarks")] impl BenchmarkHelper for () { - fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { RuntimeOrigin::from(pallet_xcm_origin::Origin(location)) } } @@ -260,11 +260,11 @@ pub fn new_test_ext(genesis_build: bool) -> sp_io::TestExternalities { // Test helpers -pub fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { +pub fn make_xcm_origin(location: Location) -> RuntimeOrigin { pallet_xcm_origin::Origin(location).into() } -pub fn make_agent_id(location: MultiLocation) -> AgentId { +pub fn make_agent_id(location: Location) -> AgentId { ::AgentIdOf::convert_location(&location) .expect("convert location") } diff --git a/bridges/snowbridge/parachain/pallets/system/src/tests.rs b/bridges/snowbridge/parachain/pallets/system/src/tests.rs index e07481c1e33..8b417c258ea 100644 --- a/bridges/snowbridge/parachain/pallets/system/src/tests.rs +++ b/bridges/snowbridge/parachain/pallets/system/src/tests.rs @@ -11,8 +11,8 @@ use sp_runtime::{AccountId32, DispatchError::BadOrigin, TokenError}; fn create_agent() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; - let agent_id = make_agent_id(origin_location); + let origin_location = Location::new(1, [Parachain(origin_para_id)]); + let agent_id = make_agent_id(origin_location.clone()); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); // fund sovereign account of origin @@ -30,7 +30,7 @@ fn create_agent() { #[test] fn test_agent_for_here() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation::here(); + let origin_location = Location::here(); let agent_id = make_agent_id(origin_location); assert_eq!( agent_id, @@ -42,7 +42,7 @@ fn test_agent_for_here() { #[test] fn create_agent_fails_on_funds_unavailable() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; + let origin_location = Location::new(1, [Parachain(2000)]); let origin = make_xcm_origin(origin_location); // Reset balance of sovereign_account to zero so to trigger the FundsUnavailable error let sovereign_account = sibling_sovereign_account::(2000.into()); @@ -56,19 +56,16 @@ fn create_agent_bad_origin() { new_test_ext(true).execute_with(|| { // relay chain location not allowed assert_noop!( - EthereumSystem::create_agent(make_xcm_origin(MultiLocation { - parents: 1, - interior: Here, - })), + EthereumSystem::create_agent(make_xcm_origin(Location::new(1, [],))), BadOrigin, ); // local account location not allowed assert_noop!( - EthereumSystem::create_agent(make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - })), + EthereumSystem::create_agent(make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + ))), BadOrigin, ); @@ -243,7 +240,7 @@ fn set_token_transfer_fees_invalid() { fn create_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -259,7 +256,7 @@ fn create_channel() { fn create_channel_fail_already_exists() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -282,7 +279,7 @@ fn create_channel_bad_origin() { // relay chain location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { parents: 1, interior: Here }), + make_xcm_origin(Location::new(1, [])), OperatingMode::Normal, ), BadOrigin, @@ -291,13 +288,10 @@ fn create_channel_bad_origin() { // child of sibling location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - }), + make_xcm_origin(Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), OperatingMode::Normal, ), BadOrigin, @@ -306,10 +300,10 @@ fn create_channel_bad_origin() { // local account location not allowed assert_noop!( EthereumSystem::create_channel( - make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - }), + make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), OperatingMode::Normal, ), BadOrigin, @@ -333,7 +327,7 @@ fn create_channel_bad_origin() { fn update_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -359,23 +353,17 @@ fn update_channel_bad_origin() { // relay chain location not allowed assert_noop!( - EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { parents: 1, interior: Here }), - mode, - ), + EthereumSystem::update_channel(make_xcm_origin(Location::new(1, [])), mode,), BadOrigin, ); // child of sibling location not allowed assert_noop!( EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - }), + make_xcm_origin(Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), mode, ), BadOrigin, @@ -384,10 +372,10 @@ fn update_channel_bad_origin() { // local account location not allowed assert_noop!( EthereumSystem::update_channel( - make_xcm_origin(MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [67u8; 32] }), - }), + make_xcm_origin(Location::new( + 0, + [Junction::AccountId32 { network: None, id: [67u8; 32] }], + )), mode, ), BadOrigin, @@ -407,7 +395,7 @@ fn update_channel_bad_origin() { #[test] fn update_channel_fails_not_exist() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; + let origin_location = Location::new(1, [Parachain(2000)]); let origin = make_xcm_origin(origin_location); // Now try to update it @@ -422,7 +410,7 @@ fn update_channel_fails_not_exist() { fn force_update_channel() { new_test_ext(true).execute_with(|| { let origin_para_id = 2000; - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(origin_para_id)) }; + let origin_location = Location::new(1, [Parachain(origin_para_id)]); let sovereign_account = sibling_sovereign_account::(origin_para_id.into()); let origin = make_xcm_origin(origin_location); @@ -468,8 +456,8 @@ fn force_update_channel_bad_origin() { #[test] fn transfer_native_from_agent() { new_test_ext(true).execute_with(|| { - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; - let origin = make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(2000)]); + let origin = make_xcm_origin(origin_location.clone()); let recipient: H160 = [27u8; 20].into(); let amount = 103435; @@ -477,7 +465,7 @@ fn transfer_native_from_agent() { assert_ok!(EthereumSystem::create_agent(origin.clone())); assert_ok!(EthereumSystem::create_channel(origin, OperatingMode::Normal)); - let origin = make_xcm_origin(origin_location); + let origin = make_xcm_origin(origin_location.clone()); assert_ok!(EthereumSystem::transfer_native_from_agent(origin, recipient, amount),); System::assert_last_event(RuntimeEvent::EthereumSystem( @@ -494,13 +482,13 @@ fn transfer_native_from_agent() { fn force_transfer_native_from_agent() { new_test_ext(true).execute_with(|| { let origin = RuntimeOrigin::root(); - let location = MultiLocation { parents: 1, interior: X1(Parachain(2000)) }; - let versioned_location: Box = Box::new(location.into()); + let location = Location::new(1, [Parachain(2000)]); + let versioned_location: Box = Box::new(location.clone().into()); let recipient: H160 = [27u8; 20].into(); let amount = 103435; // First create the agent - Agents::::insert(make_agent_id(location), ()); + Agents::::insert(make_agent_id(location.clone()), ()); assert_ok!(EthereumSystem::force_transfer_native_from_agent( origin, @@ -530,13 +518,10 @@ fn force_transfer_native_from_agent_bad_origin() { EthereumSystem::force_transfer_native_from_agent( RuntimeOrigin::signed([14; 32].into()), Box::new( - MultiLocation { - parents: 1, - interior: X2( - Parachain(2000), - Junction::AccountId32 { network: None, id: [67u8; 32] } - ), - } + Location::new( + 1, + [Parachain(2000), Junction::AccountId32 { network: None, id: [67u8; 32] }], + ) .into() ), recipient, @@ -571,8 +556,8 @@ fn check_sibling_sovereign_account() { fn charge_fee_for_create_agent() { new_test_ext(true).execute_with(|| { let para_id: u32 = TestParaId::get(); - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(para_id)) }; - let origin = make_xcm_origin(origin_location); + let origin_location = Location::new(1, [Parachain(para_id)]); + let origin = make_xcm_origin(origin_location.clone()); let sovereign_account = sibling_sovereign_account::(para_id.into()); let (_, agent_id) = ensure_sibling::(&origin_location).unwrap(); @@ -605,10 +590,10 @@ fn charge_fee_for_create_agent() { fn charge_fee_for_transfer_native_from_agent() { new_test_ext(true).execute_with(|| { let para_id: u32 = TestParaId::get(); - let origin_location = MultiLocation { parents: 1, interior: X1(Parachain(para_id)) }; + let origin_location = Location::new(1, [Parachain(para_id)]); let recipient: H160 = [27u8; 20].into(); let amount = 103435; - let origin = make_xcm_origin(origin_location); + let origin = make_xcm_origin(origin_location.clone()); let (_, agent_id) = ensure_sibling::(&origin_location).unwrap(); let sovereign_account = sibling_sovereign_account::(para_id.into()); diff --git a/bridges/snowbridge/parachain/primitives/core/src/lib.rs b/bridges/snowbridge/parachain/primitives/core/src/lib.rs index ecbc3bb365f..a464557a72b 100644 --- a/bridges/snowbridge/parachain/primitives/core/src/lib.rs +++ b/bridges/snowbridge/parachain/primitives/core/src/lib.rs @@ -28,11 +28,7 @@ use sp_core::H256; use sp_io::hashing::keccak_256; use sp_runtime::{traits::AccountIdConversion, RuntimeDebug}; use sp_std::prelude::*; -use xcm::prelude::{ - Junction::Parachain, - Junctions::{Here, X1}, - MultiLocation, -}; +use xcm::prelude::{Junction::Parachain, Location}; use xcm_builder::{DescribeAllTerminal, DescribeFamily, DescribeLocation, HashedDescription}; /// The ID of an agent contract @@ -53,9 +49,9 @@ pub fn sibling_sovereign_account_raw(para_id: ParaId) -> [u8; 32] { } pub struct AllowSiblingsOnly; -impl Contains for AllowSiblingsOnly { - fn contains(location: &MultiLocation) -> bool { - matches!(location, MultiLocation { parents: 1, interior: X1(Parachain(_)) }) +impl Contains for AllowSiblingsOnly { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(_)])) } } @@ -161,14 +157,14 @@ pub const SECONDARY_GOVERNANCE_CHANNEL: ChannelId = pub struct DescribeHere; impl DescribeLocation for DescribeHere { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, l.interior) { - (0, Here) => Some(Vec::::new().encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, []) => Some(Vec::::new().encode()), _ => None, } } } -/// Creates an AgentId from a MultiLocation. An AgentId is a unique mapping to a Agent contract on -/// Ethereum which acts as the sovereign account for the MultiLocation. +/// Creates an AgentId from a Location. An AgentId is a unique mapping to a Agent contract on +/// Ethereum which acts as the sovereign account for the Location. pub type AgentIdOf = HashedDescription)>; diff --git a/bridges/snowbridge/parachain/primitives/core/tests/mod.rs b/bridges/snowbridge/parachain/primitives/core/tests/mod.rs index 2da5d2df182..c91063a8148 100644 --- a/bridges/snowbridge/parachain/primitives/core/tests/mod.rs +++ b/bridges/snowbridge/parachain/primitives/core/tests/mod.rs @@ -2,12 +2,12 @@ mod tests { use frame_support::traits::Contains; use snowbridge_core::AllowSiblingsOnly; - use xcm::prelude::{Junction::Parachain, Junctions::X1, MultiLocation}; + use xcm::prelude::{Junction::Parachain, Location}; #[test] fn allow_siblings_predicate_only_allows_siblings() { - let sibling = MultiLocation::new(1, X1(Parachain(1000))); - let child = MultiLocation::new(0, X1(Parachain(1000))); + let sibling = Location::new(1, [Parachain(1000)]); + let child = Location::new(0, [Parachain(1000)]); assert!(AllowSiblingsOnly::contains(&sibling), "Sibling returns true."); assert!(!AllowSiblingsOnly::contains(&child), "Child returns false."); } diff --git a/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs b/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs index a07e0eae5d7..c20554c6d18 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/inbound/mod.rs @@ -161,13 +161,13 @@ where { fn convert_register_token(chain_id: u64, token: H160, fee: u128) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; - let xcm_fee: MultiAsset = (MultiLocation::parent(), fee).into(); - let deposit: MultiAsset = (MultiLocation::parent(), CreateAssetDeposit::get()).into(); + let xcm_fee: Asset = (Location::parent(), fee).into(); + let deposit: Asset = (Location::parent(), CreateAssetDeposit::get()).into(); let total_amount = fee + CreateAssetDeposit::get(); - let total: MultiAsset = (MultiLocation::parent(), total_amount).into(); + let total: Asset = (Location::parent(), total_amount).into(); - let bridge_location: MultiLocation = (Parent, Parent, GlobalConsensus(network)).into(); + let bridge_location: Location = (Parent, Parent, GlobalConsensus(network)).into(); let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); let asset_id = Self::convert_token_address(network, token); @@ -182,7 +182,7 @@ where // Fund the snowbridge sovereign with the required deposit for creation. DepositAsset { assets: Definite(deposit.into()), beneficiary: bridge_location }, // Only our inbound-queue pallet is allowed to invoke `UniversalOrigin` - DescendOrigin(X1(PalletInstance(inbound_queue_pallet_index))), + DescendOrigin(PalletInstance(inbound_queue_pallet_index).into()), // Change origin to the bridge. UniversalOrigin(GlobalConsensus(network)), // Call create_asset on foreign assets pallet. @@ -216,40 +216,37 @@ where asset_hub_fee: u128, ) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; - let asset_hub_fee_asset: MultiAsset = (MultiLocation::parent(), asset_hub_fee).into(); - let asset: MultiAsset = (Self::convert_token_address(network, token), amount).into(); + let asset_hub_fee_asset: Asset = (Location::parent(), asset_hub_fee).into(); + let asset: Asset = (Self::convert_token_address(network, token), amount).into(); let (dest_para_id, beneficiary, dest_para_fee) = match destination { // Final destination is a 32-byte account on AssetHub - Destination::AccountId32 { id } => ( - None, - MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id }) }, - 0, - ), + Destination::AccountId32 { id } => + (None, Location::new(0, [AccountId32 { network: None, id }]), 0), // Final destination is a 32-byte account on a sibling of AssetHub Destination::ForeignAccountId32 { para_id, id, fee } => ( Some(para_id), - MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id }) }, + Location::new(0, [AccountId32 { network: None, id }]), // Total fee needs to cover execution on AssetHub and Sibling fee, ), // Final destination is a 20-byte account on a sibling of AssetHub Destination::ForeignAccountId20 { para_id, id, fee } => ( Some(para_id), - MultiLocation { parents: 0, interior: X1(AccountKey20 { network: None, key: id }) }, + Location::new(0, [AccountKey20 { network: None, key: id }]), // Total fee needs to cover execution on AssetHub and Sibling fee, ), }; let total_fees = asset_hub_fee.saturating_add(dest_para_fee); - let total_fee_asset: MultiAsset = (MultiLocation::parent(), total_fees).into(); + let total_fee_asset: Asset = (Location::parent(), total_fees).into(); let inbound_queue_pallet_index = InboundQueuePalletInstance::get(); let mut instructions = vec![ ReceiveTeleportedAsset(total_fee_asset.into()), BuyExecution { fees: asset_hub_fee_asset, weight_limit: Unlimited }, - DescendOrigin(X1(PalletInstance(inbound_queue_pallet_index))), + DescendOrigin(PalletInstance(inbound_queue_pallet_index).into()), UniversalOrigin(GlobalConsensus(network)), ReserveAssetDeposited(asset.clone().into()), ClearOrigin, @@ -257,14 +254,13 @@ where match dest_para_id { Some(dest_para_id) => { - let dest_para_fee_asset: MultiAsset = - (MultiLocation::parent(), dest_para_fee).into(); + let dest_para_fee_asset: Asset = (Location::parent(), dest_para_fee).into(); instructions.extend(vec![ // Perform a deposit reserve to send to destination chain. DepositReserveAsset { assets: Definite(vec![dest_para_fee_asset.clone(), asset.clone()].into()), - dest: MultiLocation { parents: 1, interior: X1(Parachain(dest_para_id)) }, + dest: Location::new(1, [Parachain(dest_para_id)]), xcm: vec![ // Buy execution on target. BuyExecution { fees: dest_para_fee_asset, weight_limit: Unlimited }, @@ -286,15 +282,12 @@ where (instructions.into(), total_fees.into()) } - // Convert ERC20 token address to a Multilocation that can be understood by Assets Hub. - fn convert_token_address(network: NetworkId, token: H160) -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(network), - AccountKey20 { network: None, key: token.into() }, - ), - } + // Convert ERC20 token address to a location that can be understood by Assets Hub. + fn convert_token_address(network: NetworkId, token: H160) -> Location { + Location::new( + 2, + [GlobalConsensus(network), AccountKey20 { network: None, key: token.into() }], + ) } } @@ -303,12 +296,11 @@ impl ConvertLocation for GlobalConsensusEthereumConvertsFo where AccountId: From<[u8; 32]> + Clone, { - fn convert_location(location: &MultiLocation) -> Option { - if let MultiLocation { interior: X1(GlobalConsensus(Ethereum { chain_id })), .. } = location - { - Some(Self::from_chain_id(chain_id).into()) - } else { - None + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (_, [GlobalConsensus(Ethereum { chain_id })]) => + Some(Self::from_chain_id(chain_id).into()), + _ => None, } } } diff --git a/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs b/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs index 8c96c13cf22..c46b88a84a4 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/inbound/tests.rs @@ -2,7 +2,7 @@ use super::GlobalConsensusEthereumConvertsFor; use crate::inbound::CallIndex; use frame_support::parameter_types; use hex_literal::hex; -use xcm::v3::prelude::*; +use xcm::v4::prelude::*; use xcm_executor::traits::ConvertLocation; const NETWORK: NetworkId = Ethereum { chain_id: 11155111 }; @@ -20,7 +20,7 @@ parameter_types! { fn test_contract_location_with_network_converts_successfully() { let expected_account: [u8; 32] = hex!("ce796ae65569a670d0c1cc1ac12515a3ce21b5fbf729d63d7b289baad070139d"); - let contract_location = MultiLocation { parents: 2, interior: X1(GlobalConsensus(NETWORK)) }; + let contract_location = Location::new(2, [GlobalConsensus(NETWORK)]); let account = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::convert_location(&contract_location) @@ -31,8 +31,7 @@ fn test_contract_location_with_network_converts_successfully() { #[test] fn test_contract_location_with_incorrect_location_fails_convert() { - let contract_location = - MultiLocation { parents: 2, interior: X2(GlobalConsensus(Polkadot), Parachain(1000)) }; + let contract_location = Location::new(2, [GlobalConsensus(Polkadot), Parachain(1000)]); assert_eq!( GlobalConsensusEthereumConvertsFor::<[u8; 32]>::convert_location(&contract_location), diff --git a/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs b/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs index c7f2f440834..21823992db7 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/outbound/mod.rs @@ -16,7 +16,7 @@ use snowbridge_core::{ }; use sp_core::{H160, H256}; use sp_std::{iter::Peekable, marker::PhantomData, prelude::*}; -use xcm::v3::prelude::*; +use xcm::v4::prelude::*; use xcm_executor::traits::{ConvertLocation, ExportXcm}; pub struct EthereumBlobExporter< @@ -29,7 +29,7 @@ pub struct EthereumBlobExporter< impl ExportXcm for EthereumBlobExporter where - UniversalLocation: Get, + UniversalLocation: Get, EthereumNetwork: Get, OutboundQueue: SendMessage, AgentHashedDescription: ConvertLocation, @@ -39,8 +39,8 @@ where fn validate( network: NetworkId, _channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let expected_network = EthereumNetwork::get(); @@ -74,8 +74,8 @@ where return Err(SendError::NotApplicable) } - let para_id = match local_sub { - X1(Parachain(para_id)) => para_id, + let para_id = match local_sub.as_slice() { + [Parachain(para_id)] => *para_id, _ => { log::error!(target: "xcm::ethereum_blob_exporter", "could not get parachain id from universal source '{local_sub:?}'."); return Err(SendError::MissingArgument) @@ -93,7 +93,7 @@ where SendError::Unroutable })?; - let source_location: MultiLocation = MultiLocation { parents: 1, interior: local_sub }; + let source_location = Location::new(1, local_sub.clone()); let agent_id = match AgentHashedDescription::convert_location(&source_location) { Some(id) => id, None => { @@ -116,8 +116,8 @@ where SendError::Unroutable })?; - // convert fee to MultiAsset - let fee = MultiAsset::from((MultiLocation::parent(), fee.total())).into(); + // convert fee to Asset + let fee = Asset::from((Location::parent(), fee.total())).into(); Ok(((ticket.encode(), message_id), fee)) } @@ -216,8 +216,8 @@ impl<'a, Call> XcmConverter<'a, Call> { // assert that the beneficiary is AccountKey20. let recipient = match_expression!( - beneficiary, - MultiLocation { parents: 0, interior: X1(AccountKey20 { network, key }) } + beneficiary.unpack(), + (0, [AccountKey20 { network, key }]) if self.network_matches(network), H160(*key) ) @@ -245,14 +245,15 @@ impl<'a, Call> XcmConverter<'a, Call> { } } - let (token, amount) = match_expression!( - reserve_asset, - MultiAsset { - id: Concrete(MultiLocation { parents: 0, interior: X1(AccountKey20 { network , key })}), - fun: Fungible(amount) - } if self.network_matches(network), - (H160(*key), *amount) - ) + let (token, amount) = match reserve_asset { + Asset { id: AssetId(inner_location), fun: Fungible(amount) } => + match inner_location.unpack() { + (0, [AccountKey20 { network, key }]) if self.network_matches(network) => + Some((H160(*key), *amount)), + _ => None, + }, + _ => None, + } .ok_or(AssetResolutionFailed)?; // transfer amount must be greater than 0. diff --git a/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs b/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs index 153d934c390..111243bb45a 100644 --- a/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs +++ b/bridges/snowbridge/parachain/primitives/router/src/outbound/tests.rs @@ -11,7 +11,7 @@ use super::*; parameter_types! { const MaxMessageSize: u32 = u32::MAX; const RelayNetwork: NetworkId = Polkadot; - const UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(1013)); + UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(1013)].into(); const BridgedNetwork: NetworkId = Ethereum{ chain_id: 1 }; const NonBridgedNetwork: NetworkId = Ethereum{ chain_id: 2 }; } @@ -61,8 +61,8 @@ impl SendMessageFeeProvider for MockErrOutboundQueue { fn exporter_validate_with_unknown_network_yields_not_applicable() { let network = Ethereum { chain_id: 1337 }; let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = None; + let mut universal_source: Option = None; + let mut destination: Option = None; let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -80,8 +80,8 @@ fn exporter_validate_with_unknown_network_yields_not_applicable() { fn exporter_validate_with_invalid_destination_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = None; + let mut universal_source: Option = None; + let mut destination: Option = None; let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -99,10 +99,11 @@ fn exporter_validate_with_invalid_destination_yields_missing_argument() { fn exporter_validate_with_x8_destination_yields_not_applicable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = Some(X8( - OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, - )); + let mut universal_source: Option = None; + let mut destination: Option = Some( + [OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild] + .into(), + ); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -120,8 +121,8 @@ fn exporter_validate_with_x8_destination_yields_not_applicable() { fn exporter_validate_without_universal_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = None; - let mut destination: Option = Here.into(); + let mut universal_source: Option = None; + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -139,8 +140,8 @@ fn exporter_validate_without_universal_source_yields_missing_argument() { fn exporter_validate_without_global_universal_location_yields_unroutable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Here.into(); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Here.into(); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -158,8 +159,8 @@ fn exporter_validate_without_global_universal_location_yields_unroutable() { fn exporter_validate_without_global_bridge_location_yields_not_applicable() { let network = NonBridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Here.into(); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Here.into(); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -177,9 +178,9 @@ fn exporter_validate_without_global_bridge_location_yields_not_applicable() { fn exporter_validate_with_remote_universal_source_yields_not_applicable() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X2(GlobalConsensus(Kusama), Parachain(1000))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Kusama), Parachain(1000)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -197,8 +198,8 @@ fn exporter_validate_with_remote_universal_source_yields_not_applicable() { fn exporter_validate_without_para_id_in_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = Some(X1(GlobalConsensus(Polkadot))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = Some(GlobalConsensus(Polkadot).into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -216,9 +217,9 @@ fn exporter_validate_without_para_id_in_source_yields_missing_argument() { fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X3(GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(12))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000), PalletInstance(12)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -236,9 +237,9 @@ fn exporter_validate_complex_para_id_in_source_yields_missing_argument() { fn exporter_validate_without_xcm_message_yields_missing_argument() { let network = BridgedNetwork::get(); let channel: u32 = 0; - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); - let mut destination: Option = Here.into(); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); + let mut destination: Option = Here.into(); let mut message: Option> = None; let result = EthereumBlobExporter::< @@ -255,23 +256,23 @@ fn exporter_validate_without_xcm_message_yields_missing_argument() { #[test] fn exporter_validate_with_max_target_fee_yields_unroutable() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); let channel: u32 = 0; - let fee = MultiAsset { id: Concrete(Here.into()), fun: Fungible(1000) }; - let fees: MultiAssets = vec![fee.clone()].into(); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let fee = Asset { id: AssetId(Here.into()), fun: Fungible(1000) }; + let fees: Assets = vec![fee.clone()].into(); + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let mut message: Option> = Some( vec![ @@ -280,7 +281,7 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { WithdrawAsset(assets), DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: Some(network), key: beneficiary_address }) + beneficiary: AccountKey20 { network: Some(network), key: beneficiary_address } .into(), }, SetTopic([0; 32]), @@ -303,14 +304,14 @@ fn exporter_validate_with_max_target_fee_yields_unroutable() { #[test] fn exporter_validate_with_unparsable_xcm_yields_unroutable() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let channel: u32 = 0; - let fee = MultiAsset { id: Concrete(Here.into()), fun: Fungible(1000) }; - let fees: MultiAssets = vec![fee.clone()].into(); + let fee = Asset { id: AssetId(Here.into()), fun: Fungible(1000) }; + let fees: Assets = vec![fee.clone()].into(); let mut message: Option> = Some(vec![WithdrawAsset(fees), BuyExecution { fees: fee, weight_limit: Unlimited }].into()); @@ -330,22 +331,22 @@ fn exporter_validate_with_unparsable_xcm_yields_unroutable() { #[test] fn exporter_validate_xcm_success_case_1() { let network = BridgedNetwork::get(); - let mut destination: Option = Here.into(); + let mut destination: Option = Here.into(); - let mut universal_source: Option = - Some(X2(GlobalConsensus(Polkadot), Parachain(1000))); + let mut universal_source: Option = + Some([GlobalConsensus(Polkadot), Parachain(1000)].into()); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); let channel: u32 = 0; - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); let fee = assets.clone().get(0).unwrap().clone(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let mut message: Option> = Some( vec![ @@ -354,7 +355,7 @@ fn exporter_validate_xcm_success_case_1() { BuyExecution { fees: fee, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -391,12 +392,12 @@ fn xcm_converter_convert_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -404,7 +405,7 @@ fn xcm_converter_convert_success() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -426,18 +427,18 @@ fn xcm_converter_convert_without_buy_execution_yields_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -459,12 +460,12 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(All); + let filter: AssetFilter = Wild(All); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -472,7 +473,7 @@ fn xcm_converter_convert_with_wildcard_all_asset_filter_succeeds() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -494,13 +495,12 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(500) }; + let asset_location: Location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = Asset { id: AssetId(asset_location.clone()), fun: Fungible(500) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -508,7 +508,7 @@ fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -530,19 +530,19 @@ fn xcm_converter_convert_without_set_topic_yields_set_topic_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, ClearTopic, ] @@ -557,8 +557,8 @@ fn xcm_converter_convert_with_partial_message_yields_unexpected_end_of_xcm() { let network = BridgedNetwork::get(); let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); @@ -576,16 +576,13 @@ fn xcm_converter_with_different_fee_asset_fails() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { - id: Concrete(MultiLocation { parents: 0, interior: Here }), - fun: Fungible(1000), - }; + let asset_location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = + Asset { id: AssetId(Location { parents: 0, interior: Here }), fun: Fungible(1000) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -593,7 +590,7 @@ fn xcm_converter_with_different_fee_asset_fails() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -610,13 +607,12 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); - let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(1001) }; + let asset_location: Location = [AccountKey20 { network: None, key: token_address }].into(); + let fee_asset = Asset { id: AssetId(asset_location.clone()), fun: Fungible(1001) }; - let assets: MultiAssets = - vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + let assets: Assets = vec![Asset { id: AssetId(asset_location), fun: Fungible(1000) }].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -624,7 +620,7 @@ fn xcm_converter_with_fees_greater_than_reserve_fails() { BuyExecution { fees: fee_asset, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -653,12 +649,12 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -666,7 +662,7 @@ fn xcm_converter_convert_with_extra_instructions_yields_end_of_xcm_message_expec BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ClearError, @@ -685,19 +681,19 @@ fn xcm_converter_convert_without_withdraw_asset_yields_withdraw_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId([AccountKey20 { network: None, key: token_address }].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ ClearOrigin, BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -714,8 +710,8 @@ fn xcm_converter_convert_without_withdraw_asset_yields_deposit_expected() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); @@ -741,11 +737,11 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![].into(); - let filter: MultiAssetFilter = assets.clone().into(); + let assets: Assets = vec![].into(); + let filter: AssetFilter = assets.clone().into(); - let fee = MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let fee = Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }; @@ -755,7 +751,7 @@ fn xcm_converter_convert_without_assets_yields_no_reserve_assets() { BuyExecution { fees: fee, weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -774,18 +770,18 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { let token_address_2: [u8; 20] = hex!("1100000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![ - MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address_1 }).into()), + let assets: Assets = vec![ + Asset { + id: AssetId(AccountKey20 { network: None, key: token_address_1 }.into()), fun: Fungible(1000), }, - MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address_2 }).into()), + Asset { + id: AssetId(AccountKey20 { network: None, key: token_address_2 }.into()), fun: Fungible(500), }, ] .into(); - let filter: MultiAssetFilter = assets.clone().into(); + let filter: AssetFilter = assets.clone().into(); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -793,7 +789,7 @@ fn xcm_converter_convert_with_two_assets_yields_too_many_assets() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -811,12 +807,12 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(0)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(0)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -824,7 +820,7 @@ fn xcm_converter_convert_without_consuming_filter_yields_filter_does_not_consume BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -842,12 +838,12 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(0), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -855,7 +851,7 @@ fn xcm_converter_convert_with_zero_amount_asset_yields_zero_asset_transfer() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -872,12 +868,12 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X3(GlobalConsensus(Polkadot), Parachain(1000), GeneralIndex(0)).into()), + let assets: Assets = vec![Asset { + id: AssetId([GlobalConsensus(Polkadot), Parachain(1000), GeneralIndex(0)].into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -885,7 +881,7 @@ fn xcm_converter_convert_non_ethereum_asset_yields_asset_resolution_failed() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -903,14 +899,14 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete( - X1(AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: token_address }).into(), + let assets: Assets = vec![Asset { + id: AssetId( + AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: token_address }.into(), ), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -918,7 +914,7 @@ fn xcm_converter_convert_non_ethereum_chain_asset_yields_asset_resolution_failed BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -936,14 +932,14 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete( - X1(AccountKey20 { network: Some(NonBridgedNetwork::get()), key: token_address }).into(), + let assets: Assets = vec![Asset { + id: AssetId( + [AccountKey20 { network: Some(NonBridgedNetwork::get()), key: token_address }].into(), ), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -951,7 +947,7 @@ fn xcm_converter_convert_non_ethereum_chain_yields_asset_resolution_failed() { BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + beneficiary: AccountKey20 { network: None, key: beneficiary_address }.into(), }, SetTopic([0; 32]), ] @@ -971,23 +967,23 @@ fn xcm_converter_convert_with_non_ethereum_beneficiary_yields_beneficiary_resolu let beneficiary_address: [u8; 32] = hex!("2000000000000000000000000000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), ClearOrigin, BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X3( + beneficiary: [ GlobalConsensus(Polkadot), Parachain(1000), AccountId32 { network: Some(Polkadot), id: beneficiary_address }, - ) + ] .into(), }, SetTopic([0; 32]), @@ -1007,12 +1003,12 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); - let assets: MultiAssets = vec![MultiAsset { - id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + let assets: Assets = vec![Asset { + id: AssetId(AccountKey20 { network: None, key: token_address }.into()), fun: Fungible(1000), }] .into(); - let filter: MultiAssetFilter = Wild(WildMultiAsset::AllCounted(1)); + let filter: AssetFilter = Wild(WildAsset::AllCounted(1)); let message: Xcm<()> = vec![ WithdrawAsset(assets.clone()), @@ -1020,10 +1016,10 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, DepositAsset { assets: filter, - beneficiary: X1(AccountKey20 { + beneficiary: AccountKey20 { network: Some(Ethereum { chain_id: 2 }), key: beneficiary_address, - }) + } .into(), }, SetTopic([0; 32]), @@ -1037,14 +1033,13 @@ fn xcm_converter_convert_with_non_ethereum_chain_beneficiary_yields_beneficiary_ #[test] fn test_describe_asset_hub() { - let legacy_location: MultiLocation = - MultiLocation { parents: 0, interior: X1(Parachain(1000)) }; + let legacy_location: Location = Location::new(0, [Parachain(1000)]); let legacy_agent_id = AgentIdOf::convert_location(&legacy_location).unwrap(); assert_eq!( legacy_agent_id, hex!("72456f48efed08af20e5b317abf8648ac66e86bb90a411d9b0b713f7364b75b4").into() ); - let location: MultiLocation = MultiLocation { parents: 1, interior: X1(Parachain(1000)) }; + let location: Location = Location::new(1, [Parachain(1000)]); let agent_id = AgentIdOf::convert_location(&location).unwrap(); assert_eq!( agent_id, @@ -1054,7 +1049,7 @@ fn test_describe_asset_hub() { #[test] fn test_describe_here() { - let location: MultiLocation = MultiLocation { parents: 0, interior: Here }; + let location: Location = Location::new(0, []); let agent_id = AgentIdOf::convert_location(&location).unwrap(); assert_eq!( agent_id, diff --git a/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs b/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs index b7f54d262bb..1a9b704f356 100644 --- a/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs +++ b/bridges/snowbridge/parachain/runtime/runtime-common/src/lib.rs @@ -46,43 +46,38 @@ impl where Balance: BaseArithmetic + Unsigned + Copy + From + Into, AccountId: Clone + Into<[u8; 32]> + From<[u8; 32]>, - FeeAssetLocation: Get, + FeeAssetLocation: Get, EthereumNetwork: Get, AssetTransactor: TransactAsset, FeeProvider: SendMessageFeeProvider, { - fn handle_fee( - fees: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fees: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets { let token_location = FeeAssetLocation::get(); // Check the reason to see if this export is for snowbridge. if !matches!( reason, - FeeReason::Export { network: bridged_network, destination } - if bridged_network == EthereumNetwork::get() && destination == Here + FeeReason::Export { network: bridged_network, ref destination } + if bridged_network == EthereumNetwork::get() && destination == &Here ) { return fees } // Get the parachain sovereign from the `context`. - let para_sovereign = if let Some(XcmContext { - origin: Some(MultiLocation { parents: 1, interior }), - .. - }) = context - { - if let Some(Parachain(sibling_para_id)) = interior.first() { - let account: AccountId = - sibling_sovereign_account_raw((*sibling_para_id).into()).into(); - account + let para_sovereign = + if let Some(XcmContext { origin: Some(Location { parents: 1, interior }), .. }) = + context + { + if let Some(Parachain(sibling_para_id)) = interior.first() { + let account: AccountId = + sibling_sovereign_account_raw((*sibling_para_id).into()).into(); + account + } else { + return fees + } } else { return fees - } - } else { - return fees - }; + }; // Get the total fee offered by export message. let maybe_total_supplied_fee: Option<(usize, Balance)> = fees @@ -90,8 +85,8 @@ impl (0u128).into() { // Refund remote component of fee to physical origin deposit_or_burn_fee::( - MultiAsset { id: Concrete(token_location), fun: Fungible(remote_fee.into()) } + Asset { id: AssetId(token_location.clone()), fun: Fungible(remote_fee.into()) } .into(), context, para_sovereign, @@ -112,8 +107,8 @@ impl::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + XcmExecutor::::prepare_and_execute( assethub_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ) } @@ -176,7 +175,7 @@ pub fn send_unpaid_transfer_token_message( XcmConfig: xcm_executor::Config, ValidatorIdOf: From>, { - let assethub_parachain_location = MultiLocation::new(1, Parachain(assethub_parachain_id)); + let assethub_parachain_location = Location::new(1, Parachain(assethub_parachain_id)); ExtBuilder::::default() .with_collators(collator_session_key.collators()) @@ -194,28 +193,25 @@ pub fn send_unpaid_transfer_token_message( ) .unwrap(); - let asset = MultiAsset { - id: Concrete(MultiLocation { - parents: 0, - interior: X1(AccountKey20 { network: None, key: weth_contract_address.into() }), - }), + let asset = Asset { + id: AssetId(Location::new( + 0, + [AccountKey20 { network: None, key: weth_contract_address.into() }], + )), fun: Fungible(1000000000), }; let assets = vec![asset.clone()]; let inner_xcm = Xcm(vec![ - WithdrawAsset(MultiAssets::from(assets.clone())), + WithdrawAsset(Assets::from(assets.clone())), ClearOrigin, BuyExecution { fees: asset, weight_limit: Unlimited }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { - parents: 0, - interior: X1(AccountKey20 { - network: None, - key: destination_contract.into(), - }), - }, + beneficiary: Location::new( + 0, + [AccountKey20 { network: None, key: destination_contract.into() }], + ), }, SetTopic([0; 32]), ]); @@ -231,12 +227,13 @@ pub fn send_unpaid_transfer_token_message( ]); // execute XCM - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let outcome = XcmExecutor::::prepare_and_execute( assethub_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); // check error is barrier assert_err!(outcome.ensure_complete(), Barrier); diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs index 71cd21d45f7..5b900769622 100644 --- a/cumulus/pallets/xcmp-queue/src/lib.rs +++ b/cumulus/pallets/xcmp-queue/src/lib.rs @@ -135,7 +135,7 @@ pub mod pallet { /// The origin that is allowed to resume or suspend the XCMP queue. type ControllerOrigin: EnsureOrigin; - /// The conversion function used to attempt to convert an XCM `MultiLocation` origin to a + /// The conversion function used to attempt to convert an XCM `Location` origin to a /// superuser origin. type ControllerOriginConverter: ConvertOrigin; @@ -903,14 +903,14 @@ impl SendXcm for Pallet { type Ticket = (ParaId, VersionedXcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult<(ParaId, VersionedXcm<()>)> { let d = dest.take().ok_or(SendError::MissingArgument)?; - match &d { + match d.unpack() { // An HRMP message for a sibling parachain. - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => { + (1, [Parachain(id)]) => { let xcm = msg.take().ok_or(SendError::MissingArgument)?; let id = ParaId::from(*id); let price = T::PriceForSiblingDelivery::price_for_delivery(id, &xcm); diff --git a/cumulus/pallets/xcmp-queue/src/mock.rs b/cumulus/pallets/xcmp-queue/src/mock.rs index a41be6fa9ca..031c0721753 100644 --- a/cumulus/pallets/xcmp-queue/src/mock.rs +++ b/cumulus/pallets/xcmp-queue/src/mock.rs @@ -124,8 +124,8 @@ impl cumulus_pallet_parachain_system::Config for Test { } parameter_types! { - pub const RelayChain: MultiLocation = MultiLocation::parent(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(1u32)); + pub const RelayChain: Location = Location::parent(); + pub UniversalLocation: InteriorLocation = [Parachain(1u32)].into(); pub UnitWeightCost: Weight = Weight::from_parts(1_000_000, 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; @@ -138,7 +138,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -187,17 +187,14 @@ impl ConvertOrigin for SystemParachainAsSuperuser { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); if kind == OriginKind::Superuser && matches!( - origin, - MultiLocation { - parents: 1, - interior: X1(Parachain(id)), - } if ParaId::from(id).is_system(), + origin.unpack(), + (1, [Parachain(id)]) if ParaId::from(*id).is_system(), ) { Ok(RuntimeOrigin::root()) } else { @@ -256,7 +253,7 @@ impl> EnqueueMessage for EnqueueToLocalStorage parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RelayChain::get()); + pub FeeAssetId: AssetId = AssetId(RelayChain::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: Balance = 300_000_000; /// The fee per byte diff --git a/cumulus/pallets/xcmp-queue/src/tests.rs b/cumulus/pallets/xcmp-queue/src/tests.rs index 8e8f6e852e1..0b41095828f 100644 --- a/cumulus/pallets/xcmp-queue/src/tests.rs +++ b/cumulus/pallets/xcmp-queue/src/tests.rs @@ -333,11 +333,11 @@ struct OkFixedXcmHashWithAssertingRequiredInputsSender; impl OkFixedXcmHashWithAssertingRequiredInputsSender { const FIXED_XCM_HASH: [u8; 32] = [9; 32]; - fn fixed_delivery_asset() -> MultiAssets { - MultiAssets::new() + fn fixed_delivery_asset() -> Assets { + Assets::new() } - fn expected_delivery_result() -> Result<(XcmHash, MultiAssets), SendError> { + fn expected_delivery_result() -> Result<(XcmHash, Assets), SendError> { Ok((Self::FIXED_XCM_HASH, Self::fixed_delivery_asset())) } } @@ -345,7 +345,7 @@ impl SendXcm for OkFixedXcmHashWithAssertingRequiredInputsSender { type Ticket = (); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { assert!(destination.is_some()); @@ -392,8 +392,8 @@ fn xcmp_queue_consumes_dest_and_msg_on_ok_validate() { let message = Xcm(vec![Trap(5)]); // XcmpQueue - check dest/msg is valid - let dest = (Parent, X1(Parachain(5555))); - let mut dest_wrapper = Some(dest.into()); + let dest: Location = (Parent, Parachain(5555)).into(); + let mut dest_wrapper = Some(dest.clone()); let mut msg_wrapper = Some(message.clone()); new_test_ext().execute_with(|| { @@ -416,7 +416,7 @@ fn xcmp_queue_consumes_dest_and_msg_on_ok_validate() { #[test] fn xcmp_queue_validate_nested_xcm_works() { - let dest = (Parent, X1(Parachain(5555))); + let dest = (Parent, Parachain(5555)); // Message that is not too deeply nested: let mut good = Xcm(vec![ClearOrigin]); for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { @@ -441,7 +441,7 @@ fn xcmp_queue_validate_nested_xcm_works() { #[test] fn send_xcm_nested_works() { - let dest = (Parent, X1(Parachain(HRMP_PARA_ID))); + let dest = (Parent, Parachain(HRMP_PARA_ID)); // Message that is not too deeply nested: let mut good = Xcm(vec![ClearOrigin]); for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { @@ -455,7 +455,7 @@ fn send_xcm_nested_works() { XcmpQueue::take_outbound_messages(usize::MAX), vec![( HRMP_PARA_ID.into(), - (XcmpMessageFormat::ConcatenatedVersionedXcm, VersionedXcm::V3(good.clone())) + (XcmpMessageFormat::ConcatenatedVersionedXcm, VersionedXcm::V4(good.clone())) .encode(), )] ); @@ -474,7 +474,7 @@ fn hrmp_signals_are_prioritized() { let message = Xcm(vec![Trap(5)]); let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))); + let dest = (Parent, Parachain(sibling_para_id.into())); let mut dest_wrapper = Some(dest.into()); let mut msg_wrapper = Some(message.clone()); @@ -511,7 +511,7 @@ fn hrmp_signals_are_prioritized() { // Without a signal we get the messages in order: let mut expected_msg = XcmpMessageFormat::ConcatenatedVersionedXcm.encode(); for _ in 0..31 { - expected_msg.extend(VersionedXcm::V3(message.clone()).encode()); + expected_msg.extend(VersionedXcm::V4(message.clone()).encode()); } hypothetically!({ @@ -590,7 +590,7 @@ fn take_first_concatenated_xcm_good_recursion_depth_works() { for _ in 0..MAX_XCM_DECODE_DEPTH - 1 { good = Xcm(vec![SetAppendix(good)]); } - let good = VersionedXcm::V3(good); + let good = VersionedXcm::V4(good); let page = good.encode(); assert_ok!(XcmpQueue::take_first_concatenated_xcm(&mut &page[..], &mut WeightMeter::new())); @@ -603,7 +603,7 @@ fn take_first_concatenated_xcm_good_bad_depth_errors() { for _ in 0..MAX_XCM_DECODE_DEPTH { bad = Xcm(vec![SetAppendix(bad)]); } - let bad = VersionedXcm::V3(bad); + let bad = VersionedXcm::V4(bad); let page = bad.encode(); assert_err!( @@ -699,12 +699,12 @@ fn lazy_migration_noop_when_out_of_weight() { fn xcmp_queue_send_xcm_works() { new_test_ext().execute_with(|| { let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))).into(); + let dest: Location = (Parent, Parachain(sibling_para_id.into())).into(); let msg = Xcm(vec![ClearOrigin]); // try to send without opened HRMP channel to the sibling_para_id assert_eq!( - send_xcm::(dest, msg.clone()), + send_xcm::(dest.clone(), msg.clone()), Err(SendError::Transport("NoChannel")), ); @@ -728,7 +728,7 @@ fn xcmp_queue_send_xcm_works() { fn xcmp_queue_send_too_big_xcm_fails() { new_test_ext().execute_with(|| { let sibling_para_id = ParaId::from(12345); - let dest = (Parent, X1(Parachain(sibling_para_id.into()))).into(); + let dest = (Parent, Parachain(sibling_para_id.into())).into(); let max_message_size = 100_u32; @@ -774,7 +774,7 @@ fn verify_fee_factor_increase_and_decrease() { use sp_runtime::FixedU128; let sibling_para_id = ParaId::from(12345); - let destination = (Parent, Parachain(sibling_para_id.into())).into(); + let destination: Location = (Parent, Parachain(sibling_para_id.into())).into(); let xcm = Xcm(vec![ClearOrigin; 100]); let versioned_xcm = VersionedXcm::from(xcm.clone()); let mut xcmp_message = XcmpMessageFormat::ConcatenatedVersionedXcm.encode(); @@ -799,15 +799,15 @@ fn verify_fee_factor_increase_and_decrease() { // Fee factor is only increased in `send_fragment`, which is called by `send_xcm`. // When queue is not congested, fee factor doesn't change. - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 104 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 208 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 312 - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 416 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 104 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 208 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 312 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 416 assert_eq!(DeliveryFeeFactor::::get(sibling_para_id), initial); // Sending the message right now is cheap - let (_, delivery_fees) = - validate_send::(destination, xcm.clone()).expect("message can be sent; qed"); + let (_, delivery_fees) = validate_send::(destination.clone(), xcm.clone()) + .expect("message can be sent; qed"); let Fungible(delivery_fee_amount) = delivery_fees.inner()[0].fun else { unreachable!("asset is fungible; qed"); }; @@ -817,18 +817,18 @@ fn verify_fee_factor_increase_and_decrease() { // When we get to half of `max_total_size`, because `THRESHOLD_FACTOR` is 2, // then the fee factor starts to increase. - assert_ok!(send_xcm::(destination, xcm.clone())); // Size 520 + assert_ok!(send_xcm::(destination.clone(), xcm.clone())); // Size 520 assert_eq!(DeliveryFeeFactor::::get(sibling_para_id), FixedU128::from_float(1.05)); for _ in 0..12 { // We finish at size 929 - assert_ok!(send_xcm::(destination, smaller_xcm.clone())); + assert_ok!(send_xcm::(destination.clone(), smaller_xcm.clone())); } assert!(DeliveryFeeFactor::::get(sibling_para_id) > FixedU128::from_float(1.88)); // Sending the message right now is expensive - let (_, delivery_fees) = - validate_send::(destination, xcm.clone()).expect("message can be sent; qed"); + let (_, delivery_fees) = validate_send::(destination.clone(), xcm.clone()) + .expect("message can be sent; qed"); let Fungible(delivery_fee_amount) = delivery_fees.inner()[0].fun else { unreachable!("asset is fungible; qed"); }; diff --git a/cumulus/parachain-template/runtime/src/xcm_config.rs b/cumulus/parachain-template/runtime/src/xcm_config.rs index 7d1a748819c..d407292d0bd 100644 --- a/cumulus/parachain-template/runtime/src/xcm_config.rs +++ b/cumulus/parachain-template/runtime/src/xcm_config.rs @@ -3,8 +3,8 @@ use super::{ Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, Everything, Nothing}, + parameter_types, + traits::{ConstU32, Contains, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -25,13 +25,13 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -50,7 +50,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -86,11 +86,11 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; +pub struct ParentOrParentsExecutivePlurality; +impl Contains for ParentOrParentsExecutivePlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }])) + } } pub type Barrier = TrailingSetTopicAsId< diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs index beb655134ad..69da325dd4f 100644 --- a/cumulus/parachains/common/src/impls.rs +++ b/cumulus/parachains/common/src/impls.rs @@ -24,8 +24,8 @@ use pallet_asset_tx_payment::HandleCredit; use sp_runtime::traits::Zero; use sp_std::{marker::PhantomData, prelude::*}; use xcm::latest::{ - AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, MultiAsset, - MultiLocation, Parent, WeightLimit, + Asset, AssetId, Fungibility, Fungibility::Fungible, Junction, Junctions::Here, Location, + Parent, WeightLimit, }; use xcm_executor::traits::ConvertLocation; @@ -113,11 +113,11 @@ where /// Asset filter that allows all assets from a certain location. pub struct AssetsFrom(PhantomData); -impl> ContainsPair for AssetsFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for AssetsFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if asset_loc.match_and_split(&loc).is_some()) } } @@ -148,7 +148,7 @@ where Err(amount) => amount, }; let imbalance = amount.peek(); - let root_location: MultiLocation = Here.into(); + let root_location: Location = Here.into(); let root_account: AccountIdOf = match AccountIdConverter::convert_location(&root_location) { Some(a) => a, @@ -329,13 +329,13 @@ mod tests { #[test] fn assets_from_filters_correctly() { parameter_types! { - pub SomeSiblingParachain: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); + pub SomeSiblingParachain: Location = (Parent, Parachain(1234)).into(); } let asset_location = SomeSiblingParachain::get() .pushed_with_interior(GeneralIndex(42)) - .expect("multilocation will only have 2 junctions; qed"); - let asset = MultiAsset { id: Concrete(asset_location), fun: 1_000_000u128.into() }; + .expect("location will only have 2 junctions; qed"); + let asset = Asset { id: AssetId(asset_location), fun: 1_000_000u128.into() }; assert!( AssetsFrom::::contains(&asset, &SomeSiblingParachain::get()), "AssetsFrom should allow assets from any of its interior locations" diff --git a/cumulus/parachains/common/src/xcm_config.rs b/cumulus/parachains/common/src/xcm_config.rs index 7a63e720b07..15b090923d5 100644 --- a/cumulus/parachains/common/src/xcm_config.rs +++ b/cumulus/parachains/common/src/xcm_config.rs @@ -66,37 +66,36 @@ where } } -/// Accepts an asset if it is a native asset from a particular `MultiLocation`. -pub struct ConcreteNativeAssetFrom(PhantomData); -impl> ContainsPair - for ConcreteNativeAssetFrom +/// Accepts an asset if it is a native asset from a particular `Location`. +pub struct ConcreteNativeAssetFrom(PhantomData); +impl> ContainsPair + for ConcreteNativeAssetFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::filter_asset_location", "ConcreteNativeAsset asset: {:?}, origin: {:?}, location: {:?}", - asset, origin, Location::get()); - matches!(asset.id, Concrete(ref id) if id == origin && origin == &Location::get()) + asset, origin, LocationValue::get()); + asset.id.0 == *origin && origin == &LocationValue::get() } } pub struct RelayOrOtherSystemParachains< - SystemParachainMatcher: Contains, + SystemParachainMatcher: Contains, Runtime: parachain_info::Config, > { _runtime: PhantomData<(SystemParachainMatcher, Runtime)>, } -impl, Runtime: parachain_info::Config> - Contains for RelayOrOtherSystemParachains +impl, Runtime: parachain_info::Config> Contains + for RelayOrOtherSystemParachains { - fn contains(l: &MultiLocation) -> bool { + fn contains(l: &Location) -> bool { let self_para_id: u32 = parachain_info::Pallet::::get().into(); - if let MultiLocation { parents: 0, interior: X1(Parachain(para_id)) } = l { + if let (0, [Parachain(para_id)]) = l.unpack() { if *para_id == self_para_id { return false } } - matches!(l, MultiLocation { parents: 1, interior: Here }) || - SystemParachainMatcher::contains(l) + matches!(l.unpack(), (1, [])) || SystemParachainMatcher::contains(l) } } @@ -105,14 +104,12 @@ impl, Runtime: parachain_info::C /// This structure can only be used at a parachain level. In the Relay Chain, please use /// the `xcm_builder::IsChildSystemParachain` matcher. pub struct AllSiblingSystemParachains; - -impl Contains for AllSiblingSystemParachains { - fn contains(l: &MultiLocation) -> bool { +impl Contains for AllSiblingSystemParachains { + fn contains(l: &Location) -> bool { log::trace!(target: "xcm::contains", "AllSiblingSystemParachains location: {:?}", l); - match *l { + match l.unpack() { // System parachain - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - ParaId::from(id).is_system(), + (1, [Parachain(id)]) => ParaId::from(*id).is_system(), // Everything else _ => false, } @@ -121,21 +118,20 @@ impl Contains for AllSiblingSystemParachains { /// Accepts an asset if it is a concrete asset from the system (Relay Chain or system parachain). pub struct ConcreteAssetFromSystem(PhantomData); -impl> ContainsPair +impl> ContainsPair for ConcreteAssetFromSystem { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "ConcreteAssetFromSystem asset: {:?}, origin: {:?}", asset, origin); - let is_system = match origin { + let is_system = match origin.unpack() { // The Relay Chain - MultiLocation { parents: 1, interior: Here } => true, + (1, []) => true, // System parachain - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - ParaId::from(*id).is_system(), + (1, [Parachain(id)]) => ParaId::from(*id).is_system(), // Others _ => false, }; - matches!(asset.id, Concrete(id) if id == AssetLocation::get()) && is_system + asset.id.0 == AssetLocation::get() && is_system } } @@ -144,13 +140,9 @@ impl> ContainsPair /// This type should only be used within the context of a parachain, since it does not verify that /// the parent is indeed a Relay Chain. pub struct ParentRelayOrSiblingParachains; -impl Contains for ParentRelayOrSiblingParachains { - fn contains(location: &MultiLocation) -> bool { - matches!( - location, - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - ) +impl Contains for ParentRelayOrSiblingParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) } } @@ -159,20 +151,20 @@ mod tests { use frame_support::{parameter_types, traits::Contains}; use super::{ - AllSiblingSystemParachains, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, Here, - MultiAsset, MultiLocation, PalletInstance, Parachain, Parent, + AllSiblingSystemParachains, Asset, ConcreteAssetFromSystem, ContainsPair, GeneralIndex, + Here, Location, PalletInstance, Parachain, Parent, }; use polkadot_primitives::LOWEST_PUBLIC_ID; use xcm::latest::prelude::*; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); } #[test] fn concrete_asset_from_relay_works() { - let expected_asset: MultiAsset = (Parent, 1000000).into(); - let expected_origin: MultiLocation = (Parent, Here).into(); + let expected_asset: Asset = (Parent, 1000000).into(); + let expected_origin: Location = (Parent, Here).into(); assert!(>::contains( &expected_asset, @@ -182,12 +174,12 @@ mod tests { #[test] fn concrete_asset_from_sibling_system_para_fails_for_wrong_asset() { - let unexpected_assets: Vec = vec![ + let unexpected_assets: Vec = vec![ (Here, 1000000).into(), ((PalletInstance(50), GeneralIndex(1)), 1000000).into(), ((Parent, Parachain(1000), PalletInstance(50), GeneralIndex(1)), 1000000).into(), ]; - let expected_origin: MultiLocation = (Parent, Parachain(1000)).into(); + let expected_origin: Location = (Parent, Parachain(1000)).into(); unexpected_assets.iter().for_each(|asset| { assert!(!>::contains(asset, &expected_origin)); @@ -206,10 +198,10 @@ mod tests { (2001, false), // Not a System Parachain ]; - let expected_asset: MultiAsset = (Parent, 1000000).into(); + let expected_asset: Asset = (Parent, 1000000).into(); for (para_id, expected_result) in test_data { - let origin: MultiLocation = (Parent, Parachain(para_id)).into(); + let origin: Location = (Parent, Parachain(para_id)).into(); assert_eq!( expected_result, >::contains(&expected_asset, &origin) @@ -220,15 +212,15 @@ mod tests { #[test] fn all_sibling_system_parachains_works() { // system parachain - assert!(AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(Parachain(1))))); + assert!(AllSiblingSystemParachains::contains(&Location::new(1, [Parachain(1)]))); // non-system parachain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new( + assert!(!AllSiblingSystemParachains::contains(&Location::new( 1, - X1(Parachain(LOWEST_PUBLIC_ID.into())) + [Parachain(LOWEST_PUBLIC_ID.into())] ))); // when used at relay chain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(0, X1(Parachain(1))))); + assert!(!AllSiblingSystemParachains::contains(&Location::new(0, [Parachain(1)]))); // when used with non-parachain - assert!(!AllSiblingSystemParachains::contains(&MultiLocation::new(1, X1(OnlyChild)))); + assert!(!AllSiblingSystemParachains::contains(&Location::new(1, [OnlyChild]))); } } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs index 244a846bbc2..8f586a46a75 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs @@ -15,7 +15,9 @@ mod genesis; pub use genesis::{genesis, ED, PARA_ID_A, PARA_ID_B}; -pub use penpal_runtime::xcm_config::{LocalTeleportableToAssetHub, XcmConfig}; +pub use penpal_runtime::xcm_config::{ + LocalTeleportableToAssetHub, LocalTeleportableToAssetHubV3, XcmConfig, +}; // Substrate use frame_support::traits::OnInitialize; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index aa3ec214f8c..4bbb4701e43 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -38,8 +38,9 @@ pub use polkadot_runtime_parachains::{ inclusion::{AggregateMessageOrigin, UmpQueueId}, }; pub use xcm::{ - prelude::{MultiLocation, OriginKind, Outcome, VersionedXcm, XcmVersion}, - v3::Error, + prelude::{Location, OriginKind, Outcome, VersionedXcm, XcmVersion}, + v3, + v4::Error as XcmError, DoubleEncoded, }; @@ -209,7 +210,7 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { Self, vec![ [<$chain RuntimeEvent>]::::XcmPallet( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete { used: weight } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), @@ -224,21 +225,21 @@ macro_rules! impl_assert_events_helpers_for_relay_chain { /// Asserts a dispatchable is incompletely executed and XCM sent pub fn assert_xcm_pallet_attempted_incomplete( expected_weight: Option<$crate::impls::Weight>, - expected_error: Option<$crate::impls::Error>, + expected_error: Option<$crate::impls::XcmError>, ) { $crate::impls::assert_expected_events!( Self, vec![ // Dispatchable is properly executed and XCM message sent [<$chain RuntimeEvent>]::::XcmPallet( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete { used: weight, error } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), expected_weight.unwrap_or(*weight), *weight ), - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); @@ -365,7 +366,7 @@ macro_rules! impl_send_transact_helpers_for_relay_chain { ::execute_with(|| { let root_origin = ::RuntimeOrigin::root(); - let destination: $crate::impls::MultiLocation = ::child_location_of(recipient); + let destination: $crate::impls::Location = ::child_location_of(recipient); let xcm = $crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Superuser); // Send XCM `Transact` @@ -416,13 +417,13 @@ macro_rules! impl_accounts_helpers_for_parachain { network_id: $crate::impls::NetworkId, para_id: $crate::impls::ParaId, ) -> $crate::impls::AccountId { - let remote_location = $crate::impls::MultiLocation { - parents: 2, - interior: $crate::impls::Junctions::X2( + let remote_location = $crate::impls::Location::new( + 2, + [ $crate::impls::Junction::GlobalConsensus(network_id), $crate::impls::Junction::Parachain(para_id.into()), - ), - }; + ], + ); ::execute_with(|| { Self::sovereign_account_id_of(remote_location) }) @@ -445,7 +446,7 @@ macro_rules! impl_assert_events_helpers_for_parachain { Self, vec![ [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete { used: weight } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), @@ -460,36 +461,36 @@ macro_rules! impl_assert_events_helpers_for_parachain { /// Asserts a dispatchable is incompletely executed and XCM sent pub fn assert_xcm_pallet_attempted_incomplete( expected_weight: Option<$crate::impls::Weight>, - expected_error: Option<$crate::impls::Error>, + expected_error: Option<$crate::impls::XcmError>, ) { $crate::impls::assert_expected_events!( Self, vec![ // Dispatchable is properly executed and XCM message sent [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete { used: weight, error } } ) => { weight: $crate::impls::weight_within_threshold( ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), expected_weight.unwrap_or(*weight), *weight ), - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); } /// Asserts a dispatchable throws and error when trying to be sent - pub fn assert_xcm_pallet_attempted_error(expected_error: Option<$crate::impls::Error>) { + pub fn assert_xcm_pallet_attempted_error(expected_error: Option<$crate::impls::XcmError>) { $crate::impls::assert_expected_events!( Self, vec![ // Execution fails in the origin with `Barrier` [<$chain RuntimeEvent>]::::PolkadotXcm( - $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error(error) } + $crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Error { error } } ) => { - error: *error == expected_error.unwrap_or(*error), + error: *error == expected_error.unwrap_or((*error).into()).into(), }, ] ); @@ -639,7 +640,7 @@ macro_rules! impl_assets_helpers_for_parachain { ::execute_with(|| { $crate::impls::assert_ok!(]>::Assets::mint( signed_origin, - id.into(), + id.clone().into(), beneficiary.clone().into(), amount_to_mint )); @@ -717,7 +718,7 @@ macro_rules! impl_assets_helpers_for_parachain { ] ); - assert!(]>::Assets::asset_exists(id.into())); + assert!(]>::Assets::asset_exists(id.clone().into())); }); } } @@ -732,7 +733,7 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { impl $chain { /// Create foreign assets using sudo `ForeignAssets::force_create()` pub fn force_create_foreign_asset( - id: $crate::impls::MultiLocation, + id: $crate::impls::v3::Location, owner: $crate::impls::AccountId, is_sufficient: bool, min_balance: u128, @@ -744,13 +745,13 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { $crate::impls::assert_ok!( ]>::ForeignAssets::force_create( sudo_origin, - id, + id.clone(), owner.clone().into(), is_sufficient, min_balance, ) ); - assert!(]>::ForeignAssets::asset_exists(id)); + assert!(]>::ForeignAssets::asset_exists(id.clone())); type RuntimeEvent = <$chain as $crate::impls::Chain>::RuntimeEvent; $crate::impls::assert_expected_events!( Self, @@ -767,21 +768,21 @@ macro_rules! impl_foreign_assets_helpers_for_parachain { for (beneficiary, amount) in prefund_accounts.into_iter() { let signed_origin = <$chain as $crate::impls::Chain>::RuntimeOrigin::signed(owner.clone()); - Self::mint_foreign_asset(signed_origin, id, beneficiary, amount); + Self::mint_foreign_asset(signed_origin, id.clone(), beneficiary, amount); } } /// Mint assets making use of the ForeignAssets pallet-assets instance pub fn mint_foreign_asset( signed_origin: ::RuntimeOrigin, - id: $crate::impls::MultiLocation, + id: $crate::impls::v3::Location, beneficiary: $crate::impls::AccountId, amount_to_mint: u128, ) { ::execute_with(|| { $crate::impls::assert_ok!(]>::ForeignAssets::mint( signed_origin, - id.into(), + id.clone().into(), beneficiary.clone().into(), amount_to_mint )); @@ -813,7 +814,7 @@ macro_rules! impl_xcm_helpers_for_parachain { $crate::impls::paste::paste! { impl $chain { /// Set XCM version for destination. - pub fn force_xcm_version(dest: $crate::impls::MultiLocation, version: $crate::impls::XcmVersion) { + pub fn force_xcm_version(dest: $crate::impls::Location, version: $crate::impls::XcmVersion) { ::execute_with(|| { $crate::impls::assert_ok!(]>::PolkadotXcm::force_xcm_version( ::RuntimeOrigin::root(), diff --git a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs index 48ee1a3b780..ad69d5576aa 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/lib.rs @@ -40,6 +40,7 @@ use polkadot_service::chain_spec::get_authority_keys_from_seed_no_beefy; pub const XCM_V2: u32 = 2; pub const XCM_V3: u32 = 3; +pub const XCM_V4: u32 = 4; pub const REF_TIME_THRESHOLD: u64 = 33; pub const PROOF_SIZE_THRESHOLD: u64 = 33; diff --git a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs index 8718f1e83a0..01a376e4dbf 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/macros.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/macros.rs @@ -48,7 +48,7 @@ macro_rules! test_parachain_is_trusted_teleporter { <$receiver_para as $crate::macros::Chain>::account_data_of(receiver.clone()).free; let para_destination = <$sender_para>::sibling_location_of(<$receiver_para>::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = $crate::macros::AccountId32 { network: None, id: receiver.clone().into() }.into(); // Send XCM message from Origin Parachain @@ -57,8 +57,8 @@ macro_rules! test_parachain_is_trusted_teleporter { <$sender_para>::execute_with(|| { assert_ok!(<$sender_para as [<$sender_para Pallet>]>::PolkadotXcm::limited_teleport_assets( origin.clone(), - bx!(para_destination.into()), - bx!(beneficiary.into()), + bx!(para_destination.clone().into()), + bx!(beneficiary.clone().into()), bx!($assets.clone().into()), fee_asset_item, weight_limit.clone(), @@ -127,8 +127,8 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { $crate::impls::paste::paste! { pub fn penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal: u32, - foreign_asset_at_asset_hub: MultiLocation, - ah_as_seen_by_penpal: MultiLocation, + foreign_asset_at_asset_hub: v3::Location, + ah_as_seen_by_penpal: Location, is_sufficient: bool, asset_owner: AccountId, prefund_amount: u128, @@ -144,14 +144,14 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { // prefund SA of Penpal on AssetHub with enough native tokens to pay for creating // new foreign asset, also prefund CheckingAccount with ED, because teleported asset // itself might not be sufficient and CheckingAccount cannot be created otherwise - let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah); + let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah.clone()); $asset_hub::fund_accounts(vec![ (sov_penpal_on_ah.clone().into(), $relay_ed * 100_000_000_000), (ah_check_account.clone().into(), $relay_ed * 1000), ]); // prefund SA of AssetHub on Penpal with native asset - let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal); + let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal.clone()); $penpal::fund_accounts(vec![ (sov_ah_on_penpal.into(), $relay_ed * 1_000_000_000), (penpal_check_account.clone().into(), $relay_ed * 1000), @@ -183,8 +183,8 @@ macro_rules! include_penpal_create_foreign_asset_on_asset_hub { let buy_execution_fee_amount = $weight_to_fee::weight_to_fee( &Weight::from_parts(10_100_000_000_000, 300_000), ); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + let buy_execution_fee = Asset { + id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(buy_execution_fee_amount), }; let xcm = VersionedXcm::from(Xcm(vec![ diff --git a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs index 70a9408c309..25e1cffad54 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs @@ -23,12 +23,12 @@ use xcm::{prelude::*, DoubleEncoded}; pub fn xcm_transact_paid_execution( call: DoubleEncoded<()>, origin_kind: OriginKind, - native_asset: MultiAsset, + native_asset: Asset, beneficiary: AccountId, ) -> VersionedXcm<()> { let weight_limit = WeightLimit::Unlimited; let require_weight_at_most = Weight::from_parts(1000000000, 200000); - let native_assets: MultiAssets = native_asset.clone().into(); + let native_assets: Assets = native_asset.clone().into(); VersionedXcm::from(Xcm(vec![ WithdrawAsset(native_assets), @@ -37,9 +37,9 @@ pub fn xcm_transact_paid_execution( RefundSurplus, DepositAsset { assets: All.into(), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { network: None, id: beneficiary.into() }), + interior: [AccountId32 { network: None, id: beneficiary.into() }].into(), }, }, ])) @@ -61,15 +61,11 @@ pub fn xcm_transact_unpaid_execution( } /// Helper method to get the non-fee asset used in multiple assets transfer -pub fn non_fee_asset(assets: &MultiAssets, fee_idx: usize) -> Option<(MultiLocation, u128)> { +pub fn non_fee_asset(assets: &Assets, fee_idx: usize) -> Option<(Location, u128)> { let asset = assets.inner().into_iter().enumerate().find(|a| a.0 != fee_idx)?.1.clone(); - let asset_id = match asset.id { - Concrete(id) => id, - _ => return None, - }; let asset_amount = match asset.fun { Fungible(amount) => amount, _ => return None, }; - Some((asset_id, asset_amount)) + Some((asset.id.0, asset_amount)) } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs index 721f8b511ea..155c952327a 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/lib.rs @@ -26,7 +26,7 @@ pub use frame_support::{ // Polkadot pub use xcm::{ prelude::{AccountId32 as AccountId32Junction, *}, - v3::{Error, NetworkId::Rococo as RococoId}, + v3::{self, Error, NetworkId::Rococo as RococoId}, }; // Cumulus diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs index 24a71d3fb45..dfc0bc6ff39 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/reserve_transfer.rs @@ -30,7 +30,7 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == Rococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -53,7 +53,7 @@ fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -130,7 +130,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { asset_id: *asset_id == ASSET_ID, from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -190,10 +190,10 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn reserve_transfer_native_asset_from_relay_to_system_para_fails() { let signed_origin = ::RuntimeOrigin::signed(RococoSender::get().into()); let destination = Rococo::child_location_of(AssetHubRococo::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); let amount_to_send: Balance = ROCOCO_ED * 1000; - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -225,11 +225,11 @@ fn reserve_transfer_native_asset_from_system_para_to_relay_fails() { ::RuntimeOrigin::signed(AssetHubRococoSender::get().into()); let destination = AssetHubRococo::parent_location(); let beneficiary_id = RococoReceiver::get(); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: beneficiary_id.into() }.into(); let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000; - let assets: MultiAssets = (Parent, amount_to_send).into(); + let assets: Assets = (Parent, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -418,9 +418,9 @@ fn reserve_transfer_assets_from_system_para_to_para() { let beneficiary_id = PenpalAReceiver::get(); let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let assets: MultiAssets = vec![ + let assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send) + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], asset_amount_to_send) .into(), ] .into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs index 8faba50fc88..7d630d36805 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/set_xcm_versions.rs @@ -19,14 +19,13 @@ use crate::*; fn relay_sets_system_para_xcm_supported_version() { // Init tests variables let sudo_origin = ::RuntimeOrigin::root(); - let system_para_destination: MultiLocation = - Rococo::child_location_of(AssetHubRococo::para_id()); + let system_para_destination: Location = Rococo::child_location_of(AssetHubRococo::para_id()); // Relay Chain sets supported version for Asset Parachain Rococo::execute_with(|| { assert_ok!(::XcmPallet::force_xcm_version( sudo_origin, - bx!(system_para_destination), + bx!(system_para_destination.clone()), XCM_V3 )); @@ -52,7 +51,7 @@ fn system_para_sets_relay_xcm_supported_version() { ::RuntimeCall::PolkadotXcm(pallet_xcm::Call::< ::Runtime, >::force_xcm_version { - location: bx!(parent_location), + location: bx!(parent_location.clone()), version: XCM_V3, }) .encode() diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs index b1af69a1cd1..d6aade68086 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/swap.rs @@ -15,16 +15,19 @@ use crate::*; use parachains_common::rococo::currency::EXISTENTIAL_DEPOSIT; -use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; use sp_runtime::ModuleError; #[test] fn swap_locally_on_chain_using_local_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let asset_one = MultiLocation { - parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), - }; + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); + let asset_one = Box::new(v3::Location::new( + 0, + [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ], + )); AssetHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -46,8 +49,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), )); assert_expected_events!( @@ -59,8 +62,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -75,7 +78,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![Box::new(asset_native), Box::new(asset_one)]; + let path = vec![asset_native.clone(), asset_one.clone()]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -100,8 +103,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native, + asset_one, 1414213562273 - EXISTENTIAL_DEPOSIT * 2, // all but the 2 EDs can't be retrieved. 0, 0, @@ -112,16 +115,16 @@ fn swap_locally_on_chain_using_local_assets() { #[test] fn swap_locally_on_chain_using_foreign_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalASender::get(); let foreign_asset_at_asset_hub_rococo = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalA::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); @@ -167,7 +170,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 4. Create pool: assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), )); @@ -181,7 +184,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 5. Add liquidity: assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), 1_000_000_000_000, 2_000_000_000_000, @@ -200,7 +203,7 @@ fn swap_locally_on_chain_using_foreign_assets() { ); // 6. Swap! - let path = vec![Box::new(asset_native), Box::new(foreign_asset_at_asset_hub_rococo)]; + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo)]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -226,7 +229,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 7. Remove liquidity assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, @@ -238,9 +241,11 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let mut asset_one = asset_hub_rococo_runtime::xcm_config::PoolAssetsPalletLocation::get(); - asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets"); + let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get()); + let mut asset_one = asset_hub_rococo_runtime::xcm_config::PoolAssetsPalletLocationV3::get(); + asset_one + .append_with(v3::Junction::GeneralIndex(ASSET_ID.into())) + .expect("pool assets"); AssetHubRococo::execute_with(|| { let pool_owner_account_id = asset_hub_rococo_runtime::AssetConversionOrigin::get(); @@ -263,7 +268,7 @@ fn cannot_create_pool_from_pool_assets() { assert_matches::assert_matches!( ::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(asset_native), + asset_native, Box::new(asset_one), ), Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) @@ -273,10 +278,14 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocation::get(); - let asset_one = MultiLocation { + let asset_native = asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get(); + let asset_one = xcm::v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), }; let penpal = AssetHubRococo::sovereign_account_id_of(AssetHubRococo::sibling_location_of( PenpalA::para_id(), @@ -365,8 +374,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { let penpal_root = ::RuntimeOrigin::root(); let fee_amount = 4_000_000_000_000u128; let asset_one = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) - .into(); + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); let asset_hub_location = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); let xcm = xcm_transact_paid_execution( call, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs index a07463cec50..218234cc78e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/teleport.rs @@ -17,7 +17,7 @@ use crate::*; use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig; use emulated_integration_tests_common::xcm_helpers::non_fee_asset; use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig; -use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; fn relay_origin_assertions(t: RelayToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -143,6 +143,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { ); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -157,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { who: *who == t.receiver.account_id, }, RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.receiver.account_id, amount: *amount == expected_foreign_asset_amount, }, @@ -174,6 +175,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { AssetHubRococo::assert_xcm_pallet_attempted_complete(None); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubRococo, vec![ @@ -183,13 +185,13 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubRococo::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, // foreign asset is burned locally as part of teleportation RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.sender.account_id, balance: *balance == expected_foreign_asset_amount, }, @@ -542,7 +544,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() { #[test] fn teleport_to_other_system_parachains_works() { let amount = ASSET_HUB_ROCOCO_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( AssetHubRococo, // Origin @@ -557,20 +559,20 @@ fn teleport_to_other_system_parachains_works() { #[test] fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalASender::get(); let foreign_asset_at_asset_hub_rococo = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalA::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); super::penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal, foreign_asset_at_asset_hub_rococo, - ah_as_seen_by_penpal, + ah_as_seen_by_penpal.clone(), false, asset_owner_on_penpal, ASSET_MIN_BALANCE * 1_000_000, @@ -580,9 +582,10 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 10_000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let penpal_assets: MultiAssets = vec![ + let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap(); + let penpal_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (asset_location_on_penpal, asset_amount_to_send).into(), + (asset_location_on_penpal_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = penpal_assets @@ -670,11 +673,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { )); }); + let foreign_asset_at_asset_hub_rococo_latest: Location = + foreign_asset_at_asset_hub_rococo.try_into().unwrap(); let ah_to_penpal_beneficiary_id = PenpalAReceiver::get(); let penpal_as_seen_by_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id()); - let ah_assets: MultiAssets = vec![ + let ah_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (foreign_asset_at_asset_hub_rococo, asset_amount_to_send).into(), + (foreign_asset_at_asset_hub_rococo_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = ah_assets diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs index fbeb08649e7..018e948e5d7 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/lib.rs @@ -28,7 +28,7 @@ pub use frame_support::{ // Polkadot pub use xcm::{ prelude::{AccountId32 as AccountId32Junction, *}, - v3::{Error, NetworkId::Westend as WestendId}, + v3::{self, Error, NetworkId::Westend as WestendId}, }; // Cumulus diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs index d7de0a451f2..11e1e1762db 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/fellowship_treasury.rs @@ -24,22 +24,20 @@ fn create_and_claim_treasury_spend() { const ASSET_ID: u32 = 1984; const SPEND_AMOUNT: u128 = 1_000_000; // treasury location from a sibling parachain. - let treasury_location: MultiLocation = MultiLocation::new( - 1, - X2(Parachain(CollectivesWestend::para_id().into()), PalletInstance(65)), - ); + let treasury_location: Location = + Location::new(1, [Parachain(CollectivesWestend::para_id().into()), PalletInstance(65)]); // treasury account on a sibling parachain. let treasury_account = asset_hub_westend_runtime::xcm_config::LocationToAccountId::convert_location( &treasury_location, ) .unwrap(); - let asset_hub_location = MultiLocation::new(1, Parachain(AssetHubWestend::para_id().into())); + let asset_hub_location = Location::new(1, [Parachain(AssetHubWestend::para_id().into())]); let root = ::RuntimeOrigin::root(); // asset kind to be spent from the treasury. - let asset_kind = VersionedLocatableAsset::V3 { + let asset_kind = VersionedLocatableAsset::V4 { location: asset_hub_location, - asset_id: AssetId::Concrete((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), + asset_id: AssetId((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), }; // treasury spend beneficiary. let alice: AccountId = Westend::account_id_of(ALICE); @@ -75,7 +73,7 @@ fn create_and_claim_treasury_spend() { root, Box::new(asset_kind), SPEND_AMOUNT, - Box::new(MultiLocation::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), None, )); // claim the spend. diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs index 3cce6c4417e..a2934be9758 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/reserve_transfer.rs @@ -32,7 +32,7 @@ fn relay_to_para_sender_assertions(t: RelayToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == Westend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -57,7 +57,7 @@ fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -140,7 +140,7 @@ fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) { asset_id: *asset_id == ASSET_ID, from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, @@ -200,10 +200,10 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa fn reserve_transfer_native_asset_from_relay_to_system_para_fails() { let signed_origin = ::RuntimeOrigin::signed(WestendSender::get().into()); let destination = Westend::child_location_of(AssetHubWestend::para_id()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); let amount_to_send: Balance = WESTEND_ED * 1000; - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -235,10 +235,10 @@ fn reserve_transfer_native_asset_from_system_para_to_relay_fails() { ::RuntimeOrigin::signed(AssetHubWestendSender::get().into()); let destination = AssetHubWestend::parent_location(); let beneficiary_id = WestendReceiver::get(); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: beneficiary_id.into() }.into(); let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000; - let assets: MultiAssets = (Parent, amount_to_send).into(); + let assets: Assets = (Parent, amount_to_send).into(); let fee_asset_item = 0; // this should fail @@ -428,9 +428,9 @@ fn reserve_transfer_assets_from_system_para_to_para() { let beneficiary_id = PenpalBReceiver::get(); let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let assets: MultiAssets = vec![ + let assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send) + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], asset_amount_to_send) .into(), ] .into(); diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs index 2133d5e5fb7..130454551d2 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/set_xcm_versions.rs @@ -19,14 +19,13 @@ use crate::*; fn relay_sets_system_para_xcm_supported_version() { // Init tests variables let sudo_origin = ::RuntimeOrigin::root(); - let system_para_destination: MultiLocation = - Westend::child_location_of(AssetHubWestend::para_id()); + let system_para_destination: Location = Westend::child_location_of(AssetHubWestend::para_id()); // Relay Chain sets supported version for Asset Parachain Westend::execute_with(|| { assert_ok!(::XcmPallet::force_xcm_version( sudo_origin, - bx!(system_para_destination), + bx!(system_para_destination.clone()), XCM_V3 )); @@ -52,7 +51,7 @@ fn system_para_sets_relay_xcm_supported_version() { ::RuntimeCall::PolkadotXcm(pallet_xcm::Call::< ::Runtime, >::force_xcm_version { - location: bx!(parent_location), + location: bx!(parent_location.clone()), version: XCM_V3, }) .encode() diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs index c768a1366fa..b39cc2159de 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/swap.rs @@ -14,15 +14,19 @@ // limitations under the License. use crate::*; -use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; #[test] fn swap_locally_on_chain_using_local_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let asset_one = MultiLocation { + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); + let asset_one = Box::new(v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), - }; + interior: [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), + }); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -44,8 +48,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), )); assert_expected_events!( @@ -57,8 +61,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -73,7 +77,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![Box::new(asset_native), Box::new(asset_one)]; + let path = vec![asset_native.clone(), asset_one.clone()]; assert_ok!(::AssetConversion::swap_exact_tokens_for_tokens( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), @@ -96,8 +100,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), - Box::new(asset_one), + asset_native.clone(), + asset_one.clone(), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, 0, @@ -108,16 +112,16 @@ fn swap_locally_on_chain_using_local_assets() { #[test] fn swap_locally_on_chain_using_foreign_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalBSender::get(); let foreign_asset_at_asset_hub_westend = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalB::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); @@ -163,7 +167,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 4. Create pool: assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), )); @@ -177,7 +181,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 5. Add liquidity: assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), 1_000_000_000_000, 2_000_000_000_000, @@ -196,7 +200,7 @@ fn swap_locally_on_chain_using_foreign_assets() { ); // 6. Swap! - let path = vec![Box::new(asset_native), Box::new(foreign_asset_at_asset_hub_westend)]; + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend)]; assert_ok!(::AssetConversion::swap_exact_tokens_for_tokens( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), @@ -220,7 +224,7 @@ fn swap_locally_on_chain_using_foreign_assets() { // 7. Remove liquidity assert_ok!(::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()), - Box::new(asset_native), + asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend), 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, @@ -232,9 +236,11 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let mut asset_one = asset_hub_westend_runtime::xcm_config::PoolAssetsPalletLocation::get(); - asset_one.append_with(GeneralIndex(ASSET_ID.into())).expect("pool assets"); + let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get()); + let mut asset_one = asset_hub_westend_runtime::xcm_config::PoolAssetsPalletLocationV3::get(); + asset_one + .append_with(v3::Junction::GeneralIndex(ASSET_ID.into())) + .expect("pool assets"); AssetHubWestend::execute_with(|| { let pool_owner_account_id = asset_hub_westend_runtime::AssetConversionOrigin::get(); @@ -257,7 +263,7 @@ fn cannot_create_pool_from_pool_assets() { assert_matches::assert_matches!( ::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(asset_native), + asset_native, Box::new(asset_one), ), Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) @@ -267,10 +273,14 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocation::get(); - let asset_one = MultiLocation { + let asset_native = asset_hub_westend_runtime::xcm_config::WestendLocationV3::get(); + let asset_one = xcm::v3::Location { parents: 0, - interior: X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), }; let penpal = AssetHubWestend::sovereign_account_id_of(AssetHubWestend::sibling_location_of( PenpalB::para_id(), @@ -359,8 +369,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { let penpal_root = ::RuntimeOrigin::root(); let fee_amount = 4_000_000_000_000u128; let asset_one = - (X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), fee_amount) - .into(); + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); let asset_hub_location = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); let xcm = xcm_transact_paid_execution( call, diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs index 27a6e7aaaf4..01498f7bb4e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/teleport.rs @@ -17,7 +17,7 @@ use crate::*; use asset_hub_westend_runtime::xcm_config::XcmConfig as AssetHubWestendXcmConfig; use emulated_integration_tests_common::xcm_helpers::non_fee_asset; use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig; -use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3; fn relay_origin_assertions(t: RelayToSystemParaTest) { type RuntimeEvent = ::RuntimeEvent; @@ -143,6 +143,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { ); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -157,7 +158,7 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) { who: *who == t.receiver.account_id, }, RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.receiver.account_id, amount: *amount == expected_foreign_asset_amount, }, @@ -174,6 +175,7 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { AssetHubWestend::assert_xcm_pallet_attempted_complete(None); let (expected_foreign_asset_id, expected_foreign_asset_amount) = non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap(); + let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap(); assert_expected_events!( AssetHubWestend, vec![ @@ -183,13 +185,13 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) { ) => { from: *from == t.sender.account_id, to: *to == AssetHubWestend::sovereign_account_id_of( - t.args.dest + t.args.dest.clone() ), amount: *amount == t.args.amount, }, // foreign asset is burned locally as part of teleportation RuntimeEvent::ForeignAssets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { - asset_id: *asset_id == expected_foreign_asset_id, + asset_id: *asset_id == expected_foreign_asset_id_v3, owner: *owner == t.sender.account_id, balance: *balance == expected_foreign_asset_amount, }, @@ -542,7 +544,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() { #[test] fn teleport_to_other_system_parachains_works() { let amount = ASSET_HUB_WESTEND_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( AssetHubWestend, // Origin @@ -557,20 +559,20 @@ fn teleport_to_other_system_parachains_works() { #[test] fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id()); - let asset_location_on_penpal = PenpalLocalTeleportableToAssetHub::get(); + let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get(); let asset_id_on_penpal = match asset_location_on_penpal.last() { - Some(GeneralIndex(id)) => *id as u32, + Some(v3::Junction::GeneralIndex(id)) => *id as u32, _ => unreachable!(), }; let asset_owner_on_penpal = PenpalBSender::get(); let foreign_asset_at_asset_hub_westend = - MultiLocation { parents: 1, interior: X1(Parachain(PenpalB::para_id().into())) } + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) .appended_with(asset_location_on_penpal) .unwrap(); super::penpal_create_foreign_asset_on_asset_hub( asset_id_on_penpal, foreign_asset_at_asset_hub_westend, - ah_as_seen_by_penpal, + ah_as_seen_by_penpal.clone(), false, asset_owner_on_penpal, ASSET_MIN_BALANCE * 1_000_000, @@ -580,9 +582,10 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000; let asset_amount_to_send = ASSET_MIN_BALANCE * 1000; - let penpal_assets: MultiAssets = vec![ + let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap(); + let penpal_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (asset_location_on_penpal, asset_amount_to_send).into(), + (asset_location_on_penpal_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = penpal_assets @@ -670,11 +673,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() { )); }); + let foreign_asset_at_asset_hub_westend_latest: Location = + foreign_asset_at_asset_hub_westend.try_into().unwrap(); let ah_to_penpal_beneficiary_id = PenpalBReceiver::get(); let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalB::para_id()); - let ah_assets: MultiAssets = vec![ + let ah_assets: Assets = vec![ (Parent, fee_amount_to_send).into(), - (foreign_asset_at_asset_hub_westend, asset_amount_to_send).into(), + (foreign_asset_at_asset_hub_westend_latest, asset_amount_to_send).into(), ] .into(); let fee_asset_index = ah_assets diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs index 32089f7ecec..8e82059a32d 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/treasury.rs @@ -24,19 +24,19 @@ fn create_and_claim_treasury_spend() { const ASSET_ID: u32 = 1984; const SPEND_AMOUNT: u128 = 1_000_000; // treasury location from a sibling parachain. - let treasury_location: MultiLocation = MultiLocation::new(1, PalletInstance(37)); + let treasury_location: Location = Location::new(1, PalletInstance(37)); // treasury account on a sibling parachain. let treasury_account = asset_hub_westend_runtime::xcm_config::LocationToAccountId::convert_location( &treasury_location, ) .unwrap(); - let asset_hub_location = MultiLocation::new(0, Parachain(AssetHubWestend::para_id().into())); + let asset_hub_location = Location::new(0, Parachain(AssetHubWestend::para_id().into())); let root = ::RuntimeOrigin::root(); // asset kind to be spend from the treasury. - let asset_kind = VersionedLocatableAsset::V3 { + let asset_kind = VersionedLocatableAsset::V4 { location: asset_hub_location, - asset_id: AssetId::Concrete((PalletInstance(50), GeneralIndex(ASSET_ID.into())).into()), + asset_id: AssetId([PalletInstance(50), GeneralIndex(ASSET_ID.into())].into()), }; // treasury spend beneficiary. let alice: AccountId = Westend::account_id_of(ALICE); @@ -71,7 +71,7 @@ fn create_and_claim_treasury_spend() { root, Box::new(asset_kind), SPEND_AMOUNT, - Box::new(MultiLocation::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), None, )); // claim the spend. diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index 608aa388ce8..0039eb087fe 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -22,7 +22,7 @@ pub use xcm::{ latest::ParentThen, prelude::{AccountId32 as AccountId32Junction, *}, v3::{ - Error, + self, Error, NetworkId::{Rococo as RococoId, Westend as WestendId}, }, }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs index 8b5a72a8e62..a203de0f8c9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs @@ -15,14 +15,14 @@ use crate::tests::*; -fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amount: u128) { +fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: Location, amount: u128) { let destination = asset_hub_westend_location(); // fund the AHR's SA on BHR for paying bridge transport fees BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), 10_000_000_000_000u128); // set XCM versions - AssetHubRococo::force_xcm_version(destination, XCM_VERSION); + AssetHubRococo::force_xcm_version(destination.clone(), XCM_VERSION); BridgeHubRococo::force_xcm_version(bridge_hub_westend_location(), XCM_VERSION); // send message over bridge @@ -33,9 +33,9 @@ fn send_asset_from_asset_hub_rococo_to_asset_hub_westend(id: MultiLocation, amou #[test] fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { - let roc_at_asset_hub_rococo: MultiLocation = Parent.into(); + let roc_at_asset_hub_rococo: v3::Location = v3::Parent.into(); let roc_at_asset_hub_westend = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubWestend::force_create_foreign_asset( roc_at_asset_hub_westend, @@ -62,7 +62,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(roc_at_asset_hub_westend), )); @@ -75,7 +75,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubWestendSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(roc_at_asset_hub_westend), 1_000_000_000_000, 2_000_000_000_000, @@ -101,8 +101,9 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { >::balance(roc_at_asset_hub_westend, &AssetHubWestendReceiver::get()) }); + let roc_at_asset_hub_rococo_latest: Location = roc_at_asset_hub_rococo.try_into().unwrap(); let amount = ASSET_HUB_ROCOCO_ED * 1_000_000; - send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo, amount); + send_asset_from_asset_hub_rococo_to_asset_hub_westend(roc_at_asset_hub_rococo_latest, amount); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( @@ -142,7 +143,7 @@ fn send_rocs_from_asset_hub_rococo_to_asset_hub_westend() { fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() { let prefund_amount = 10_000_000_000_000u128; let wnd_at_asset_hub_rococo = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubRococo::force_create_foreign_asset( wnd_at_asset_hub_rococo, @@ -170,8 +171,12 @@ fn send_wnds_from_asset_hub_rococo_to_asset_hub_westend() { let receiver_wnds_before = ::account_data_of(AssetHubWestendReceiver::get()).free; + let wnd_at_asset_hub_rococo_latest: Location = wnd_at_asset_hub_rococo.try_into().unwrap(); let amount_to_send = ASSET_HUB_WESTEND_ED * 1_000; - send_asset_from_asset_hub_rococo_to_asset_hub_westend(wnd_at_asset_hub_rococo, amount_to_send); + send_asset_from_asset_hub_rococo_to_asset_hub_westend( + wnd_at_asset_hub_rococo_latest.clone(), + amount_to_send, + ); AssetHubWestend::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs index e71a022af4c..a33d2fab753 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs @@ -20,37 +20,31 @@ mod send_xcm; mod snowbridge; mod teleport; -pub(crate) fn asset_hub_westend_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Westend), - Parachain(AssetHubWestend::para_id().into()), - ), - } +pub(crate) fn asset_hub_westend_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Westend), Parachain(AssetHubWestend::para_id().into())], + ) } -pub(crate) fn bridge_hub_westend_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Westend), - Parachain(BridgeHubWestend::para_id().into()), - ), - } +pub(crate) fn bridge_hub_westend_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Westend), Parachain(BridgeHubWestend::para_id().into())], + ) } pub(crate) fn send_asset_from_asset_hub_rococo( - destination: MultiLocation, - (id, amount): (MultiLocation, u128), + destination: Location, + (id, amount): (Location, u128), ) -> DispatchResult { let signed_origin = ::RuntimeOrigin::signed(AssetHubRococoSender::get().into()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into(); - let assets: MultiAssets = (id, amount).into(); + let assets: Assets = (id, amount).into(); let fee_asset_item = 0; AssetHubRococo::execute_with(|| { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs index a3a7d96a14a..a1d871cdb61 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs @@ -29,8 +29,8 @@ fn send_xcm_from_rococo_relay_to_westend_asset_hub_should_fail_on_not_applicable let xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit, check_origin }, ExportMessage { - network: WestendId, - destination: X1(Parachain(AssetHubWestend::para_id().into())), + network: WestendId.into(), + destination: [Parachain(AssetHubWestend::para_id().into())].into(), xcm: remote_xcm, }, ])); @@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // prepare data let destination = asset_hub_westend_location(); - let native_token = MultiLocation::parent(); + let native_token = Location::parent(); let amount = ASSET_HUB_ROCOCO_ED * 1_000; // fund the AHR's SA on BHR for paying bridge transport fees @@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // send XCM from AssetHubRococo - fails - destination version not known assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // set destination version - AssetHubRococo::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION); + AssetHubRococo::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION); // TODO: remove this block, when removing `xcm:v2` { @@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // version, which does not have the `ExportMessage` instruction. If the default `2` is // changed to `3`, then this assert can go away" assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubRococo - fails - `ExportMessage` is not in `2` assert_err!( - send_asset_from_asset_hub_rococo(destination, (native_token, amount)), + send_asset_from_asset_hub_rococo(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { xcm::v3::prelude::XCM_VERSION, ); // send XCM from AssetHubRococo - ok - assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_rococo( + destination.clone(), + (native_token.clone(), amount) + )); // `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known assert_bridge_hub_rococo_message_accepted(false); @@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubRococo - ok - assert_ok!(send_asset_from_asset_hub_rococo(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_rococo( + destination.clone(), + (native_token.clone(), amount) + )); assert_bridge_hub_rococo_message_accepted(true); assert_bridge_hub_westend_message_received(); // message delivered and processed at destination diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 85547f210a7..fe0e479d8e5 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -61,7 +61,7 @@ fn create_agent() { let remote_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -109,14 +109,14 @@ fn create_channel() { BridgeHubRococo::fund_para_sovereign(origin_para.into(), INITIAL_FUND); let sudo_origin = ::RuntimeOrigin::root(); - let destination: VersionedMultiLocation = + let destination: VersionedLocation = Rococo::child_location_of(BridgeHubRococo::para_id()).into(); let create_agent_call = SnowbridgeControl::Control(ControlCall::CreateAgent {}); let create_agent_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -129,7 +129,7 @@ fn create_channel() { let create_channel_xcm = VersionedXcm::from(Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - DescendOrigin(X1(Parachain(origin_para))), + DescendOrigin(Parachain(origin_para).into()), Transact { require_weight_at_most: 3000000000.into(), origin_kind: OriginKind::Xcm, @@ -218,10 +218,10 @@ fn register_weth_token_from_ethereum_to_asset_hub() { #[test] fn send_token_from_ethereum_to_penpal() { - let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation { - parents: 1, - interior: X1(Parachain(AssetHubRococo::para_id().into())), - }); + let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new( + 1, + [Parachain(AssetHubRococo::para_id().into())], + )); BridgeHubRococo::fund_accounts(vec![(asset_hub_sovereign.clone(), INITIAL_FUND)]); PenpalA::fund_accounts(vec![ @@ -229,9 +229,9 @@ fn send_token_from_ethereum_to_penpal() { (PenpalASender::get(), INITIAL_FUND), ]); - let weth_asset_location: MultiLocation = + let weth_asset_location: Location = (Parent, Parent, EthereumNetwork::get(), AccountKey20 { network: None, key: WETH }).into(); - let weth_asset_id = weth_asset_location.into(); + let weth_asset_id: v3::Location = weth_asset_location.try_into().unwrap(); let origin_location = (Parent, Parent, EthereumNetwork::get()).into(); @@ -375,18 +375,15 @@ fn send_token_from_ethereum_to_asset_hub() { #[test] fn send_weth_asset_from_asset_hub_to_ethereum() { use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee; - let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(MultiLocation { - parents: 1, - interior: X1(Parachain(AssetHubRococo::para_id().into())), - }); + let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new( + 1, + [Parachain(AssetHubRococo::para_id().into())], + )); AssetHubRococo::force_default_xcm_version(Some(XCM_VERSION)); BridgeHubRococo::force_default_xcm_version(Some(XCM_VERSION)); AssetHubRococo::force_xcm_version( - MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })), - }, + Location::new(2, [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })]), XCM_VERSION, ); @@ -437,27 +434,27 @@ fn send_weth_asset_from_asset_hub_to_ethereum() { RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, ] ); - let assets = vec![MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X2( + let assets = vec![Asset { + id: AssetId(Location::new( + 2, + [ GlobalConsensus(Ethereum { chain_id: CHAIN_ID }), AccountKey20 { network: None, key: WETH }, - ), - }), + ], + )), fun: Fungible(WETH_AMOUNT), }]; - let multi_assets = VersionedMultiAssets::V3(MultiAssets::from(assets)); + let multi_assets = VersionedAssets::V4(Assets::from(assets)); - let destination = VersionedMultiLocation::V3(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Ethereum { chain_id: CHAIN_ID })), - }); + let destination = VersionedLocation::V4(Location::new( + 2, + [GlobalConsensus(Ethereum { chain_id: CHAIN_ID })], + )); - let beneficiary = VersionedMultiLocation::V3(MultiLocation { - parents: 0, - interior: X1(AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }), - }); + let beneficiary = VersionedLocation::V4(Location::new( + 0, + [AccountKey20 { network: None, key: ETHEREUM_DESTINATION_ADDRESS.into() }], + )); let free_balance_before = ::Balances::free_balance( AssetHubRococoReceiver::get(), diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs index f00288a4d8c..43f8af9244f 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/teleport.rs @@ -19,7 +19,7 @@ use bridge_hub_rococo_runtime::xcm_config::XcmConfig; #[test] fn teleport_to_other_system_parachains_works() { let amount = BRIDGE_HUB_ROCOCO_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( BridgeHubRococo, // Origin diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs index 17255320f1d..223979cc9c9 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/lib.rs @@ -21,7 +21,8 @@ pub use sp_runtime::DispatchError; pub use xcm::{ latest::ParentThen, prelude::{AccountId32 as AccountId32Junction, *}, - v3::{ + v3, + v4::{ Error, NetworkId::{Rococo as RococoId, Westend as WestendId}, }, diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs index a4b2719e9fd..c2a9c008902 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs @@ -14,14 +14,14 @@ // limitations under the License. use crate::tests::*; -fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amount: u128) { +fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: Location, amount: u128) { let destination = asset_hub_rococo_location(); // fund the AHW's SA on BHW for paying bridge transport fees BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), 10_000_000_000_000u128); // set XCM versions - AssetHubWestend::force_xcm_version(destination, XCM_VERSION); + AssetHubWestend::force_xcm_version(destination.clone(), XCM_VERSION); BridgeHubWestend::force_xcm_version(bridge_hub_rococo_location(), XCM_VERSION); // send message over bridge @@ -32,9 +32,9 @@ fn send_asset_from_asset_hub_westend_to_asset_hub_rococo(id: MultiLocation, amou #[test] fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { - let wnd_at_asset_hub_westend: MultiLocation = Parent.into(); + let wnd_at_asset_hub_westend: Location = Parent.into(); let wnd_at_asset_hub_rococo = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Westend)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Westend)]); let owner: AccountId = AssetHubRococo::account_id_of(ALICE); AssetHubRococo::force_create_foreign_asset( wnd_at_asset_hub_rococo, @@ -61,7 +61,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(wnd_at_asset_hub_rococo), )); @@ -74,7 +74,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubRococoSender::get()), - Box::new(Parent.into()), + Box::new(xcm::v3::Parent.into()), Box::new(wnd_at_asset_hub_rococo), 1_000_000_000_000, 2_000_000_000_000, @@ -141,7 +141,7 @@ fn send_wnds_from_asset_hub_westend_to_asset_hub_rococo() { fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() { let prefund_amount = 10_000_000_000_000u128; let roc_at_asset_hub_westend = - MultiLocation { parents: 2, interior: X1(GlobalConsensus(NetworkId::Rococo)) }; + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Rococo)]); let owner: AccountId = AssetHubWestend::account_id_of(ALICE); AssetHubWestend::force_create_foreign_asset( roc_at_asset_hub_westend, @@ -169,8 +169,12 @@ fn send_rocs_from_asset_hub_westend_to_asset_hub_rococo() { let receiver_rocs_before = ::account_data_of(AssetHubRococoReceiver::get()).free; + let roc_at_asset_hub_westend_latest: Location = roc_at_asset_hub_westend.try_into().unwrap(); let amount_to_send = ASSET_HUB_ROCOCO_ED * 1_000; - send_asset_from_asset_hub_westend_to_asset_hub_rococo(roc_at_asset_hub_westend, amount_to_send); + send_asset_from_asset_hub_westend_to_asset_hub_rococo( + roc_at_asset_hub_westend_latest.clone(), + amount_to_send, + ); AssetHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs index ec2e68fc889..186b96b3976 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs @@ -19,37 +19,31 @@ mod asset_transfers; mod send_xcm; mod teleport; -pub(crate) fn asset_hub_rococo_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Rococo), - Parachain(AssetHubRococo::para_id().into()), - ), - } +pub(crate) fn asset_hub_rococo_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Rococo), Parachain(AssetHubRococo::para_id().into())], + ) } -pub(crate) fn bridge_hub_rococo_location() -> MultiLocation { - MultiLocation { - parents: 2, - interior: X2( - GlobalConsensus(NetworkId::Rococo), - Parachain(BridgeHubRococo::para_id().into()), - ), - } +pub(crate) fn bridge_hub_rococo_location() -> Location { + Location::new( + 2, + [GlobalConsensus(NetworkId::Rococo), Parachain(BridgeHubRococo::para_id().into())], + ) } pub(crate) fn send_asset_from_asset_hub_westend( - destination: MultiLocation, - (id, amount): (MultiLocation, u128), + destination: Location, + (id, amount): (Location, u128), ) -> DispatchResult { let signed_origin = ::RuntimeOrigin::signed(AssetHubWestendSender::get().into()); - let beneficiary: MultiLocation = + let beneficiary: Location = AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into(); - let assets: MultiAssets = (id, amount).into(); + let assets: Assets = (id, amount).into(); let fee_asset_item = 0; AssetHubWestend::execute_with(|| { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs index 0773cbb0599..b01be5e8dc8 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs @@ -30,7 +30,7 @@ fn send_xcm_from_westend_relay_to_rococo_asset_hub_should_fail_on_not_applicable UnpaidExecution { weight_limit, check_origin }, ExportMessage { network: RococoId, - destination: X1(Parachain(AssetHubRococo::para_id().into())), + destination: [Parachain(AssetHubRococo::para_id().into())].into(), xcm: remote_xcm, }, ])); @@ -68,7 +68,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // prepare data let destination = asset_hub_rococo_location(); - let native_token = MultiLocation::parent(); + let native_token = Location::parent(); let amount = ASSET_HUB_WESTEND_ED * 1_000; // fund the AHR's SA on BHR for paying bridge transport fees @@ -78,7 +78,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // send XCM from AssetHubWestend - fails - destination version not known assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -87,7 +87,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // set destination version - AssetHubWestend::force_xcm_version(destination, xcm::v3::prelude::XCM_VERSION); + AssetHubWestend::force_xcm_version(destination.clone(), xcm::v3::prelude::XCM_VERSION); // TODO: remove this block, when removing `xcm:v2` { @@ -95,7 +95,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { // version, which does not have the `ExportMessage` instruction. If the default `2` is // changed to `3`, then this assert can go away" assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -110,7 +110,7 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubWestend - fails - `ExportMessage` is not in `2` assert_err!( - send_asset_from_asset_hub_westend(destination, (native_token, amount)), + send_asset_from_asset_hub_westend(destination.clone(), (native_token.clone(), amount)), DispatchError::Module(sp_runtime::ModuleError { index: 31, error: [1, 0, 0, 0], @@ -125,7 +125,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { xcm::v3::prelude::XCM_VERSION, ); // send XCM from AssetHubWestend - ok - assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_westend( + destination.clone(), + (native_token.clone(), amount) + )); // `ExportMessage` on local BridgeHub - fails - remote BridgeHub version not known assert_bridge_hub_westend_message_accepted(false); @@ -142,7 +145,10 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() { ); // send XCM from AssetHubWestend - ok - assert_ok!(send_asset_from_asset_hub_westend(destination, (native_token, amount))); + assert_ok!(send_asset_from_asset_hub_westend( + destination.clone(), + (native_token.clone(), amount) + )); assert_bridge_hub_westend_message_accepted(true); assert_bridge_hub_rococo_message_received(); // message delivered and processed at destination diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs index 8dff6c29295..edffaf16596 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/teleport.rs @@ -19,7 +19,7 @@ use bridge_hub_westend_runtime::xcm_config::XcmConfig; #[test] fn teleport_to_other_system_parachains_works() { let amount = BRIDGE_HUB_WESTEND_ED * 100; - let native_asset: MultiAssets = (Parent, amount).into(); + let native_asset: Assets = (Parent, amount).into(); test_parachain_is_trusted_teleporter!( BridgeHubWestend, // Origin diff --git a/cumulus/parachains/pallets/ping/src/lib.rs b/cumulus/parachains/pallets/ping/src/lib.rs index feda3d0b6f9..a738c05e036 100644 --- a/cumulus/parachains/pallets/ping/src/lib.rs +++ b/cumulus/parachains/pallets/ping/src/lib.rs @@ -77,9 +77,9 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - PingSent(ParaId, u32, Vec, XcmHash, MultiAssets), + PingSent(ParaId, u32, Vec, XcmHash, Assets), Pinged(ParaId, u32, Vec), - PongSent(ParaId, u32, Vec, XcmHash, MultiAssets), + PongSent(ParaId, u32, Vec, XcmHash, Assets), Ponged(ParaId, u32, Vec, BlockNumberFor), ErrorSendingPing(SendError, ParaId, u32, Vec), ErrorSendingPong(SendError, ParaId, u32, Vec), diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 8cfa4565187..53b41892685 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -31,7 +31,7 @@ use assets_common::{ foreign_creators::ForeignCreators, local_and_foreign_assets::{LocalFromLeft, TargetFromLeft}, matching::{FromNetwork, FromSiblingParachain}, - AssetIdForTrustBackedAssetsConvert, MultiLocationForAssetId, + AssetIdForTrustBackedAssetsConvert, }; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; @@ -80,13 +80,11 @@ use parachains_common::{ Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; - use sp_runtime::{Perbill, RuntimeDebug}; -use xcm::opaque::v3::MultiLocation; use xcm_config::{ ForeignAssetsConvertedConcreteId, ForeignCreatorsSovereignAccountOf, GovernanceLocation, - PoolAssetsConvertedConcreteId, TokenLocation, TrustBackedAssetsConvertedConcreteId, - TrustBackedAssetsPalletLocation, + PoolAssetsConvertedConcreteId, TokenLocation, TokenLocationV3, + TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3, }; #[cfg(any(feature = "std", test))] @@ -95,7 +93,13 @@ pub use sp_runtime::BuildStorage; // Polkadot imports use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; -use xcm::latest::prelude::*; +// We exclude `Assets` since it's the name of a pallet +#[cfg(feature = "runtime-benchmarks")] +use xcm::latest::prelude::{ + Asset, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, + NonFungible, Parent, ParentThen, Response, XCM_VERSION, +}; +use xcm::latest::prelude::{AssetId, BodyId}; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; @@ -317,10 +321,11 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, + xcm::v3::Location, >, - MultiLocation, + xcm::v3::Location, AccountId, >; @@ -328,8 +333,8 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< pub type NativeAndAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, - TargetFromLeft, - MultiLocation, + TargetFromLeft, + xcm::v3::Location, AccountId, >; @@ -337,15 +342,15 @@ impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; - type AssetKind = MultiLocation; + type AssetKind = xcm::v3::Location; type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = - pallet_asset_conversion::WithFirstAsset; + pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam - type PoolSetupFeeAsset = TokenLocation; + type PoolSetupFeeAsset = TokenLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; @@ -355,9 +360,10 @@ impl pallet_asset_conversion::Config for Runtime { type WeightInfo = weights::pallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< - TokenLocation, + TokenLocationV3, parachain_info::Pallet, - xcm_config::AssetsPalletIndex, + xcm_config::TrustBackedAssetsPalletIndex, + xcm::v3::Location, >; } @@ -379,16 +385,17 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::MultiLocation; + type AssetIdParameter = xcm::v3::MultiLocation; type Currency = Balances; type CreateOrigin = ForeignCreators< ( - FromSiblingParachain>, - FromNetwork, + FromSiblingParachain, xcm::v3::Location>, + FromNetwork, ), ForeignCreatorsSovereignAccountOf, AccountId, + xcm::v3::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; @@ -664,7 +671,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -753,7 +760,7 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = - AssetConversionAdapter; + AssetConversionAdapter; } parameter_types! { @@ -1157,18 +1164,16 @@ impl_runtime_apis! { impl pallet_asset_conversion::AssetConversionApi< Block, Balance, - MultiLocation, + xcm::v3::Location, > for Runtime { - fn quote_price_exact_tokens_for_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_exact_tokens_for_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } - - fn quote_price_tokens_for_exact_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_tokens_for_exact_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } - - fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> { + fn get_reserves(asset1: xcm::v3::Location, asset2: xcm::v3::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } @@ -1222,7 +1227,7 @@ impl_runtime_apis! { AccountId, > for Runtime { - fn query_account_balances(account: AccountId) -> Result { + fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pallet_balance @@ -1346,45 +1351,45 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // AH can reserve transfer native token to some random parachain. let random_para_id = 43211234; ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( random_para_id.into() ); Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, ParentThen(Parachain(random_para_id).into()).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(xcm::v4::Assets, u32, Location, Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) let dest = Parent.into(); let fee_amount = EXISTENTIAL_DEPOSIT; - let fee_asset: MultiAsset = (MultiLocation::parent(), fee_amount).into(); + let fee_asset: Asset = (Location::parent(), fee_amount).into(); let who = frame_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit @@ -1402,13 +1407,13 @@ impl_runtime_apis! { Runtime, pallet_assets::Instance1 >(true, initial_asset_amount); - let asset_location = MultiLocation::new( + let asset_location = Location::new( 0, - X2(PalletInstance(50), GeneralIndex(u32::from(asset_id).into())) + [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); - let transfer_asset: MultiAsset = (asset_location, asset_amount).into(); + let transfer_asset: Asset = (asset_location, asset_amount).into(); - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset].into(); + let assets: xcm::v4::Assets = vec![fee_asset.clone(), transfer_asset].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully @@ -1432,14 +1437,14 @@ impl_runtime_apis! { xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } - fn ensure_bridged_target_destination() -> Result { + fn ensure_bridged_target_destination() -> Result { ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_westend::AssetHubWestend::get(); let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), - Box::new(bridged_asset_hub), + Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { log::error!( @@ -1455,12 +1460,11 @@ impl_runtime_apis! { } } - use xcm::latest::prelude::*; use xcm_config::{TokenLocation, MaxAssetsIntoHolding}; use pallet_xcm_benchmarks::asset_instance_from; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -1471,33 +1475,33 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(TokenLocation::get()) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> xcm::v4::Assets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles.saturating_sub(1); let fungibles_amount: u128 = 100; let mut assets = (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: GeneralIndex(i as u128).into(), fun: Fungible(fungibles_amount * i as u128), } }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: Here.into(), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: GeneralIndex(i as u128).into(), fun: NonFungible(asset_instance_from(i)), })) .collect::>(); - assets.push(MultiAsset { - id: Concrete(TokenLocation::get()), + assets.push(Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }); assets.into() @@ -1505,16 +1509,16 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( TokenLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; // AssetHubRococo trusts AssetHubWestend as reserve for WNDs - pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + pub TrustedReserve: Option<(Location, Asset)> = Some( ( xcm_config::bridging::to_westend::AssetHubWestend::get(), - MultiAsset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128)) + Asset::from((xcm_config::bridging::to_westend::WndLocation::get(), 1000000000000 as u128)) ) ); } @@ -1526,9 +1530,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(UNITS), } } @@ -1542,42 +1546,42 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(xcm::v4::Assets, xcm::v4::Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() { Some(alias) => Ok(alias), None => Err(BenchmarkError::Skip) } } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(TokenLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, xcm::v4::Assets), BenchmarkError> { let origin = TokenLocation::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: xcm::v4::Assets = (TokenLocation::get(), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } 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 2fbbd61654b..8e675ad0cf8 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 @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct AssetHubRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for AssetHubRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,43 +107,35 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for AssetHubRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index f88d1066488..98b23efc06e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -20,12 +20,12 @@ use super::{ ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ - local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, + local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, matching::{FromNetwork, FromSiblingParachain, IsForeignConcreteAsset}, - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess, @@ -64,26 +64,32 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const TokenLocation: MultiLocation = MultiLocation::parent(); + pub const TokenLocation: Location = Location::parent(); + pub const TokenLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Rococo; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); - pub AssetsPalletIndex: u32 = ::index() as u32; - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(AssetsPalletIndex::get() as u8).into(); - pub ForeignAssetsPalletLocation: MultiLocation = + pub TrustBackedAssetsPalletLocation: Location = + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); + pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); - pub PoolAssetsPalletLocation: MultiLocation = + pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub PoolAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub const GovernanceLocation: Location = Location::parent(); pub StakingPot: AccountId = CollatorSelection::account_id(); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -110,7 +116,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -128,7 +134,7 @@ pub type FungiblesTransactor = FungiblesAdapter< Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -145,8 +151,8 @@ pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConverte // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore assets that start explicitly with our `GlobalConsensus(NetworkId)`, means: - // - foreign assets from our consensus should be: `MultiLocation {parents: 1, - // X*(Parachain(xyz), ..)}` + // - foreign assets from our consensus should be: `Location {parents: 1, X*(Parachain(xyz), + // ..)}` // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` won't // be accepted here StartsWithExplicitGlobalConsensus, @@ -160,7 +166,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -180,7 +186,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -195,20 +201,32 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); -/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`. -pub struct LocalAndForeignAssetsMultiLocationMatcher; -impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher { - fn is_local(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - TrustBackedAssetsConvertedConcreteId::contains(location) +/// Simple `Location` matcher for Local and Foreign asset `Location`. +pub struct LocalAndForeignAssetsLocationMatcher; +impl MatchesLocalAndForeignAssetsLocation + for LocalAndForeignAssetsLocationMatcher +{ + fn is_local(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + TrustBackedAssetsConvertedConcreteId::contains(&latest_location) } - fn is_foreign(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - ForeignAssetsConvertedConcreteId::contains(location) + fn is_foreign(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + ForeignAssetsConvertedConcreteId::contains(&latest_location) } } -impl Contains for LocalAndForeignAssetsMultiLocationMatcher { - fn contains(location: &MultiLocation) -> bool { +impl Contains for LocalAndForeignAssetsLocationMatcher { + fn contains(location: &xcm::v3::Location) -> bool { Self::is_local(location) || Self::is_foreign(location) } } @@ -243,11 +261,11 @@ parameter_types! { pub XcmAssetFeesReceiver: Option = Authorship::author(); } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -556,12 +574,12 @@ impl xcm_executor::Config for XcmConfig { type Trader = ( UsingComponents>, cumulus_primitives_utility::SwapFirstAssetTrader< - TokenLocation, + TokenLocationV3, crate::AssetConversion, WeightToFee, crate::NativeAndAssets, ( - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, @@ -588,7 +606,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -664,9 +682,9 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } @@ -698,7 +716,7 @@ pub mod bridging { pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID; - pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + pub SiblingBridgeHub: Location = Location::new(1, [Parachain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = TokenLocation::get().into(); @@ -722,25 +740,25 @@ pub mod bridging { use super::*; parameter_types! { - pub SiblingBridgeHubWithBridgeHubWestendInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithBridgeHubWestendInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX) - ) + ] ); pub const WestendNetwork: NetworkId = NetworkId::Westend; - pub AssetHubWestend: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(WestendNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID))); - pub WndLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(WestendNetwork::get()))); + pub AssetHubWestend: Location = Location::new(2, [GlobalConsensus(WestendNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID)]); + pub WndLocation: Location = Location::new(2, [GlobalConsensus(WestendNetwork::get())]); - pub WndFromAssetHubWestend: (MultiAssetFilter, MultiLocation) = ( - Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), + pub WndFromAssetHubWestend: (AssetFilter, Location) = ( + Wild(AllOf { fun: WildFungible, id: AssetId(WndLocation::get()) }), AssetHubWestend::get() ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( WestendNetwork::get(), @@ -757,15 +775,15 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithBridgeHubWestendInstance::get(), GlobalConsensus(WestendNetwork::get())) ] ); } - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -804,16 +822,16 @@ pub mod bridging { /// Polkadot uses 10 decimals, Kusama and Rococo 12 decimals. pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000; pub storage BridgeHubEthereumBaseFee: Balance = DefaultBridgeHubEthereumBaseFee::get(); - pub SiblingBridgeHubWithEthereumInboundQueueInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithEthereumInboundQueueInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(parachains_common::rococo::snowbridge::INBOUND_QUEUE_PALLET_INDEX) - ) + ] ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( EthereumNetwork::get(), @@ -827,7 +845,7 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithEthereumInboundQueueInstance::get(), GlobalConsensus(EthereumNetwork::get())), ] @@ -837,8 +855,8 @@ pub mod bridging { pub type IsTrustedBridgedReserveLocationForForeignAsset = matching::IsForeignConcreteAsset>; - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -850,7 +868,7 @@ pub mod bridging { #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { - pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_westend::UniversalAliases::get() .into_iter() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index c67374126d3..3da1a1e66bd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -19,12 +19,18 @@ use asset_hub_rococo_runtime::{ xcm_config, - xcm_config::{bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation}, + xcm_config::{ + bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation, + TokenLocationV3, + }, AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, }; pub use asset_hub_rococo_runtime::{ - xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + xcm_config::{ + CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + XcmConfig, + }, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, TrustBackedAssetsInstance, @@ -49,14 +55,18 @@ use parachains_common::{ }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; -use xcm::latest::prelude::*; -use xcm_executor::traits::{Identity, JustTry, WeightTrader}; +use xcm::latest::prelude::{Assets as XcmAssets, *}; +use xcm_builder::V4V3LocationConverter; +use xcm_executor::traits::{JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = - assets_common::AssetIdForTrustBackedAssetsConvert; + assets_common::AssetIdForTrustBackedAssetsConvert; + +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; type RuntimeHelper = asset_test_utils::RuntimeHelper; @@ -99,7 +109,7 @@ fn test_buy_and_refund_weight_in_native() { let fee = WeightToFee::weight_to_fee(&weight); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (native_location, fee + extra_amount).into(); + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -108,7 +118,7 @@ fn test_buy_and_refund_weight_in_native() { // assert. let unused_amount = - unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Balances::total_issuance(), total_issuance); @@ -144,7 +154,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); let asset_1: u32 = 1; - let native_location = TokenLocation::get(); + let native_location = TokenLocationV3::get(); let asset_1_location = AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); // bob's initial balance for native and `asset1` assets. @@ -180,6 +190,8 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let asset_total_issuance = Assets::total_issuance(asset_1); let native_total_issuance = Balances::total_issuance(); + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -187,7 +199,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -195,8 +207,10 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); @@ -210,7 +224,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -239,9 +253,15 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { .execute_with(|| { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); - let native_location = TokenLocation::get(); - let foreign_location = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let native_location = TokenLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; // bob's initial balance for native and `asset1` assets. let initial_balance = 200 * UNITS; // liquidity for both arms of (native, asset1) pool. @@ -280,6 +300,8 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); let native_total_issuance = Balances::total_issuance(); + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -287,7 +309,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -295,8 +317,10 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!( ForeignAssets::total_issuance(foreign_location), @@ -313,7 +337,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -343,19 +367,21 @@ fn test_assets_balances_api_works() { .build() .execute_with(|| { let local_asset_id = 1; - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let foreign_asset_id_location = xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(1234), xcm::v3::Junction::GeneralIndex(12345)], + ); // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 0 ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() - .try_as::() + .try_as::() .unwrap() .is_none()); @@ -386,7 +412,7 @@ fn test_assets_balances_api_works() { let foreign_asset_minimum_asset_balance = 3333333_u128; assert_ok!(ForeignAssets::force_create( RuntimeHelper::root_origin(), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(SOME_ASSET_ADMIN).into(), false, foreign_asset_minimum_asset_balance @@ -395,7 +421,7 @@ fn test_assets_balances_api_works() { // We first mint enough asset for the account to exist for assets assert_ok!(ForeignAssets::mint( RuntimeHelper::origin_of(AccountId::from(SOME_ASSET_ADMIN)), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(ALICE).into(), 6 * foreign_asset_minimum_asset_balance )); @@ -406,12 +432,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 6 * minimum_asset_balance ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency); - let result: MultiAssets = Runtime::query_account_balances(AccountId::from(ALICE)) + let result: XcmAssets = Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() .try_into() .unwrap(); @@ -426,13 +452,13 @@ fn test_assets_balances_api_works() { ))); // check trusted asset assert!(result.inner().iter().any(|asset| asset.eq(&( - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(), + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(), minimum_asset_balance ) .into()))); // check foreign asset assert!(result.inner().iter().any(|asset| asset.eq(&( - Identity::convert_back(&foreign_asset_id_multilocation).unwrap(), + V4V3LocationConverter::convert_back(&foreign_asset_id_location).unwrap(), 6 * foreign_asset_minimum_asset_balance ) .into()))); @@ -503,7 +529,7 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ XcmConfig, TrustBackedAssetsInstance, AssetIdForTrustBackedAssets, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, collator_session_keys(), ExistentialDeposit::get(), 12345, @@ -520,11 +546,14 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ Runtime, XcmConfig, ForeignAssetsInstance, - MultiLocation, + xcm::v3::Location, JustTry, collator_session_keys(), ExistentialDeposit::get(), - MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(1313), xcm::v3::Junction::GeneralIndex(12345)] + ), Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); }), @@ -539,8 +568,8 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p WeightToFee, ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, - MultiLocation, - JustTry, + xcm::v3::Location, + V4V3LocationConverter, collator_session_keys(), ExistentialDeposit::get(), AssetDeposit::get(), @@ -637,12 +666,12 @@ mod asset_hub_rococo_tests { AccountId::from([73; 32]), AccountId::from(BLOCK_AUTHOR_ACCOUNT), // receiving WNDs - (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Westend)) }, 1000000000000, 1_000_000_000), + (xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Westend)]), 1000000000000, 1_000_000_000), bridging_to_asset_hub_westend, ( - X1(PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX)), + [PalletInstance(bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX)].into(), GlobalConsensus(Westend), - X1(Parachain(1000)) + [Parachain(1000)].into() ) ) } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 8543500fa23..cf10c0ac052 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -76,21 +76,25 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::opaque::v3::MultiLocation; use xcm_config::{ ForeignAssetsConvertedConcreteId, PoolAssetsConvertedConcreteId, - TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocation, WestendLocation, - XcmOriginToTransactDispatchOrigin, + TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3, WestendLocation, + WestendLocationV3, XcmOriginToTransactDispatchOrigin, }; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -use assets_common::{ - foreign_creators::ForeignCreators, matching::FromSiblingParachain, MultiLocationForAssetId, -}; +use assets_common::{foreign_creators::ForeignCreators, matching::FromSiblingParachain}; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; -use xcm::latest::prelude::*; +// We exclude `Assets` since it's the name of a pallet +use xcm::latest::prelude::AssetId; + +#[cfg(feature = "runtime-benchmarks")] +use xcm::latest::prelude::{ + Asset, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, NetworkId, + NonFungible, Parent, ParentThen, Response, XCM_VERSION, +}; use crate::xcm_config::ForeignCreatorsSovereignAccountOf; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; @@ -300,10 +304,11 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< Assets, ForeignAssets, LocalFromLeft< - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvert, AssetIdForTrustBackedAssets, + xcm::v3::Location, >, - MultiLocation, + xcm::v3::Location, AccountId, >; @@ -311,8 +316,8 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< pub type NativeAndAssets = fungible::UnionOf< Balances, LocalAndForeignAssets, - TargetFromLeft, - MultiLocation, + TargetFromLeft, + xcm::v3::Location, AccountId, >; @@ -320,15 +325,15 @@ impl pallet_asset_conversion::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; - type AssetKind = MultiLocation; + type AssetKind = xcm::v3::Location; type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = - pallet_asset_conversion::WithFirstAsset; + pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam - type PoolSetupFeeAsset = WestendLocation; + type PoolSetupFeeAsset = WestendLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; @@ -338,9 +343,10 @@ impl pallet_asset_conversion::Config for Runtime { type WeightInfo = weights::pallet_asset_conversion::WeightInfo; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< - WestendLocation, + WestendLocationV3, parachain_info::Pallet, - xcm_config::AssetsPalletIndex, + xcm_config::TrustBackedAssetsPalletIndex, + xcm::v3::Location, >; } @@ -362,13 +368,14 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::Location; + type AssetIdParameter = xcm::v3::Location; type Currency = Balances; type CreateOrigin = ForeignCreators< - (FromSiblingParachain>,), + FromSiblingParachain, xcm::v3::Location>, ForeignCreatorsSovereignAccountOf, AccountId, + xcm::v3::Location, >; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ForeignAssetsAssetDeposit; @@ -644,7 +651,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WestendLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -728,7 +735,7 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Fungibles = LocalAndForeignAssets; type OnChargeAssetTransaction = - AssetConversionAdapter; + AssetConversionAdapter; } parameter_types! { @@ -1229,18 +1236,18 @@ impl_runtime_apis! { impl pallet_asset_conversion::AssetConversionApi< Block, Balance, - MultiLocation, + xcm::v3::Location, > for Runtime { - fn quote_price_exact_tokens_for_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_exact_tokens_for_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_exact_tokens_for_tokens(asset1, asset2, amount, include_fee) } - fn quote_price_tokens_for_exact_tokens(asset1: MultiLocation, asset2: MultiLocation, amount: Balance, include_fee: bool) -> Option { + fn quote_price_tokens_for_exact_tokens(asset1: xcm::v3::Location, asset2: xcm::v3::Location, amount: Balance, include_fee: bool) -> Option { AssetConversion::quote_price_tokens_for_exact_tokens(asset1, asset2, amount, include_fee) } - fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> { + fn get_reserves(asset1: xcm::v3::Location, asset2: xcm::v3::Location) -> Option<(Balance, Balance)> { AssetConversion::get_reserves(asset1, asset2).ok() } } @@ -1294,7 +1301,7 @@ impl_runtime_apis! { AccountId, > for Runtime { - fn query_account_balances(account: AccountId) -> Result { + fn query_account_balances(account: AccountId) -> Result { use assets_common::fungible_conversion::{convert, convert_balance}; Ok([ // collect pallet_balance @@ -1413,45 +1420,45 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // AH can reserve transfer native token to some random parachain. let random_para_id = 43211234; ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( random_para_id.into() ); Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, ParentThen(Parachain(random_para_id).into()).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(xcm::v4::Assets, u32, Location, Box)> { // Transfer to Relay some local AH asset (local-reserve-transfer) while paying // fees using teleported native token. // (We don't care that Relay doesn't accept incoming unknown AH local asset) let dest = Parent.into(); let fee_amount = EXISTENTIAL_DEPOSIT; - let fee_asset: MultiAsset = (MultiLocation::parent(), fee_amount).into(); + let fee_asset: Asset = (Location::parent(), fee_amount).into(); let who = frame_benchmarking::whitelisted_caller(); // Give some multiple of the existential deposit @@ -1469,13 +1476,13 @@ impl_runtime_apis! { Runtime, pallet_assets::Instance1 >(true, initial_asset_amount); - let asset_location = MultiLocation::new( + let asset_location = Location::new( 0, - X2(PalletInstance(50), GeneralIndex(u32::from(asset_id).into())) + [PalletInstance(50), GeneralIndex(u32::from(asset_id).into())] ); - let transfer_asset: MultiAsset = (asset_location, asset_amount).into(); + let transfer_asset: Asset = (asset_location, asset_amount).into(); - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset].into(); + let assets: xcm::v4::Assets = vec![fee_asset.clone(), transfer_asset].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; // verify transferred successfully @@ -1504,14 +1511,14 @@ impl_runtime_apis! { xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); } - fn ensure_bridged_target_destination() -> Result { + fn ensure_bridged_target_destination() -> Result { ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( xcm_config::bridging::SiblingBridgeHubParaId::get().into() ); let bridged_asset_hub = xcm_config::bridging::to_rococo::AssetHubRococo::get(); let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), - Box::new(bridged_asset_hub), + Box::new(bridged_asset_hub.clone()), XCM_VERSION, ).map_err(|e| { log::error!( @@ -1527,12 +1534,11 @@ impl_runtime_apis! { } } - use xcm::latest::prelude::*; use xcm_config::{MaxAssetsIntoHolding, WestendLocation}; use pallet_xcm_benchmarks::asset_instance_from; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WestendLocation::get(), ExistentialDeposit::get() ).into()); @@ -1543,33 +1549,33 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WestendLocation::get()) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> xcm::v4::Assets { // A mix of fungible, non-fungible, and concrete assets. let holding_non_fungibles = MaxAssetsIntoHolding::get() / 2 - depositable_count; let holding_fungibles = holding_non_fungibles - 1; let fungibles_amount: u128 = 100; let mut assets = (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * i as u128), } }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>(); - assets.push(MultiAsset { - id: Concrete(WestendLocation::get()), + assets.push(Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS), }); assets.into() @@ -1577,16 +1583,16 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WestendLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; // AssetHubWestend trusts AssetHubRococo as reserve for ROCs - pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + pub TrustedReserve: Option<(Location, Asset)> = Some( ( xcm_config::bridging::to_rococo::AssetHubRococo::get(), - MultiAsset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128)) + Asset::from((xcm_config::bridging::to_rococo::RocLocation::get(), 1000000000000 as u128)) ) ); } @@ -1598,9 +1604,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WestendLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(UNITS), } } @@ -1614,42 +1620,42 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(xcm::v4::Assets, xcm::v4::Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { match xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() { Some(alias) => Ok(alias), None => Err(BenchmarkError::Skip) } } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WestendLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WestendLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, xcm::v4::Assets), BenchmarkError> { let origin = WestendLocation::get(); - let assets: MultiAssets = (Concrete(WestendLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: xcm::v4::Assets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } 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 bcd51167f97..8c77774da2d 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 @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,40 +49,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct AssetHubWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for AssetHubWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -110,44 +106,36 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for AssetHubWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 28876d1d454..b2498418cc7 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -20,12 +20,12 @@ use super::{ ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use assets_common::{ - local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, + local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, matching::{FromSiblingParachain, IsForeignConcreteAsset}, - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess, @@ -61,25 +61,31 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); + pub const WestendLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); - pub AssetsPalletIndex: u32 = ::index() as u32; - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(AssetsPalletIndex::get() as u8).into(); - pub ForeignAssetsPalletLocation: MultiLocation = + pub TrustBackedAssetsPalletLocation: Location = + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); + pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); - pub PoolAssetsPalletLocation: MultiLocation = + pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub PoolAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); pub StakingPot: AccountId = CollatorSelection::account_id(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -104,7 +110,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -122,7 +128,7 @@ pub type FungiblesTransactor = FungiblesAdapter< Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -139,8 +145,8 @@ pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConverte // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore asset which starts explicitly with our `GlobalConsensus(NetworkId)`, means: - // - foreign assets from our consensus should be: `MultiLocation {parents: 1, - // X*(Parachain(xyz), ..)} + // - foreign assets from our consensus should be: `Location {parents: 1, X*(Parachain(xyz), + // ..)} // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont // be accepted here StartsWithExplicitGlobalConsensus, @@ -154,7 +160,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -174,7 +180,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -189,21 +195,33 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); -/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`. -pub struct LocalAndForeignAssetsMultiLocationMatcher; -impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher { - fn is_local(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - TrustBackedAssetsConvertedConcreteId::contains(location) +/// Simple `Location` matcher for Local and Foreign asset `Location`. +pub struct LocalAndForeignAssetsLocationMatcher; +impl MatchesLocalAndForeignAssetsLocation + for LocalAndForeignAssetsLocationMatcher +{ + fn is_local(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + TrustBackedAssetsConvertedConcreteId::contains(&latest_location) } - fn is_foreign(location: &MultiLocation) -> bool { - use assets_common::fungible_conversion::MatchesMultiLocation; - ForeignAssetsConvertedConcreteId::contains(location) + fn is_foreign(location: &xcm::v3::Location) -> bool { + use assets_common::fungible_conversion::MatchesLocation; + let latest_location: Location = if let Ok(location) = (*location).try_into() { + location + } else { + return false; + }; + ForeignAssetsConvertedConcreteId::contains(&latest_location) } } -impl Contains for LocalAndForeignAssetsMultiLocationMatcher { - fn contains(location: &MultiLocation) -> bool { +impl Contains for LocalAndForeignAssetsLocationMatcher { + fn contains(location: &xcm::v3::Location) -> bool { Self::is_local(location) || Self::is_foreign(location) } } @@ -238,23 +256,30 @@ parameter_types! { pub XcmAssetFeesReceiver: Option = Authorship::author(); } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type FellowshipEntities: impl Contains = { - // Fellowship Plurality - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } | - // Fellowship Salary Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(64)) } | - // Fellowship Treasury Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(65)) } - }; - pub type AmbassadorEntities: impl Contains = { - // Ambassador Salary Pallet - MultiLocation { parents: 1, interior: X2(Parachain(1001), PalletInstance(74)) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct FellowshipEntities; +impl Contains for FellowshipEntities { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }]) | + (1, [Parachain(1001), PalletInstance(64)]) | + (1, [Parachain(1001), PalletInstance(65)]) + ) + } +} + +pub struct AmbassadorEntities; +impl Contains for AmbassadorEntities { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), PalletInstance(74)])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -573,12 +598,12 @@ impl xcm_executor::Config for XcmConfig { type Trader = ( UsingComponents>, cumulus_primitives_utility::SwapFirstAssetTrader< - WestendLocation, + WestendLocationV3, crate::AssetConversion, WeightToFee, crate::NativeAndAssets, ( - TrustBackedAssetsAsMultiLocation, + TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, @@ -671,9 +696,9 @@ pub type ForeignCreatorsSovereignAccountOf = ( /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } @@ -704,7 +729,7 @@ pub mod bridging { pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID; - pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + pub SiblingBridgeHub: Location = Location::new(1, [Parachain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = WestendLocation::get().into(); @@ -721,25 +746,25 @@ pub mod bridging { use super::*; parameter_types! { - pub SiblingBridgeHubWithBridgeHubRococoInstance: MultiLocation = MultiLocation::new( + pub SiblingBridgeHubWithBridgeHubRococoInstance: Location = Location::new( 1, - X2( + [ Parachain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX) - ) + ] ); pub const RococoNetwork: NetworkId = NetworkId::Rococo; - pub AssetHubRococo: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID))); - pub RocLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(RococoNetwork::get()))); + pub AssetHubRococo: Location = Location::new(2, [GlobalConsensus(RococoNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID)]); + pub RocLocation: Location = Location::new(2, [GlobalConsensus(RococoNetwork::get())]); - pub RocFromAssetHubRococo: (MultiAssetFilter, MultiLocation) = ( - Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) }), + pub RocFromAssetHubRococo: (AssetFilter, Location) = ( + Wild(AllOf { fun: WildFungible, id: AssetId(RocLocation::get()) }), AssetHubRococo::get() ); /// Set up exporters configuration. - /// `Option` represents static "base fee" which is used for total delivery fee calculation. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ NetworkExportTableItem::new( RococoNetwork::get(), @@ -756,15 +781,15 @@ pub mod bridging { ]; /// Universal aliases - pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ (SiblingBridgeHubWithBridgeHubRococoInstance::get(), GlobalConsensus(RococoNetwork::get())) ] ); } - impl Contains<(MultiLocation, Junction)> for UniversalAliases { - fn contains(alias: &(MultiLocation, Junction)) -> bool { + impl Contains<(Location, Junction)> for UniversalAliases { + fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } @@ -799,7 +824,7 @@ pub mod bridging { #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { - pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_rococo::UniversalAliases::get().into_iter().find_map(|(location, junction)| { match to_rococo::SiblingBridgeHubWithBridgeHubRococoInstance::get() diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index c50a8f3661d..28fc7ba705a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -21,12 +21,16 @@ use asset_hub_westend_runtime::{ xcm_config, xcm_config::{ bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, + WestendLocationV3, }, AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, }; pub use asset_hub_westend_runtime::{ - xcm_config::{CheckingAccount, TrustBackedAssetsPalletLocation, XcmConfig}, + xcm_config::{ + CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + XcmConfig, + }, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, TrustBackedAssetsInstance, @@ -51,14 +55,18 @@ use parachains_common::{ }; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; -use xcm::latest::prelude::*; -use xcm_executor::traits::{Identity, JustTry, WeightTrader}; +use xcm::latest::prelude::{Assets as XcmAssets, *}; +use xcm_builder::V4V3LocationConverter; +use xcm_executor::traits::{JustTry, WeightTrader}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type AssetIdForTrustBackedAssetsConvert = - assets_common::AssetIdForTrustBackedAssetsConvert; + assets_common::AssetIdForTrustBackedAssetsConvert; + +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; type RuntimeHelper = asset_test_utils::RuntimeHelper; @@ -101,7 +109,7 @@ fn test_buy_and_refund_weight_in_native() { let fee = WeightToFee::weight_to_fee(&weight); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (native_location, fee + extra_amount).into(); + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -110,7 +118,7 @@ fn test_buy_and_refund_weight_in_native() { // assert. let unused_amount = - unused_asset.fungible.get(&native_location.into()).map_or(0, |a| *a); + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Balances::total_issuance(), total_issuance); @@ -146,7 +154,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); let asset_1: u32 = 1; - let native_location = WestendLocation::get(); + let native_location = WestendLocationV3::get(); let asset_1_location = AssetIdForTrustBackedAssetsConvert::convert_back(&asset_1).unwrap(); // bob's initial balance for native and `asset1` assets. @@ -182,6 +190,8 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { let asset_total_issuance = Assets::total_issuance(asset_1); let native_total_issuance = Balances::total_issuance(); + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -189,7 +199,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (asset_1_location, asset_fee + extra_amount).into(); + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -197,8 +207,10 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&asset_1_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); @@ -212,7 +224,7 @@ fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (asset_1_location, asset_refund).into()); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -241,9 +253,15 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { .execute_with(|| { let bob: AccountId = SOME_ASSET_ADMIN.into(); let staking_pot = CollatorSelection::account_id(); - let native_location = WestendLocation::get(); - let foreign_location = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let native_location = WestendLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; // bob's initial balance for native and `asset1` assets. let initial_balance = 200 * UNITS; // liquidity for both arms of (native, asset1) pool. @@ -282,6 +300,8 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); let native_total_issuance = Balances::total_issuance(); + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + // prepare input to buy weight. let weight = Weight::from_parts(4_000_000_000, 0); let fee = WeightToFee::weight_to_fee(&weight); @@ -289,7 +309,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); let extra_amount = 100; let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - let payment: MultiAsset = (foreign_location, asset_fee + extra_amount).into(); + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); // init trader and buy weight. let mut trader = ::Trader::new(); @@ -297,8 +317,10 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); // assert. - let unused_amount = - unused_asset.fungible.get(&foreign_location.into()).map_or(0, |a| *a); + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); assert_eq!(unused_amount, extra_amount); assert_eq!( ForeignAssets::total_issuance(foreign_location), @@ -315,7 +337,7 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { // refund. let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); - assert_eq!(actual_refund, (foreign_location, asset_refund).into()); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); // assert. assert_eq!(Balances::balance(&staking_pot), initial_balance); @@ -345,19 +367,25 @@ fn test_assets_balances_api_works() { .build() .execute_with(|| { let local_asset_id = 1; - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) }; + let foreign_asset_id_location = xcm::v3::Location { + parents: 1, + interior: [ + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ] + .into(), + }; // check before assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 0 ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0); assert!(Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() - .try_as::() + .try_as::() .unwrap() .is_none()); @@ -388,7 +416,7 @@ fn test_assets_balances_api_works() { let foreign_asset_minimum_asset_balance = 3333333_u128; assert_ok!(ForeignAssets::force_create( RuntimeHelper::root_origin(), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(SOME_ASSET_ADMIN).into(), false, foreign_asset_minimum_asset_balance @@ -397,7 +425,7 @@ fn test_assets_balances_api_works() { // We first mint enough asset for the account to exist for assets assert_ok!(ForeignAssets::mint( RuntimeHelper::origin_of(AccountId::from(SOME_ASSET_ADMIN)), - foreign_asset_id_multilocation, + foreign_asset_id_location, AccountId::from(ALICE).into(), 6 * foreign_asset_minimum_asset_balance )); @@ -408,12 +436,12 @@ fn test_assets_balances_api_works() { minimum_asset_balance ); assert_eq!( - ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)), + ForeignAssets::balance(foreign_asset_id_location, AccountId::from(ALICE)), 6 * minimum_asset_balance ); assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency); - let result: MultiAssets = Runtime::query_account_balances(AccountId::from(ALICE)) + let result: XcmAssets = Runtime::query_account_balances(AccountId::from(ALICE)) .unwrap() .try_into() .unwrap(); @@ -428,13 +456,13 @@ fn test_assets_balances_api_works() { ))); // check trusted asset assert!(result.inner().iter().any(|asset| asset.eq(&( - AssetIdForTrustBackedAssetsConvert::convert_back(&local_asset_id).unwrap(), + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(), minimum_asset_balance ) .into()))); // check foreign asset assert!(result.inner().iter().any(|asset| asset.eq(&( - Identity::convert_back(&foreign_asset_id_multilocation).unwrap(), + V4V3LocationConverter::convert_back(&foreign_asset_id_location).unwrap(), 6 * foreign_asset_minimum_asset_balance ) .into()))); @@ -505,7 +533,7 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ XcmConfig, TrustBackedAssetsInstance, AssetIdForTrustBackedAssets, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, collator_session_keys(), ExistentialDeposit::get(), 12345, @@ -522,11 +550,15 @@ asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_ Runtime, XcmConfig, ForeignAssetsInstance, - MultiLocation, + xcm::v3::Location, JustTry, collator_session_keys(), ExistentialDeposit::get(), - MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) }, + xcm::v3::Location { + parents: 1, + interior: [xcm::v3::Junction::Parachain(1313), xcm::v3::Junction::GeneralIndex(12345)] + .into() + }, Box::new(|| { assert!(Assets::asset_ids().collect::>().is_empty()); }), @@ -541,8 +573,8 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p WeightToFee, ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, - MultiLocation, - JustTry, + xcm::v3::Location, + V4V3LocationConverter, collator_session_keys(), ExistentialDeposit::get(), AssetDeposit::get(), @@ -626,12 +658,12 @@ fn receive_reserve_asset_deposited_roc_from_asset_hub_rococo_works() { AccountId::from([73; 32]), AccountId::from(BLOCK_AUTHOR_ACCOUNT), // receiving ROCs - (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Rococo)) }, 1000000000000, 1_000_000_000), + (xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Rococo)]), 1000000000000, 1_000_000_000), bridging_to_asset_hub_rococo, ( - X1(PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)), + [PalletInstance(bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX)].into(), GlobalConsensus(Rococo), - X1(Parachain(1000)) + [Parachain(1000)].into() ) ) } diff --git a/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs b/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs index 344cb5ca336..44bda1eb370 100644 --- a/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs +++ b/cumulus/parachains/runtimes/assets/common/src/benchmarks.rs @@ -19,26 +19,25 @@ use sp_std::marker::PhantomData; use xcm::latest::prelude::*; /// Creates asset pairs for liquidity pools with `Target` always being the first asset. -pub struct AssetPairFactory( - PhantomData<(Target, SelfParaId, PalletId)>, +pub struct AssetPairFactory( + PhantomData<(Target, SelfParaId, PalletId, L)>, ); -impl, SelfParaId: Get, PalletId: Get> - pallet_asset_conversion::BenchmarkHelper - for AssetPairFactory +impl, SelfParaId: Get, PalletId: Get, L: TryFrom> + pallet_asset_conversion::BenchmarkHelper for AssetPairFactory { - fn create_pair(seed1: u32, seed2: u32) -> (MultiLocation, MultiLocation) { - let with_id = MultiLocation::new( + fn create_pair(seed1: u32, seed2: u32) -> (L, L) { + let with_id = Location::new( 1, - X3( + [ Parachain(SelfParaId::get().into()), PalletInstance(PalletId::get() as u8), GeneralIndex(seed2.into()), - ), + ], ); if seed1 % 2 == 0 { - (with_id, Target::get()) + (with_id.try_into().map_err(|_| "Something went wrong").unwrap(), Target::get()) } else { - (Target::get(), with_id) + (Target::get(), with_id.try_into().map_err(|_| "Something went wrong").unwrap()) } } } diff --git a/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs b/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs index 1ed7bd0538c..a9fd79bf939 100644 --- a/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs +++ b/cumulus/parachains/runtimes/assets/common/src/foreign_creators.rs @@ -17,21 +17,21 @@ use frame_support::traits::{ ContainsPair, EnsureOrigin, EnsureOriginWithArg, Everything, OriginTrait, }; use pallet_xcm::{EnsureXcm, Origin as XcmOrigin}; -use xcm::latest::MultiLocation; +use xcm::latest::Location; use xcm_executor::traits::ConvertLocation; /// `EnsureOriginWithArg` impl for `CreateOrigin` that allows only XCM origins that are locations /// containing the class location. -pub struct ForeignCreators( - sp_std::marker::PhantomData<(IsForeign, AccountOf, AccountId)>, +pub struct ForeignCreators( + sp_std::marker::PhantomData<(IsForeign, AccountOf, AccountId, L)>, ); impl< - IsForeign: ContainsPair, + IsForeign: ContainsPair, AccountOf: ConvertLocation, AccountId: Clone, RuntimeOrigin: From + OriginTrait + Clone, - > EnsureOriginWithArg - for ForeignCreators + L: TryFrom + TryInto + Clone, + > EnsureOriginWithArg for ForeignCreators where RuntimeOrigin::PalletsOrigin: From + TryInto, @@ -40,17 +40,20 @@ where fn try_origin( origin: RuntimeOrigin, - asset_location: &MultiLocation, + asset_location: &L, ) -> sp_std::result::Result { - let origin_location = EnsureXcm::::try_origin(origin.clone())?; + let origin_location = EnsureXcm::::try_origin(origin.clone())?; if !IsForeign::contains(asset_location, &origin_location) { return Err(origin) } - AccountOf::convert_location(&origin_location).ok_or(origin) + let latest_location: Location = + origin_location.clone().try_into().map_err(|_| origin.clone())?; + AccountOf::convert_location(&latest_location).ok_or(origin) } #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(a: &MultiLocation) -> Result { - Ok(pallet_xcm::Origin::Xcm(*a).into()) + fn try_successful_origin(a: &L) -> Result { + let latest_location: Location = (*a).clone().try_into().map_err(|_| ())?; + Ok(pallet_xcm::Origin::Xcm(latest_location).into()) } } diff --git a/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs b/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs index 80f8a971d21..e21203485a7 100644 --- a/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs +++ b/cumulus/parachains/runtimes/assets/common/src/fungible_conversion.rs @@ -19,52 +19,48 @@ use crate::runtime_api::FungiblesAccessError; use frame_support::traits::Contains; use sp_runtime::traits::MaybeEquivalence; use sp_std::{borrow::Borrow, vec::Vec}; -use xcm::latest::{MultiAsset, MultiLocation}; +use xcm::latest::{Asset, Location}; use xcm_builder::{ConvertedConcreteId, MatchedConvertedConcreteId}; use xcm_executor::traits::MatchesFungibles; -/// Converting any [`(AssetId, Balance)`] to [`MultiAsset`] -pub trait MultiAssetConverter: +/// Converting any [`(AssetId, Balance)`] to [`Asset`] +pub trait AssetConverter: MatchesFungibles where AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result; + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result; } -/// Checks for `MultiLocation`. -pub trait MatchesMultiLocation: +/// Checks for `Location`. +pub trait MatchesLocation: MatchesFungibles where AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, { - fn contains(location: &MultiLocation) -> bool; + fn contains(location: &Location) -> bool; } impl< AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MultiAssetConverter + > AssetConverter for ConvertedConcreteId { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result { + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result { let (asset_id, balance) = value.borrow(); match ConvertAssetId::convert_back(asset_id) { - Some(asset_id_as_multilocation) => match ConvertBalance::convert_back(balance) { - Some(amount) => Ok((asset_id_as_multilocation, amount).into()), + Some(asset_id_as_location) => match ConvertBalance::convert_back(balance) { + Some(amount) => Ok((asset_id_as_location, amount).into()), None => Err(FungiblesAccessError::AmountToBalanceConversionFailed), }, None => Err(FungiblesAccessError::AssetIdConversionFailed), @@ -75,19 +71,17 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MultiAssetConverter + > AssetConverter for MatchedConvertedConcreteId { - fn convert_ref( - value: impl Borrow<(AssetId, Balance)>, - ) -> Result { + fn convert_ref(value: impl Borrow<(AssetId, Balance)>) -> Result { let (asset_id, balance) = value.borrow(); match ConvertAssetId::convert_back(asset_id) { - Some(asset_id_as_multilocation) => match ConvertBalance::convert_back(balance) { - Some(amount) => Ok((asset_id_as_multilocation, amount).into()), + Some(asset_id_as_location) => match ConvertBalance::convert_back(balance) { + Some(amount) => Ok((asset_id_as_location, amount).into()), None => Err(FungiblesAccessError::AmountToBalanceConversionFailed), }, None => Err(FungiblesAccessError::AssetIdConversionFailed), @@ -98,13 +92,13 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MatchesMultiLocation + > MatchesLocation for MatchedConvertedConcreteId { - fn contains(location: &MultiLocation) -> bool { + fn contains(location: &Location) -> bool { MatchAssetId::contains(location) } } @@ -113,12 +107,12 @@ impl< impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - > MatchesMultiLocation for Tuple + > MatchesLocation for Tuple { - fn contains(location: &MultiLocation) -> bool { + fn contains(location: &Location) -> bool { for_tuples!( #( match Tuple::contains(location) { o @ true => return o, _ => () } )* ); @@ -127,27 +121,24 @@ impl< } } -/// Helper function to convert collections with [`(AssetId, Balance)`] to [`MultiAsset`] +/// Helper function to convert collections with [`(AssetId, Balance)`] to [`Asset`] pub fn convert<'a, AssetId, Balance, ConvertAssetId, ConvertBalance, Converter>( items: impl Iterator, -) -> Result, FungiblesAccessError> +) -> Result, FungiblesAccessError> where AssetId: Clone + 'a, Balance: Clone + 'a, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, - Converter: MultiAssetConverter, + Converter: AssetConverter, { items.map(Converter::convert_ref).collect() } -/// Helper function to convert `Balance` with MultiLocation` to `MultiAsset` -pub fn convert_balance< - T: frame_support::pallet_prelude::Get, - Balance: TryInto, ->( +/// Helper function to convert `Balance` with Location` to `Asset` +pub fn convert_balance, Balance: TryInto>( balance: Balance, -) -> Result { +) -> Result { match balance.try_into() { Ok(balance) => Ok((T::get(), balance).into()), Err(_) => Err(FungiblesAccessError::AmountToBalanceConversionFailed), @@ -162,20 +153,20 @@ mod tests { use xcm::latest::prelude::*; use xcm_executor::traits::{Identity, JustTry}; - type Converter = MatchedConvertedConcreteId; + type Converter = MatchedConvertedConcreteId; #[test] fn converted_concrete_id_fungible_multi_asset_conversion_roundtrip_works() { - let location = MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))); + let location = Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))]); let amount = 123456_u64; - let expected_multi_asset = MultiAsset { - id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))), + let expected_multi_asset = Asset { + id: AssetId(Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))])), fun: Fungible(123456_u128), }; assert_eq!( Converter::matches_fungibles(&expected_multi_asset).map_err(|_| ()), - Ok((location, amount)) + Ok((location.clone(), amount)) ); assert_eq!(Converter::convert_ref((location, amount)), Ok(expected_multi_asset)); @@ -184,17 +175,17 @@ mod tests { #[test] fn converted_concrete_id_fungible_multi_asset_conversion_collection_works() { let data = vec![ - (MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))), 123456_u64), - (MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32])))), 654321_u64), + (Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))]), 123456_u64), + (Location::new(1, [GlobalConsensus(ByGenesis([1; 32]))]), 654321_u64), ]; let expected_data = vec![ - MultiAsset { - id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))), + Asset { + id: AssetId(Location::new(0, [GlobalConsensus(ByGenesis([0; 32]))])), fun: Fungible(123456_u128), }, - MultiAsset { - id: Concrete(MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32]))))), + Asset { + id: AssetId(Location::new(1, [GlobalConsensus(ByGenesis([1; 32]))])), fun: Fungible(654321_u128), }, ]; diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index b0e47143929..f21e1766436 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -23,15 +23,24 @@ pub mod local_and_foreign_assets; pub mod matching; pub mod runtime_api; -use crate::matching::{LocalMultiLocationPattern, ParentLocation}; +use crate::matching::{LocalLocationPattern, ParentLocation}; use frame_support::traits::{Equals, EverythingBut}; use parachains_common::AssetIdForTrustBackedAssets; -use xcm::prelude::MultiLocation; -use xcm_builder::{AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith}; -use xcm_executor::traits::{Identity, JustTry}; +use xcm_builder::{ + AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith, V4V3LocationConverter, +}; +use xcm_executor::traits::JustTry; -/// `MultiLocation` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets` +/// `Location` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets` pub type AssetIdForTrustBackedAssetsConvert = + AsPrefixedGeneralIndex< + TrustBackedAssetsPalletLocation, + AssetIdForTrustBackedAssets, + JustTry, + xcm::v3::Location, + >; + +pub type AssetIdForTrustBackedAssetsConvertLatest = AsPrefixedGeneralIndex; /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` @@ -40,59 +49,55 @@ pub type TrustBackedAssetsConvertedConcreteId, - AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssetsConvertLatest, JustTry, >; -/// AssetId used for identifying assets by MultiLocation. -pub type MultiLocationForAssetId = MultiLocation; +/// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `Location`. +pub type LocationConvertedConcreteId = MatchedConvertedConcreteId< + xcm::v3::Location, + Balance, + LocationFilter, + V4V3LocationConverter, + JustTry, +>; /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` -pub type TrustBackedAssetsAsMultiLocation = +pub type TrustBackedAssetsAsLocation = MatchedConvertedConcreteId< - MultiLocationForAssetId, + xcm::v3::Location, Balance, StartsWith, - Identity, - JustTry, - >; - -/// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `MultiLocation`. -pub type MultiLocationConvertedConcreteId = - MatchedConvertedConcreteId< - MultiLocationForAssetId, - Balance, - MultiLocationFilter, - Identity, + V4V3LocationConverter, JustTry, >; /// [`MatchedConvertedConcreteId`] converter dedicated for storing `ForeignAssets` with `AssetId` as -/// `MultiLocation`. +/// `Location`. /// /// Excludes by default: /// - parent as relay chain -/// - all local MultiLocations +/// - all local Locations /// -/// `AdditionalMultiLocationExclusionFilter` can customize additional excluded MultiLocations -pub type ForeignAssetsConvertedConcreteId = - MultiLocationConvertedConcreteId< +/// `AdditionalLocationExclusionFilter` can customize additional excluded Locations +pub type ForeignAssetsConvertedConcreteId = + LocationConvertedConcreteId< EverythingBut<( // Excludes relay/parent chain currency Equals, // Here we rely on fact that something like this works: - // assert!(MultiLocation::new(1, - // X1(Parachain(100))).starts_with(&MultiLocation::parent())); - // assert!(X1(Parachain(100)).starts_with(&Here)); - StartsWith, + // assert!(Location::new(1, + // [Parachain(100)]).starts_with(&Location::parent())); + // assert!([Parachain(100)].into().starts_with(&Here)); + StartsWith, // Here we can exclude more stuff or leave it as `()` - AdditionalMultiLocationExclusionFilter, + AdditionalLocationExclusionFilter, )>, Balance, >; type AssetIdForPoolAssets = u32; -/// `MultiLocation` vs `AssetIdForPoolAssets` converter for `PoolAssets`. +/// `Location` vs `AssetIdForPoolAssets` converter for `PoolAssets`. pub type AssetIdForPoolAssetsConvert = AsPrefixedGeneralIndex; /// [`MatchedConvertedConcreteId`] converter dedicated for `PoolAssets` @@ -109,28 +114,28 @@ pub type PoolAssetsConvertedConcreteId = mod tests { use super::*; use sp_runtime::traits::MaybeEquivalence; - use xcm::latest::prelude::*; + use xcm::prelude::*; use xcm_builder::StartsWithExplicitGlobalConsensus; use xcm_executor::traits::{Error as MatchError, MatchesFungibles}; #[test] fn asset_id_for_trust_backed_assets_convert_works() { frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(5, X1(PalletInstance(13))); + pub TrustBackedAssetsPalletLocation: Location = Location::new(5, [PalletInstance(13)]); } let local_asset_id = 123456789 as AssetIdForTrustBackedAssets; let expected_reverse_ref = - MultiLocation::new(5, X2(PalletInstance(13), GeneralIndex(local_asset_id.into()))); + Location::new(5, [PalletInstance(13), GeneralIndex(local_asset_id.into())]); assert_eq!( - AssetIdForTrustBackedAssetsConvert::::convert_back( + AssetIdForTrustBackedAssetsConvertLatest::::convert_back( &local_asset_id ) .unwrap(), expected_reverse_ref ); assert_eq!( - AssetIdForTrustBackedAssetsConvert::::convert( + AssetIdForTrustBackedAssetsConvertLatest::::convert( &expected_reverse_ref ) .unwrap(), @@ -141,7 +146,7 @@ mod tests { #[test] fn trust_backed_assets_match_fungibles_works() { frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(0, X1(PalletInstance(13))); + pub TrustBackedAssetsPalletLocation: Location = Location::new(0, [PalletInstance(13)]); } // setup convert type TrustBackedAssetsConvert = @@ -149,85 +154,86 @@ mod tests { let test_data = vec![ // missing GeneralIndex - (ma_1000(0, X1(PalletInstance(13))), Err(MatchError::AssetIdConversionFailed)), + (ma_1000(0, [PalletInstance(13)].into()), Err(MatchError::AssetIdConversionFailed)), ( - ma_1000(0, X2(PalletInstance(13), GeneralKey { data: [0; 32], length: 32 })), + ma_1000(0, [PalletInstance(13), GeneralKey { data: [0; 32], length: 32 }].into()), Err(MatchError::AssetIdConversionFailed), ), ( - ma_1000(0, X2(PalletInstance(13), Parachain(1000))), + ma_1000(0, [PalletInstance(13), Parachain(1000)].into()), Err(MatchError::AssetIdConversionFailed), ), // OK - (ma_1000(0, X2(PalletInstance(13), GeneralIndex(1234))), Ok((1234, 1000))), + (ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Ok((1234, 1000))), ( - ma_1000(0, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(0, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Ok((1234, 1000)), ), ( ma_1000( 0, - X4( + [ PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222), GeneralKey { data: [0; 32], length: 32 }, - ), + ] + .into(), ), Ok((1234, 1000)), ), // wrong pallet instance ( - ma_1000(0, X2(PalletInstance(77), GeneralIndex(1234))), + ma_1000(0, [PalletInstance(77), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(0, X3(PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(0, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // wrong parent ( - ma_1000(1, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(1, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(1, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X2(PalletInstance(77), GeneralIndex(1234))), + ma_1000(1, [PalletInstance(77), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(1, X3(PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(1, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // wrong parent ( - ma_1000(2, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(2, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(2, X3(PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222))), + ma_1000(2, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()), Err(MatchError::AssetNotHandled), ), // missing GeneralIndex - (ma_1000(0, X1(PalletInstance(77))), Err(MatchError::AssetNotHandled)), - (ma_1000(1, X1(PalletInstance(13))), Err(MatchError::AssetNotHandled)), - (ma_1000(2, X1(PalletInstance(13))), Err(MatchError::AssetNotHandled)), + (ma_1000(0, [PalletInstance(77)].into()), Err(MatchError::AssetNotHandled)), + (ma_1000(1, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)), + (ma_1000(2, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)), ]; - for (multi_asset, expected_result) in test_data { + for (asset, expected_result) in test_data { assert_eq!( - >::matches_fungibles(&multi_asset), - expected_result, "multi_asset: {:?}", multi_asset); + >::matches_fungibles(&asset.clone().try_into().unwrap()), + expected_result, "asset: {:?}", asset); } } #[test] - fn multi_location_converted_concrete_id_converter_works() { + fn location_converted_concrete_id_converter_works() { frame_support::parameter_types! { - pub Parachain100Pattern: MultiLocation = MultiLocation::new(1, X1(Parachain(100))); + pub Parachain100Pattern: Location = Location::new(1, [Parachain(100)]); pub UniversalLocationNetworkId: NetworkId = NetworkId::ByGenesis([9; 32]); } @@ -243,95 +249,125 @@ mod tests { let test_data = vec![ // excluded as local (ma_1000(0, Here), Err(MatchError::AssetNotHandled)), - (ma_1000(0, X1(Parachain(100))), Err(MatchError::AssetNotHandled)), + (ma_1000(0, [Parachain(100)].into()), Err(MatchError::AssetNotHandled)), ( - ma_1000(0, X2(PalletInstance(13), GeneralIndex(1234))), + ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), // excluded as parent (ma_1000(1, Here), Err(MatchError::AssetNotHandled)), // excluded as additional filter - Parachain100Pattern - (ma_1000(1, X1(Parachain(100))), Err(MatchError::AssetNotHandled)), - (ma_1000(1, X2(Parachain(100), GeneralIndex(1234))), Err(MatchError::AssetNotHandled)), + (ma_1000(1, [Parachain(100)].into()), Err(MatchError::AssetNotHandled)), ( - ma_1000(1, X3(Parachain(100), PalletInstance(13), GeneralIndex(1234))), + ma_1000(1, [Parachain(100), GeneralIndex(1234)].into()), + Err(MatchError::AssetNotHandled), + ), + ( + ma_1000(1, [Parachain(100), PalletInstance(13), GeneralIndex(1234)].into()), Err(MatchError::AssetNotHandled), ), // excluded as additional filter - StartsWithExplicitGlobalConsensus ( - ma_1000(1, X1(GlobalConsensus(NetworkId::ByGenesis([9; 32])))), + ma_1000(1, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()), Err(MatchError::AssetNotHandled), ), ( - ma_1000(2, X1(GlobalConsensus(NetworkId::ByGenesis([9; 32])))), + ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()), Err(MatchError::AssetNotHandled), ), ( ma_1000( 2, - X3( + [ GlobalConsensus(NetworkId::ByGenesis([9; 32])), Parachain(200), GeneralIndex(1234), - ), + ] + .into(), ), Err(MatchError::AssetNotHandled), ), // ok - (ma_1000(1, X1(Parachain(200))), Ok((MultiLocation::new(1, X1(Parachain(200))), 1000))), - (ma_1000(2, X1(Parachain(200))), Ok((MultiLocation::new(2, X1(Parachain(200))), 1000))), ( - ma_1000(1, X2(Parachain(200), GeneralIndex(1234))), - Ok((MultiLocation::new(1, X2(Parachain(200), GeneralIndex(1234))), 1000)), + ma_1000(1, [Parachain(200)].into()), + Ok((xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(200)]), 1000)), + ), + ( + ma_1000(2, [Parachain(200)].into()), + Ok((xcm::v3::Location::new(2, [xcm::v3::Junction::Parachain(200)]), 1000)), ), ( - ma_1000(2, X2(Parachain(200), GeneralIndex(1234))), - Ok((MultiLocation::new(2, X2(Parachain(200), GeneralIndex(1234))), 1000)), + ma_1000(1, [Parachain(200), GeneralIndex(1234)].into()), + Ok(( + xcm::v3::Location::new( + 1, + [xcm::v3::Junction::Parachain(200), xcm::v3::Junction::GeneralIndex(1234)], + ), + 1000, + )), ), ( - ma_1000(2, X1(GlobalConsensus(NetworkId::ByGenesis([7; 32])))), + ma_1000(2, [Parachain(200), GeneralIndex(1234)].into()), Ok(( - MultiLocation::new(2, X1(GlobalConsensus(NetworkId::ByGenesis([7; 32])))), + xcm::v3::Location::new( + 2, + [xcm::v3::Junction::Parachain(200), xcm::v3::Junction::GeneralIndex(1234)], + ), + 1000, + )), + ), + ( + ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([7; 32]))].into()), + Ok(( + xcm::v3::Location::new( + 2, + [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::ByGenesis( + [7; 32], + ))], + ), 1000, )), ), ( ma_1000( 2, - X3( + [ GlobalConsensus(NetworkId::ByGenesis([7; 32])), Parachain(200), GeneralIndex(1234), - ), + ] + .into(), ), Ok(( - MultiLocation::new( + xcm::v3::Location::new( 2, - X3( - GlobalConsensus(NetworkId::ByGenesis([7; 32])), - Parachain(200), - GeneralIndex(1234), - ), + [ + xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::ByGenesis( + [7; 32], + )), + xcm::v3::Junction::Parachain(200), + xcm::v3::Junction::GeneralIndex(1234), + ], ), 1000, )), ), ]; - for (multi_asset, expected_result) in test_data { + for (asset, expected_result) in test_data { assert_eq!( - >::matches_fungibles( - &multi_asset + >::matches_fungibles( + &asset.clone().try_into().unwrap() ), expected_result, - "multi_asset: {:?}", - multi_asset + "asset: {:?}", + asset ); } } - // Create MultiAsset - fn ma_1000(parents: u8, interior: Junctions) -> MultiAsset { - (MultiLocation::new(parents, interior), 1000).into() + // Create Asset + fn ma_1000(parents: u8, interior: Junctions) -> Asset { + (Location::new(parents, interior), 1000).into() } } diff --git a/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs b/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs index 7dd497797ea..7c237660610 100644 --- a/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs +++ b/cumulus/parachains/runtimes/assets/common/src/local_and_foreign_assets.rs @@ -20,32 +20,32 @@ use sp_runtime::{ Either::{Left, Right}, }; use sp_std::marker::PhantomData; -use xcm::latest::MultiLocation; +use xcm::latest::Location; -/// Converts a given [`MultiLocation`] to [`Either::Left`] when equal to `Target`, or +/// Converts a given [`Location`] to [`Either::Left`] when equal to `Target`, or /// [`Either::Right`] otherwise. /// /// Suitable for use as a `Criterion` with [`frame_support::traits::tokens::fungible::UnionOf`]. -pub struct TargetFromLeft(PhantomData); -impl> Convert> - for TargetFromLeft -{ - fn convert(l: MultiLocation) -> Either<(), MultiLocation> { +pub struct TargetFromLeft(PhantomData<(Target, L)>); +impl, L: PartialEq + Eq> Convert> for TargetFromLeft { + fn convert(l: L) -> Either<(), L> { Target::get().eq(&l).then(|| Left(())).map_or(Right(l), |n| n) } } -/// Converts a given [`MultiLocation`] to [`Either::Left`] based on the `Equivalence` criteria. +/// Converts a given [`Location`] to [`Either::Left`] based on the `Equivalence` criteria. /// Returns [`Either::Right`] if not equivalent. /// /// Suitable for use as a `Criterion` with [`frame_support::traits::tokens::fungibles::UnionOf`]. -pub struct LocalFromLeft(PhantomData<(Equivalence, AssetId)>); -impl Convert> - for LocalFromLeft +pub struct LocalFromLeft( + PhantomData<(Equivalence, AssetId, L)>, +); +impl Convert> + for LocalFromLeft where - Equivalence: MaybeEquivalence, + Equivalence: MaybeEquivalence, { - fn convert(l: MultiLocation) -> Either { + fn convert(l: L) -> Either { match Equivalence::convert(&l) { Some(id) => Left(id), None => Right(l), @@ -53,7 +53,7 @@ where } } -pub trait MatchesLocalAndForeignAssetsMultiLocation { - fn is_local(location: &MultiLocation) -> bool; - fn is_foreign(location: &MultiLocation) -> bool; +pub trait MatchesLocalAndForeignAssetsLocation { + fn is_local(location: &L) -> bool; + fn is_foreign(location: &L) -> bool; } diff --git a/cumulus/parachains/runtimes/assets/common/src/matching.rs b/cumulus/parachains/runtimes/assets/common/src/matching.rs index d6ecc3ec99f..478bba4565d 100644 --- a/cumulus/parachains/runtimes/assets/common/src/matching.rs +++ b/cumulus/parachains/runtimes/assets/common/src/matching.rs @@ -15,67 +15,72 @@ use cumulus_primitives_core::ParaId; use frame_support::{pallet_prelude::Get, traits::ContainsPair}; -use xcm::{ - latest::prelude::{MultiAsset, MultiLocation}, - prelude::*, -}; +use xcm::prelude::*; + use xcm_builder::ensure_is_remote; frame_support::parameter_types! { - pub LocalMultiLocationPattern: MultiLocation = MultiLocation::new(0, Here); - pub ParentLocation: MultiLocation = MultiLocation::parent(); + pub LocalLocationPattern: Location = Location::new(0, Here); + pub ParentLocation: Location = Location::parent(); } /// Accepts an asset if it is from the origin. pub struct IsForeignConcreteAsset(sp_std::marker::PhantomData); -impl> ContainsPair +impl> ContainsPair for IsForeignConcreteAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "IsForeignConcreteAsset asset: {:?}, origin: {:?}", asset, origin); - matches!(asset.id, Concrete(ref id) if IsForeign::contains(id, origin)) + matches!(asset.id, AssetId(ref id) if IsForeign::contains(id, origin)) } } -/// Checks if `a` is from sibling location `b`. Checks that `MultiLocation-a` starts with -/// `MultiLocation-b`, and that the `ParaId` of `b` is not equal to `a`. -pub struct FromSiblingParachain(sp_std::marker::PhantomData); -impl> ContainsPair - for FromSiblingParachain +/// Checks if `a` is from sibling location `b`. Checks that `Location-a` starts with +/// `Location-b`, and that the `ParaId` of `b` is not equal to `a`. +pub struct FromSiblingParachain( + sp_std::marker::PhantomData<(SelfParaId, L)>, +); +impl, L: TryFrom + TryInto + Clone> ContainsPair + for FromSiblingParachain { - fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { - // `a` needs to be from `b` at least - if !a.starts_with(b) { - return false - } + fn contains(a: &L, b: &L) -> bool { + // We convert locations to latest + let a = match ((*a).clone().try_into(), (*b).clone().try_into()) { + (Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least + _ => return false, + }; // here we check if sibling - match a { - MultiLocation { parents: 1, interior } => + match a.unpack() { + (1, interior) => matches!(interior.first(), Some(Parachain(sibling_para_id)) if sibling_para_id.ne(&u32::from(SelfParaId::get()))), _ => false, } } } -/// Checks if `a` is from the expected global consensus network. Checks that `MultiLocation-a` -/// starts with `MultiLocation-b`, and that network is a foreign consensus system. -pub struct FromNetwork( - sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId)>, +/// Checks if `a` is from the expected global consensus network. Checks that `Location-a` +/// starts with `Location-b`, and that network is a foreign consensus system. +pub struct FromNetwork( + sp_std::marker::PhantomData<(UniversalLocation, ExpectedNetworkId, L)>, ); -impl, ExpectedNetworkId: Get> - ContainsPair for FromNetwork +impl< + UniversalLocation: Get, + ExpectedNetworkId: Get, + L: TryFrom + TryInto + Clone, + > ContainsPair for FromNetwork { - fn contains(&a: &MultiLocation, b: &MultiLocation) -> bool { - // `a` needs to be from `b` at least - if !a.starts_with(b) { - return false - } + fn contains(a: &L, b: &L) -> bool { + // We convert locations to latest + let a = match ((*a).clone().try_into(), (*b).clone().try_into()) { + (Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least + _ => return false, + }; let universal_source = UniversalLocation::get(); - // ensure that `a`` is remote and from the expected network - match ensure_is_remote(universal_source, a) { + // ensure that `a` is remote and from the expected network + match ensure_is_remote(universal_source.clone(), a.clone()) { Ok((network_id, _)) => network_id == ExpectedNetworkId::get(), Err(e) => { log::trace!( @@ -89,19 +94,17 @@ impl, ExpectedNetworkId: Get( sp_std::marker::PhantomData<(UniversalLocation, Reserves)>, ); -impl< - UniversalLocation: Get, - Reserves: ContainsPair, - > ContainsPair +impl, Reserves: ContainsPair> + ContainsPair for IsTrustedBridgedReserveLocationForConcreteAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::contains", @@ -110,7 +113,7 @@ impl< ); // check remote origin - let _ = match ensure_is_remote(universal_source, *origin) { + let _ = match ensure_is_remote(universal_source.clone(), origin.clone()) { Ok(devolved) => devolved, Err(_) => { log::trace!( @@ -133,14 +136,14 @@ mod tests { use frame_support::parameter_types; parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Rococo), Parachain(1000)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(Rococo), Parachain(1000)].into(); pub ExpectedNetworkId: NetworkId = Wococo; } #[test] fn from_network_contains_works() { // asset and origin from foreign consensus works - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Wococo), @@ -149,12 +152,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); assert!(FromNetwork::::contains(&asset, &origin)); // asset and origin from local consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Rococo), @@ -163,17 +165,16 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Rococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Rococo), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset and origin from here fails - let asset: MultiLocation = (PalletInstance(1), GeneralIndex(1)).into(); - let origin: MultiLocation = Here.into(); + let asset: Location = (PalletInstance(1), GeneralIndex(1)).into(); + let origin: Location = Here.into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset from different consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Polkadot), @@ -182,12 +183,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Wococo), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // origin from different consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Wococo), @@ -196,12 +196,11 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); // asset and origin from unexpected consensus fails - let asset: MultiLocation = ( + let asset: Location = ( Parent, Parent, GlobalConsensus(Polkadot), @@ -210,8 +209,7 @@ mod tests { GeneralIndex(1), ) .into(); - let origin: MultiLocation = - (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); + let origin: Location = (Parent, Parent, GlobalConsensus(Polkadot), Parachain(1000)).into(); assert!(!FromNetwork::::contains(&asset, &origin)); } } diff --git a/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs b/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs index 0a166a04819..19977cbedab 100644 --- a/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs +++ b/cumulus/parachains/runtimes/assets/common/src/runtime_api.rs @@ -18,12 +18,12 @@ use codec::{Codec, Decode, Encode}; use sp_runtime::RuntimeDebug; #[cfg(feature = "std")] -use {sp_std::vec::Vec, xcm::latest::MultiAsset}; +use {sp_std::vec::Vec, xcm::latest::Asset}; /// The possible errors that can happen querying the storage of assets. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug, scale_info::TypeInfo)] pub enum FungiblesAccessError { - /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + /// `Location` to `AssetId`/`ClassId` conversion failed. AssetIdConversionFailed, /// `u128` amount to currency `Balance` conversion failed. AmountToBalanceConversionFailed, @@ -36,11 +36,11 @@ sp_api::decl_runtime_apis! { where AccountId: Codec, { - /// Returns the list of all [`MultiAsset`] that an `AccountId` has. + /// Returns the list of all [`Asset`] that an `AccountId` has. #[changed_in(2)] - fn query_account_balances(account: AccountId) -> Result, FungiblesAccessError>; + fn query_account_balances(account: AccountId) -> Result, FungiblesAccessError>; - /// Returns the list of all [`MultiAsset`] that an `AccountId` has. - fn query_account_balances(account: AccountId) -> Result; + /// Returns the list of all [`Asset`] that an `AccountId` has. + fn query_account_balances(account: AccountId) -> Result; } } diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs b/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs index 872ad06ddd5..877d61780ce 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/lib.rs @@ -28,7 +28,7 @@ use xcm::latest::prelude::*; use xcm_builder::{CreateMatcher, MatchXcm}; /// Given a message, a sender, and a destination, it returns the delivery fees -fn get_fungible_delivery_fees(destination: MultiLocation, message: Xcm<()>) -> u128 { +fn get_fungible_delivery_fees(destination: Location, message: Xcm<()>) -> u128 { let Ok((_, delivery_fees)) = validate_send::(destination, message) else { unreachable!("message can be sent; qed") }; @@ -46,8 +46,8 @@ fn get_fungible_delivery_fees(destination: MultiLocation, message: X /// chain as part of a reserve-asset-transfer. pub(crate) fn assert_matches_reserve_asset_deposited_instructions( xcm: &mut Xcm, - expected_reserve_assets_deposited: &MultiAssets, - expected_beneficiary: &MultiLocation, + expected_reserve_assets_deposited: &Assets, + expected_beneficiary: &Location, ) { let _ = xcm .0 diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index 915d99470c3..e981fae8015 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -37,7 +37,7 @@ use sp_runtime::{ traits::{MaybeEquivalence, StaticLookup, Zero}, DispatchError, Saturating, }; -use xcm::{latest::prelude::*, VersionedMultiAssets}; +use xcm::{latest::prelude::*, VersionedAssets}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; type RuntimeHelper = @@ -110,7 +110,7 @@ pub fn teleports_for_native_asset_works< 0.into() ); - let native_asset_id = MultiLocation::parent(); + let native_asset_id = Location::parent(); let buy_execution_fee_amount_eta = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 1024)); let native_asset_amount_unit = existential_deposit; @@ -119,38 +119,40 @@ pub fn teleports_for_native_asset_works< // 1. process received teleported assets from relaychain let xcm = Xcm(vec![ - ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(native_asset_id), + ReceiveTeleportedAsset(Assets::from(vec![Asset { + id: AssetId(native_asset_id.clone()), fun: Fungible(native_asset_amount_received.into()), }])), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(native_asset_id), + fees: Asset { + id: AssetId(native_asset_id.clone()), fun: Fungible(buy_execution_fee_amount_eta), }, weight_limit: Limited(Weight::from_parts(3035310000, 65536)), }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: target_account.clone().into(), - }), + }] + .into(), }, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( Parent, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Parent), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -163,14 +165,14 @@ pub fn teleports_for_native_asset_works< // 2. try to teleport asset back to the relaychain { - let dest = MultiLocation::parent(); - let mut dest_beneficiary = MultiLocation::parent() + let dest = Location::parent(); + let mut dest_beneficiary = Location::parent() .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::free_balance(&target_account); @@ -183,11 +185,11 @@ pub fn teleports_for_native_asset_works< // Mint funds into account to ensure it has enough balance to pay delivery fees let delivery_fees = xcm_helpers::transfer_assets_delivery_fees::( - (native_asset_id, native_asset_to_teleport_away.into()).into(), + (native_asset_id.clone(), native_asset_to_teleport_away.into()).into(), 0, Unlimited, - dest_beneficiary, - dest, + dest_beneficiary.clone(), + dest.clone(), ); >::mint_into( &target_account, @@ -199,7 +201,7 @@ pub fn teleports_for_native_asset_works< RuntimeHelper::::origin_of(target_account.clone()), dest, dest_beneficiary, - (native_asset_id, native_asset_to_teleport_away.into()), + (native_asset_id.clone(), native_asset_to_teleport_away.into()), None, included_head.clone(), &alice, @@ -228,14 +230,14 @@ pub fn teleports_for_native_asset_works< // trust `IsTeleporter` for `(relay-native-asset, para(2345))` pair { let other_para_id = 2345; - let dest = MultiLocation::new(1, X1(Parachain(other_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id))) + let dest = Location::new(1, [Parachain(other_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(other_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::free_balance(&target_account); @@ -245,6 +247,7 @@ pub fn teleports_for_native_asset_works< native_asset_to_teleport_away < target_account_balance_before_teleport - existential_deposit ); + assert_eq!( RuntimeHelper::::do_teleport_assets::( RuntimeHelper::::origin_of(target_account.clone()), @@ -356,9 +359,9 @@ pub fn teleports_for_foreign_assets_works< ::Balance: From + Into, SovereignAccountOf: ConvertLocation>, >::AssetId: - From + Into, + From + Into, >::AssetIdParameter: - From + Into, + From + Into, >::Balance: From + Into, ::AccountId: @@ -370,23 +373,25 @@ pub fn teleports_for_foreign_assets_works< { // foreign parachain with the same consensus currency as asset let foreign_para_id = 2222; - let foreign_asset_id_multilocation = MultiLocation { + let foreign_asset_id_location = xcm::v3::Location { parents: 1, - interior: X2(Parachain(foreign_para_id), GeneralIndex(1234567)), + interior: [ + xcm::v3::Junction::Parachain(foreign_para_id), + xcm::v3::Junction::GeneralIndex(1234567), + ] + .into(), }; // foreign creator, which can be sibling parachain to match ForeignCreators - let foreign_creator = MultiLocation { parents: 1, interior: X1(Parachain(foreign_para_id)) }; + let foreign_creator = Location { parents: 1, interior: [Parachain(foreign_para_id)].into() }; let foreign_creator_as_account_id = SovereignAccountOf::convert_location(&foreign_creator).expect(""); // we want to buy execution with local relay chain currency let buy_execution_fee_amount = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 0)); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation::parent()), - fun: Fungible(buy_execution_fee_amount), - }; + let buy_execution_fee = + Asset { id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount) }; let teleported_foreign_asset_amount = 10_000_000_000_000; let runtime_para_id = 1000; @@ -425,14 +430,14 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -441,14 +446,14 @@ pub fn teleports_for_foreign_assets_works< assert_total::< pallet_assets::Pallet, AccountIdOf, - >(foreign_asset_id_multilocation, 0, 0); + >(foreign_asset_id_location, 0, 0); // create foreign asset (0 total issuance) let asset_minimum_asset_balance = 3333333_u128; assert_ok!( >::force_create( RuntimeHelper::::root_origin(), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), asset_owner.into(), false, asset_minimum_asset_balance.into() @@ -457,47 +462,52 @@ pub fn teleports_for_foreign_assets_works< assert_total::< pallet_assets::Pallet, AccountIdOf, - >(foreign_asset_id_multilocation, 0, 0); + >(foreign_asset_id_location, 0, 0); assert!(teleported_foreign_asset_amount > asset_minimum_asset_balance); + let foreign_asset_id_location_latest: Location = + foreign_asset_id_location.try_into().unwrap(); + // 1. process received teleported assets from sibling parachain (foreign_para_id) let xcm = Xcm(vec![ // BuyExecution with relaychain native token WithdrawAsset(buy_execution_fee.clone().into()), BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation::parent()), + fees: Asset { + id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount), }, weight_limit: Limited(Weight::from_parts(403531000, 65536)), }, // Process teleported asset - ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + ReceiveTeleportedAsset(Assets::from(vec![Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(teleported_foreign_asset_amount), }])), DepositAsset { assets: Wild(AllOf { - id: Concrete(foreign_asset_id_multilocation), + id: AssetId(foreign_asset_id_location_latest.clone()), fun: WildFungibility::Fungible, }), - beneficiary: MultiLocation { + beneficiary: Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: target_account.clone().into(), - }), + }] + .into(), }, }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( foreign_creator, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -508,7 +518,7 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), teleported_foreign_asset_amount.into() @@ -520,7 +530,7 @@ pub fn teleports_for_foreign_assets_works< ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -530,25 +540,25 @@ pub fn teleports_for_foreign_assets_works< pallet_assets::Pallet, AccountIdOf, >( - foreign_asset_id_multilocation, + foreign_asset_id_location, teleported_foreign_asset_amount, teleported_foreign_asset_amount, ); // 2. try to teleport asset back to source parachain (foreign_para_id) { - let dest = MultiLocation::new(1, X1(Parachain(foreign_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(foreign_para_id))) + let dest = Location::new(1, [Parachain(foreign_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(foreign_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let target_account_balance_before_teleport = >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account, ); let asset_to_teleport_away = asset_minimum_asset_balance * 3; @@ -562,11 +572,11 @@ pub fn teleports_for_foreign_assets_works< // Make sure the target account has enough native asset to pay for delivery fees let delivery_fees = xcm_helpers::transfer_assets_delivery_fees::( - (foreign_asset_id_multilocation, asset_to_teleport_away).into(), + (foreign_asset_id_location_latest.clone(), asset_to_teleport_away).into(), 0, Unlimited, - dest_beneficiary, - dest, + dest_beneficiary.clone(), + dest.clone(), ); >::mint_into( &target_account, @@ -578,7 +588,7 @@ pub fn teleports_for_foreign_assets_works< RuntimeHelper::::origin_of(target_account.clone()), dest, dest_beneficiary, - (foreign_asset_id_multilocation, asset_to_teleport_away), + (foreign_asset_id_location_latest.clone(), asset_to_teleport_away), Some((runtime_para_id, foreign_para_id)), included_head, &alice, @@ -587,14 +597,14 @@ pub fn teleports_for_foreign_assets_works< // check balances assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), (target_account_balance_before_teleport - asset_to_teleport_away.into()) ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &CheckingAccount::get() ), 0.into() @@ -604,7 +614,7 @@ pub fn teleports_for_foreign_assets_works< pallet_assets::Pallet, AccountIdOf, >( - foreign_asset_id_multilocation, + foreign_asset_id_location, teleported_foreign_asset_amount - asset_to_teleport_away, teleported_foreign_asset_amount - asset_to_teleport_away, ); @@ -717,17 +727,19 @@ pub fn asset_transactor_transfer_with_local_consensus_currency_works BOB let _ = RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: source_account.clone().into() }), + interior: [AccountId32 { network: None, id: source_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: target_account.clone().into() }), + interior: [AccountId32 { network: None, id: target_account.clone().into() }] + .into(), }, // local_consensus_currency_asset, e.g.: relaychain token (KSM, DOT, ...) ( - MultiLocation { parents: 1, interior: Here }, + Location { parents: 1, interior: Here }, (BalanceOf::::from(1_u128) * unit).into(), ), ) @@ -779,7 +791,7 @@ macro_rules! include_asset_transactor_transfer_with_local_consensus_currency_wor } ); -///Test-case makes sure that `Runtime`'s `xcm::AssetTransactor` can handle native relay chain +/// Test-case makes sure that `Runtime`'s `xcm::AssetTransactor` can handle native relay chain /// currency pub fn asset_transactor_transfer_with_pallet_assets_instance_works< Runtime, @@ -820,8 +832,8 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< <::Lookup as StaticLookup>::Source: From<::AccountId>, AssetsPalletInstance: 'static, - AssetId: Clone + Copy, - AssetIdConverter: MaybeEquivalence, + AssetId: Clone, + AssetIdConverter: MaybeEquivalence, { ExtBuilder::::default() .with_collators(collator_session_keys.collators()) @@ -836,10 +848,10 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< .execute_with(|| { // create some asset class let asset_minimum_asset_balance = 3333333_u128; - let asset_id_as_multilocation = AssetIdConverter::convert_back(&asset_id).unwrap(); + let asset_id_as_location = AssetIdConverter::convert_back(&asset_id).unwrap(); assert_ok!(>::force_create( RuntimeHelper::::root_origin(), - asset_id.into(), + asset_id.clone().into(), asset_owner.clone().into(), false, asset_minimum_asset_balance.into() @@ -848,7 +860,7 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // We first mint enough asset for the account to exist for assets assert_ok!(>::mint( RuntimeHelper::::origin_of(asset_owner.clone()), - asset_id.into(), + asset_id.clone().into(), alice_account.clone().into(), (6 * asset_minimum_asset_balance).into() )); @@ -856,28 +868,28 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // check Assets before assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &alice_account ), (6 * asset_minimum_asset_balance).into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &bob_account ), 0.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &charlie_account ), 0.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &asset_owner ), 0.into() @@ -904,21 +916,20 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // ExistentialDeposit) assert_noop!( RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { - network: None, - id: alice_account.clone().into() - }), + interior: [AccountId32 { network: None, id: alice_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { + interior: [AccountId32 { network: None, id: charlie_account.clone().into() - }), + }] + .into(), }, - (asset_id_as_multilocation, asset_minimum_asset_balance), + (asset_id_as_location.clone(), asset_minimum_asset_balance), ), XcmError::FailedToTransactAsset(Into::<&str>::into( sp_runtime::TokenError::CannotCreate @@ -928,18 +939,17 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // transfer_asset (deposit/withdraw) ALICE -> BOB (ok - has ExistentialDeposit) assert!(matches!( RuntimeHelper::::do_transfer( - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { - network: None, - id: alice_account.clone().into() - }), + interior: [AccountId32 { network: None, id: alice_account.clone().into() }] + .into(), }, - MultiLocation { + Location { parents: 0, - interior: X1(AccountId32 { network: None, id: bob_account.clone().into() }), + interior: [AccountId32 { network: None, id: bob_account.clone().into() }] + .into(), }, - (asset_id_as_multilocation, asset_minimum_asset_balance), + (asset_id_as_location, asset_minimum_asset_balance), ), Ok(_) )); @@ -947,21 +957,21 @@ pub fn asset_transactor_transfer_with_pallet_assets_instance_works< // check Assets after assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &alice_account ), (5 * asset_minimum_asset_balance).into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &bob_account ), asset_minimum_asset_balance.into() ); assert_eq!( >::balance( - asset_id.into(), + asset_id.clone().into(), &charlie_account ), 0.into() @@ -1093,26 +1103,23 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor <::Lookup as StaticLookup>::Source: From<::AccountId>, ForeignAssetsPalletInstance: 'static, - AssetId: Clone + Copy, - AssetIdConverter: MaybeEquivalence, + AssetId: Clone, + AssetIdConverter: MaybeEquivalence, { - // foreign parachain with the same consensus currency as asset - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(2222), GeneralIndex(1234567)) }; - let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap(); + // foreign parachain with the same consenus currency as asset + let foreign_asset_id_location = Location::new(1, [Parachain(2222), GeneralIndex(1234567)]); + let asset_id = AssetIdConverter::convert(&foreign_asset_id_location).unwrap(); // foreign creator, which can be sibling parachain to match ForeignCreators - let foreign_creator = MultiLocation { parents: 1, interior: X1(Parachain(2222)) }; + let foreign_creator = Location { parents: 1, interior: [Parachain(2222)].into() }; let foreign_creator_as_account_id = SovereignAccountOf::convert_location(&foreign_creator).expect(""); // we want to buy execution with local relay chain currency let buy_execution_fee_amount = WeightToFee::weight_to_fee(&Weight::from_parts(90_000_000_000, 0)); - let buy_execution_fee = MultiAsset { - id: Concrete(MultiLocation::parent()), - fun: Fungible(buy_execution_fee_amount), - }; + let buy_execution_fee = + Asset { id: AssetId(Location::parent()), fun: Fungible(buy_execution_fee_amount) }; const ASSET_NAME: &str = "My super coin"; const ASSET_SYMBOL: &str = "MY_S_COIN"; @@ -1152,7 +1159,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::create { - id: asset_id.into(), + id: asset_id.clone().into(), // admin as sovereign_account admin: foreign_creator_as_account_id.clone().into(), min_balance: 1.into(), @@ -1162,7 +1169,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::set_metadata { - id: asset_id.into(), + id: asset_id.clone().into(), name: Vec::from(ASSET_NAME), symbol: Vec::from(ASSET_SYMBOL), decimals: 12, @@ -1172,7 +1179,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor Runtime, ForeignAssetsPalletInstance, >::set_team { - id: asset_id.into(), + id: asset_id.clone().into(), issuer: foreign_creator_as_account_id.clone().into(), admin: foreign_creator_as_account_id.clone().into(), freezer: bob_account.clone().into(), @@ -1202,14 +1209,15 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor ]); // messages with different consensus should go through the local bridge-hub - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( - foreign_creator, + let outcome = XcmExecutor::::prepare_and_execute( + foreign_creator.clone(), xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -1230,25 +1238,25 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor use frame_support::traits::fungibles::roles::Inspect as InspectRoles; assert_eq!( >::owner( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::admin( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::issuer( - asset_id.into() + asset_id.clone().into() ), Some(foreign_creator_as_account_id.clone()) ); assert_eq!( >::freezer( - asset_id.into() + asset_id.clone().into() ), Some(bob_account.clone()) ); @@ -1262,13 +1270,13 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor assert_metadata::< pallet_assets::Pallet, AccountIdOf, - >(asset_id, ASSET_NAME, ASSET_SYMBOL, 12); + >(asset_id.clone(), ASSET_NAME, ASSET_SYMBOL, 12); // check if changed freezer, can freeze assert_noop!( >::freeze( RuntimeHelper::::origin_of(bob_account), - asset_id.into(), + asset_id.clone().into(), alice_account.clone().into() ), pallet_assets::Error::::NoAccount @@ -1284,9 +1292,9 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor // lets try create asset for different parachain(3333) (foreign_creator(2222) can create // just his assets) - let foreign_asset_id_multilocation = - MultiLocation { parents: 1, interior: X2(Parachain(3333), GeneralIndex(1234567)) }; - let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap(); + let foreign_asset_id_location = + Location { parents: 1, interior: [Parachain(3333), GeneralIndex(1234567)].into() }; + let asset_id = AssetIdConverter::convert(&foreign_asset_id_location).unwrap(); // prepare data for xcm::Transact(create) let foreign_asset_create = runtime_call_encode(pallet_assets::Call::< @@ -1310,14 +1318,15 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor ]); // messages with different consensus should go through the local bridge-hub - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( foreign_creator, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -1441,15 +1450,15 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< // reserve-transfer native asset with local reserve to remote parachain (2345) let other_para_id = 2345; - let native_asset = MultiLocation::parent(); - let dest = MultiLocation::new(1, X1(Parachain(other_para_id))); - let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id))) + let native_asset = Location::parent(); + let dest = Location::new(1, [Parachain(other_para_id)]); + let mut dest_beneficiary = Location::new(1, [Parachain(other_para_id)]) .appended_with(AccountId32 { network: None, id: sp_runtime::AccountId32::new([3; 32]).into(), }) .unwrap(); - dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap(); + dest_beneficiary.reanchor(&dest, &XcmConfig::UniversalLocation::get()).unwrap(); let reserve_account = LocationToAccountId::convert_location(&dest) .expect("Sovereign account for reserves"); @@ -1495,17 +1504,15 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< ); // local native asset (pallet_balances) - let asset_to_transfer = MultiAsset { - fun: Fungible(balance_to_transfer.into()), - id: Concrete(native_asset), - }; + let asset_to_transfer = + Asset { fun: Fungible(balance_to_transfer.into()), id: AssetId(native_asset) }; // pallet_xcm call reserve transfer assert_ok!(>::limited_reserve_transfer_assets( RuntimeHelper::::origin_of(alice_account.clone()), - Box::new(dest.into_versioned()), - Box::new(dest_beneficiary.into_versioned()), - Box::new(VersionedMultiAssets::from(MultiAssets::from(asset_to_transfer))), + Box::new(dest.clone().into_versioned()), + Box::new(dest_beneficiary.clone().into_versioned()), + Box::new(VersionedAssets::from(Assets::from(asset_to_transfer))), 0, weight_limit, )); @@ -1535,9 +1542,12 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< ) .unwrap(); + let v4_xcm: Xcm<()> = xcm_sent.clone().try_into().unwrap(); + dbg!(&v4_xcm); + let delivery_fees = get_fungible_delivery_fees::< ::XcmSender, - >(dest, Xcm::try_from(xcm_sent.clone()).unwrap()); + >(dest.clone(), Xcm::try_from(xcm_sent.clone()).unwrap()); assert_eq!( xcm_sent_message_hash, @@ -1547,8 +1557,8 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< // check sent XCM Program to other parachain println!("reserve_transfer_native_asset_works sent xcm: {:?}", xcm_sent); - let reserve_assets_deposited = MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + let reserve_assets_deposited = Assets::from(vec![Asset { + id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(1000000000000), }]); diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index d7441880426..878dddc9137 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -31,15 +31,15 @@ use parachains_runtimes_test_utils::{ }; use sp_runtime::{traits::StaticLookup, Saturating}; use sp_std::ops::Mul; -use xcm::{latest::prelude::*, VersionedMultiAssets}; +use xcm::{latest::prelude::*, VersionedAssets}; use xcm_builder::{CreateMatcher, MatchXcm}; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; pub struct TestBridgingConfig { pub bridged_network: NetworkId, pub local_bridge_hub_para_id: u32, - pub local_bridge_hub_location: MultiLocation, - pub bridged_target_location: MultiLocation, + pub local_bridge_hub_location: Location, + pub bridged_target_location: Location, } /// Test-case makes sure that `Runtime` can initiate **reserve transfer assets** over bridge. @@ -117,7 +117,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< LocationToAccountId::convert_location(&target_location_from_different_consensus) .expect("Sovereign account for reserves"); let balance_to_transfer = 1_000_000_000_000_u128; - let native_asset = MultiLocation::parent(); + let native_asset = Location::parent(); // open HRMP to bridge hub mock_open_hrmp_channel::( @@ -163,35 +163,33 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< .unwrap_or(0.into()); // local native asset (pallet_balances) - let asset_to_transfer = MultiAsset { - fun: Fungible(balance_to_transfer.into()), - id: Concrete(native_asset), - }; + let asset_to_transfer = + Asset { fun: Fungible(balance_to_transfer.into()), id: native_asset.into() }; // destination is (some) account relative to the destination different consensus - let target_destination_account = MultiLocation { - parents: 0, - interior: X1(AccountId32 { + let target_destination_account = Location::new( + 0, + [AccountId32 { network: Some(bridged_network), id: sp_runtime::AccountId32::new([3; 32]).into(), - }), - }; + }], + ); - let assets_to_transfer = MultiAssets::from(asset_to_transfer); + let assets_to_transfer = Assets::from(asset_to_transfer); let mut expected_assets = assets_to_transfer.clone(); let context = XcmConfig::UniversalLocation::get(); expected_assets - .reanchor(&target_location_from_different_consensus, context) + .reanchor(&target_location_from_different_consensus, &context) .unwrap(); - let expected_beneficiary = target_destination_account; + let expected_beneficiary = target_destination_account.clone(); // do pallet_xcm call reserve transfer assert_ok!(>::limited_reserve_transfer_assets( RuntimeHelper::::origin_of(alice_account.clone()), - Box::new(target_location_from_different_consensus.into_versioned()), + Box::new(target_location_from_different_consensus.clone().into_versioned()), Box::new(target_destination_account.into_versioned()), - Box::new(VersionedMultiAssets::from(assets_to_transfer)), + Box::new(VersionedAssets::from(assets_to_transfer)), 0, weight_limit, )); @@ -266,13 +264,17 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< let (_, target_location_junctions_without_global_consensus) = target_location_from_different_consensus .interior + .clone() .split_global() .expect("split works"); assert_eq!(destination, &target_location_junctions_without_global_consensus); // Call `SendXcm::validate` to get delivery fees. delivery_fees = get_fungible_delivery_fees::< ::XcmSender, - >(target_location_from_different_consensus, inner_xcm.clone()); + >( + target_location_from_different_consensus.clone(), + inner_xcm.clone(), + ); assert_matches_reserve_asset_deposited_instructions( inner_xcm, &expected_assets, @@ -322,10 +324,10 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< target_account: AccountIdOf, block_author_account: AccountIdOf, ( - foreign_asset_id_multilocation, + foreign_asset_id_location, transfered_foreign_asset_id_amount, foreign_asset_id_minimum_balance, - ): (MultiLocation, u128, u128), + ): (xcm::v3::Location, u128, u128), prepare_configuration: fn() -> TestBridgingConfig, (bridge_instance, universal_origin, descend_origin): (Junctions, Junction, Junctions), /* bridge adds origin manipulation on the way */ ) where @@ -347,9 +349,9 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< XcmConfig: xcm_executor::Config, LocationToAccountId: ConvertLocation>, >::AssetId: - From + Into, + From + Into, >::AssetIdParameter: - From + Into, + From + Into, >::Balance: From + Into + From, ::AccountId: Into<<::RuntimeOrigin as OriginTrait>::AccountId> @@ -357,7 +359,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< <::Lookup as StaticLookup>::Source: From<::AccountId>, ::AssetKind: - From + Into, + From + Into, ::Balance: From, ForeignAssetsPalletInstance: 'static, { @@ -385,7 +387,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // sovereign account as foreign asset owner (can be whoever for this scenario, doesnt // matter) let sovereign_account_as_owner_of_foreign_asset = - LocationToAccountId::convert_location(&MultiLocation::parent()).unwrap(); + LocationToAccountId::convert_location(&Location::parent()).unwrap(); // staking pot account for collecting local native fees from `BuyExecution` let staking_pot = >::account_id(); @@ -398,16 +400,16 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< assert_ok!( >::force_create( RuntimeHelper::::root_origin(), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), sovereign_account_as_owner_of_foreign_asset.clone().into(), true, // is_sufficient=true foreign_asset_id_minimum_balance.into() ) ); - // setup a pool to pay fees with `foreign_asset_id_multilocation` tokens + // setup a pool to pay fees with `foreign_asset_id_location` tokens let pool_owner: AccountIdOf = [1u8; 32].into(); - let native_asset = MultiLocation::parent(); + let native_asset = xcm::v3::Location::parent(); let pool_liquidity: u128 = existential_deposit.into().max(foreign_asset_id_minimum_balance).mul(100_000); @@ -420,7 +422,7 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< RuntimeHelper::::origin_of( sovereign_account_as_owner_of_foreign_asset ), - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), pool_owner.clone().into(), (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), )); @@ -428,13 +430,13 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< assert_ok!(>::create_pool( RuntimeHelper::::origin_of(pool_owner.clone()), Box::new(native_asset.into()), - Box::new(foreign_asset_id_multilocation.into()) + Box::new(foreign_asset_id_location.into()) )); assert_ok!(>::add_liquidity( RuntimeHelper::::origin_of(pool_owner.clone()), Box::new(native_asset.into()), - Box::new(foreign_asset_id_multilocation.into()), + Box::new(foreign_asset_id_location.into()), pool_liquidity.into(), pool_liquidity.into(), 1.into(), @@ -459,34 +461,37 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // ForeignAssets balances before assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &block_author_account ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &staking_pot ), 0.into() ); - let expected_assets = MultiAssets::from(vec![MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + let foreign_asset_id_location_latest: Location = + foreign_asset_id_location.try_into().unwrap(); + + let expected_assets = Assets::from(vec![Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(transfered_foreign_asset_id_amount), }]); - let expected_beneficiary = MultiLocation { - parents: 0, - interior: X1(AccountId32 { network: None, id: target_account.clone().into() }), - }; + let expected_beneficiary = Location::new( + 0, + [AccountId32 { network: None, id: target_account.clone().into() }], + ); // Call received XCM execution let xcm = Xcm(vec![ @@ -496,13 +501,16 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< ReserveAssetDeposited(expected_assets.clone()), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(foreign_asset_id_multilocation), + fees: Asset { + id: AssetId(foreign_asset_id_location_latest.clone()), fun: Fungible(transfered_foreign_asset_id_amount), }, weight_limit: Unlimited, }, - DepositAsset { assets: Wild(AllCounted(1)), beneficiary: expected_beneficiary }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: expected_beneficiary.clone(), + }, SetTopic([ 220, 188, 144, 32, 213, 83, 111, 175, 44, 210, 111, 19, 90, 165, 191, 112, 140, 247, 192, 124, 42, 17, 153, 141, 114, 34, 189, 20, 83, 69, 237, 173, @@ -514,16 +522,17 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< &expected_beneficiary, ); - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( local_bridge_hub_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight( XcmReceivedFrom::Sibling, ), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); @@ -545,20 +554,20 @@ pub fn receive_reserve_asset_deposited_from_different_consensus_works< // ForeignAssets balances after assert!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &target_account ) > 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &staking_pot ), 0.into() ); assert_eq!( >::balance( - foreign_asset_id_multilocation.into(), + foreign_asset_id_location.into(), &block_author_account ), 0.into() @@ -614,14 +623,15 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< // Call received XCM execution let xcm = if is_congested { congested_message() } else { uncongested_message() }; - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do - let outcome = XcmExecutor::::execute_xcm( + let outcome = XcmExecutor::::prepare_and_execute( local_bridge_hub_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ); assert_ok!(outcome.ensure_complete()); assert_eq!(is_congested, pallet_xcm_bridge_hub_router::Pallet::::bridge().is_congested); diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs index 0aebe38fef5..f509a3a8aca 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/xcm_helpers.rs @@ -23,11 +23,11 @@ use xcm::latest::prelude::*; /// Because it returns only a `u128`, it assumes delivery fees are only paid /// in one asset and that asset is known. pub fn transfer_assets_delivery_fees( - assets: MultiAssets, + assets: Assets, fee_asset_item: u32, weight_limit: WeightLimit, - beneficiary: MultiLocation, - destination: MultiLocation, + beneficiary: Location, + destination: Location, ) -> u128 { let message = teleport_assets_dummy_message(assets, fee_asset_item, weight_limit, beneficiary); get_fungible_delivery_fees::(destination, message) @@ -35,7 +35,7 @@ pub fn transfer_assets_delivery_fees( /// Returns the delivery fees amount for a query response as a result of the execution /// of a `ExpectError` instruction with no error. -pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 { +pub fn query_response_delivery_fees(querier: Location) -> u128 { // Message to calculate delivery fees, it's encoded size is what's important. // This message reports that there was no error, if an error is reported, the encoded size would // be different. @@ -45,7 +45,7 @@ pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 query_id: 0, // Dummy query id response: Response::ExecutionResult(None), max_weight: Weight::zero(), - querier: Some(querier), + querier: Some(querier.clone()), }, SetTopic([0u8; 32]), // Dummy topic ]); @@ -55,9 +55,9 @@ pub fn query_response_delivery_fees(querier: MultiLocation) -> u128 /// Returns the delivery fees amount for the execution of `PayOverXcm` pub fn pay_over_xcm_delivery_fees( interior: Junctions, - destination: MultiLocation, - beneficiary: MultiLocation, - asset: MultiAsset, + destination: Location, + beneficiary: Location, + asset: Asset, ) -> u128 { // This is a dummy message. // The encoded size is all that matters for delivery fees. @@ -66,7 +66,11 @@ pub fn pay_over_xcm_delivery_fees( UnpaidExecution { weight_limit: Unlimited, check_origin: None }, SetAppendix(Xcm(vec![ SetFeesMode { jit_withdraw: true }, - ReportError(QueryResponseInfo { destination, query_id: 0, max_weight: Weight::zero() }), + ReportError(QueryResponseInfo { + destination: destination.clone(), + query_id: 0, + max_weight: Weight::zero(), + }), ])), TransferAsset { beneficiary, assets: vec![asset].into() }, ]); @@ -78,10 +82,10 @@ pub fn pay_over_xcm_delivery_fees( /// However, it should have the same encoded size, which is what matters for delivery fees. /// Also has same encoded size as the one created by the reserve transfer assets extrinsic. fn teleport_assets_dummy_message( - assets: MultiAssets, + assets: Assets, fee_asset_item: u32, weight_limit: WeightLimit, - beneficiary: MultiLocation, + beneficiary: Location, ) -> Xcm<()> { Xcm(vec![ ReceiveTeleportedAsset(assets.clone()), // Same encoded size as `ReserveAssetDeposited` @@ -93,7 +97,7 @@ fn teleport_assets_dummy_message( } /// Given a message, a sender, and a destination, it returns the delivery fees -fn get_fungible_delivery_fees(destination: MultiLocation, message: Xcm<()>) -> u128 { +fn get_fungible_delivery_fees(destination: Location, message: Xcm<()>) -> u128 { let Ok((_, delivery_fees)) = validate_send::(destination, message) else { unreachable!("message can be sent; qed") }; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index c9d7f60e71a..1c7bdd4cbff 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -48,7 +48,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess}; use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -65,16 +65,16 @@ parameter_types! { /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. pub const RococoBulletinChainId: bp_runtime::ChainId = bp_runtime::POLKADOT_BULLETIN_CHAIN_ID; /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. - pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorMultiLocation = X1( + pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [ PalletInstance(::index() as u8) - ); + ].into(); /// Rococo Bulletin Network identifier. pub RococoBulletinGlobalConsensusNetwork: NetworkId = NetworkId::PolkadotBulletin; /// Relative location of the Rococo Bulletin chain. - pub RococoBulletinGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())) - }; + pub RococoBulletinGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())] + ); /// All active lanes that the current bridge supports. pub ActiveOutboundLanesToRococoBulletin: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN]; @@ -94,11 +94,11 @@ parameter_types! { /// A route (XCM location and bridge lane) that the Rococo People Chain -> Rococo Bulletin Chain /// message is following. pub FromRococoPeopleToRococoBulletinRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(RococoPeopleParaId::get().into()))).into(), + ParentThen(Parachain(RococoPeopleParaId::get().into()).into()).into(), XCM_LANE_FOR_ROCOCO_PEOPLE_TO_ROCOCO_BULLETIN, ); /// All active routes and their destinations. - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromRococoPeopleToRococoBulletinRoute::get(), (RococoBulletinGlobalConsensusNetwork::get(), Here) @@ -282,11 +282,11 @@ mod tests { PriorityBoostPerMessage, >(FEE_BOOST_PER_MESSAGE); - assert_eq!( - BridgeRococoToRococoBulletinMessagesPalletInstance::get(), - X1(PalletInstance( - bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX - )) - ); + let expected: InteriorLocation = PalletInstance( + bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX, + ) + .into(); + + assert_eq!(BridgeRococoToRococoBulletinMessagesPalletInstance::get(), expected,); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 961b47e1e13..4e8fe6454cc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -48,7 +48,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess}; use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -58,12 +58,12 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; - pub BridgeRococoToWestendMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(::index() as u8)); + pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; - pub WestendGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(WestendGlobalConsensusNetwork::get())) - }; + pub WestendGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(WestendGlobalConsensusNetwork::get())] + ); // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; @@ -74,26 +74,26 @@ parameter_types! { pub ActiveOutboundLanesToBridgeHubWestend: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND]; pub const AssetHubRococoToAssetHubWestendMessagesLane: bp_messages::LaneId = XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND; pub FromAssetHubRococoToAssetHubWestendRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(AssetHubRococoParaId::get().into()))).into(), + ParentThen([Parachain(AssetHubRococoParaId::get().into())].into()).into(), XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, ); - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromAssetHubRococoToAssetHubWestendRoute::get(), - (WestendGlobalConsensusNetwork::get(), X1(Parachain(AssetHubWestendParaId::get().into()))) + (WestendGlobalConsensusNetwork::get(), [Parachain(AssetHubWestendParaId::get().into())].into()) ) ]; pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); - pub BridgeHubWestendLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X2( + pub BridgeHubWestendLocation: Location = Location::new( + 2, + [ GlobalConsensus(WestendGlobalConsensusNetwork::get()), Parachain(::PARACHAIN_ID) - ) - }; + ] + ); } pub const XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND: LaneId = LaneId([0, 0, 0, 2]); @@ -327,11 +327,11 @@ mod tests { PriorityBoostPerMessage, >(FEE_BOOST_PER_MESSAGE); - assert_eq!( - BridgeRococoToWestendMessagesPalletInstance::get(), - X1(PalletInstance( - bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX - )) - ); + let expected: InteriorLocation = [PalletInstance( + bp_bridge_hub_rococo::WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX, + )] + .into(); + + assert_eq!(BridgeRococoToWestendMessagesPalletInstance::get(), expected,); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 0052e9dcb38..7e99b039309 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -78,7 +78,7 @@ use bridge_hub_common::{ use pallet_xcm::EnsureXcm; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::{MultiAddress, Perbill, Permill}; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; use xcm_config::{TreasuryAccount, XcmOriginToTransactDispatchOrigin, XcmRouter}; #[cfg(any(feature = "std", test))] @@ -385,7 +385,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -517,7 +517,7 @@ pub mod benchmark_helpers { use snowbridge_beacon_primitives::CompactExecutionHeader; use snowbridge_pallet_inbound_queue::BenchmarkHelper; use sp_core::H256; - use xcm::latest::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; + use xcm::latest::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; impl BenchmarkHelper for Runtime { fn initialize_storage(block_hash: H256, header: CompactExecutionHeader) { @@ -530,10 +530,10 @@ pub mod benchmark_helpers { type Ticket = Xcm<()>; fn validate( - _dest: &mut Option, + _dest: &mut Option, xcm: &mut Option>, ) -> SendResult { - Ok((xcm.clone().unwrap(), MultiAssets::new())) + Ok((xcm.clone().unwrap(), Assets::new())) } fn deliver(xcm: Xcm<()>) -> Result { let hash = xcm.using_encoded(sp_io::hashing::blake2_256); @@ -542,7 +542,7 @@ pub mod benchmark_helpers { } impl snowbridge_pallet_system::BenchmarkHelper for () { - fn make_xcm_origin(location: MultiLocation) -> RuntimeOrigin { + fn make_xcm_origin(location: Location) -> RuntimeOrigin { RuntimeOrigin::from(pallet_xcm::Origin::Xcm(location)) } } @@ -1016,7 +1016,7 @@ impl_runtime_apis! { } impl snowbridge_system_runtime_api::ControlApi for Runtime { - fn agent_id(location: VersionedMultiLocation) -> Option { + fn agent_id(location: VersionedLocation) -> Option { snowbridge_pallet_system::api::agent_id::(location) } } @@ -1095,28 +1095,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between BH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on BH. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = Parent.into(); @@ -1132,7 +1132,7 @@ impl_runtime_apis! { use xcm_config::TokenLocation; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -1143,17 +1143,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(TokenLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(TokenLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -1162,12 +1162,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( TokenLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(TokenLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -1177,9 +1177,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(UNITS), } } @@ -1193,35 +1193,35 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((TokenLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(TokenLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = TokenLocation::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // save XCM version for remote bridge hub let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), @@ -1241,12 +1241,12 @@ impl_runtime_apis! { ( bridge_to_westend_config::FromAssetHubRococoToAssetHubWestendRoute::get().location, NetworkId::Westend, - X1(Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())) + [Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())].into() ) ) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } @@ -1296,7 +1296,7 @@ impl_runtime_apis! { Runtime, bridge_common_config::BridgeGrandpaWestendInstance, bridge_to_westend_config::WithBridgeHubWestendMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Rococo), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } fn prepare_message_delivery_proof( @@ -1331,7 +1331,7 @@ impl_runtime_apis! { Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, bridge_to_bulletin_config::WithRococoBulletinMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Rococo), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Rococo), Parachain(42)].into())) } fn prepare_message_delivery_proof( 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 1c2334a89e2..4f5bae0fe59 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 @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct BridgeHubRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for BridgeHubRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,44 +107,36 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -163,7 +151,7 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -175,13 +163,13 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -215,16 +203,16 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { let inner_encoded_len = inner.encode().len() as u32; XcmGeneric::::export_message(inner_encoded_len) } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -236,11 +224,11 @@ impl XcmWeightInfo for BridgeHubRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs index dc98622cafc..f641b428d4c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/xcm_config.rs @@ -32,7 +32,7 @@ use bp_messages::LaneId; use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::ChainId; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -69,19 +69,19 @@ use xcm_executor::{ }; parameter_types! { - pub const TokenLocation: MultiLocation = MultiLocation::parent(); + pub const TokenLocation: Location = Location::parent(); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub RelayNetwork: NetworkId = NetworkId::Rococo; - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); - pub SiblingPeople: MultiLocation = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub SiblingPeople: Location = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -100,7 +100,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -132,11 +132,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -331,7 +331,7 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -407,14 +407,10 @@ impl< BridgeLaneId, > { - fn handle_fee( - fee: MultiAssets, - maybe_context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, maybe_context: Option<&XcmContext>, reason: FeeReason) -> Assets { if matches!(reason, FeeReason::Export { network: bridged_network, destination } if bridged_network == DestNetwork::get() && - destination == X1(Parachain(DestParaId::get().into()))) + destination == [Parachain(DestParaId::get().into())]) { // We have 2 relayer rewards accounts: // - the SA of the source parachain on this BH: this pays the relayers for delivering @@ -445,14 +441,14 @@ impl< Fungible(total_fee) => { let source_fee = total_fee / 2; deposit_or_burn_fee::( - MultiAsset { id: asset.id, fun: Fungible(source_fee) }.into(), + Asset { id: asset.id.clone(), fun: Fungible(source_fee) }.into(), maybe_context, source_para_account.clone(), ); let dest_fee = total_fee - source_fee; deposit_or_burn_fee::( - MultiAsset { id: asset.id, fun: Fungible(dest_fee) }.into(), + Asset { id: asset.id, fun: Fungible(dest_fee) }.into(), maybe_context, dest_para_account.clone(), ); @@ -467,7 +463,7 @@ impl< } } - return MultiAssets::new() + return Assets::new() } fee @@ -477,10 +473,10 @@ impl< pub struct XcmFeeManagerFromComponentsBridgeHub( PhantomData<(WaivedLocations, HandleFee)>, ); -impl, FeeHandler: HandleFee> FeeManager +impl, FeeHandler: HandleFee> FeeManager for XcmFeeManagerFromComponentsBridgeHub { - fn is_waived(origin: Option<&MultiLocation>, fee_reason: FeeReason) -> bool { + fn is_waived(origin: Option<&Location>, fee_reason: FeeReason) -> bool { let Some(loc) = origin else { return false }; if let Export { network, destination: Here } = fee_reason { return !(network == EthereumNetwork::get()) @@ -488,7 +484,7 @@ impl, FeeHandler: HandleFee> FeeManager WaivedLocations::contains(loc) } - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) { FeeHandler::handle_fee(fee, context, reason); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 0fba28c47b4..63e64506ec7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -241,7 +241,7 @@ mod bridge_hub_westend_tests { _ => None, } }), - || ExportMessage { network: Westend, destination: X1(Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())), xcm: Xcm(vec![]) }, + || ExportMessage { network: Westend, destination: [Parachain(bridge_to_westend_config::AssetHubWestendParaId::get().into())].into(), xcm: Xcm(vec![]) }, XCM_LANE_FOR_ASSET_HUB_ROCOCO_TO_ASSET_HUB_WESTEND, Some((TokenLocation::get(), ExistentialDeposit::get()).into()), // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index eb5493872b4..716e01b85b4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -47,7 +47,7 @@ use frame_support::{ use sp_runtime::RuntimeDebug; use xcm::{ latest::prelude::*, - prelude::{InteriorMultiLocation, NetworkId}, + prelude::{InteriorLocation, NetworkId}, }; use xcm_builder::BridgeBlobDispatcher; @@ -63,12 +63,12 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; - pub BridgeWestendToRococoMessagesPalletInstance: InteriorMultiLocation = X1(PalletInstance(::index() as u8)); + pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; - pub RococoGlobalConsensusNetworkLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(RococoGlobalConsensusNetwork::get())) - }; + pub RococoGlobalConsensusNetworkLocation: Location = Location::new( + 2, + [GlobalConsensus(RococoGlobalConsensusNetwork::get())] + ); // see the `FEE_BOOST_PER_MESSAGE` constant to get the meaning of this value pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; @@ -79,26 +79,26 @@ parameter_types! { pub ActiveOutboundLanesToBridgeHubRococo: &'static [bp_messages::LaneId] = &[XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO]; pub const AssetHubWestendToAssetHubRococoMessagesLane: bp_messages::LaneId = XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO; pub FromAssetHubWestendToAssetHubRococoRoute: SenderAndLane = SenderAndLane::new( - ParentThen(X1(Parachain(AssetHubWestendParaId::get().into()))).into(), + ParentThen([Parachain(AssetHubWestendParaId::get().into())].into()).into(), XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, ); - pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![ + pub ActiveLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ ( FromAssetHubWestendToAssetHubRococoRoute::get(), - (RococoGlobalConsensusNetwork::get(), X1(Parachain(AssetHubRococoParaId::get().into()))) + (RococoGlobalConsensusNetwork::get(), [Parachain(AssetHubRococoParaId::get().into())].into()) ) ]; pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); - pub BridgeHubRococoLocation: MultiLocation = MultiLocation { - parents: 2, - interior: X2( + pub BridgeHubRococoLocation: Location = Location::new( + 2, + [ GlobalConsensus(RococoGlobalConsensusNetwork::get()), Parachain(::PARACHAIN_ID) - ) - }; + ] + ); } pub const XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO: LaneId = LaneId([0, 0, 0, 2]); @@ -363,9 +363,9 @@ mod tests { assert_eq!( BridgeWestendToRococoMessagesPalletInstance::get(), - X1(PalletInstance( + [PalletInstance( bp_bridge_hub_westend::WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX - )) + )] ); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 717cde6280d..d920f5a98cf 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -352,7 +352,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WestendLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WestendLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -797,28 +797,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between BH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on BH. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // BH only supports teleports to system parachain. // Relay/native token can be teleported between BH and Relay. let native_location = Parent.into(); @@ -834,7 +834,7 @@ impl_runtime_apis! { use xcm_config::WestendLocation; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WestendLocation::get(), ExistentialDeposit::get() ).into()); @@ -845,17 +845,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WestendLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { - // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(WestendLocation::get()), + fn worst_case_holding(_depositable_count: u32) -> Assets { + // just assets according to relay chain. + let assets: Vec = vec![ + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -864,12 +864,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WestendLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WestendLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -879,9 +879,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WestendLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WestendLocation::get()), fun: Fungible(UNITS), } } @@ -895,35 +895,35 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WestendLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WestendLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = WestendLocation::get(); - let assets: MultiAssets = (Concrete(WestendLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(WestendLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // save XCM version for remote bridge hub let _ = PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), @@ -943,12 +943,12 @@ impl_runtime_apis! { ( bridge_to_rococo_config::FromAssetHubWestendToAssetHubRococoRoute::get().location, NetworkId::Rococo, - X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())) + [Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())].into() ) ) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } @@ -995,7 +995,7 @@ impl_runtime_apis! { Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, bridge_to_rococo_config::WithBridgeHubRococoMessageBridge, - >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Westend), Parachain(42)))) + >(params, generate_xcm_builder_bridge_message_sample([GlobalConsensus(Westend), Parachain(42)].into())) } fn prepare_message_delivery_proof( 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 7269fa84f84..e8950678b40 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 @@ -25,14 +25,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -51,40 +51,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct BridgeHubWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for BridgeHubWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,44 +108,36 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -164,7 +152,7 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -176,13 +164,13 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -216,16 +204,16 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { let inner_encoded_len = inner.encode().len() as u32; XcmGeneric::::export_message(inner_encoded_len) } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -237,11 +225,11 @@ impl XcmWeightInfo for BridgeHubWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs index 397019190f3..085608acf5d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/xcm_config.rs @@ -21,7 +21,7 @@ use super::{ }; use crate::bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -52,18 +52,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Westend; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -82,7 +82,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -114,11 +114,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -270,7 +270,7 @@ impl xcm_executor::Config for XcmConfig { pub type PriceForParentDelivery = ExponentialPrice; -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 0e58b7b408e..1237a231390 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -207,7 +207,7 @@ fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { _ => None, } }), - || ExportMessage { network: Rococo, destination: X1(Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())), xcm: Xcm(vec![]) }, + || ExportMessage { network: Rococo, destination: [Parachain(bridge_to_rococo_config::AssetHubRococoParaId::get().into())].into(), xcm: Xcm(vec![]) }, XCM_LANE_FOR_ASSET_HUB_WESTEND_TO_ASSET_HUB_ROCOCO, Some((WestendLocation::get(), ExistentialDeposit::get()).into()), // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs index 3e821d45569..c1bba65b0ab 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs @@ -23,7 +23,7 @@ use pallet_message_queue::OnQueueChanged; use scale_info::TypeInfo; use snowbridge_core::ChannelId; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::v3::{Junction, MultiLocation}; +use xcm::v4::{Junction, Location}; /// The aggregate origin of an inbound message. /// This is specialized for BridgeHub, as the snowbridge-outbound-queue-pallet is also using @@ -46,16 +46,16 @@ pub enum AggregateMessageOrigin { Snowbridge(ChannelId), } -impl From for MultiLocation { +impl From for Location { fn from(origin: AggregateMessageOrigin) -> Self { use AggregateMessageOrigin::*; match origin { - Here => MultiLocation::here(), - Parent => MultiLocation::parent(), - Sibling(id) => MultiLocation::new(1, Junction::Parachain(id.into())), + Here => Location::here(), + Parent => Location::parent(), + Sibling(id) => Location::new(1, Junction::Parachain(id.into())), // NOTE: We don't need this conversion for Snowbridge. However we have to // implement it anyway as xcm_builder::ProcessXcmMessage requires it. - Snowbridge(_) => MultiLocation::default(), + Snowbridge(_) => Location::default(), } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index e0e75f093cf..5eca85d3112 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -336,9 +336,9 @@ where (), >( LaneId::default(), - vec![xcm::v3::Instruction::<()>::ClearOrigin; 1_024].into(), + vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, - X2(GlobalConsensus(Polkadot), Parachain(1_000)), + [GlobalConsensus(Polkadot), Parachain(1_000)].into(), 1u32.into(), ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 91bebb36b18..6e638b7b350 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -418,9 +418,9 @@ where (), >( LaneId::default(), - vec![xcm::v3::Instruction::<()>::ClearOrigin; 1_024].into(), + vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, - X2(GlobalConsensus(Polkadot), Parachain(1_000)), + [GlobalConsensus(Polkadot), Parachain(1_000)].into(), 1, 5, 1_000, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index 69aa61db3cc..ba58aeb046e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -230,7 +230,7 @@ pub fn relayed_incoming_message_works( prepare_message_proof_import: impl FnOnce( Runtime::AccountId, Runtime::InboundRelayer, - InteriorMultiLocation, + InteriorLocation, MessageNonce, Xcm<()>, ) -> CallsAndVerifiers, @@ -276,21 +276,21 @@ pub fn relayed_incoming_message_works( // set up relayer details and proofs - let message_destination = - X2(GlobalConsensus(local_relay_chain_id), Parachain(sibling_parachain_id)); + let message_destination: InteriorLocation = + [GlobalConsensus(local_relay_chain_id), Parachain(sibling_parachain_id)].into(); // some random numbers (checked by test) let message_nonce = 1; - let xcm = vec![xcm::v3::Instruction::<()>::ClearOrigin; 42]; + let xcm = vec![Instruction::<()>::ClearOrigin; 42]; let expected_dispatch = xcm::latest::Xcm::<()>({ let mut expected_instructions = xcm.clone(); // dispatch prepends bridge pallet instance expected_instructions.insert( 0, - DescendOrigin(X1(PalletInstance( + DescendOrigin([PalletInstance( as PalletInfoAccess>::index() as u8, - ))), + )].into()), ); expected_instructions }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index 64ec8726599..eb7ba132168 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -319,8 +319,8 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< >, export_message_instruction: fn() -> Instruction, expected_lane_id: LaneId, - existential_deposit: Option, - maybe_paid_export_message: Option, + existential_deposit: Option, + maybe_paid_export_message: Option, prepare_configuration: impl Fn(), ) where Runtime: BasicParachainRuntime + BridgeMessagesConfig, @@ -328,7 +328,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< MessagesPalletInstance: 'static, { assert_ne!(runtime_para_id, sibling_parachain_id); - let sibling_parachain_location = MultiLocation::new(1, Parachain(sibling_parachain_id)); + let sibling_parachain_location = Location::new(1, [Parachain(sibling_parachain_id)]); run_test::(collator_session_key, runtime_para_id, vec![], || { prepare_configuration(); @@ -361,7 +361,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< .expect("deposited fee"); Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![fee.clone()])), + WithdrawAsset(Assets::from(vec![fee.clone()])), BuyExecution { fees: fee, weight_limit: Unlimited }, export_message_instruction(), ]) @@ -373,12 +373,13 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< }; // execute XCM - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - assert_ok!(XcmExecutor::::execute_xcm( + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + assert_ok!(XcmExecutor::::prepare_and_execute( sibling_parachain_location, xcm, - hash, + &mut hash, RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + Weight::zero(), ) .ensure_complete()); @@ -446,9 +447,9 @@ pub fn message_dispatch_routing_works< NetworkDistanceAsParentCount: Get, { struct NetworkWithParentCount(core::marker::PhantomData<(N, C)>); - impl, C: Get> Get for NetworkWithParentCount { - fn get() -> MultiLocation { - MultiLocation { parents: C::get(), interior: X1(GlobalConsensus(N::get())) } + impl, C: Get> Get for NetworkWithParentCount { + fn get() -> Location { + Location::new(C::get(), [GlobalConsensus(N::get())]) } } @@ -495,7 +496,7 @@ pub fn message_dispatch_routing_works< BridgedNetwork, NetworkWithParentCount, AlwaysLatest, - >((RuntimeNetwork::get(), X1(Parachain(sibling_parachain_id)))); + >((RuntimeNetwork::get(), [Parachain(sibling_parachain_id)].into())); // 2.1. WITHOUT opened hrmp channel -> RoutingError let result = @@ -565,52 +566,43 @@ where { // data here are not relevant for weighing let mut xcm = Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), + WithdrawAsset(Assets::from(vec![Asset { + id: AssetId(Location::new(1, [])), fun: Fungible(34333299), }])), BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation { parents: 1, interior: Here }), - fun: Fungible(34333299), - }, + fees: Asset { id: AssetId(Location::new(1, [])), fun: Fungible(34333299) }, weight_limit: Unlimited, }, ExportMessage { network: Polkadot, - destination: X1(Parachain(1000)), + destination: [Parachain(1000)].into(), xcm: Xcm(vec![ - ReserveAssetDeposited(MultiAssets::from(vec![MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Kusama)), - }), + ReserveAssetDeposited(Assets::from(vec![Asset { + id: AssetId(Location::new(2, [GlobalConsensus(Kusama)])), fun: Fungible(1000000000000), }])), ClearOrigin, BuyExecution { - fees: MultiAsset { - id: Concrete(MultiLocation { - parents: 2, - interior: X1(GlobalConsensus(Kusama)), - }), + fees: Asset { + id: AssetId(Location::new(2, [GlobalConsensus(Kusama)])), fun: Fungible(1000000000000), }, weight_limit: Unlimited, }, DepositAsset { assets: Wild(AllCounted(1)), - beneficiary: MultiLocation { - parents: 0, - interior: X1(xcm::latest::prelude::AccountId32 { + beneficiary: Location::new( + 0, + [xcm::latest::prelude::AccountId32 { network: None, id: [ 212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125, ], - }), - }, + }], + ), }, SetTopic([ 116, 82, 194, 132, 171, 114, 217, 165, 23, 37, 161, 177, 165, 179, 247, 114, @@ -618,10 +610,7 @@ where ]), ]), }, - DepositAsset { - assets: Wild(All), - beneficiary: MultiLocation { parents: 1, interior: X1(Parachain(1000)) }, - }, + DepositAsset { assets: Wild(All), beneficiary: Location::new(1, [Parachain(1000)]) }, SetTopic([ 36, 224, 250, 165, 82, 195, 67, 110, 160, 170, 140, 87, 217, 62, 201, 164, 42, 98, 219, 157, 124, 105, 248, 25, 131, 218, 199, 36, 109, 173, 100, 122, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs index f905d21b187..9285a1e7ad4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs @@ -37,10 +37,10 @@ use xcm_executor::traits::{validate_export, ExportXcm}; pub fn prepare_inbound_xcm( xcm_message: Xcm, - destination: InteriorMultiLocation, + destination: InteriorLocation, ) -> Vec { - let location = xcm::VersionedInteriorMultiLocation::V3(destination); - let xcm = xcm::VersionedXcm::::V3(xcm_message); + let location = xcm::VersionedInteriorLocation::V4(destination); + let xcm = xcm::VersionedXcm::::V4(xcm_message); // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor // or public fields, so just tuple // (double encoding, because `.encode()` is called on original Xcm BLOB when it is pushed @@ -101,7 +101,7 @@ macro_rules! grab_haul_blob ( /// which are transferred over bridge. pub(crate) fn simulate_message_exporter_on_bridged_chain< SourceNetwork: Get, - DestinationNetwork: Get, + DestinationNetwork: Get, DestinationVersion: GetVersion, >( (destination_network, destination_junctions): (NetworkId, Junctions), @@ -109,8 +109,8 @@ pub(crate) fn simulate_message_exporter_on_bridged_chain< grab_haul_blob!(GrabbingHaulBlob, GRABBED_HAUL_BLOB_PAYLOAD); // lets pretend that some parachain on bridged chain exported the message - let universal_source_on_bridged_chain = - X2(GlobalConsensus(SourceNetwork::get()), Parachain(5678)); + let universal_source_on_bridged_chain: Junctions = + [GlobalConsensus(SourceNetwork::get()), Parachain(5678)].into(); let channel = 1_u32; // simulate XCM message export diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs index 9f6378de53a..05b3427ef43 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/ambassador/mod.rs @@ -215,7 +215,7 @@ pub type AmbassadorSalaryInstance = pallet_salary::Instance2; parameter_types! { // The interior location on AssetHub for the paying account. This is the Ambassador Salary // pallet instance (which sits at index 74). This sovereign account will need funding. - pub AmbassadorSalaryLocation: InteriorMultiLocation = PalletInstance(74).into(); + pub AmbassadorSalaryLocation: InteriorLocation = PalletInstance(74).into(); } /// [`PayOverXcm`] setup to pay the Ambassador salary on the AssetHub in WND. diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs index f49306bf8e3..273fa6a3415 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs @@ -43,7 +43,7 @@ use parachains_common::{ westend::{account, currency::GRAND}, }; use polkadot_runtime_common::impls::{ - LocatableAssetConverter, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; use sp_arithmetic::Permill; use sp_core::{ConstU128, ConstU32}; @@ -202,7 +202,7 @@ pub type FellowshipSalaryInstance = pallet_salary::Instance1; parameter_types! { // The interior location on AssetHub for the paying account. This is the Fellowship Salary // pallet instance (which sits at index 64). This sovereign account will need funding. - pub Interior: InteriorMultiLocation = PalletInstance(64).into(); + pub Interior: InteriorLocation = PalletInstance(64).into(); } const USDT_UNITS: u128 = 1_000_000; @@ -250,7 +250,7 @@ parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); // The asset's interior location for the paying account. This is the Fellowship Treasury // pallet instance (which sits at index 65). - pub FellowshipTreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(65).into(); + pub FellowshipTreasuryInteriorLocation: InteriorLocation = PalletInstance(65).into(); } #[cfg(feature = "runtime-benchmarks")] @@ -269,10 +269,10 @@ pub type FellowshipTreasuryPaymaster = PayOverXcm< crate::xcm_config::XcmRouter, crate::PolkadotXcm, ConstU32<{ 6 * HOURS }>, - VersionedMultiLocation, + VersionedLocation, VersionedLocatableAsset, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; pub type FellowshipTreasuryInstance = pallet_treasury::Instance1; @@ -327,7 +327,7 @@ impl pallet_treasury::Config for Runtime { >, >; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; #[cfg(not(feature = "runtime-benchmarks"))] type Paymaster = FellowshipTreasuryPaymaster; diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 6cb8e096e4b..a527f620137 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -427,7 +427,7 @@ impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(xcm_config::WndLocation::get()); + pub FeeAssetId: AssetId = AssetId(xcm_config::WndLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -974,28 +974,28 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between Collectives and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }.into(), Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on Collectives. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Collectives only supports teleports to system parachain. // Relay/native token can be teleported between Collectives and Relay. let native_location = Parent.into(); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs index 2e64127d6a1..aa7dbe991e4 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ TransactionByteFee, WeightToFee, WestendTreasuryAccount, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, weights::Weight, }; @@ -51,17 +51,17 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WndLocation: MultiLocation = MultiLocation::parent(); + pub const WndLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); pub const FellowshipAdminBodyId: BodyId = BodyId::Index(xcm_constants::body::FELLOWSHIP_ADMIN_INDEX); + pub AssetHub: Location = (Parent, Parachain(1000)).into(); pub const TreasurerBodyId: BodyId = BodyId::Index(xcm_constants::body::TREASURER_INDEX); - pub AssetHub: MultiLocation = (Parent, Parachain(1000)).into(); pub AssetHubUsdtId: AssetId = (PalletInstance(50), GeneralIndex(1984)).into(); pub UsdtAssetHub: LocatableAssetId = LocatableAssetId { location: AssetHub::get(), @@ -73,7 +73,7 @@ parameter_types! { }; } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -92,7 +92,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -136,11 +136,11 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -292,7 +292,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -310,10 +310,10 @@ pub type XcmRouter = WithUniqueTopic<( #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = Some(Parent.into()); + pub ReachableDest: Option = Some(Parent.into()); } -/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +/// Type to convert the Fellows origin to a Plurality `Location` value. pub type FellowsToPlurality = OriginToPluralityVoice; impl pallet_xcm::Config for Runtime { diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 79b6b6be299..bc7d94889a1 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -704,28 +704,28 @@ impl_runtime_apis! { use xcm::latest::prelude::*; use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between Contracts-System-Para and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled on Contracts-System-Para. None } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Contracts-System-Para only supports teleports to system parachain. // Relay/native token can be teleported between Contracts-System-Para and Relay. let native_location = Parent.into(); diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs index 569ca6e587c..e2cf2c8e51a 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/xcm_config.rs @@ -20,8 +20,8 @@ use super::{ use crate::common::rococo::currency::CENTS; use cumulus_primitives_core::AggregateMessageOrigin; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, EitherOfDiverse, Equals, Everything, Nothing}, + parameter_types, + traits::{ConstU32, Contains, EitherOfDiverse, Equals, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -51,13 +51,13 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); pub const ExecutiveBody: BodyId = BodyId::Executive; pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } /// We allow root and the Relay Chain council to execute privileged collator selection operations. @@ -66,7 +66,7 @@ pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< EnsureXcm>, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -85,7 +85,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -123,11 +123,11 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } pub type Barrier = TrailingSetTopicAsId< @@ -200,7 +200,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. +/// Converts a local signed origin into an XCM location. /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; @@ -254,7 +254,7 @@ impl cumulus_pallet_xcm::Config for Runtime { parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs index f8a5dc6398a..a46051212de 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs @@ -98,7 +98,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Request to update schedulable cores sent successfully." @@ -128,7 +128,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Request for revenue information sent successfully." @@ -157,7 +157,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Instruction to credit account sent successfully." @@ -192,7 +192,7 @@ impl CoretimeInterface for CoretimeAllocator { }, ]); - match PolkadotXcm::send_xcm(Here, MultiLocation::parent(), message.clone()) { + match PolkadotXcm::send_xcm(Here, Location::parent(), message.clone()) { Ok(_) => log::info!( target: "runtime::coretime", "Core assignment sent successfully." diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index c381d78b57f..c5843c1ef29 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -315,7 +315,7 @@ pub type RootOrFellows = EitherOfDiverse< parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(RocRelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RocRelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -698,29 +698,29 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled None } } parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RocRelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -730,18 +730,18 @@ impl_runtime_apis! { type XcmConfig = xcm_config::XcmConfig; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; type AccountIdConverter = xcm_config::LocationToAccountId; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RocRelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RocRelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RocRelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -750,12 +750,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RocRelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RocRelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RocRelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -765,9 +765,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RocRelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RocRelayLocation::get()), fun: Fungible(UNITS), } } @@ -781,39 +781,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RocRelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RocRelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RocRelayLocation::get(); - let assets: MultiAssets = (Concrete(RocRelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RocRelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } 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 2319c2e3a5b..8815312f304 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 @@ -24,14 +24,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -50,40 +50,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct CoretimeRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for CoretimeRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -111,43 +107,35 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for CoretimeRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs index 00bbe5b5037..927d8f0a78e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ TransactionByteFee, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -51,18 +51,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RocRelayLocation: MultiLocation = MultiLocation::parent(); + pub const RocRelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); - pub const FellowshipLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); + pub const FellowshipLocation: Location = Location::parent(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -81,7 +81,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -114,11 +114,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -191,7 +191,7 @@ pub type Barrier = TrailingSetTopicAsId< parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Locations that will not be charged fees in the executor, neither for execution nor delivery. @@ -240,7 +240,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 742b3a29275..59ed8d7c603 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -306,7 +306,7 @@ pub type RootOrFellows = EitherOfDiverse< parameter_types! { /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(WndRelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(WndRelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -689,29 +689,29 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between AH and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Reserve transfers are disabled None } } parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( WndRelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -721,18 +721,18 @@ impl_runtime_apis! { type XcmConfig = xcm_config::XcmConfig; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForParentDelivery, >; type AccountIdConverter = xcm_config::LocationToAccountId; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(WndRelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(WndRelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(WndRelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -741,12 +741,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( WndRelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(WndRelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(WndRelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -756,9 +756,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(WndRelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(WndRelayLocation::get()), fun: Fungible(UNITS), } } @@ -772,39 +772,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((WndRelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(WndRelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = WndRelayLocation::get(); - let assets: MultiAssets = (Concrete(WndRelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(WndRelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } 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 3dc7b82efc2..a14da7c7a38 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 @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,40 +49,36 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct CoretimeWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for CoretimeWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -110,44 +106,36 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmFungibleWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -162,7 +150,7 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -174,13 +162,13 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -213,16 +201,16 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -234,11 +222,11 @@ impl XcmWeightInfo for CoretimeWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs index 59d76d10d90..f468f29540a 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ TransactionByteFee, WeightToFee, XcmpQueue, }; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -51,18 +51,18 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const WndRelayLocation: MultiLocation = MultiLocation::parent(); + pub const WndRelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub FellowshipLocation: Location = Location::new(1, Parachain(1001)); + pub const GovernanceLocation: Location = Location::parent(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -81,7 +81,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -114,14 +114,18 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type FellowsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } - }; +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct FellowsPlurality; +impl Contains for FellowsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -192,7 +196,7 @@ pub type Barrier = TrailingSetTopicAsId< parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Locations that will not be charged fees in the executor, neither for execution nor delivery. @@ -241,7 +245,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs index 5ebb0ade123..1c37241563e 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ RuntimeOrigin, }; use frame_support::{ - match_types, parameter_types, - traits::{Everything, Nothing}, + parameter_types, + traits::{Contains, Everything, Nothing}, weights::Weight, }; use xcm::latest::prelude::*; @@ -29,9 +29,9 @@ use xcm_builder::{ }; parameter_types! { - pub const WestendLocation: MultiLocation = MultiLocation::parent(); + pub const WestendLocation: Location = Location::parent(); pub const WestendNetwork: Option = Some(NetworkId::Westend); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -47,8 +47,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, ); -match_types! { - pub type JustTheParent: impl Contains = { MultiLocation { parents:1, interior: Here } }; +pub struct JustTheParent; +impl Contains for JustTheParent { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [])) + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 7805e0ad982..f5398829c73 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -682,22 +682,22 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between People and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } } @@ -706,7 +706,7 @@ impl_runtime_apis! { use xcm_config::{PriceForParentDelivery, RelayLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -717,17 +717,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -736,12 +736,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -751,9 +751,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(UNITS), } } @@ -767,39 +767,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location::new(0, []); Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } 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 c90a96c7f82..4afd65bdcfe 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 @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,42 +49,38 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct PeopleRococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for PeopleRococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } // Currently there is no trusted reserve - fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + fn reserve_asset_deposited(_assets: &Assets) -> Weight { // TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974 Weight::from_parts(1_000_000_000_u64, 0) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,47 +108,39 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()); + let weight = assets.weigh_assets(XcmFungibleWeight::::deposit_asset()); hardcoded_weight.min(weight) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmGeneric::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -167,7 +155,7 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -179,13 +167,13 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -218,16 +206,16 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -239,11 +227,11 @@ impl XcmWeightInfo for PeopleRococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs index 7a2f28aa813..7ef6cb2fac9 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::{TransactionByteFee, CENTS}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -49,22 +49,22 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RootLocation: Location = Location::here(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); - pub const FellowshipLocation: MultiLocation = MultiLocation::parent(); + pub const GovernanceLocation: Location = Location::parent(); + pub const FellowshipLocation: Location = Location::parent(); /// The asset ID for the asset that we use to pay for message delivery fees. Just ROC. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -82,7 +82,7 @@ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender: XcmpQueue, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -103,7 +103,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's `AccountId` type (we can't get away without mentioning it explicitly): @@ -136,18 +136,25 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type ParentOrSiblings: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Plurality { .. }])) + } +} + +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct ParentOrSiblings; +impl Contains for ParentOrSiblings { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -268,7 +275,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 8ea29c8aa21..33f0d511705 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -682,22 +682,22 @@ impl_runtime_apis! { use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark; impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parent.into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported between People and Relay. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Parent.into()) + id: AssetId(Parent.into()) }, Parent.into(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } } @@ -706,7 +706,7 @@ impl_runtime_apis! { use xcm_config::{PriceForParentDelivery, RelayLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( RelayLocation::get(), ExistentialDeposit::get() ).into()); @@ -717,17 +717,17 @@ impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationToAccountId; type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, PriceForParentDelivery, >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(RelayLocation::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // just concrete assets according to relay chain. - let assets: Vec = vec![ - MultiAsset { - id: Concrete(RelayLocation::get()), + let assets: Vec = vec![ + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(1_000_000 * UNITS), } ]; @@ -736,12 +736,12 @@ impl_runtime_apis! { } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub const TrustedTeleporter: Option<(Location, Asset)> = Some(( RelayLocation::get(), - MultiAsset { fun: Fungible(UNITS), id: Concrete(RelayLocation::get()) }, + Asset { fun: Fungible(UNITS), id: AssetId(RelayLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -751,9 +751,9 @@ impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(RelayLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(RelayLocation::get()), fun: Fungible(UNITS), } } @@ -767,39 +767,39 @@ impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((RelayLocation::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(RelayLocation::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = RelayLocation::get(); - let assets: MultiAssets = (Concrete(RelayLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(RelayLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { Err(BenchmarkError::Skip) } } 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 5d6f90e9f1b..b2579230c9e 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 @@ -23,14 +23,14 @@ use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; use sp_std::prelude::*; use xcm::{latest::prelude::*, DoubleEncoded}; -trait WeighMultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, weight: Weight) -> Weight; } const MAX_ASSETS: u64 = 100; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, weight: Weight) -> Weight { match self { Self::Definite(assets) => weight.saturating_mul(assets.inner().iter().count() as u64), Self::Wild(asset) => match asset { @@ -49,42 +49,38 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, weight: Weight) -> Weight { weight.saturating_mul(self.inner().iter().count() as u64) } } pub struct PeopleWestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for PeopleWestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::withdraw_asset()) } // Currently there is no trusted reserve - fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + fn reserve_asset_deposited(_assets: &Assets) -> Weight { // TODO: hardcoded - fix https://github.com/paritytech/cumulus/issues/1974 Weight::from_parts(1_000_000_000_u64, 0) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::transfer_reserve_asset()) } fn transact( _origin_type: &OriginKind, @@ -112,50 +108,42 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(1_000_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::deposit_asset()); + let weight = assets.weigh_assets(XcmFungibleWeight::::deposit_asset()); hardcoded_weight.min(weight) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmFungibleWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmFungibleWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmGeneric::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { // Hardcoded till the XCM pallet is fixed let hardcoded_weight = Weight::from_parts(200_000_000_u64, 0); - let weight = assets.weigh_multi_assets(XcmFungibleWeight::::initiate_teleport()); + let weight = assets.weigh_assets(XcmFungibleWeight::::initiate_teleport()); hardcoded_weight.min(weight) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -170,7 +158,7 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -182,13 +170,13 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -221,16 +209,16 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { Weight::MAX } fn set_fees_mode(_: &bool) -> Weight { @@ -242,11 +230,11 @@ impl XcmWeightInfo for PeopleWestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 0a51cf72d5b..59c00dc5ff6 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::{TransactionByteFee, CENTS}; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ConstU32, Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; @@ -49,22 +49,22 @@ use xcm_builder::{ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RootLocation: Location = Location::here(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Westend); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = + [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); - pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); + pub FellowshipLocation: Location = Location::new(1, Parachain(1001)); + pub const GovernanceLocation: Location = Location::parent(); /// The asset ID for the asset that we use to pay for message delivery fees. Just WND. - pub FeeAssetId: AssetId = Concrete(RelayLocation::get()); + pub FeeAssetId: AssetId = AssetId(RelayLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); - pub RelayTreasuryLocation: MultiLocation = + pub RelayTreasuryLocation: Location = (Parent, PalletInstance(westend_runtime_constants::TREASURY_PALLET_ID)).into(); } @@ -82,7 +82,7 @@ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common::xcm_sender: XcmpQueue, >; -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -103,7 +103,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an `AccountId32` `MultiLocation` into a native chain + // Do a simple punn to convert an `AccountId32` `Location` into a native chain // `AccountId`: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): @@ -136,21 +136,32 @@ pub type XcmOriginToTransactDispatchOrigin = ( XcmPassthrough, ); -match_types! { - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; - pub type ParentOrParentsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { .. }) } - }; - pub type ParentOrSiblings: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; - pub type FellowsPlurality: impl Contains = { - MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) } - }; +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Plurality { .. }])) + } +} + +pub struct ParentOrParentsPlurality; +impl Contains for ParentOrParentsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) + } +} + +pub struct ParentOrSiblings; +impl Contains for ParentOrSiblings { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Parachain(_)])) + } +} + +pub struct FellowsPlurality; +impl Contains for FellowsPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1001), Plurality { id: BodyId::Technical, .. }])) + } } /// A call filter for the XCM Transact instruction. This is a temporary measure until we properly @@ -272,7 +283,7 @@ impl xcm_executor::Config for XcmConfig { type Aliasers = Nothing; } -/// Converts a local signed origin into an XCM multilocation. Forms the basis for local origins +/// Converts a local signed origin into an XCM location. Forms the basis for local origins /// sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; diff --git a/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs b/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs index ff773ca7816..f5ceabb1eb4 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/xcm_config.rs @@ -18,8 +18,8 @@ use super::{ RuntimeOrigin, }; use frame_support::{ - match_types, parameter_types, - traits::{Everything, Nothing}, + parameter_types, + traits::{Contains, Everything, Nothing}, weights::Weight, }; use xcm::latest::prelude::*; @@ -29,9 +29,9 @@ use xcm_builder::{ }; parameter_types! { - pub const RococoLocation: MultiLocation = MultiLocation::parent(); + pub const RococoLocation: Location = Location::parent(); pub const RococoNetwork: Option = Some(NetworkId::Rococo); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -47,8 +47,11 @@ pub type XcmOriginToTransactDispatchOrigin = ( ParentAsSuperuser, ); -match_types! { - pub type JustTheParent: impl Contains = { MultiLocation { parents:1, interior: Here } }; +pub struct JustTheParent; +impl Contains for JustTheParent { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [])) + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 6d43875a886..88e878c73a3 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -37,11 +37,11 @@ use sp_consensus_aura::{SlotDuration, AURA_ENGINE_ID}; use sp_core::Encode; use sp_runtime::{traits::Header, BuildStorage, Digest, DigestItem}; use xcm::{ - latest::{MultiAsset, MultiLocation, XcmContext, XcmHash}, + latest::{Asset, Location, XcmContext, XcmHash}, prelude::*, VersionedXcm, MAX_XCM_DECODE_DEPTH, }; -use xcm_executor::{traits::TransactAsset, Assets}; +use xcm_executor::{traits::TransactAsset, AssetsInHolding}; pub mod test_cases; @@ -307,12 +307,12 @@ impl RuntimeHelper { pub fn do_transfer( - from: MultiLocation, - to: MultiLocation, - (asset, amount): (MultiLocation, u128), - ) -> Result { + from: Location, + to: Location, + (asset, amount): (Location, u128), + ) -> Result { ::transfer_asset( - &MultiAsset { id: Concrete(asset), fun: Fungible(amount) }, + &Asset { id: AssetId(asset), fun: Fungible(amount) }, &from, &to, // We aren't able to track the XCM that initiated the fee deposit, so we create a @@ -329,9 +329,9 @@ impl< { pub fn do_teleport_assets( origin: ::RuntimeOrigin, - dest: MultiLocation, - beneficiary: MultiLocation, - (asset, amount): (MultiLocation, u128), + dest: Location, + beneficiary: Location, + (asset, amount): (Location, u128), open_hrmp_channel: Option<(u32, u32)>, included_head: HeaderFor, slot_digest: &[u8], @@ -356,7 +356,7 @@ impl< origin, Box::new(dest.into()), Box::new(beneficiary.into()), - Box::new((Concrete(asset), amount).into()), + Box::new((AssetId(asset), amount).into()), 0, ) } @@ -379,12 +379,13 @@ impl< ]); // execute xcm as parent origin - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - <::XcmExecutor>::execute_xcm( - MultiLocation::parent(), + let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); + <::XcmExecutor>::prepare_and_execute( + Location::parent(), xcm, - hash, + &mut hash, Self::xcm_max_weight(XcmReceivedFrom::Parent), + Weight::zero(), ) } } @@ -451,7 +452,7 @@ impl< } pub fn assert_metadata( - asset_id: impl Into + Copy, + asset_id: impl Into + Clone, expected_name: &str, expected_symbol: &str, expected_decimals: u8, @@ -459,20 +460,20 @@ pub fn assert_metadata( Fungibles: frame_support::traits::fungibles::metadata::Inspect + frame_support::traits::fungibles::Inspect, { - assert_eq!(Fungibles::name(asset_id.into()), Vec::from(expected_name),); - assert_eq!(Fungibles::symbol(asset_id.into()), Vec::from(expected_symbol),); + assert_eq!(Fungibles::name(asset_id.clone().into()), Vec::from(expected_name),); + assert_eq!(Fungibles::symbol(asset_id.clone().into()), Vec::from(expected_symbol),); assert_eq!(Fungibles::decimals(asset_id.into()), expected_decimals); } pub fn assert_total( - asset_id: impl Into + Copy, + asset_id: impl Into + Clone, expected_total_issuance: impl Into, expected_active_issuance: impl Into, ) where Fungibles: frame_support::traits::fungibles::metadata::Inspect + frame_support::traits::fungibles::Inspect, { - assert_eq!(Fungibles::total_issuance(asset_id.into()), expected_total_issuance.into()); + assert_eq!(Fungibles::total_issuance(asset_id.clone().into()), expected_total_issuance.into()); assert_eq!(Fungibles::active_issuance(asset_id.into()), expected_active_issuance.into()); } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 541bcd05644..37a8454d62a 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -32,7 +32,6 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod weights; pub mod xcm_config; -use assets_common::MultiLocationForAssetId; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ @@ -474,8 +473,8 @@ pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocationForAssetId; - type AssetIdParameter = MultiLocationForAssetId; + type AssetId = xcm::v3::Location; + type AssetIdParameter = xcm::v3::Location; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 9287ac30514..b3f84a4bb9c 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -29,7 +29,7 @@ use super::{ }; use core::marker::PhantomData; use frame_support::{ - match_types, parameter_types, + parameter_types, traits::{ fungibles::{self, Balanced, Credit}, ConstU32, Contains, ContainsPair, Everything, Get, Nothing, @@ -59,13 +59,13 @@ use xcm_builder::{ use xcm_executor::{traits::JustTry, XcmExecutor}; parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -84,7 +84,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -115,7 +115,7 @@ pub type FungiblesTransactor = FungiblesAdapter< JustTry, >, ), - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -180,14 +180,18 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type ParentOrParentsExecutivePlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } - }; - pub type CommonGoodAssetsParachain: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(1000)) } - }; +pub struct ParentOrParentsExecutivePlurality; +impl Contains for ParentOrParentsExecutivePlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Executive, .. }])) + } +} + +pub struct CommonGoodAssetsParachain; +impl Contains for CommonGoodAssetsParachain { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1000)])) + } } pub type Barrier = TrailingSetTopicAsId< @@ -224,15 +228,15 @@ pub type AccountIdOf = ::AccountId; /// Asset filter that allows all assets from a certain location matching asset id. pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); -impl ContainsPair for AssetPrefixFrom +impl ContainsPair for AssetPrefixFrom where - Prefix: Get, - Origin: Get, + Prefix: Get, + Origin: Get, { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = Origin::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if asset_loc.starts_with(&Prefix::get())) } } @@ -241,12 +245,12 @@ type AssetsFrom = AssetPrefixFrom; /// Asset filter that allows native/relay asset if coming from a certain location. pub struct NativeAssetFrom(PhantomData); -impl> ContainsPair for NativeAssetFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for NativeAssetFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); &loc == origin && - matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } - if *asset_loc == MultiLocation::from(Parent)) + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + if *asset_loc == Location::from(Parent)) } } @@ -282,29 +286,34 @@ where pub const TELEPORTABLE_ASSET_ID: u32 = 2; parameter_types! { /// The location that this chain recognizes as the Relay network's Asset Hub. - pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]); // ALWAYS ensure that the index in PalletInstance stays up-to-date with // the Relay Chain's Asset Hub's Assets pallet index - pub SystemAssetHubAssetsPalletLocation: MultiLocation = - MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); - pub AssetsPalletLocation: MultiLocation = - MultiLocation::new(0, X1(PalletInstance(50))); + pub SystemAssetHubAssetsPalletLocation: Location = + Location::new(1, [Parachain(1000), PalletInstance(50)]); + pub AssetsPalletLocation: Location = + Location::new(0, [PalletInstance(50)]); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub LocalTeleportableToAssetHub: MultiLocation = MultiLocation::new( + pub LocalTeleportableToAssetHub: Location = Location::new( + 0, + [PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())] + ); + pub LocalTeleportableToAssetHubV3: xcm::v3::Location = xcm::v3::Location::new( 0, - X2(PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())) + [xcm::v3::Junction::PalletInstance(50), xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into())] ); - pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(EthereumNetwork::get()))); + pub EthereumLocation: Location = Location::new(2, [GlobalConsensus(EthereumNetwork::get())]); } /// Accepts asset with ID `AssetLocation` and is coming from `Origin` chain. pub struct AssetFromChain(PhantomData<(AssetLocation, Origin)>); -impl, Origin: Get> - ContainsPair for AssetFromChain +impl, Origin: Get> ContainsPair + for AssetFromChain { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "AssetFromChain asset: {:?}, origin: {:?}", asset, origin); - *origin == Origin::get() && matches!(asset.id, Concrete(id) if id == AssetLocation::get()) + *origin == Origin::get() && + matches!(asset.id.clone(), AssetId(id) if id == AssetLocation::get()) } } @@ -398,8 +407,8 @@ impl cumulus_pallet_xcm::Config for Runtime { /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> xcm::v3::Location { + xcm::v3::Location::new(1, [xcm::v3::Junction::Parachain(id)]) } } diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 7faee4258f6..102127479d2 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -42,10 +42,10 @@ pub use frame_support::{ construct_runtime, derive_impl, dispatch::DispatchClass, genesis_builder_helper::{build_config, create_default_config}, - match_types, parameter_types, + parameter_types, traits::{ - AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, - IsInVec, Nothing, Randomness, + AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, + Everything, IsInVec, Nothing, Randomness, }, weights::{ constants::{ @@ -330,14 +330,14 @@ impl pallet_message_queue::Config for Runtime { impl cumulus_pallet_aura_ext::Config for Runtime {} parameter_types! { - pub const RocLocation: MultiLocation = MultiLocation::parent(); + pub const RocLocation: Location = Location::parent(); pub const RococoNetwork: Option = Some(NetworkId::Rococo); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } -/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( @@ -356,7 +356,7 @@ pub type CurrencyTransactor = CurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -379,7 +379,7 @@ pub type FungiblesTransactor = FungiblesAdapter< >, JustTry, >, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -420,20 +420,22 @@ parameter_types! { // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); // One ROC buys 1 second of weight. - pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), ROC); + pub const WeightPrice: (Location, u128) = (Location::parent(), ROC); pub const MaxInstructions: u32 = 100; } -match_types! { - // The parent or the parent's unit plurality. - pub type ParentOrParentsUnitPlurality: impl Contains = { - MultiLocation { parents: 1, interior: Here } | - MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Unit, .. }) } - }; - // The location recognized as the Relay network's Asset Hub. - pub type AssetHub: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(1000)) } - }; +pub struct ParentOrParentsUnitPlurality; +impl Contains for ParentOrParentsUnitPlurality { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, []) | (1, [Plurality { id: BodyId::Unit, .. }])) + } +} + +pub struct AssetHub; +impl Contains for AssetHub { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (1, [Parachain(1000)])) + } } pub type Barrier = TrailingSetTopicAsId<( @@ -451,11 +453,11 @@ pub type Barrier = TrailingSetTopicAsId<( parameter_types! { pub MaxAssetsIntoHolding: u32 = 64; - pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]); // ALWAYS ensure that the index in PalletInstance stays up-to-date with // the Relay Chain's Asset Hub's Assets pallet index - pub SystemAssetHubAssetsPalletLocation: MultiLocation = - MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); + pub SystemAssetHubAssetsPalletLocation: Location = + Location::new(1, [Parachain(1000), PalletInstance(50)]); } pub type Reserves = (NativeAsset, AssetsFrom); diff --git a/cumulus/primitives/core/src/lib.rs b/cumulus/primitives/core/src/lib.rs index 835c9de649e..7f735368565 100644 --- a/cumulus/primitives/core/src/lib.rs +++ b/cumulus/primitives/core/src/lib.rs @@ -93,13 +93,12 @@ pub enum AggregateMessageOrigin { Sibling(ParaId), } -impl From for xcm::v3::MultiLocation { +impl From for Location { fn from(origin: AggregateMessageOrigin) -> Self { match origin { - AggregateMessageOrigin::Here => MultiLocation::here(), - AggregateMessageOrigin::Parent => MultiLocation::parent(), - AggregateMessageOrigin::Sibling(id) => - MultiLocation::new(1, Junction::Parachain(id.into())), + AggregateMessageOrigin::Here => Location::here(), + AggregateMessageOrigin::Parent => Location::parent(), + AggregateMessageOrigin::Sibling(id) => Location::new(1, Junction::Parachain(id.into())), } } } diff --git a/cumulus/primitives/utility/src/lib.rs b/cumulus/primitives/utility/src/lib.rs index 7216000cb45..bd13ee1119b 100644 --- a/cumulus/primitives/utility/src/lib.rs +++ b/cumulus/primitives/utility/src/lib.rs @@ -35,7 +35,10 @@ use sp_runtime::{ use sp_std::{marker::PhantomData, prelude::*}; use xcm::{latest::prelude::*, WrapVersion}; use xcm_builder::TakeRevenue; -use xcm_executor::traits::{MatchesFungibles, TransactAsset, WeightTrader}; +use xcm_executor::{ + traits::{MatchesFungibles, TransactAsset, WeightTrader}, + AssetsInHolding, +}; #[cfg(test)] mod tests; @@ -56,10 +59,7 @@ where { type Ticket = Vec; - fn validate( - dest: &mut Option, - msg: &mut Option>, - ) -> SendResult> { + fn validate(dest: &mut Option, msg: &mut Option>) -> SendResult> { let d = dest.take().ok_or(SendError::MissingArgument)?; if d.contains_parents_only(1) { @@ -95,14 +95,14 @@ struct AssetTraderRefunder { // The amount of weight bought minus the weigh already refunded weight_outstanding: Weight, // The concrete asset containing the asset location and outstanding balance - outstanding_concrete_asset: MultiAsset, + outstanding_concrete_asset: Asset, } -/// Charges for execution in the first multiasset of those selected for fee payment +/// Charges for execution in the first asset of those selected for fee payment /// Only succeeds for Concrete Fungible Assets -/// First tries to convert the this MultiAsset into a local assetId +/// First tries to convert the this Asset into a local assetId /// Then charges for this assetId as described by FeeCharger -/// Weight, paid balance, local asset Id and the multilocation is stored for +/// Weight, paid balance, local asset Id and the location is stored for /// later refund purposes /// Important: Errors if the Trader is being called twice by 2 BuyExecution instructions /// Alternatively we could just return payment in the aforementioned case @@ -128,15 +128,15 @@ impl< fn new() -> Self { Self(None, PhantomData) } - // We take first multiasset + // We take first asset // Check whether we can convert fee to asset_fee (is_sufficient, min_deposit) // If everything goes well, we charge. fn buy_weight( &mut self, weight: Weight, - payment: xcm_executor::Assets, + payment: xcm_executor::AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!(target: "xcm::weight", "TakeFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); // Make sure we dont enter twice @@ -144,12 +144,12 @@ impl< return Err(XcmError::NotWithdrawable) } - // We take the very first multiasset from payment + // We take the very first asset from payment // (assets are sorted by fungibility/amount after this conversion) - let multiassets: MultiAssets = payment.clone().into(); + let assets: Assets = payment.clone().into(); - // Take the first multiasset from the selected MultiAssets - let first = multiassets.get(0).ok_or(XcmError::AssetNotFound)?; + // Take the first asset from the selected Assets + let first = assets.get(0).ok_or(XcmError::AssetNotFound)?; // Get the local asset id in which we can pay for fees let (local_asset_id, _) = @@ -171,13 +171,13 @@ impl< .try_into() .map_err(|_| XcmError::Overflow)?; - // Convert to the same kind of multiasset, with the required fungible balance - let required = first.id.into_multiasset(asset_balance.into()); + // Convert to the same kind of asset, with the required fungible balance + let required = first.id.clone().into_asset(asset_balance.into()); // Substract payment let unused = payment.checked_sub(required.clone()).map_err(|_| XcmError::TooExpensive)?; - // record weight and multiasset + // record weight and asset self.0 = Some(AssetTraderRefunder { weight_outstanding: weight, outstanding_concrete_asset: required, @@ -186,16 +186,16 @@ impl< Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "TakeFirstAssetTrader::refund_weight weight: {:?}, context: {:?}", weight, context); if let Some(AssetTraderRefunder { mut weight_outstanding, - outstanding_concrete_asset: MultiAsset { id, fun }, + outstanding_concrete_asset: Asset { id, fun }, }) = self.0.clone() { // Get the local asset id in which we can refund fees let (local_asset_id, outstanding_balance) = - Matcher::matches_fungibles(&(id, fun).into()).ok()?; + Matcher::matches_fungibles(&(id.clone(), fun).into()).ok()?; let minimum_balance = ConcreteAssets::minimum_balance(local_asset_id.clone()); @@ -225,7 +225,8 @@ impl< // Construct outstanding_concrete_asset with the same location id and substracted // balance - let outstanding_concrete_asset: MultiAsset = (id, outstanding_minus_substracted).into(); + let outstanding_concrete_asset: Asset = + (id.clone(), outstanding_minus_substracted).into(); // Substract from existing weight and balance weight_outstanding = weight_outstanding.saturating_sub(weight); @@ -272,11 +273,11 @@ impl< ReceiverAccount: Get>, > TakeRevenue for XcmFeesTo32ByteAccount { - fn take_revenue(revenue: MultiAsset) { + fn take_revenue(revenue: Asset) { if let Some(receiver) = ReceiverAccount::get() { let ok = FungiblesMutateAdapter::deposit_asset( &revenue, - &(X1(AccountId32 { network: None, id: receiver.into() }).into()), + &([AccountId32 { network: None, id: receiver.into() }].into()), None, ) .is_ok(); @@ -307,7 +308,7 @@ pub trait ChargeWeightInFungibles Result { + ) -> Result { log::trace!( target: "xcm::weight", "SwapFirstAssetTrader::buy_weight weight: {:?}, payment: {:?}", weight, payment, ); - let first_asset: MultiAsset = + let first_asset: Asset = payment.fungible.pop_first().ok_or(XcmError::AssetNotFound)?.into(); let (fungibles_asset, balance) = FungiblesAssetMatcher::matches_fungibles(&first_asset) .map_err(|_| XcmError::AssetNotFound)?; @@ -424,14 +425,14 @@ impl< }, _ => (), }; - self.last_fee_asset = Some(first_asset.id); + self.last_fee_asset = Some(first_asset.id.clone()); payment.fungible.insert(first_asset.id, credit_change.peek().into()); drop(credit_change); Ok(payment) } - fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, _context: &XcmContext) -> Option { log::trace!( target: "xcm::weight", "SwapFirstAssetTrader::refund_weight weight: {:?}, self.total_fee: {:?}", @@ -444,7 +445,7 @@ impl< } let mut refund_asset = if let Some(asset) = &self.last_fee_asset { // create an initial zero refund in the asset used in the last `buy_weight`. - (*asset, Fungible(0)).into() + (asset.clone(), Fungible(0)).into() } else { return None }; @@ -529,11 +530,11 @@ mod test_xcm_router { impl OkFixedXcmHashWithAssertingRequiredInputsSender { const FIXED_XCM_HASH: [u8; 32] = [9; 32]; - fn fixed_delivery_asset() -> MultiAssets { - MultiAssets::new() + fn fixed_delivery_asset() -> Assets { + Assets::new() } - fn expected_delivery_result() -> Result<(XcmHash, MultiAssets), SendError> { + fn expected_delivery_result() -> Result<(XcmHash, Assets), SendError> { Ok((Self::FIXED_XCM_HASH, Self::fixed_delivery_asset())) } } @@ -541,7 +542,7 @@ mod test_xcm_router { type Ticket = (); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { assert!(destination.is_some()); @@ -597,7 +598,7 @@ mod test_xcm_router { // ParentAsUmp - check dest/msg is valid let dest = (Parent, Here); - let mut dest_wrapper = Some(dest.into()); + let mut dest_wrapper = Some(dest.clone().into()); let mut msg_wrapper = Some(message.clone()); assert!( as SendXcm>::validate( &mut dest_wrapper, @@ -629,7 +630,7 @@ mod test_trader { }, }; use sp_runtime::DispatchError; - use xcm_executor::{traits::Error, Assets}; + use xcm_executor::{traits::Error, AssetsInHolding}; #[test] fn take_first_asset_trader_buy_weight_called_twice_throws_error() { @@ -641,9 +642,9 @@ mod test_trader { type TestBalance = u128; struct TestAssets; impl MatchesFungibles for TestAssets { - fn matches_fungibles(a: &MultiAsset) -> Result<(TestAssetId, TestBalance), Error> { + fn matches_fungibles(a: &Asset) -> Result<(TestAssetId, TestBalance), Error> { match a { - MultiAsset { fun: Fungible(amount), id: Concrete(_id) } => Ok((1, *amount)), + Asset { fun: Fungible(amount), id: AssetId(_id) } => Ok((1, *amount)), _ => Err(Error::AssetNotHandled), } } @@ -730,7 +731,7 @@ mod test_trader { } } impl TakeRevenue for FeeChargerAssetsHandleRefund { - fn take_revenue(_: MultiAsset) {} + fn take_revenue(_: Asset) {} } // create new instance @@ -745,8 +746,8 @@ mod test_trader { let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; // prepare test data - let asset: MultiAsset = (Here, AMOUNT).into(); - let payment = Assets::from(asset); + let asset: Asset = (Here, AMOUNT).into(); + let payment = AssetsInHolding::from(asset); let weight_to_buy = Weight::from_parts(1_000, 1_000); // lets do first call (success) @@ -769,17 +770,17 @@ pub struct ToParentDeliveryHelper>, + ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, > pallet_xcm_benchmarks::EnsureDelivery for ToParentDeliveryHelper { fn ensure_successful_delivery( - origin_ref: &MultiLocation, - _dest: &MultiLocation, + origin_ref: &Location, + _dest: &Location, fee_reason: xcm_executor::traits::FeeReason, - ) -> (Option, Option) { - use xcm::latest::{MAX_INSTRUCTIONS_TO_DECODE, MAX_ITEMS_IN_MULTIASSETS}; + ) -> (Option, Option) { + use xcm::latest::{MAX_INSTRUCTIONS_TO_DECODE, MAX_ITEMS_IN_ASSETS}; use xcm_executor::{traits::FeeManager, FeesMode}; let mut fees_mode = None; @@ -792,8 +793,8 @@ impl< } // overestimate delivery fee - let mut max_assets: Vec = Vec::new(); - for i in 0..MAX_ITEMS_IN_MULTIASSETS { + let mut max_assets: Vec = Vec::new(); + for i in 0..MAX_ITEMS_IN_ASSETS { max_assets.push((GeneralIndex(i as u128), 100u128).into()); } let overestimated_xcm = diff --git a/cumulus/primitives/utility/src/tests/swap_first.rs b/cumulus/primitives/utility/src/tests/swap_first.rs index 222cd005b12..2e19db49881 100644 --- a/cumulus/primitives/utility/src/tests/swap_first.rs +++ b/cumulus/primitives/utility/src/tests/swap_first.rs @@ -18,18 +18,18 @@ use crate::*; use frame_support::{parameter_types, traits::fungibles::Inspect}; use mock::{setup_pool, AccountId, AssetId, Balance, Fungibles}; use xcm::latest::AssetId as XcmAssetId; -use xcm_executor::Assets as HoldingAsset; +use xcm_executor::AssetsInHolding; -fn create_holding_asset(asset_id: AssetId, amount: Balance) -> HoldingAsset { +fn create_holding_asset(asset_id: AssetId, amount: Balance) -> AssetsInHolding { create_asset(asset_id, amount).into() } -fn create_asset(asset_id: AssetId, amount: Balance) -> MultiAsset { - MultiAsset { id: create_asset_id(asset_id), fun: Fungible(amount) } +fn create_asset(asset_id: AssetId, amount: Balance) -> Asset { + Asset { id: create_asset_id(asset_id), fun: Fungible(amount) } } fn create_asset_id(asset_id: AssetId) -> XcmAssetId { - Concrete(MultiLocation::new(0, X1(GeneralIndex(asset_id.into())))) + AssetId(Location::new(0, [GeneralIndex(asset_id.into())])) } fn xcm_context() -> XcmContext { @@ -319,7 +319,7 @@ fn empty_holding_asset() { let mut trader = Trader::new(); assert_eq!( trader - .buy_weight(Weight::from_all(10), HoldingAsset::new(), &xcm_context()) + .buy_weight(Weight::from_all(10), AssetsInHolding::new(), &xcm_context()) .unwrap_err(), XcmError::AssetNotFound ); @@ -328,8 +328,7 @@ fn empty_holding_asset() { #[test] fn fails_to_match_holding_asset() { let mut trader = Trader::new(); - let holding_asset = - MultiAsset { id: Concrete(MultiLocation::new(1, X1(Parachain(1)))), fun: Fungible(10) }; + let holding_asset = Asset { id: AssetId(Location::new(1, [Parachain(1)])), fun: Fungible(10) }; assert_eq!( trader .buy_weight(Weight::from_all(10), holding_asset.into(), &xcm_context()) @@ -536,14 +535,15 @@ pub mod mock { pub struct FungiblesMatcher; impl MatchesFungibles for FungiblesMatcher { fn matches_fungibles( - a: &MultiAsset, + a: &Asset, ) -> core::result::Result<(AssetId, Balance), xcm_executor::traits::Error> { match a { - MultiAsset { - fun: Fungible(amount), - id: - Concrete(MultiLocation { parents: 0, interior: X1(Junction::GeneralIndex(id)) }), - } => Ok(((*id).try_into().unwrap(), *amount)), + Asset { fun: Fungible(amount), id: AssetId(inner_location) } => + match inner_location.unpack() { + (0, [Junction::GeneralIndex(id)]) => + Ok(((*id).try_into().unwrap(), *amount)), + _ => Err(xcm_executor::traits::Error::AssetNotHandled), + }, _ => Err(xcm_executor::traits::Error::AssetNotHandled), } } diff --git a/cumulus/xcm/xcm-emulator/src/lib.rs b/cumulus/xcm/xcm-emulator/src/lib.rs index c9e4de21d43..c5cc632574b 100644 --- a/cumulus/xcm/xcm-emulator/src/lib.rs +++ b/cumulus/xcm/xcm-emulator/src/lib.rs @@ -60,12 +60,9 @@ pub use polkadot_runtime_parachains::inclusion::{AggregateMessageOrigin, UmpQueu // Polkadot pub use polkadot_parachain_primitives::primitives::RelayChainBlockNumber; use sp_core::crypto::AccountId32; -pub use xcm::{ - prelude::{AccountId32 as AccountId32Junction, Here}, - v3::prelude::{ - Ancestor, MultiAssets, MultiLocation, Parachain as ParachainJunction, Parent, WeightLimit, - XcmHash, X1, - }, +pub use xcm::latest::prelude::{ + AccountId32 as AccountId32Junction, Ancestor, Assets, Here, Location, + Parachain as ParachainJunction, Parent, WeightLimit, XcmHash, }; pub use xcm_executor::traits::ConvertLocation; @@ -231,11 +228,11 @@ pub trait RelayChain: Chain { fn init(); - fn child_location_of(id: ParaId) -> MultiLocation { + fn child_location_of(id: ParaId) -> Location { (Ancestor(0), ParachainJunction(id.into())).into() } - fn sovereign_account_id_of(location: MultiLocation) -> AccountIdOf { + fn sovereign_account_id_of(location: Location) -> AccountIdOf { Self::SovereignAccountOf::convert_location(&location).unwrap() } @@ -263,15 +260,15 @@ pub trait Parachain: Chain { Self::ext_wrapper(|| Self::ParachainInfo::get()) } - fn parent_location() -> MultiLocation { + fn parent_location() -> Location { (Parent).into() } - fn sibling_location_of(para_id: ParaId) -> MultiLocation { - (Parent, X1(ParachainJunction(para_id.into()))).into() + fn sibling_location_of(para_id: ParaId) -> Location { + (Parent, ParachainJunction(para_id.into())).into() } - fn sovereign_account_id_of(location: MultiLocation) -> AccountIdOf { + fn sovereign_account_id_of(location: Location) -> AccountIdOf { Self::LocationToAccountId::convert_location(&location).unwrap() } } @@ -1432,10 +1429,10 @@ pub struct TestAccount { /// Default `Args` provided by xcm-emulator to be stored in a `Test` instance #[derive(Clone)] pub struct TestArgs { - pub dest: MultiLocation, - pub beneficiary: MultiLocation, + pub dest: Location, + pub beneficiary: Location, pub amount: Balance, - pub assets: MultiAssets, + pub assets: Assets, pub asset_id: Option, pub fee_asset_item: u32, pub weight_limit: WeightLimit, @@ -1443,7 +1440,7 @@ pub struct TestArgs { impl TestArgs { /// Returns a [`TestArgs`] instance to be used for the Relay Chain across integration tests. - pub fn new_relay(dest: MultiLocation, beneficiary_id: AccountId32, amount: Balance) -> Self { + pub fn new_relay(dest: Location, beneficiary_id: AccountId32, amount: Balance) -> Self { Self { dest, beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(), @@ -1457,10 +1454,10 @@ impl TestArgs { /// Returns a [`TestArgs`] instance to be used for parachains across integration tests. pub fn new_para( - dest: MultiLocation, + dest: Location, beneficiary_id: AccountId32, amount: Balance, - assets: MultiAssets, + assets: Assets, asset_id: Option, fee_asset_item: u32, ) -> Self { diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index d71c626cd98..a9edb196627 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -21,7 +21,7 @@ use frame_support::traits::{Currency, Imbalance, OnUnbalanced}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::Balance; use sp_runtime::{traits::TryConvert, Perquintill, RuntimeDebug}; -use xcm::VersionedMultiLocation; +use xcm::VersionedLocation; /// Logic for the author to get a portion of fees. pub struct ToAuthor(sp_std::marker::PhantomData); @@ -107,12 +107,9 @@ pub fn era_payout( )] pub enum VersionedLocatableAsset { #[codec(index = 3)] - V3 { - /// The (relative) location in which the asset ID is meaningful. - location: xcm::v3::MultiLocation, - /// The asset's ID. - asset_id: xcm::v3::AssetId, - }, + V3 { location: xcm::v3::MultiLocation, asset_id: xcm::v3::AssetId }, + #[codec(index = 4)] + V4 { location: xcm::v4::Location, asset_id: xcm::v4::AssetId }, } /// Converts the [`VersionedLocatableAsset`] to the [`xcm_builder::LocatableAssetId`]. @@ -125,22 +122,29 @@ impl TryConvert ) -> Result { match asset { VersionedLocatableAsset::V3 { location, asset_id } => - Ok(xcm_builder::LocatableAssetId { asset_id, location }), + Ok(xcm_builder::LocatableAssetId { + location: location.try_into().map_err(|_| asset.clone())?, + asset_id: asset_id.try_into().map_err(|_| asset.clone())?, + }), + VersionedLocatableAsset::V4 { location, asset_id } => + Ok(xcm_builder::LocatableAssetId { location, asset_id }), } } } -/// Converts the [`VersionedMultiLocation`] to the [`xcm::latest::MultiLocation`]. -pub struct VersionedMultiLocationConverter; -impl TryConvert<&VersionedMultiLocation, xcm::latest::MultiLocation> - for VersionedMultiLocationConverter -{ +/// Converts the [`VersionedLocation`] to the [`xcm::latest::Location`]. +pub struct VersionedLocationConverter; +impl TryConvert<&VersionedLocation, xcm::latest::Location> for VersionedLocationConverter { fn try_convert( - location: &VersionedMultiLocation, - ) -> Result { + location: &VersionedLocation, + ) -> Result { let latest = match location.clone() { - VersionedMultiLocation::V2(l) => l.try_into().map_err(|_| location)?, - VersionedMultiLocation::V3(l) => l, + VersionedLocation::V2(l) => { + let v3: xcm::v3::MultiLocation = l.try_into().map_err(|_| location)?; + v3.try_into().map_err(|_| location)? + }, + VersionedLocation::V3(l) => l.try_into().map_err(|_| location)?, + VersionedLocation::V4(l) => l, }; Ok(latest) } @@ -161,11 +165,14 @@ pub mod benchmarks { pub struct AssetRateArguments; impl AssetKindFactory for AssetRateArguments { fn create_asset_kind(seed: u32) -> VersionedLocatableAsset { - VersionedLocatableAsset::V3 { - location: xcm::v3::MultiLocation::new(0, X1(Parachain(seed))), - asset_id: xcm::v3::MultiLocation::new( + VersionedLocatableAsset::V4 { + location: xcm::v4::Location::new(0, [xcm::v4::Junction::Parachain(seed)]), + asset_id: xcm::v4::Location::new( 0, - X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())), + [ + xcm::v4::Junction::PalletInstance(seed.try_into().unwrap()), + xcm::v4::Junction::GeneralIndex(seed.into()), + ], ) .into(), } @@ -173,29 +180,35 @@ pub mod benchmarks { } /// Provide factory methods for the [`VersionedLocatableAsset`] and the `Beneficiary` of the - /// [`VersionedMultiLocation`]. The location of the asset is determined as a Parachain with an + /// [`VersionedLocation`]. The location of the asset is determined as a Parachain with an /// ID equal to the passed seed. pub struct TreasuryArguments, ParaId = ConstU32<0>>( PhantomData<(Parents, ParaId)>, ); impl, ParaId: Get> - TreasuryArgumentsFactory + TreasuryArgumentsFactory for TreasuryArguments { fn create_asset_kind(seed: u32) -> VersionedLocatableAsset { VersionedLocatableAsset::V3 { - location: xcm::v3::MultiLocation::new(Parents::get(), X1(Parachain(ParaId::get()))), + location: xcm::v3::MultiLocation::new( + Parents::get(), + [xcm::v3::Junction::Parachain(ParaId::get())], + ), asset_id: xcm::v3::MultiLocation::new( 0, - X2(PalletInstance(seed.try_into().unwrap()), GeneralIndex(seed.into())), + [ + xcm::v3::Junction::PalletInstance(seed.try_into().unwrap()), + xcm::v3::Junction::GeneralIndex(seed.into()), + ], ) .into(), } } - fn create_beneficiary(seed: [u8; 32]) -> VersionedMultiLocation { - VersionedMultiLocation::V3(xcm::v3::MultiLocation::new( + fn create_beneficiary(seed: [u8; 32]) -> VersionedLocation { + VersionedLocation::V4(xcm::v4::Location::new( 0, - X1(AccountId32 { network: None, id: seed }), + [xcm::v4::Junction::AccountId32 { network: None, id: seed }], )) } } diff --git a/polkadot/runtime/common/src/xcm_sender.rs b/polkadot/runtime/common/src/xcm_sender.rs index 4d31c92cdd3..7f1100a1361 100644 --- a/polkadot/runtime/common/src/xcm_sender.rs +++ b/polkadot/runtime/common/src/xcm_sender.rs @@ -35,13 +35,13 @@ pub trait PriceForMessageDelivery { /// Type used for charging different prices to different destinations type Id; /// Return the assets required to deliver `message` to the given `para` destination. - fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> MultiAssets; + fn price_for_delivery(id: Self::Id, message: &Xcm<()>) -> Assets; } impl PriceForMessageDelivery for () { type Id = (); - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { - MultiAssets::new() + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { + Assets::new() } } @@ -49,17 +49,17 @@ pub struct NoPriceForMessageDelivery(PhantomData); impl PriceForMessageDelivery for NoPriceForMessageDelivery { type Id = Id; - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { - MultiAssets::new() + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { + Assets::new() } } /// Implementation of [`PriceForMessageDelivery`] which returns a fixed price. pub struct ConstantPrice(sp_std::marker::PhantomData); -impl> PriceForMessageDelivery for ConstantPrice { +impl> PriceForMessageDelivery for ConstantPrice { type Id = (); - fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> MultiAssets { + fn price_for_delivery(_: Self::Id, _: &Xcm<()>) -> Assets { T::get() } } @@ -84,7 +84,7 @@ impl, B: Get, M: Get, F: FeeTracker> PriceForMessage { type Id = F::Id; - fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> MultiAssets { + fn price_for_delivery(id: Self::Id, msg: &Xcm<()>) -> Assets { let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); let fee_sum = B::get().saturating_add(msg_fee); let amount = F::get_fee_factor(id).saturating_mul_int(fee_sum); @@ -103,11 +103,11 @@ where type Ticket = (HostConfiguration>, ParaId, Vec); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult<(HostConfiguration>, ParaId, Vec)> { let d = dest.take().ok_or(MissingArgument)?; - let id = if let MultiLocation { parents: 0, interior: X1(Parachain(id)) } = &d { + let id = if let (0, [Parachain(id)]) = d.unpack() { *id } else { *dest = Some(d); @@ -160,7 +160,7 @@ pub struct ToParachainDeliveryHelper< #[cfg(feature = "runtime-benchmarks")] impl< XcmConfig: xcm_executor::Config, - ExistentialDeposit: Get>, + ExistentialDeposit: Get>, PriceForDelivery: PriceForMessageDelivery, Parachain: Get, ToParachainHelper: EnsureForParachain, @@ -174,10 +174,10 @@ impl< > { fn ensure_successful_delivery( - origin_ref: &MultiLocation, - _dest: &MultiLocation, + origin_ref: &Location, + _dest: &Location, fee_reason: xcm_executor::traits::FeeReason, - ) -> (Option, Option) { + ) -> (Option, Option) { use xcm_executor::{ traits::{FeeManager, TransactAsset}, FeesMode, @@ -234,7 +234,7 @@ mod tests { parameter_types! { pub const BaseDeliveryFee: u128 = 300_000_000; pub const TransactionByteFee: u128 = 1_000_000; - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = AssetId(Here.into()); } struct TestFeeTracker; diff --git a/polkadot/runtime/parachains/src/coretime/migration.rs b/polkadot/runtime/parachains/src/coretime/migration.rs index c720cf0617a..e64d3fbd6a9 100644 --- a/polkadot/runtime/parachains/src/coretime/migration.rs +++ b/polkadot/runtime/parachains/src/coretime/migration.rs @@ -46,9 +46,7 @@ mod v_coretime { #[cfg(feature = "try-runtime")] use sp_std::vec::Vec; use sp_std::{iter, prelude::*, result}; - use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, SendError, WeightLimit, Xcm, - }; + use xcm::v4::{send_xcm, Instruction, Junction, Location, SendError, WeightLimit, Xcm}; /// Return information about a legacy lease of a parachain. pub trait GetLegacyLease { @@ -64,7 +62,7 @@ mod v_coretime { sp_std::marker::PhantomData<(T, SendXcm, LegacyLease)>, ); - impl>> + impl>> MigrateToCoretime { fn already_migrated() -> bool { @@ -95,7 +93,7 @@ mod v_coretime { impl< T: Config + crate::dmp::Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, > OnRuntimeUpgrade for MigrateToCoretime { @@ -155,7 +153,7 @@ mod v_coretime { // NOTE: Also migrates coretime_cores config value in configuration::ActiveConfig. fn migrate_to_coretime< T: Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, >() -> Weight { let legacy_paras = paras::Pallet::::parachains(); @@ -209,7 +207,7 @@ mod v_coretime { fn migrate_send_assignments_to_coretime_chain< T: Config, - SendXcm: xcm::v3::SendXcm, + SendXcm: xcm::v4::SendXcm, LegacyLease: GetLegacyLease>, >() -> result::Result<(), SendError> { let legacy_paras = paras::Pallet::::parachains(); @@ -280,10 +278,7 @@ mod v_coretime { for message in messages { send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, + Location::new(0, Junction::Parachain(T::BrokerId::get())), message, )?; } diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index aa074a293c9..531f5c2e4e4 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -26,10 +26,7 @@ pub use pallet::*; use pallet_broker::{CoreAssignment, CoreIndex as BrokerCoreIndex}; use primitives::{CoreIndex, Id as ParaId}; use sp_arithmetic::traits::SaturatedConversion; -use xcm::v3::{ - send_xcm, Instruction, Junction, Junctions, MultiLocation, OriginKind, SendXcm, WeightLimit, - Xcm, -}; +use xcm::v4::{send_xcm, Instruction, Junction, Location, OriginKind, SendXcm, WeightLimit, Xcm}; use crate::{ assigner_coretime::{self, PartsOf57600}, @@ -229,10 +226,7 @@ impl Pallet { mk_coretime_call(crate::coretime::CoretimeCalls::NotifyCoreCount(core_count)), ]); if let Err(err) = send_xcm::( - MultiLocation { - parents: 0, - interior: Junctions::X1(Junction::Parachain(T::BrokerId::get())), - }, + Location::new(0, [Junction::Parachain(T::BrokerId::get())]), message, ) { log::error!("Sending `NotifyCoreCount` to coretime chain failed: {:?}", err); diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index fbaab1d24aa..c08bab0ef0f 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -52,7 +52,7 @@ use sp_runtime::{ }; use sp_std::collections::vec_deque::VecDeque; use std::{cell::RefCell, collections::HashMap}; -use xcm::v3::{MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash}; +use xcm::v4::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlockU32; @@ -384,11 +384,8 @@ impl coretime::Config for Test { pub struct DummyXcmSender; impl SendXcm for DummyXcmSender { type Ticket = (); - fn validate( - _: &mut Option, - _: &mut Option>, - ) -> SendResult { - Ok(((), MultiAssets::new())) + fn validate(_: &mut Option, _: &mut Option>) -> SendResult { + Ok(((), Assets::new())) } /// Actually carry out the delivery operation for a previously validated message sending. diff --git a/polkadot/runtime/rococo/src/impls.rs b/polkadot/runtime/rococo/src/impls.rs index eddbfacc3b1..ac7100d7858 100644 --- a/polkadot/runtime/rococo/src/impls.rs +++ b/polkadot/runtime/rococo/src/impls.rs @@ -22,7 +22,7 @@ use primitives::Balance; use rococo_runtime_constants::currency::*; use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; -use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any @@ -95,9 +95,9 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let roc = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; + let roc = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 - let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + let destination: Location = Location::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -138,11 +138,9 @@ where ); // reanchor - let roc_reanchored: MultiAssets = vec![MultiAsset { - id: Concrete(MultiLocation::new(1, Here)), - fun: Fungible(total_to_send), - }] - .into(); + let roc_reanchored: Assets = + vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }] + .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); @@ -172,8 +170,8 @@ where // send let _ = >::send( RawOrigin::Root.into(), - Box::new(VersionedMultiLocation::V3(destination)), - Box::new(VersionedXcm::V3(program)), + Box::new(VersionedLocation::V4(destination)), + Box::new(VersionedXcm::V4(program)), )?; Ok(()) } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index e492caddc8f..fec82fc86f9 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -35,7 +35,7 @@ use rococo_runtime_constants::system_parachain::BROKER_ID; use runtime_common::{ assigned_slots, auctions, claims, crowdloan, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, traits::Leaser, @@ -99,10 +99,7 @@ use sp_staking::SessionIndex; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::{ - latest::{InteriorMultiLocation, Junction, Junction::PalletInstance}, - VersionedMultiLocation, -}; +use xcm::{latest::prelude::*, VersionedLocation}; use xcm_builder::PayOverXcm; pub use frame_system::Call as SystemCall; @@ -461,7 +458,7 @@ parameter_types! { pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 18). - pub TreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(18).into(); + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(18).into(); pub const TipCountdown: BlockNumber = 1 * DAYS; pub const TipFindersFee: Percent = Percent::from_percent(20); @@ -492,7 +489,7 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = Bounties; type SpendOrigin = TreasurySpender; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Paymaster = PayOverXcm< TreasuryInteriorLocation, @@ -502,7 +499,7 @@ impl pallet_treasury::Config for Runtime { Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; type BalanceConverter = AssetRate; type PayoutPeriod = PayoutSpendPeriod; @@ -538,7 +535,7 @@ impl pallet_bounties::Config for Runtime { parameter_types! { pub const MaxActiveChildBountyCount: u32 = 100; - pub const ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; + pub ChildBountyValueMinimum: Balance = BountyValueMinimum::get() / 10; } impl pallet_child_bounties::Config for Runtime { @@ -1209,7 +1206,7 @@ impl pallet_nis::Config for Runtime { } parameter_types! { - pub const BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); + pub BeefySetIdSessionEntries: u32 = BondingDuration::get() * SessionsPerEra::get(); } impl pallet_beefy::Config for Runtime { @@ -2270,7 +2267,7 @@ sp_api::impl_runtime_apis! { }; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -2280,34 +2277,34 @@ sp_api::impl_runtime_apis! { impl frame_system_benchmarking::Config for Runtime {} impl frame_benchmarking::baseline::Config for Runtime {} impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(crate::xcm_config::AssetHub::get()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported to/from AH. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, crate::xcm_config::AssetHub::get(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Relay can reserve transfer native token to some random parachain. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, Parachain(43211234).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. @@ -2325,29 +2322,29 @@ sp_api::impl_runtime_apis! { type AccountIdConverter = LocationConverter; type DeliveryHelper = runtime_common::xcm_sender::ToParachainDeliveryHelper< XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, ToParachain, (), >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(AssetHub::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // Rococo only knows about ROC - vec![MultiAsset{ - id: Concrete(TokenLocation::get()), + vec![Asset{ + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }].into() } } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( AssetHub::get(), - MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2357,9 +2354,9 @@ sp_api::impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1 * UNITS), } } @@ -2373,43 +2370,43 @@ sp_api::impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { // Rococo doesn't support asset exchanges Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { // The XCM executor of Rococo doesn't have a configured `UniversalAliases` Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(AssetHub::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = AssetHub::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { // Rococo doesn't support asset locking Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // Rococo doesn't support exporting messages Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // The XCM executor of Rococo doesn't have a configured `Aliasers` Err(BenchmarkError::Skip) } diff --git a/polkadot/runtime/rococo/src/weights/xcm/mod.rs b/polkadot/runtime/rococo/src/weights/xcm/mod.rs index cc485dfbaf7..12f3df897b1 100644 --- a/polkadot/runtime/rococo/src/weights/xcm/mod.rs +++ b/polkadot/runtime/rococo/src/weights/xcm/mod.rs @@ -33,25 +33,25 @@ pub enum AssetTypes { Unknown, } -impl From<&MultiAsset> for AssetTypes { - fn from(asset: &MultiAsset) -> Self { +impl From<&Asset> for AssetTypes { + fn from(asset: &Asset) -> Self { match asset { - MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + Asset { id: AssetId(Location { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } -trait WeighMultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight; } // Rococo only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() @@ -72,11 +72,11 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() - .map(|m| >::from(m)) + .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, @@ -87,32 +87,28 @@ impl WeighMultiAssets for MultiAssets { pub struct RococoXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for RococoXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, @@ -140,45 +136,37 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_response_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { // Rococo does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -193,7 +181,7 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -205,13 +193,13 @@ impl XcmWeightInfo for RococoXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -246,19 +234,19 @@ impl XcmWeightInfo for RococoXcmWeight { // Rococo relay should not support export message operations Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { // Rococo does not currently support asset locking operations Weight::MAX } @@ -271,19 +259,19 @@ impl XcmWeightInfo for RococoXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { - let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let assets = AssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); - assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); + assert_eq!(assets.weigh_assets(weight), weight * MAX_ASSETS); } diff --git a/polkadot/runtime/rococo/src/xcm_config.rs b/polkadot/runtime/rococo/src/xcm_config.rs index f3a2ca6f3a6..bfa9beb8209 100644 --- a/polkadot/runtime/rococo/src/xcm_config.rs +++ b/polkadot/runtime/rococo/src/xcm_config.rs @@ -24,8 +24,8 @@ use super::{ use crate::governance::StakingAdmin; use frame_support::{ - match_types, parameter_types, - traits::{Equals, Everything, Nothing}, + parameter_types, + traits::{Contains, Equals, Everything, Nothing}, weights::Weight, }; use frame_system::EnsureRoot; @@ -50,10 +50,10 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub TokenLocation: Location = Here.into_location(); + pub RootLocation: Location = Location::here(); pub const ThisNetwork: NetworkId = NetworkId::Rococo; - pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); + pub UniversalLocation: InteriorLocation = ThisNetwork::get().into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); pub TreasuryAccount: AccountId = Treasury::account_id(); @@ -69,7 +69,7 @@ pub type LocationConverter = ( ); /// Our asset transactor. This is what allows us to interest with the runtime facilities from the -/// point of view of XCM-only concepts like `MultiLocation` and `MultiAsset`. +/// point of view of XCM-only concepts like `Location` and `Asset`. /// /// Ours is only aware of the Balances pallet, which is mapped to `RocLocation`. #[allow(deprecated)] @@ -78,7 +78,7 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // We can convert the MultiLocations with our converter above: + // We can convert the Locations with our converter above: LocationConverter, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -100,7 +100,7 @@ parameter_types! { /// The amount of weight an XCM operation takes. This is a safe overestimate. pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -116,25 +116,25 @@ pub type XcmRouter = WithUniqueTopic< >; parameter_types! { - pub const Roc: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); - pub const Contracts: MultiLocation = Parachain(CONTRACTS_ID).into_location(); - pub const Encointer: MultiLocation = Parachain(ENCOINTER_ID).into_location(); - pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); - pub const People: MultiLocation = Parachain(PEOPLE_ID).into_location(); - pub const Broker: MultiLocation = Parachain(BROKER_ID).into_location(); - pub const Tick: MultiLocation = Parachain(100).into_location(); - pub const Trick: MultiLocation = Parachain(110).into_location(); - pub const Track: MultiLocation = Parachain(120).into_location(); - pub const RocForTick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Tick::get()); - pub const RocForTrick: (MultiAssetFilter, MultiLocation) = (Roc::get(), Trick::get()); - pub const RocForTrack: (MultiAssetFilter, MultiLocation) = (Roc::get(), Track::get()); - pub const RocForAssetHub: (MultiAssetFilter, MultiLocation) = (Roc::get(), AssetHub::get()); - pub const RocForContracts: (MultiAssetFilter, MultiLocation) = (Roc::get(), Contracts::get()); - pub const RocForEncointer: (MultiAssetFilter, MultiLocation) = (Roc::get(), Encointer::get()); - pub const RocForBridgeHub: (MultiAssetFilter, MultiLocation) = (Roc::get(), BridgeHub::get()); - pub const RocForPeople: (MultiAssetFilter, MultiLocation) = (Roc::get(), People::get()); - pub const RocForBroker: (MultiAssetFilter, MultiLocation) = (Roc::get(), Broker::get()); + pub Roc: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) }); + pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location(); + pub Contracts: Location = Parachain(CONTRACTS_ID).into_location(); + pub Encointer: Location = Parachain(ENCOINTER_ID).into_location(); + pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location(); + pub People: Location = Parachain(PEOPLE_ID).into_location(); + pub Broker: Location = Parachain(BROKER_ID).into_location(); + pub Tick: Location = Parachain(100).into_location(); + pub Trick: Location = Parachain(110).into_location(); + pub Track: Location = Parachain(120).into_location(); + pub RocForTick: (AssetFilter, Location) = (Roc::get(), Tick::get()); + pub RocForTrick: (AssetFilter, Location) = (Roc::get(), Trick::get()); + pub RocForTrack: (AssetFilter, Location) = (Roc::get(), Track::get()); + pub RocForAssetHub: (AssetFilter, Location) = (Roc::get(), AssetHub::get()); + pub RocForContracts: (AssetFilter, Location) = (Roc::get(), Contracts::get()); + pub RocForEncointer: (AssetFilter, Location) = (Roc::get(), Encointer::get()); + pub RocForBridgeHub: (AssetFilter, Location) = (Roc::get(), BridgeHub::get()); + pub RocForPeople: (AssetFilter, Location) = (Roc::get(), People::get()); + pub RocForBroker: (AssetFilter, Location) = (Roc::get(), Broker::get()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -150,13 +150,18 @@ pub type TrustedTeleporters = ( xcm_builder::Case, ); -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Parachain(_)])) + } +} + +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Plurality { .. }])) + } } /// The barriers one of which must be passed for an XCM message to be executed. @@ -227,26 +232,26 @@ parameter_types! { pub const FellowsBodyId: BodyId = BodyId::Technical; } -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// Type to convert an `Origin` type value into a `Location` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 SignedToAccountId32, ); -/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +/// Type to convert the Fellows origin to a Plurality `Location` value. pub type FellowsToPlurality = OriginToPluralityVoice; -/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( - // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, - // Fellows origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // Fellows origin to be used in XCM as a corresponding Plurality `Location` value. FellowsToPlurality, ); diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index f472b619ba7..e80412232d0 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -604,7 +604,7 @@ pub mod pallet_test_notifier { pub enum Event { QueryPrepared(QueryId), NotifyQueryPrepared(QueryId), - ResponseReceived(MultiLocation, QueryId, Response), + ResponseReceived(Location, QueryId, Response), } #[pallet::error] diff --git a/polkadot/runtime/test-runtime/src/xcm_config.rs b/polkadot/runtime/test-runtime/src/xcm_config.rs index ae4faecf700..d9d3d6e0752 100644 --- a/polkadot/runtime/test-runtime/src/xcm_config.rs +++ b/polkadot/runtime/test-runtime/src/xcm_config.rs @@ -27,7 +27,7 @@ use xcm_builder::{ }; use xcm_executor::{ traits::{TransactAsset, WeightTrader}, - Assets, + AssetsInHolding, }; parameter_types! { @@ -35,10 +35,10 @@ parameter_types! { pub const AnyNetwork: Option = None; pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 16; - pub const UniversalLocation: xcm::latest::InteriorMultiLocation = xcm::latest::Junctions::Here; + pub const UniversalLocation: xcm::latest::InteriorLocation = xcm::latest::Junctions::Here; } -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior +/// Type to convert an `Origin` type value into a `Location` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 @@ -48,8 +48,8 @@ pub type LocalOriginToLocation = ( pub struct DoNothingRouter; impl SendXcm for DoNothingRouter { type Ticket = (); - fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { - Ok(((), MultiAssets::new())) + fn validate(_dest: &mut Option, _msg: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) } fn deliver(_: ()) -> Result { Ok([0; 32]) @@ -60,20 +60,16 @@ pub type Barrier = AllowUnpaidExecutionFrom; pub struct DummyAssetTransactor; impl TransactAsset for DummyAssetTransactor { - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { - let asset: MultiAsset = (Parent, 100_000).into(); + ) -> Result { + let asset: Asset = (Parent, 100_000).into(); Ok(asset.into()) } } @@ -87,10 +83,10 @@ impl WeightTrader for DummyWeightTrader { fn buy_weight( &mut self, _weight: Weight, - _payment: Assets, + _payment: AssetsInHolding, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/polkadot/runtime/westend/src/impls.rs b/polkadot/runtime/westend/src/impls.rs index 5f23bd373b1..71e6b696a20 100644 --- a/polkadot/runtime/westend/src/impls.rs +++ b/polkadot/runtime/westend/src/impls.rs @@ -22,7 +22,7 @@ use primitives::Balance; use runtime_common::identity_migrator::{OnReapIdentity, WeightInfo}; use sp_std::{marker::PhantomData, prelude::*}; use westend_runtime_constants::currency::*; -use xcm::{latest::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{latest::prelude::*, VersionedLocation, VersionedXcm}; use xcm_executor::traits::TransactAsset; /// A type containing the encoding of the People Chain pallets in its runtime. Used to construct any @@ -95,9 +95,9 @@ where let total_to_send = Self::calculate_remote_deposit(fields, subs); // define asset / destination from relay perspective - let wnd = MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(total_to_send) }; + let wnd = Asset { id: AssetId(Here.into_location()), fun: Fungible(total_to_send) }; // People Chain: ParaId 1004 - let destination: MultiLocation = MultiLocation::new(0, Parachain(1004)); + let destination: Location = Location::new(0, Parachain(1004)); // Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support // unpaid teleports. @@ -138,11 +138,9 @@ where ); // reanchor - let wnd_reanchored: MultiAssets = vec![MultiAsset { - id: Concrete(MultiLocation::new(1, Here)), - fun: Fungible(total_to_send), - }] - .into(); + let wnd_reanchored: Assets = + vec![Asset { id: AssetId(Location::new(1, Here)), fun: Fungible(total_to_send) }] + .into(); let poke = PeopleRuntimePallets::::IdentityMigrator(PokeDeposit(who.clone())); let remote_weight_limit = MigratorWeights::::poke_deposit().saturating_mul(2); @@ -172,8 +170,8 @@ where // send let _ = >::send( RawOrigin::Root.into(), - Box::new(VersionedMultiLocation::V3(destination)), - Box::new(VersionedXcm::V3(program)), + Box::new(VersionedLocation::V4(destination)), + Box::new(VersionedXcm::V4(program)), )?; Ok(()) } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index e1416c4b754..92efdf0c0c5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -59,7 +59,7 @@ use runtime_common::{ elections::OnChainAccuracy, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedMultiLocationConverter, + LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, BalanceToU256, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, U256ToBalance, @@ -98,8 +98,8 @@ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use sp_version::NativeVersion; use sp_version::RuntimeVersion; use xcm::{ - latest::{InteriorMultiLocation, Junction, Junction::PalletInstance}, - VersionedMultiLocation, + latest::{InteriorLocation, Junction, Junction::PalletInstance}, + VersionedLocation, }; use xcm_builder::PayOverXcm; @@ -714,7 +714,7 @@ parameter_types! { pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; // The asset's interior location for the paying account. This is the Treasury // pallet instance (which sits at index 37). - pub TreasuryInteriorLocation: InteriorMultiLocation = PalletInstance(37).into(); + pub TreasuryInteriorLocation: InteriorLocation = PalletInstance(37).into(); pub const TipCountdown: BlockNumber = 1 * DAYS; pub const TipFindersFee: Percent = Percent::from_percent(20); @@ -745,7 +745,7 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = (); type SpendOrigin = TreasurySpender; type AssetKind = VersionedLocatableAsset; - type Beneficiary = VersionedMultiLocation; + type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; type Paymaster = PayOverXcm< TreasuryInteriorLocation, @@ -755,7 +755,7 @@ impl pallet_treasury::Config for Runtime { Self::Beneficiary, Self::AssetKind, LocatableAssetConverter, - VersionedMultiLocationConverter, + VersionedLocationConverter, >; type BalanceConverter = AssetRate; type PayoutPeriod = PayoutSpendPeriod; @@ -2286,31 +2286,31 @@ sp_api::impl_runtime_apis! { impl pallet_offences_benchmarking::Config for Runtime {} impl pallet_election_provider_support_benchmarking::Config for Runtime {} impl pallet_xcm::benchmarking::Config for Runtime { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(crate::xcm_config::AssetHub::get()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { // Relay/native token can be teleported to/from AH. Some(( - MultiAsset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: Concrete(Here.into()) }, + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: AssetId(Here.into()) }, crate::xcm_config::AssetHub::get(), )) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { // Relay can reserve transfer native token to some random parachain. Some(( - MultiAsset { + Asset { fun: Fungible(EXISTENTIAL_DEPOSIT), - id: Concrete(Here.into()) + id: AssetId(Here.into()) }, crate::Junction::Parachain(43211234).into(), )) } fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + ) -> Option<(Assets, u32, Location, Box)> { // Relay supports only native token, either reserve transfer it to non-system parachains, // or teleport it to system parachain. Use the teleport case for benchmarking as it's // slightly heavier. @@ -2329,13 +2329,13 @@ sp_api::impl_runtime_apis! { impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {} use xcm::latest::{ - AssetId::*, Fungibility::*, InteriorMultiLocation, Junction, Junctions::*, - MultiAsset, MultiAssets, MultiLocation, NetworkId, Response, + AssetId, Fungibility::*, InteriorLocation, Junction, Junctions::*, + Asset, Assets, Location, NetworkId, Response, }; use xcm_config::{AssetHub, TokenLocation}; parameter_types! { - pub ExistentialDepositMultiAsset: Option = Some(( + pub ExistentialDepositAsset: Option = Some(( TokenLocation::get(), ExistentialDeposit::get() ).into()); @@ -2347,29 +2347,29 @@ sp_api::impl_runtime_apis! { type AccountIdConverter = xcm_config::LocationConverter; type DeliveryHelper = runtime_common::xcm_sender::ToParachainDeliveryHelper< xcm_config::XcmConfig, - ExistentialDepositMultiAsset, + ExistentialDepositAsset, xcm_config::PriceForChildParachainDelivery, ToParachain, (), >; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(AssetHub::get()) } - fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + fn worst_case_holding(_depositable_count: u32) -> Assets { // Westend only knows about WND. - vec![MultiAsset{ - id: Concrete(TokenLocation::get()), + vec![Asset{ + id: AssetId(TokenLocation::get()), fun: Fungible(1_000_000 * UNITS), }].into() } } parameter_types! { - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( AssetHub::get(), - MultiAsset { fun: Fungible(1 * UNITS), id: Concrete(TokenLocation::get()) }, + Asset { fun: Fungible(1 * UNITS), id: AssetId(TokenLocation::get()) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + pub const TrustedReserve: Option<(Location, Asset)> = None; } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -2379,9 +2379,9 @@ sp_api::impl_runtime_apis! { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { - MultiAsset { - id: Concrete(TokenLocation::get()), + fn get_asset() -> Asset { + Asset { + id: AssetId(TokenLocation::get()), fun: Fungible(1 * UNITS), } } @@ -2395,43 +2395,43 @@ sp_api::impl_runtime_apis! { (0u64, Response::Version(Default::default())) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { // Westend doesn't support asset exchanges Err(BenchmarkError::Skip) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { // The XCM executor of Westend doesn't have a configured `UniversalAliases` Err(BenchmarkError::Skip) } - fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + fn transact_origin_and_runtime_call() -> Result<(Location, RuntimeCall), BenchmarkError> { Ok((AssetHub::get(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(AssetHub::get()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { let origin = AssetHub::get(); - let assets: MultiAssets = (Concrete(TokenLocation::get()), 1_000 * UNITS).into(); - let ticket = MultiLocation { parents: 0, interior: Here }; + let assets: Assets = (AssetId(TokenLocation::get()), 1_000 * UNITS).into(); + let ticket = Location { parents: 0, interior: Here }; Ok((origin, ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { // Westend doesn't support asset locking Err(BenchmarkError::Skip) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // Westend doesn't support exporting messages Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { // The XCM executor of Westend doesn't have a configured `Aliasers` Err(BenchmarkError::Skip) } @@ -2503,12 +2503,11 @@ mod remote_tests { mod clean_state_migration { use super::Runtime; + #[cfg(feature = "try-runtime")] + use super::Vec; use frame_support::{pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade}; use pallet_state_trie_migration::MigrationLimits; - #[cfg(not(feature = "std"))] - use sp_std::prelude::*; - #[storage_alias] type AutoLimits = StorageValue, ValueQuery>; diff --git a/polkadot/runtime/westend/src/weights/xcm/mod.rs b/polkadot/runtime/westend/src/weights/xcm/mod.rs index d5b3d8257ba..0162012825f 100644 --- a/polkadot/runtime/westend/src/weights/xcm/mod.rs +++ b/polkadot/runtime/westend/src/weights/xcm/mod.rs @@ -36,25 +36,25 @@ pub enum AssetTypes { Unknown, } -impl From<&MultiAsset> for AssetTypes { - fn from(asset: &MultiAsset) -> Self { +impl From<&Asset> for AssetTypes { + fn from(asset: &Asset) -> Self { match asset { - MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), .. } => + Asset { id: AssetId(Location { parents: 0, interior: Here }), .. } => AssetTypes::Balances, _ => AssetTypes::Unknown, } } } -trait WeighMultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight; +trait WeighAssets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight; } // Westend only knows about one asset, the balances pallet. const MAX_ASSETS: u64 = 1; -impl WeighMultiAssets for MultiAssetFilter { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for AssetFilter { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { match self { Self::Definite(assets) => assets .inner() @@ -75,11 +75,11 @@ impl WeighMultiAssets for MultiAssetFilter { } } -impl WeighMultiAssets for MultiAssets { - fn weigh_multi_assets(&self, balances_weight: Weight) -> Weight { +impl WeighAssets for Assets { + fn weigh_assets(&self, balances_weight: Weight) -> Weight { self.inner() .into_iter() - .map(|m| >::from(m)) + .map(|m| >::from(m)) .map(|t| match t { AssetTypes::Balances => balances_weight, AssetTypes::Unknown => Weight::MAX, @@ -90,32 +90,28 @@ impl WeighMultiAssets for MultiAssets { pub struct WestendXcmWeight(core::marker::PhantomData); impl XcmWeightInfo for WestendXcmWeight { - fn withdraw_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) + fn withdraw_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::reserve_asset_deposited()) + fn reserve_asset_deposited(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::reserve_asset_deposited()) } - fn receive_teleported_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) + fn receive_teleported_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::receive_teleported_asset()) } fn query_response( _query_id: &u64, _response: &Response, _max_weight: &Weight, - _querier: &Option, + _querier: &Option, ) -> Weight { XcmGeneric::::query_response() } - fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) + fn transfer_asset(assets: &Assets, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_asset()) } - fn transfer_reserve_asset( - assets: &MultiAssets, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::transfer_reserve_asset()) + fn transfer_reserve_asset(assets: &Assets, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::transfer_reserve_asset()) } fn transact( _origin_kind: &OriginKind, @@ -143,45 +139,37 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + fn descend_origin(_who: &InteriorLocation) -> Weight { XcmGeneric::::descend_origin() } fn report_error(_query_repsonse_info: &QueryResponseInfo) -> Weight { XcmGeneric::::report_error() } - fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_asset()) + fn deposit_asset(assets: &AssetFilter, _dest: &Location) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_asset()) } - fn deposit_reserve_asset( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::deposit_reserve_asset()) + fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::deposit_reserve_asset()) } - fn exchange_asset(_give: &MultiAssetFilter, _receive: &MultiAssets, _maximal: &bool) -> Weight { + fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight { // Westend does not currently support exchange asset operations Weight::MAX } fn initiate_reserve_withdraw( - assets: &MultiAssetFilter, - _reserve: &MultiLocation, + assets: &AssetFilter, + _reserve: &Location, _xcm: &Xcm<()>, ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) + assets.weigh_assets(XcmBalancesWeight::::initiate_reserve_withdraw()) } - fn initiate_teleport( - assets: &MultiAssetFilter, - _dest: &MultiLocation, - _xcm: &Xcm<()>, - ) -> Weight { - assets.weigh_multi_assets(XcmBalancesWeight::::initiate_teleport()) + fn initiate_teleport(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight { + assets.weigh_assets(XcmBalancesWeight::::initiate_teleport()) } - fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + fn report_holding(_response_info: &QueryResponseInfo, _assets: &AssetFilter) -> Weight { XcmGeneric::::report_holding() } - fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> Weight { + fn buy_execution(_fees: &Asset, _weight_limit: &WeightLimit) -> Weight { XcmGeneric::::buy_execution() } fn refund_surplus() -> Weight { @@ -196,7 +184,7 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + fn claim_asset(_assets: &Assets, _ticket: &Location) -> Weight { XcmGeneric::::claim_asset() } fn trap(_code: &u64) -> Weight { @@ -208,13 +196,13 @@ impl XcmWeightInfo for WestendXcmWeight { fn unsubscribe_version() -> Weight { XcmGeneric::::unsubscribe_version() } - fn burn_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + fn burn_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::burn_asset()) } - fn expect_asset(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + fn expect_asset(assets: &Assets) -> Weight { + assets.weigh_assets(XcmGeneric::::expect_asset()) } - fn expect_origin(_origin: &Option) -> Weight { + fn expect_origin(_origin: &Option) -> Weight { XcmGeneric::::expect_origin() } fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { @@ -249,19 +237,19 @@ impl XcmWeightInfo for WestendXcmWeight { // Westend relay should not support export message operations Weight::MAX } - fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn lock_asset(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn unlock_asset(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn note_unlockable(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } - fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + fn request_unlock(_: &Asset, _: &Location) -> Weight { // Westend does not currently support asset locking operations Weight::MAX } @@ -274,19 +262,19 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_topic() -> Weight { XcmGeneric::::clear_topic() } - fn alias_origin(_: &MultiLocation) -> Weight { + fn alias_origin(_: &Location) -> Weight { // XCM Executor does not currently support alias origin operations Weight::MAX } - fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { XcmGeneric::::unpaid_execution() } } #[test] fn all_counted_has_a_sane_weight_upper_limit() { - let assets = MultiAssetFilter::Wild(AllCounted(4294967295)); + let assets = AssetFilter::Wild(AllCounted(4294967295)); let weight = Weight::from_parts(1000, 1000); - assert_eq!(assets.weigh_multi_assets(weight), weight * MAX_ASSETS); + assert_eq!(assets.weigh_assets(weight), weight * MAX_ASSETS); } diff --git a/polkadot/runtime/westend/src/xcm_config.rs b/polkadot/runtime/westend/src/xcm_config.rs index e4b4f50f663..3c052057d90 100644 --- a/polkadot/runtime/westend/src/xcm_config.rs +++ b/polkadot/runtime/westend/src/xcm_config.rs @@ -23,8 +23,8 @@ use super::{ }; use crate::governance::pallet_custom_origins::Treasurer; use frame_support::{ - match_types, parameter_types, - traits::{Equals, Everything, Nothing}, + parameter_types, + traits::{Contains, Equals, Everything, Nothing}, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -53,15 +53,15 @@ use xcm_builder::{ use xcm_executor::XcmExecutor; parameter_types! { - pub const RootLocation: MultiLocation = MultiLocation::here(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); + pub const RootLocation: Location = Location::here(); pub const ThisNetwork: NetworkId = Westend; - pub const UniversalLocation: InteriorMultiLocation = X1(GlobalConsensus(ThisNetwork::get())); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetwork::get())].into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); pub TreasuryAccount: AccountId = Treasury::account_id(); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); + pub FeeAssetId: AssetId = AssetId(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } @@ -81,7 +81,7 @@ pub type LocalAssetTransactor = XcmCurrencyAdapter< Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, - // We can convert the MultiLocations with our converter above: + // We can convert the Locations with our converter above: LocationConverter, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -114,17 +114,17 @@ pub type XcmRouter = WithUniqueTopic< >; parameter_types! { - pub const AssetHub: MultiLocation = Parachain(ASSET_HUB_ID).into_location(); - pub const Collectives: MultiLocation = Parachain(COLLECTIVES_ID).into_location(); - pub const BridgeHub: MultiLocation = Parachain(BRIDGE_HUB_ID).into_location(); - pub const People: MultiLocation = Parachain(PEOPLE_ID).into_location(); - pub const Wnd: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) }); - pub const WndForAssetHub: (MultiAssetFilter, MultiLocation) = (Wnd::get(), AssetHub::get()); - pub const WndForCollectives: (MultiAssetFilter, MultiLocation) = (Wnd::get(), Collectives::get()); - pub const WndForBridgeHub: (MultiAssetFilter, MultiLocation) = (Wnd::get(), BridgeHub::get()); - pub const WndForPeople: (MultiAssetFilter, MultiLocation) = (Wnd::get(), People::get()); - pub const MaxInstructions: u32 = 100; - pub const MaxAssetsIntoHolding: u32 = 64; + pub AssetHub: Location = Parachain(ASSET_HUB_ID).into_location(); + pub Collectives: Location = Parachain(COLLECTIVES_ID).into_location(); + pub BridgeHub: Location = Parachain(BRIDGE_HUB_ID).into_location(); + pub People: Location = Parachain(PEOPLE_ID).into_location(); + pub Wnd: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId(TokenLocation::get()) }); + pub WndForAssetHub: (AssetFilter, Location) = (Wnd::get(), AssetHub::get()); + pub WndForCollectives: (AssetFilter, Location) = (Wnd::get(), Collectives::get()); + pub WndForBridgeHub: (AssetFilter, Location) = (Wnd::get(), BridgeHub::get()); + pub WndForPeople: (AssetFilter, Location) = (Wnd::get(), People::get()); + pub MaxInstructions: u32 = 100; + pub MaxAssetsIntoHolding: u32 = 64; } pub type TrustedTeleporters = ( @@ -134,17 +134,29 @@ pub type TrustedTeleporters = ( xcm_builder::Case, ); -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type CollectivesOrFellows: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(COLLECTIVES_ID)) } | - MultiLocation { parents: 0, interior: X2(Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }) } - }; - pub type LocalPlurality: impl Contains = { - MultiLocation { parents: 0, interior: X1(Plurality { .. }) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) + } +} + +pub struct CollectivesOrFellows; +impl Contains for CollectivesOrFellows { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (0, [Parachain(COLLECTIVES_ID)]) | + (0, [Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }]) + ) + } +} + +pub struct LocalPlurality; +impl Contains for LocalPlurality { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Plurality { .. }])) + } } /// The barriers one of which must be passed for an XCM message to be executed. @@ -218,11 +230,10 @@ parameter_types! { pub const TreasurerBodyId: BodyId = BodyId::Index(TREASURER_INDEX); } -/// Type to convert the `GeneralAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `GeneralAdmin` origin to a Plurality `Location` value. pub type GeneralAdminToPlurality = OriginToPluralityVoice; -/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior /// location of this chain. pub type LocalOriginToLocation = ( GeneralAdminToPlurality, @@ -230,25 +241,25 @@ pub type LocalOriginToLocation = ( SignedToAccountId32, ); -/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the `FellowshipAdmin` origin to a Plurality `MultiLocation` value. +/// Type to convert the `FellowshipAdmin` origin to a Plurality `Location` value. pub type FellowshipAdminToPlurality = OriginToPluralityVoice; -/// Type to convert the `Treasurer` origin to a Plurality `MultiLocation` value. +/// Type to convert the `Treasurer` origin to a Plurality `Location` value. pub type TreasurerToPlurality = OriginToPluralityVoice; -/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an +/// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( - // GeneralAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // GeneralAdmin origin to be used in XCM as a corresponding Plurality `Location` value. GeneralAdminToPlurality, - // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, - // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `Location` value. FellowshipAdminToPlurality, // `Treasurer` origin to be used in XCM as a corresponding Plurality `MultiLocation` value. TreasurerToPlurality, diff --git a/polkadot/xcm/Cargo.toml b/polkadot/xcm/Cargo.toml index 89e3728a361..1103e07adbb 100644 --- a/polkadot/xcm/Cargo.toml +++ b/polkadot/xcm/Cargo.toml @@ -18,7 +18,7 @@ log = { version = "0.4.17", default-features = false } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive", "serde"] } sp-weights = { path = "../../substrate/primitives/weights", default-features = false, features = ["serde"] } -serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] } +serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive", "rc"] } schemars = { version = "0.8.13", default-features = true, optional = true } xcm-procedural = { path = "procedural" } environmental = { version = "1.1.4", default-features = false } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs index d32eb8d4a52..e96ec48fcba 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -24,7 +24,7 @@ use frame_support::{ }; use sp_runtime::traits::{Bounded, Zero}; use sp_std::{prelude::*, vec}; -use xcm::latest::{prelude::*, MAX_ITEMS_IN_MULTIASSETS}; +use xcm::latest::{prelude::*, MAX_ITEMS_IN_ASSETS}; use xcm_executor::traits::{ConvertLocation, FeeReason, TransactAsset}; benchmarks_instance_pallet! { @@ -43,7 +43,7 @@ benchmarks_instance_pallet! { withdraw_asset { let (sender_account, sender_location) = account_and_location::(1); let worst_case_holding = T::worst_case_holding(0); - let asset = T::get_multi_asset(); + let asset = T::get_asset(); >::deposit_asset(&asset, &sender_location, None).unwrap(); // check the assets of origin. @@ -63,8 +63,8 @@ benchmarks_instance_pallet! { transfer_asset { let (sender_account, sender_location) = account_and_location::(1); - let asset = T::get_multi_asset(); - let assets: MultiAssets = vec![ asset.clone() ].into(); + let asset = T::get_asset(); + let assets: Assets = vec![ asset.clone() ].into(); // this xcm doesn't use holding let dest_location = T::valid_destination()?; @@ -95,10 +95,10 @@ benchmarks_instance_pallet! { ); let sender_account_balance_before = T::TransactAsset::balance(&sender_account); - let asset = T::get_multi_asset(); + let asset = T::get_asset(); >::deposit_asset(&asset, &sender_location, None).unwrap(); assert!(T::TransactAsset::balance(&sender_account) > sender_account_balance_before); - let assets: MultiAssets = vec![ asset ].into(); + let assets: Assets = vec![asset].into(); assert!(T::TransactAsset::balance(&dest_account).is_zero()); let mut executor = new_executor::(sender_location); @@ -129,7 +129,7 @@ benchmarks_instance_pallet! { BenchmarkResult::from_weight(Weight::MAX) ))?; - let assets: MultiAssets = vec![ transferable_reserve_asset ].into(); + let assets: Assets = vec![ transferable_reserve_asset ].into(); let mut executor = new_executor::(trusted_reserve); let instruction = Instruction::ReserveAssetDeposited(assets.clone()); @@ -143,7 +143,7 @@ benchmarks_instance_pallet! { initiate_reserve_withdraw { let (sender_account, sender_location) = account_and_location::(1); let holding = T::worst_case_holding(1); - let assets_filter = MultiAssetFilter::Definite(holding.clone().into_inner().into_iter().take(MAX_ITEMS_IN_MULTIASSETS).collect::>().into()); + let assets_filter = AssetFilter::Definite(holding.clone().into_inner().into_iter().take(MAX_ITEMS_IN_ASSETS).collect::>().into()); let reserve = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; let (expected_fees_mode, expected_assets_in_holding) = T::DeliveryHelper::ensure_successful_delivery( @@ -188,7 +188,7 @@ benchmarks_instance_pallet! { )?; } - let assets: MultiAssets = vec![ teleportable_asset ].into(); + let assets: Assets = vec![ teleportable_asset ].into(); let mut executor = new_executor::(trusted_teleporter); let instruction = Instruction::ReceiveTeleportedAsset(assets.clone()); @@ -204,7 +204,7 @@ benchmarks_instance_pallet! { } deposit_asset { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); // Add our asset to the holding. @@ -230,7 +230,7 @@ benchmarks_instance_pallet! { } deposit_reserve_asset { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(1); // Add our asset to the holding. @@ -257,7 +257,7 @@ benchmarks_instance_pallet! { } initiate_teleport { - let asset = T::get_multi_asset(); + let asset = T::get_asset(); let mut holding = T::worst_case_holding(0); // Add our asset to the holding. diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs index 43892c31c7c..bb4b7ff6276 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -93,10 +93,10 @@ parameter_types! { pub struct MatchAnyFungible; impl xcm_executor::traits::MatchesFungible for MatchAnyFungible { - fn matches_fungible(m: &MultiAsset) -> Option { + fn matches_fungible(m: &Asset) -> Option { use sp_runtime::traits::SaturatedConversion; match m { - MultiAsset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), + Asset { fun: Fungible(amount), .. } => Some((*amount).saturated_into::()), _ => None, } } @@ -151,13 +151,12 @@ impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; type DeliveryHelper = (); - fn valid_destination() -> Result { - let valid_destination: MultiLocation = - X1(AccountId32 { network: None, id: [0u8; 32] }).into(); + fn valid_destination() -> Result { + let valid_destination: Location = [AccountId32 { network: None, id: [0u8; 32] }].into(); Ok(valid_destination) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> Assets { crate::mock_worst_case_holding( depositable_count, ::MaxAssetsIntoHolding::get(), @@ -170,19 +169,19 @@ pub type TrustedReserves = xcm_builder::Case; parameter_types! { pub const CheckingAccount: Option<(u64, MintLocation)> = Some((100, MintLocation::Local)); - pub const ChildTeleporter: MultiLocation = Parachain(1000).into_location(); - pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + pub ChildTeleporter: Location = Parachain(1000).into_location(); + pub TrustedTeleporter: Option<(Location, Asset)> = Some(( ChildTeleporter::get(), - MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + Asset { id: AssetId(Here.into_location()), fun: Fungible(100) }, )); - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some(( + pub TrustedReserve: Option<(Location, Asset)> = Some(( ChildTeleporter::get(), - MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + Asset { id: AssetId(Here.into_location()), fun: Fungible(100) }, )); - pub const TeleportConcreteFungible: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); - pub const ReserveConcreteFungible: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub TeleportConcreteFungible: (AssetFilter, Location) = + (Wild(AllOf { fun: WildFungible, id: AssetId(Here.into_location()) }), ChildTeleporter::get()); + pub ReserveConcreteFungible: (AssetFilter, Location) = + (Wild(AllOf { fun: WildFungible, id: AssetId(Here.into_location()) }), ChildTeleporter::get()); } impl xcm_balances_benchmark::Config for Test { @@ -191,10 +190,10 @@ impl xcm_balances_benchmark::Config for Test { type TrustedTeleporter = TrustedTeleporter; type TrustedReserve = TrustedReserve; - fn get_multi_asset() -> MultiAsset { + fn get_asset() -> Asset { let amount = >::minimum_balance() as u128; - MultiAsset { id: Concrete(Here.into()), fun: Fungible(amount) } + Asset { id: AssetId(Here.into()), fun: Fungible(amount) } } } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs index 292921eb595..e84355f4092 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mod.rs @@ -37,14 +37,14 @@ pub mod pallet { type CheckedAccount: Get>; /// A trusted location which we allow teleports from, and the asset we allow to teleport. - type TrustedTeleporter: Get>; + type TrustedTeleporter: Get>; /// A trusted location where reserve assets are stored, and the asset we allow to be /// reserves. - type TrustedReserve: Get>; + type TrustedReserve: Get>; /// Give me a fungible asset that your asset transactor is going to accept. - fn get_multi_asset() -> xcm::latest::MultiAsset; + fn get_asset() -> xcm::latest::Asset; } #[pallet::pallet] diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs index 50a7fe45e23..14d53c4ebf5 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -77,7 +77,7 @@ benchmarks! { let mut executor = new_executor::(Default::default()); executor.set_holding(holding); - let fee_asset = Concrete(Here.into()); + let fee_asset = AssetId(Here.into()); let instruction = Instruction::>::BuyExecution { fees: (fee_asset, 100_000_000u128).into(), // should be something inside of holding @@ -95,7 +95,7 @@ benchmarks! { let mut executor = new_executor::(Default::default()); let (query_id, response) = T::worst_case_response(); let max_weight = Weight::MAX; - let querier: Option = Some(Here.into()); + let querier: Option = Some(Here.into()); let instruction = Instruction::QueryResponse { query_id, response, max_weight, querier }; let xcm = Xcm(vec![instruction]); }: { @@ -174,15 +174,15 @@ benchmarks! { descend_origin { let mut executor = new_executor::(Default::default()); - let who = X2(OnlyChild, OnlyChild); - let instruction = Instruction::DescendOrigin(who); + let who = Junctions::from([OnlyChild, OnlyChild]); + let instruction = Instruction::DescendOrigin(who.clone()); let xcm = Xcm(vec![instruction]); } : { executor.bench_process(xcm)?; } verify { assert_eq!( executor.origin(), - &Some(MultiLocation { + &Some(Location { parents: 0, interior: who, }), @@ -242,7 +242,7 @@ benchmarks! { &origin, assets.clone().into(), &XcmContext { - origin: Some(origin), + origin: Some(origin.clone()), message_id: [0; 32], topic: None, }, @@ -279,7 +279,7 @@ benchmarks! { let origin = T::subscribe_origin()?; let query_id = Default::default(); let max_response_weight = Default::default(); - let mut executor = new_executor::(origin); + let mut executor = new_executor::(origin.clone()); let instruction = Instruction::SubscribeVersion { query_id, max_response_weight }; let xcm = Xcm(vec![instruction]); } : { @@ -299,14 +299,14 @@ benchmarks! { query_id, max_response_weight, &XcmContext { - origin: Some(origin), + origin: Some(origin.clone()), message_id: [0; 32], topic: None, }, ).map_err(|_| "Could not start subscription")?; assert!(::SubscriptionService::is_subscribed(&origin)); - let mut executor = new_executor::(origin); + let mut executor = new_executor::(origin.clone()); let instruction = Instruction::UnsubscribeVersion; let xcm = Xcm(vec![instruction]); } : { @@ -545,7 +545,7 @@ benchmarks! { } verify { use frame_support::traits::Get; let universal_location = ::UniversalLocation::get(); - assert_eq!(executor.origin(), &Some(X1(alias).relative_to(&universal_location))); + assert_eq!(executor.origin(), &Some(Junctions::from([alias]).relative_to(&universal_location))); } export_message { @@ -561,8 +561,8 @@ benchmarks! { let (expected_fees_mode, expected_assets_in_holding) = T::DeliveryHelper::ensure_successful_delivery( &origin, - &destination.into(), - FeeReason::Export { network, destination }, + &destination.clone().into(), + FeeReason::Export { network, destination: destination.clone() }, ); let sender_account = T::AccountIdConverter::convert_location(&origin).unwrap(); let sender_account_balance_before = T::TransactAsset::balance(&sender_account); @@ -575,7 +575,7 @@ benchmarks! { executor.set_holding(expected_assets_in_holding.into()); } let xcm = Xcm(vec![ExportMessage { - network, destination, xcm: inner_xcm, + network, destination: destination.clone(), xcm: inner_xcm, }]); }: { executor.bench_process(xcm)?; @@ -632,13 +632,13 @@ benchmarks! { let (unlocker, owner, asset) = T::unlockable_asset()?; - let mut executor = new_executor::(unlocker); + let mut executor = new_executor::(unlocker.clone()); // We first place the asset in lock first... ::AssetLocker::prepare_lock( unlocker, asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -658,13 +658,13 @@ benchmarks! { let (unlocker, owner, asset) = T::unlockable_asset()?; - let mut executor = new_executor::(unlocker); + let mut executor = new_executor::(unlocker.clone()); // We first place the asset in lock first... ::AssetLocker::prepare_lock( unlocker, asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -686,9 +686,9 @@ benchmarks! { // We first place the asset in lock first... ::AssetLocker::prepare_lock( - locker, + locker.clone(), asset.clone(), - owner, + owner.clone(), ) .map_err(|_| BenchmarkError::Skip)? .enact() @@ -739,7 +739,7 @@ benchmarks! { let mut executor = new_executor::(origin); - let instruction = Instruction::AliasOrigin(target); + let instruction = Instruction::AliasOrigin(target.clone()); let xcm = Xcm(vec![instruction]); }: { executor.bench_process(xcm)?; diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs index 6efd2304e28..4dd677217fc 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -19,16 +19,16 @@ use crate::{generic, mock::*, *}; use codec::Decode; use frame_support::{ - derive_impl, match_types, parameter_types, - traits::{Everything, OriginTrait}, + derive_impl, parameter_types, + traits::{Contains, Everything, OriginTrait}, weights::Weight, }; use sp_core::H256; use sp_runtime::traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}; use xcm_builder::{ test_utils::{ - Assets, TestAssetExchanger, TestAssetLocker, TestAssetTrap, TestSubscriptionService, - TestUniversalAliases, + AssetsInHolding, TestAssetExchanger, TestAssetLocker, TestAssetTrap, + TestSubscriptionService, TestUniversalAliases, }, AliasForeignAccountId32, AllowUnpaidExecutionFrom, }; @@ -81,19 +81,15 @@ impl frame_system::Config for Test { /// The benchmarks in this pallet should never need an asset transactor to begin with. pub struct NoAssetTransactor; impl xcm_executor::traits::TransactAsset for NoAssetTransactor { - fn deposit_asset( - _: &MultiAsset, - _: &MultiLocation, - _: Option<&XcmContext>, - ) -> Result<(), XcmError> { + fn deposit_asset(_: &Asset, _: &Location, _: Option<&XcmContext>) -> Result<(), XcmError> { unreachable!(); } fn withdraw_asset( - _: &MultiAsset, - _: &MultiLocation, + _: &Asset, + _: &Location, _: Option<&XcmContext>, - ) -> Result { + ) -> Result { unreachable!(); } } @@ -103,10 +99,11 @@ parameter_types! { pub const MaxAssetsIntoHolding: u32 = 64; } -match_types! { - pub type OnlyParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; +pub struct OnlyParachains; +impl Contains for OnlyParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) + } } type Aliasers = AliasForeignAccountId32; @@ -153,13 +150,13 @@ impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; type DeliveryHelper = (); - fn valid_destination() -> Result { - let valid_destination: MultiLocation = + fn valid_destination() -> Result { + let valid_destination: Location = Junction::AccountId32 { network: None, id: [0u8; 32] }.into(); Ok(valid_destination) } - fn worst_case_holding(depositable_count: u32) -> MultiAssets { + fn worst_case_holding(depositable_count: u32) -> Assets { crate::mock_worst_case_holding( depositable_count, ::MaxAssetsIntoHolding::get(), @@ -172,48 +169,47 @@ impl generic::Config for Test { type RuntimeCall = RuntimeCall; fn worst_case_response() -> (u64, Response) { - let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + let assets: Assets = (AssetId(Here.into()), 100).into(); (0, Response::Assets(assets)) } - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError> { Ok(Default::default()) } - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + fn universal_alias() -> Result<(Location, Junction), BenchmarkError> { Ok((Here.into(), GlobalConsensus(ByGenesis([0; 32])))) } fn transact_origin_and_runtime_call( - ) -> Result<(MultiLocation, ::RuntimeCall), BenchmarkError> { + ) -> Result<(Location, ::RuntimeCall), BenchmarkError> { Ok((Default::default(), frame_system::Call::remark_with_event { remark: vec![] }.into())) } - fn subscribe_origin() -> Result { + fn subscribe_origin() -> Result { Ok(Default::default()) } - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { - let assets: MultiAssets = (Concrete(Here.into()), 100).into(); - let ticket = MultiLocation { parents: 0, interior: X1(GeneralIndex(0)) }; + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError> { + let assets: Assets = (AssetId(Here.into()), 100).into(); + let ticket = Location { parents: 0, interior: [GeneralIndex(0)].into() }; Ok((Default::default(), ticket, assets)) } - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { - let assets: MultiAsset = (Concrete(Here.into()), 100).into(); + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError> { + let assets: Asset = (AssetId(Here.into()), 100).into(); Ok((Default::default(), account_id_junction::(1).into(), assets)) } fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError> { // No MessageExporter in tests Err(BenchmarkError::Skip) } - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { - let origin: MultiLocation = - (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); - let target: MultiLocation = AccountId32 { network: None, id: [0; 32] }.into(); + fn alias_origin() -> Result<(Location, Location), BenchmarkError> { + let origin: Location = (Parachain(1), AccountId32 { network: None, id: [0; 32] }).into(); + let target: Location = AccountId32 { network: None, id: [0; 32] }.into(); Ok((origin, target)) } } @@ -233,9 +229,9 @@ where ::AccountId: Decode, { fn convert_origin( - _origin: impl Into, + _origin: impl Into, _kind: OriginKind, - ) -> Result { + ) -> Result { Ok(RuntimeOrigin::signed( ::AccountId::decode(&mut TrailingZeroInput::zeroes()) .expect("infinite length input; no invalid inputs for type; qed"), diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs index 11f7bba19a9..3728baea983 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mod.rs @@ -26,10 +26,7 @@ pub mod pallet { use frame_benchmarking::BenchmarkError; use frame_support::{dispatch::GetDispatchInfo, pallet_prelude::Encode}; use sp_runtime::traits::Dispatchable; - use xcm::latest::{ - InteriorMultiLocation, Junction, MultiAsset, MultiAssets, MultiLocation, NetworkId, - Response, - }; + use xcm::latest::{Asset, Assets, InteriorLocation, Junction, Location, NetworkId, Response}; #[pallet::config] pub trait Config: frame_system::Config + crate::Config { @@ -53,44 +50,44 @@ pub mod pallet { /// from, whereas the second element represents the assets that are being exchanged to. /// /// If set to `Err`, benchmarks which rely on an `exchange_asset` will be skipped. - fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError>; + fn worst_case_asset_exchange() -> Result<(Assets, Assets), BenchmarkError>; - /// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the + /// A `(Location, Junction)` that is one of the `UniversalAliases` configured by the /// XCM executor. /// /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. - fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError>; + fn universal_alias() -> Result<(Location, Junction), BenchmarkError>; - /// The `MultiLocation` and `RuntimeCall` used for successful transaction XCMs. + /// The `Location` and `RuntimeCall` used for successful transaction XCMs. /// /// If set to `Err`, benchmarks which rely on a `transact_origin_and_runtime_call` will be /// skipped. fn transact_origin_and_runtime_call( - ) -> Result<(MultiLocation, >::RuntimeCall), BenchmarkError>; + ) -> Result<(Location, >::RuntimeCall), BenchmarkError>; - /// A valid `MultiLocation` we can successfully subscribe to. + /// A valid `Location` we can successfully subscribe to. /// /// If set to `Err`, benchmarks which rely on a `subscribe_origin` will be skipped. - fn subscribe_origin() -> Result; + fn subscribe_origin() -> Result; /// Return an origin, ticket, and assets that can be trapped and claimed. - fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError>; + fn claimable_asset() -> Result<(Location, Location, Assets), BenchmarkError>; /// Return an unlocker, owner and assets that can be locked and unlocked. - fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError>; + fn unlockable_asset() -> Result<(Location, Location, Asset), BenchmarkError>; - /// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message + /// A `(Location, NetworkId, InteriorLocation)` we can successfully export message /// to. /// /// If set to `Err`, benchmarks which rely on `export_message` will be skipped. fn export_message_origin_and_destination( - ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError>; + ) -> Result<(Location, NetworkId, InteriorLocation), BenchmarkError>; - /// A `(MultiLocation, MultiLocation)` that is one of the `Aliasers` configured by the XCM + /// A `(Location, Location)` that is one of the `Aliasers` configured by the XCM /// executor. /// /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError>; + fn alias_origin() -> Result<(Location, Location), BenchmarkError>; /// Returns a valid pallet info for `ExpectPallet` or `QueryPallet` benchmark. /// diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs index 3bf4aea1b25..6ce8d3e99e8 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs @@ -41,18 +41,18 @@ pub trait Config: frame_system::Config { /// `TransactAsset` is implemented. type XcmConfig: XcmConfig; - /// A converter between a multi-location to a sovereign account. + /// A converter between a location to a sovereign account. type AccountIdConverter: ConvertLocation; /// Helper that ensures successful delivery for XCM instructions which need `SendXcm`. type DeliveryHelper: EnsureDelivery; /// Does any necessary setup to create a valid destination for XCM messages. - /// Returns that destination's multi-location to be used in benchmarks. - fn valid_destination() -> Result; + /// Returns that destination's location to be used in benchmarks. + fn valid_destination() -> Result; /// Worst case scenario for a holding account in this runtime. - fn worst_case_holding(depositable_count: u32) -> MultiAssets; + fn worst_case_holding(depositable_count: u32) -> Assets; } const SEED: u32 = 0; @@ -66,21 +66,21 @@ pub type AssetTransactorOf = <::XcmConfig as XcmConfig>::AssetTr /// The call type of executor's config. Should eventually resolve to the same overarching call type. pub type XcmCallOf = <::XcmConfig as XcmConfig>::RuntimeCall; -pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> MultiAssets { +pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> Assets { let fungibles_amount: u128 = 100; let holding_fungibles = max_assets / 2 - depositable_count; let holding_non_fungibles = holding_fungibles; (0..holding_fungibles) .map(|i| { - MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: Fungible(fungibles_amount * i as u128), } .into() }) - .chain(core::iter::once(MultiAsset { id: Concrete(Here.into()), fun: Fungible(u128::MAX) })) - .chain((0..holding_non_fungibles).map(|i| MultiAsset { - id: Concrete(GeneralIndex(i as u128).into()), + .chain(core::iter::once(Asset { id: AssetId(Here.into()), fun: Fungible(u128::MAX) })) + .chain((0..holding_non_fungibles).map(|i| Asset { + id: AssetId(GeneralIndex(i as u128).into()), fun: NonFungible(asset_instance_from(i)), })) .collect::>() @@ -94,11 +94,11 @@ pub fn asset_instance_from(x: u32) -> AssetInstance { AssetInstance::Array4(instance) } -pub fn new_executor(origin: MultiLocation) -> ExecutorOf { +pub fn new_executor(origin: Location) -> ExecutorOf { ExecutorOf::::new(origin, [0; 32]) } -/// Build a multi-location from an account id. +/// Build a location from an account id. fn account_id_junction(index: u32) -> Junction { let account: T::AccountId = account("account", index, SEED); let mut encoded = account.encode(); @@ -108,8 +108,8 @@ fn account_id_junction(index: u32) -> Junction { Junction::AccountId32 { network: None, id } } -pub fn account_and_location(index: u32) -> (T::AccountId, MultiLocation) { - let location: MultiLocation = account_id_junction::(index).into(); +pub fn account_and_location(index: u32) -> (T::AccountId, Location) { + let location: Location = account_id_junction::(index).into(); let account = T::AccountIdConverter::convert_location(&location).unwrap(); (account, location) @@ -121,21 +121,21 @@ pub trait EnsureDelivery { /// Prepare all requirements for successful `XcmSender: SendXcm` passing (accounts, balances, /// channels ...). Returns: /// - possible `FeesMode` which is expected to be set to executor - /// - possible `MultiAssets` which are expected to be subsume to the Holding Register + /// - possible `Assets` which are expected to be subsume to the Holding Register fn ensure_successful_delivery( - origin_ref: &MultiLocation, - dest: &MultiLocation, + origin_ref: &Location, + dest: &Location, fee_reason: FeeReason, - ) -> (Option, Option); + ) -> (Option, Option); } /// `()` implementation does nothing which means no special requirements for environment. impl EnsureDelivery for () { fn ensure_successful_delivery( - _origin_ref: &MultiLocation, - _dest: &MultiLocation, + _origin_ref: &Location, + _dest: &Location, _fee_reason: FeeReason, - ) -> (Option, Option) { + ) -> (Option, Option) { // doing nothing (None, None) } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs index e02c5bf0861..78a9e5f8a01 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/mock.rs @@ -22,8 +22,8 @@ use xcm::latest::Weight; pub struct DevNull; impl xcm::opaque::latest::SendXcm for DevNull { type Ticket = (); - fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { - Ok(((), MultiAssets::new())) + fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { + Ok(((), Assets::new())) } fn deliver(_: ()) -> Result { Ok([0; 32]) @@ -31,13 +31,13 @@ impl xcm::opaque::latest::SendXcm for DevNull { } impl xcm_executor::traits::OnResponse for DevNull { - fn expecting_response(_: &MultiLocation, _: u64, _: Option<&MultiLocation>) -> bool { + fn expecting_response(_: &Location, _: u64, _: Option<&Location>) -> bool { false } fn on_response( - _: &MultiLocation, + _: &Location, _: u64, - _: Option<&MultiLocation>, + _: Option<&Location>, _: Response, _: Weight, _: &XcmContext, @@ -48,9 +48,9 @@ impl xcm_executor::traits::OnResponse for DevNull { pub struct AccountIdConverter; impl xcm_executor::traits::ConvertLocation for AccountIdConverter { - fn convert_location(ml: &MultiLocation) -> Option { - match ml { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, .. }) } => + fn convert_location(ml: &Location) -> Option { + match ml.unpack() { + (0, [Junction::AccountId32 { id, .. }]) => Some(::decode(&mut &*id.to_vec()).unwrap()), _ => None, } @@ -58,14 +58,14 @@ impl xcm_executor::traits::ConvertLocation for AccountIdConverter { } parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Junction::Parachain(101).into(); + pub UniversalLocation: InteriorLocation = Junction::Parachain(101).into(); pub UnitWeightCost: Weight = Weight::from_parts(10, 10); - pub WeightPrice: (AssetId, u128, u128) = (Concrete(Here.into()), 1_000_000, 1024); + pub WeightPrice: (AssetId, u128, u128) = (AssetId(Here.into()), 1_000_000, 1024); } pub struct AllAssetLocationsPass; -impl ContainsPair for AllAssetLocationsPass { - fn contains(_: &MultiAsset, _: &MultiLocation) -> bool { +impl ContainsPair for AllAssetLocationsPass { + fn contains(_: &Asset, _: &Location) -> bool { true } } diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index 28a198f40a0..c7d8fb24e9d 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -32,36 +32,36 @@ pub struct Pallet(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. pub trait Config: crate::Config { - /// A `MultiLocation` that can be reached via `XcmRouter`. Used only in benchmarks. + /// A `Location` that can be reached via `XcmRouter`. Used only in benchmarks. /// /// If `None`, the benchmarks that depend on a reachable destination will be skipped. - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { None } - /// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be + /// A `(Asset, Location)` pair representing asset and the destination it can be /// teleported to. Used only in benchmarks. /// /// Implementation should also make sure `dest` is reachable/connected. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { None } - /// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be + /// A `(Asset, Location)` pair representing asset and the destination it can be /// reserve-transferred to. Used only in benchmarks. /// /// Implementation should also make sure `dest` is reachable/connected. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } /// Sets up a complex transfer (usually consisting of a teleport and reserve-based transfer), so /// that runtime can properly benchmark `transfer_assets()` extrinsic. Should return a tuple - /// `(MultiAsset, u32, MultiLocation, dyn FnOnce())` representing the assets to transfer, the + /// `(Asset, u32, Location, dyn FnOnce())` representing the assets to transfer, the /// `u32` index of the asset to be used for fees, the destination chain for the transfer, and a /// `verify()` closure to verify the intended transfer side-effects. /// @@ -71,8 +71,7 @@ pub trait Config: crate::Config { /// Used only in benchmarks. /// /// If `None`, the benchmarks that depend on this will default to `Weight::MAX`. - fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { + fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { None } } @@ -90,7 +89,7 @@ benchmarks! { return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))) } let msg = Xcm(vec![ClearOrigin]); - let versioned_dest: VersionedMultiLocation = T::reachable_dest().ok_or( + let versioned_dest: VersionedLocation = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); @@ -106,7 +105,7 @@ benchmarks! { Fungible(amount) => *amount, _ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")), }.into(); - let assets: MultiAssets = asset.into(); + let assets: Assets = asset.into(); let existential_deposit = T::ExistentialDeposit::get(); let caller = whitelisted_caller(); @@ -126,10 +125,10 @@ benchmarks! { } let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) verify { // verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees) @@ -145,7 +144,7 @@ benchmarks! { Fungible(amount) => *amount, _ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")), }.into(); - let assets: MultiAssets = asset.into(); + let assets: Assets = asset.into(); let existential_deposit = T::ExistentialDeposit::get(); let caller = whitelisted_caller(); @@ -165,10 +164,10 @@ benchmarks! { } let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0) verify { // verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees) @@ -182,10 +181,10 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let send_origin = RawOrigin::Signed(caller.clone()); let recipient = [0u8; 32]; - let versioned_dest: VersionedMultiLocation = destination.into(); - let versioned_beneficiary: VersionedMultiLocation = + let versioned_dest: VersionedLocation = destination.into(); + let versioned_beneficiary: VersionedLocation = AccountId32 { network: None, id: recipient.into() }.into(); - let versioned_assets: VersionedMultiAssets = assets.into(); + let versioned_assets: VersionedAssets = assets.into(); }: _>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0, WeightLimit::Unlimited) verify { // run provided verification function @@ -214,7 +213,7 @@ benchmarks! { force_default_xcm_version {}: _(RawOrigin::Root, Some(2)) force_subscribe_version_notify { - let versioned_loc: VersionedMultiLocation = T::reachable_dest().ok_or( + let versioned_loc: VersionedLocation = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )? .into(); @@ -224,7 +223,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)), )?; - let versioned_loc: VersionedMultiLocation = loc.into(); + let versioned_loc: VersionedLocation = loc.clone().into(); let _ = crate::Pallet::::request_version_notify(loc); }: _(RawOrigin::Root, Box::new(versioned_loc)) @@ -232,7 +231,7 @@ benchmarks! { migrate_supported_version { let old_version = XCM_VERSION - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); SupportedVersion::::insert(old_version, loc, old_version); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero()); @@ -240,7 +239,7 @@ benchmarks! { migrate_version_notifiers { let old_version = XCM_VERSION - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifiers::::insert(old_version, loc, 0); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero()); @@ -250,7 +249,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads(1))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), current_version)); }: { @@ -261,7 +260,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let current_version = T::AdvertisedXcmVersion::get(); let old_version = current_version - 1; VersionNotifyTargets::::insert(current_version, loc, (0, Weight::zero(), old_version)); @@ -276,7 +275,7 @@ benchmarks! { part: v2::BodyPart::Voice, } .into(); - let bad_loc = VersionedMultiLocation::from(bad_loc); + let bad_loc = VersionedLocation::from(bad_loc); let current_version = T::AdvertisedXcmVersion::get(); VersionNotifyTargets::::insert(current_version, bad_loc, (0, Weight::zero(), current_version)); }: { @@ -286,7 +285,7 @@ benchmarks! { migrate_version_notify_targets { let current_version = T::AdvertisedXcmVersion::get(); let old_version = current_version - 1; - let loc = VersionedMultiLocation::from(MultiLocation::from(Parent)); + let loc = VersionedLocation::from(Location::from(Parent)); VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), current_version)); }: { crate::Pallet::::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero()); @@ -296,7 +295,7 @@ benchmarks! { let loc = T::reachable_dest().ok_or( BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))), )?; - let loc = VersionedMultiLocation::from(loc); + let loc = VersionedLocation::from(loc); let old_version = T::AdvertisedXcmVersion::get() - 1; VersionNotifyTargets::::insert(old_version, loc, (0, Weight::zero(), old_version)); }: { @@ -304,17 +303,17 @@ benchmarks! { } new_query { - let responder = MultiLocation::from(Parent); + let responder = Location::from(Parent); let timeout = 1u32.into(); - let match_querier = MultiLocation::from(Here); + let match_querier = Location::from(Here); }: { crate::Pallet::::new_query(responder, timeout, match_querier); } take_response { - let responder = MultiLocation::from(Parent); + let responder = Location::from(Parent); let timeout = 1u32.into(); - let match_querier = MultiLocation::from(Here); + let match_querier = Location::from(Here); let query_id = crate::Pallet::::new_query(responder, timeout, match_querier); let infos = (0 .. xcm::v3::MaxPalletsInfo::get()).map(|_| PalletInfo::new( u32::MAX, @@ -340,17 +339,17 @@ benchmarks! { pub mod helpers { use super::*; pub fn native_teleport_as_asset_transfer( - native_asset_location: MultiLocation, - destination: MultiLocation, - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> + native_asset_location: Location, + destination: Location, + ) -> Option<(Assets, u32, Location, Box)> where T: Config + pallet_balances::Config, u128: From<::Balance>, { // Relay/native token can be teleported to/from AH. let amount = T::ExistentialDeposit::get() * 100u32.into(); - let assets: MultiAssets = - MultiAsset { fun: Fungible(amount.into()), id: Concrete(native_asset_location) }.into(); + let assets: Assets = + Asset { fun: Fungible(amount.into()), id: AssetId(native_asset_location) }.into(); let fee_index = 0u32; // Give some multiple of transferred amount diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index 2848527f150..55154198a9b 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -59,7 +59,7 @@ use xcm_executor::{ DropAssets, MatchesFungible, OnResponse, Properties, QueryHandler, QueryResponseStatus, TransactAsset, TransferType, VersionChangeNotifier, WeightBounds, XcmAssetTransfers, }, - Assets, + AssetsInHolding, }; pub trait WeightInfo { @@ -202,45 +202,39 @@ pub mod pallet { // TODO: We should really use a trait which can handle multiple currencies. type Currency: LockableCurrency>; - /// The `MultiAsset` matcher for `Currency`. + /// The `Asset` matcher for `Currency`. type CurrencyMatcher: MatchesFungible>; - /// Required origin for sending XCM messages. If successful, it resolves to `MultiLocation` + /// Required origin for sending XCM messages. If successful, it resolves to `Location` /// which exists as an interior location within this chain's XCM context. - type SendXcmOrigin: EnsureOrigin< - ::RuntimeOrigin, - Success = MultiLocation, - >; + type SendXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; /// The type used to actually dispatch an XCM to its destination. type XcmRouter: SendXcm; /// Required origin for executing XCM messages, including the teleport functionality. If - /// successful, then it resolves to `MultiLocation` which exists as an interior location + /// successful, then it resolves to `Location` which exists as an interior location /// within this chain's XCM context. - type ExecuteXcmOrigin: EnsureOrigin< - ::RuntimeOrigin, - Success = MultiLocation, - >; + type ExecuteXcmOrigin: EnsureOrigin<::RuntimeOrigin, Success = Location>; /// Our XCM filter which messages to be executed using `XcmExecutor` must pass. - type XcmExecuteFilter: Contains<(MultiLocation, Xcm<::RuntimeCall>)>; + type XcmExecuteFilter: Contains<(Location, Xcm<::RuntimeCall>)>; /// Something to execute an XCM message. type XcmExecutor: ExecuteXcm<::RuntimeCall> + XcmAssetTransfers; /// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass. - type XcmTeleportFilter: Contains<(MultiLocation, Vec)>; + type XcmTeleportFilter: Contains<(Location, Vec)>; /// Our XCM filter which messages to be reserve-transferred using the dedicated extrinsic /// must pass. - type XcmReserveTransferFilter: Contains<(MultiLocation, Vec)>; + type XcmReserveTransferFilter: Contains<(Location, Vec)>; /// Means of measuring the weight consumed by an XCM message locally. type Weigher: WeightBounds<::RuntimeCall>; /// This chain's Universal Location. - type UniversalLocation: Get; + type UniversalLocation: Get; /// The runtime `Origin` type. type RuntimeOrigin: From + From<::RuntimeOrigin>; @@ -264,9 +258,9 @@ pub mod pallet { /// The assets which we consider a given origin is trusted if they claim to have placed a /// lock. - type TrustedLockers: ContainsPair; + type TrustedLockers: ContainsPair; - /// How to get an `AccountId` value from a `MultiLocation`, useful for handling asset locks. + /// How to get an `AccountId` value from a `Location`, useful for handling asset locks. type SovereignAccountOf: ConvertLocation; /// The maximum number of local XCM locks that a single account may have. @@ -296,15 +290,15 @@ pub mod pallet { max_weight: Weight, ) -> Result { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; - let hash = message.using_encoded(sp_io::hashing::blake2_256); + let mut hash = message.using_encoded(sp_io::hashing::blake2_256); let message = (*message).try_into().map_err(|()| Error::::BadVersion)?; let value = (origin_location, message); ensure!(T::XcmExecuteFilter::contains(&value), Error::::Filtered); let (origin_location, message) = value; - let outcome = T::XcmExecutor::execute_xcm_in_credit( + let outcome = T::XcmExecutor::prepare_and_execute( origin_location, message, - hash, + &mut hash, max_weight, max_weight, ); @@ -323,17 +317,17 @@ pub mod pallet { type WeightInfo = Self; fn send( origin: OriginFor, - dest: Box, + dest: Box, message: Box>, ) -> Result { let origin_location = T::SendXcmOrigin::ensure_origin(origin)?; let interior: Junctions = - origin_location.try_into().map_err(|_| Error::::InvalidOrigin)?; - let dest = MultiLocation::try_from(*dest).map_err(|()| Error::::BadVersion)?; + origin_location.clone().try_into().map_err(|_| Error::::InvalidOrigin)?; + let dest = Location::try_from(*dest).map_err(|()| Error::::BadVersion)?; let message: Xcm<()> = (*message).try_into().map_err(|()| Error::::BadVersion)?; - let message_id = - Self::send_xcm(interior, dest, message.clone()).map_err(Error::::from)?; + let message_id = Self::send_xcm(interior, dest.clone(), message.clone()) + .map_err(Error::::from)?; let e = Event::Sent { origin: origin_location, destination: dest, message, message_id }; Self::deposit_event(e); Ok(message_id) @@ -355,13 +349,13 @@ pub mod pallet { fn query( origin: OriginFor, timeout: BlockNumberFor, - match_querier: VersionedMultiLocation, + match_querier: VersionedLocation, ) -> Result { let responder = ::ExecuteXcmOrigin::ensure_origin(origin)?; let query_id = ::new_query( responder, timeout, - MultiLocation::try_from(match_querier) + Location::try_from(match_querier) .map_err(|_| Into::::into(Error::::BadVersion))?, ); @@ -375,16 +369,11 @@ pub mod pallet { /// Execution of an XCM message was attempted. Attempted { outcome: xcm::latest::Outcome }, /// A XCM message was sent. - Sent { - origin: MultiLocation, - destination: MultiLocation, - message: Xcm<()>, - message_id: XcmHash, - }, + Sent { origin: Location, destination: Location, message: Xcm<()>, message_id: XcmHash }, /// Query response received which does not match a registered query. This may be because a /// matching query was never registered, it may be because it is a duplicate response, or /// because the query timed out. - UnexpectedResponse { origin: MultiLocation, query_id: QueryId }, + UnexpectedResponse { origin: Location, query_id: QueryId }, /// Query response has been received and is ready for taking with `take_response`. There is /// no registered notification call. ResponseReady { query_id: QueryId, response: Response }, @@ -412,9 +401,9 @@ pub mod pallet { /// not match that expected. The query remains registered for a later, valid, response to /// be received and acted upon. InvalidResponder { - origin: MultiLocation, + origin: Location, query_id: QueryId, - expected_location: Option, + expected_location: Option, }, /// Expected query response has been received but the expected origin location placed in /// storage by this runtime previously cannot be decoded. The query remains registered. @@ -423,29 +412,29 @@ pub mod pallet { /// runtime should be readable prior to query timeout) and dangerous since the possibly /// valid response will be dropped. Manual governance intervention is probably going to be /// needed. - InvalidResponderVersion { origin: MultiLocation, query_id: QueryId }, + InvalidResponderVersion { origin: Location, query_id: QueryId }, /// Received query response has been read and removed. ResponseTaken { query_id: QueryId }, /// Some assets have been placed in an asset trap. - AssetsTrapped { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + AssetsTrapped { hash: H256, origin: Location, assets: VersionedAssets }, /// An XCM version change notification message has been attempted to be sent. /// /// The cost of sending it (borne by the chain) is included. VersionChangeNotified { - destination: MultiLocation, + destination: Location, result: XcmVersion, - cost: MultiAssets, + cost: Assets, message_id: XcmHash, }, /// The supported version of a location has been changed. This might be through an /// automatic notification or a manual intervention. - SupportedVersionChanged { location: MultiLocation, version: XcmVersion }, + SupportedVersionChanged { location: Location, version: XcmVersion }, /// A given location which had a version change subscription was dropped owing to an error /// sending the notification to it. - NotifyTargetSendFail { location: MultiLocation, query_id: QueryId, error: XcmError }, + NotifyTargetSendFail { location: Location, query_id: QueryId, error: XcmError }, /// A given location which had a version change subscription was dropped owing to an error /// migrating the location to our new XCM format. - NotifyTargetMigrationFail { location: VersionedMultiLocation, query_id: QueryId }, + NotifyTargetMigrationFail { location: VersionedLocation, query_id: QueryId }, /// Expected query response has been received but the expected querier location placed in /// storage by this runtime previously cannot be decoded. The query remains registered. /// @@ -453,48 +442,40 @@ pub mod pallet { /// runtime should be readable prior to query timeout) and dangerous since the possibly /// valid response will be dropped. Manual governance intervention is probably going to be /// needed. - InvalidQuerierVersion { origin: MultiLocation, query_id: QueryId }, + InvalidQuerierVersion { origin: Location, query_id: QueryId }, /// Expected query response has been received but the querier location of the response does /// not match the expected. The query remains registered for a later, valid, response to /// be received and acted upon. InvalidQuerier { - origin: MultiLocation, + origin: Location, query_id: QueryId, - expected_querier: MultiLocation, - maybe_actual_querier: Option, + expected_querier: Location, + maybe_actual_querier: Option, }, /// A remote has requested XCM version change notification from us and we have honored it. /// A version information message is sent to them and its cost is included. - VersionNotifyStarted { destination: MultiLocation, cost: MultiAssets, message_id: XcmHash }, + VersionNotifyStarted { destination: Location, cost: Assets, message_id: XcmHash }, /// We have requested that a remote chain send us XCM version change notifications. - VersionNotifyRequested { - destination: MultiLocation, - cost: MultiAssets, - message_id: XcmHash, - }, + VersionNotifyRequested { destination: Location, cost: Assets, message_id: XcmHash }, /// We have requested that a remote chain stops sending us XCM version change /// notifications. - VersionNotifyUnrequested { - destination: MultiLocation, - cost: MultiAssets, - message_id: XcmHash, - }, + VersionNotifyUnrequested { destination: Location, cost: Assets, message_id: XcmHash }, /// Fees were paid from a location for an operation (often for using `SendXcm`). - FeesPaid { paying: MultiLocation, fees: MultiAssets }, + FeesPaid { paying: Location, fees: Assets }, /// Some assets have been claimed from an asset trap - AssetsClaimed { hash: H256, origin: MultiLocation, assets: VersionedMultiAssets }, + AssetsClaimed { hash: H256, origin: Location, assets: VersionedAssets }, } #[pallet::origin] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum Origin { /// It comes from somewhere in the XCM space wanting to transact. - Xcm(MultiLocation), + Xcm(Location), /// It comes as an expected response from an XCM location. - Response(MultiLocation), + Response(Location), } - impl From for Origin { - fn from(location: MultiLocation) -> Origin { + impl From for Origin { + fn from(location: Location) -> Origin { Origin::Xcm(location) } } @@ -511,7 +492,7 @@ pub mod pallet { Filtered, /// The message's weight could not be determined. UnweighableMessage, - /// The destination `MultiLocation` provided cannot be inverted. + /// The destination `Location` provided cannot be inverted. DestinationNotInvertible, /// The assets to be sent are empty. Empty, @@ -582,25 +563,25 @@ pub mod pallet { Pending { /// The `QueryResponse` XCM must have this origin to be considered a reply for this /// query. - responder: VersionedMultiLocation, + responder: VersionedLocation, /// The `QueryResponse` XCM must have this value as the `querier` field to be /// considered a reply for this query. If `None` then the querier is ignored. - maybe_match_querier: Option, + maybe_match_querier: Option, maybe_notify: Option<(u8, u8)>, timeout: BlockNumber, }, /// The query is for an ongoing version notification subscription. - VersionNotifier { origin: VersionedMultiLocation, is_active: bool }, + VersionNotifier { origin: VersionedLocation, is_active: bool }, /// A response has been received. Ready { response: VersionedResponse, at: BlockNumber }, } #[derive(Copy, Clone)] - pub(crate) struct LatestVersionedMultiLocation<'a>(pub(crate) &'a MultiLocation); - impl<'a> EncodeLike for LatestVersionedMultiLocation<'a> {} - impl<'a> Encode for LatestVersionedMultiLocation<'a> { + pub(crate) struct LatestVersionedLocation<'a>(pub(crate) &'a Location); + impl<'a> EncodeLike for LatestVersionedLocation<'a> {} + impl<'a> Encode for LatestVersionedLocation<'a> { fn encode(&self) -> Vec { - let mut r = VersionedMultiLocation::from(MultiLocation::default()).encode(); + let mut r = VersionedLocation::from(Location::default()).encode(); r.truncate(1); self.0.using_encoded(|d| r.extend_from_slice(d)); r @@ -633,7 +614,7 @@ pub mod pallet { /// The existing asset traps. /// - /// Key is the blake2 256 hash of (origin, versioned `MultiAssets`) pair. Value is the number of + /// Key is the blake2 256 hash of (origin, versioned `Assets`) pair. Value is the number of /// times this pair has been trapped (usually just 1 if it exists at all). #[pallet::storage] #[pallet::getter(fn asset_trap)] @@ -652,7 +633,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, XcmVersion, OptionQuery, >; @@ -664,7 +645,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, QueryId, OptionQuery, >; @@ -677,7 +658,7 @@ pub mod pallet { Twox64Concat, XcmVersion, Blake2_128Concat, - VersionedMultiLocation, + VersionedLocation, (QueryId, Weight, XcmVersion), OptionQuery, >; @@ -696,7 +677,7 @@ pub mod pallet { #[pallet::whitelist_storage] pub(super) type VersionDiscoveryQueue = StorageValue< _, - BoundedVec<(VersionedMultiLocation, u32), VersionDiscoveryQueueSize>, + BoundedVec<(VersionedLocation, u32), VersionDiscoveryQueueSize>, ValueQuery, >; @@ -711,9 +692,9 @@ pub mod pallet { /// Total amount of the asset held by the remote lock. pub amount: u128, /// The owner of the locked asset. - pub owner: VersionedMultiLocation, + pub owner: VersionedLocation, /// The location which holds the original lock. - pub locker: VersionedMultiLocation, + pub locker: VersionedLocation, /// Local consumers of the remote lock with a consumer identifier and the amount /// of fungible asset every consumer holds. /// Every consumer can hold up to total amount of the remote lock. @@ -747,7 +728,7 @@ pub mod pallet { _, Blake2_128Concat, T::AccountId, - BoundedVec<(BalanceOf, VersionedMultiLocation), T::MaxLockers>, + BoundedVec<(BalanceOf, VersionedLocation), T::MaxLockers>, OptionQuery, >; @@ -795,7 +776,7 @@ pub mod pallet { weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); q.sort_by_key(|i| i.1); while let Some((versioned_dest, _)) = q.pop() { - if let Ok(dest) = MultiLocation::try_from(versioned_dest) { + if let Ok(dest) = Location::try_from(versioned_dest) { if Self::request_version_notify(dest).is_ok() { // TODO: correct weights. weight_used.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); @@ -819,12 +800,12 @@ pub mod pallet { #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] enum QueryStatusV0 { Pending { - responder: VersionedMultiLocation, + responder: VersionedLocation, maybe_notify: Option<(u8, u8)>, timeout: BlockNumber, }, VersionNotifier { - origin: VersionedMultiLocation, + origin: VersionedLocation, is_active: bool, }, Ready { @@ -840,7 +821,7 @@ pub mod pallet { responder, maybe_notify, timeout, - maybe_match_querier: Some(MultiLocation::here().into()), + maybe_match_querier: Some(Location::here().into()), }, VersionNotifier { origin, is_active } => QueryStatus::VersionNotifier { origin, is_active }, @@ -889,7 +870,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::send())] pub fn send( origin: OriginFor, - dest: Box, + dest: Box, message: Box>, ) -> DispatchResult { >::send(origin, dest, message)?; @@ -905,9 +886,9 @@ pub mod pallet { /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -916,8 +897,8 @@ pub mod pallet { /// fees. #[pallet::call_index(1)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -934,9 +915,9 @@ pub mod pallet { })] pub fn teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, ) -> DispatchResult { Self::do_teleport_assets(origin, dest, beneficiary, assets, fee_asset_item, Unlimited) @@ -963,9 +944,9 @@ pub mod pallet { /// with all fees taken as needed from the asset. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -974,8 +955,8 @@ pub mod pallet { /// fees. #[pallet::call_index(2)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -992,9 +973,9 @@ pub mod pallet { })] pub fn reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, ) -> DispatchResult { Self::do_reserve_transfer_assets( @@ -1045,16 +1026,12 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_xcm_version())] pub fn force_xcm_version( origin: OriginFor, - location: Box, + location: Box, version: XcmVersion, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; let location = *location; - SupportedVersion::::insert( - XCM_VERSION, - LatestVersionedMultiLocation(&location), - version, - ); + SupportedVersion::::insert(XCM_VERSION, LatestVersionedLocation(&location), version); Self::deposit_event(Event::SupportedVersionChanged { location, version }); Ok(()) } @@ -1083,10 +1060,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_subscribe_version_notify())] pub fn force_subscribe_version_notify( origin: OriginFor, - location: Box, + location: Box, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|()| Error::::BadLocation)?; Self::request_version_notify(location).map_err(|e| { match e { @@ -1107,10 +1084,10 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::force_unsubscribe_version_notify())] pub fn force_unsubscribe_version_notify( origin: OriginFor, - location: Box, + location: Box, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; - let location: MultiLocation = + let location: Location = (*location).try_into().map_err(|()| Error::::BadLocation)?; Self::unrequest_version_notify(location).map_err(|e| { match e { @@ -1141,9 +1118,9 @@ pub mod pallet { /// at risk. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -1153,8 +1130,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(8)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1171,9 +1148,9 @@ pub mod pallet { })] pub fn limited_reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { @@ -1195,9 +1172,9 @@ pub mod pallet { /// at risk. /// /// - `origin`: Must be capable of withdrawing the `assets` and executing XCM. - /// - `dest`: Destination context for the assets. Will typically be `X2(Parent, - /// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send - /// from relay to parachain. + /// - `dest`: Destination context for the assets. Will typically be `[Parent, + /// Parachain(..)]` to send from parachain to parachain, or `[Parachain(..)]` to send from + /// relay to parachain. /// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will /// generally be an `AccountId32` value. /// - `assets`: The assets to be withdrawn. This should include the assets used to pay the @@ -1207,8 +1184,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(9)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1225,9 +1202,9 @@ pub mod pallet { })] pub fn limited_teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { @@ -1288,8 +1265,8 @@ pub mod pallet { /// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase. #[pallet::call_index(11)] #[pallet::weight({ - let maybe_assets: Result = (*assets.clone()).try_into(); - let maybe_dest: Result = (*dest.clone()).try_into(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_dest: Result = (*dest.clone()).try_into(); match (maybe_assets, maybe_dest) { (Ok(assets), Ok(dest)) => { use sp_std::vec; @@ -1309,17 +1286,17 @@ pub mod pallet { })] pub fn transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::transfer_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}, weight_limit {:?}", @@ -1353,17 +1330,25 @@ pub mod pallet { // added to assets transfers XCM programs let fees = assets.remove(fee_asset_item); let (local_xcm, remote_xcm) = match fees_transfer_type { - TransferType::LocalReserve => - Self::local_reserve_fees_instructions(origin, dest, fees, weight_limit)?, + TransferType::LocalReserve => Self::local_reserve_fees_instructions( + origin.clone(), + dest.clone(), + fees, + weight_limit, + )?, TransferType::DestinationReserve => Self::destination_reserve_fees_instructions( - origin, - dest, + origin.clone(), + dest.clone(), fees, weight_limit, )?, - TransferType::Teleport => - Self::teleport_fees_instructions(origin, dest, fees, weight_limit)?, + TransferType::Teleport => Self::teleport_fees_instructions( + origin.clone(), + dest.clone(), + fees, + weight_limit, + )?, TransferType::RemoteReserve(_) => return Err(Error::::InvalidAssetUnsupportedReserve.into()), }; @@ -1390,7 +1375,7 @@ const MAX_ASSETS_FOR_TRANSFER: usize = 2; #[derive(Clone, PartialEq)] enum FeesHandling { /// `fees` asset can be batch-transferred with rest of assets using same XCM instructions. - Batched { fees: MultiAsset }, + Batched { fees: Asset }, /// fees cannot be batched, they are handled separately using XCM programs here. Separate { local_xcm: Xcm<::RuntimeCall>, remote_xcm: Xcm<()> }, } @@ -1416,9 +1401,9 @@ impl QueryHandler for Pallet { /// Attempt to create a new query ID and register it as a query that is yet to respond. fn new_query( - responder: impl Into, + responder: impl Into, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> Self::QueryId { Self::do_new_query(responder, None, timeout, match_querier) } @@ -1427,7 +1412,7 @@ impl QueryHandler for Pallet { /// value. fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> Result { let responder = responder.into(); @@ -1474,9 +1459,9 @@ impl Pallet { /// /// Validate `assets` to all have same `TransferType`. fn find_fee_and_assets_transfer_types( - assets: &[MultiAsset], + assets: &[Asset], fee_asset_item: usize, - dest: &MultiLocation, + dest: &Location, ) -> Result<(TransferType, TransferType), Error> { let mut fees_transfer_type = None; let mut assets_transfer_type = None; @@ -1502,7 +1487,7 @@ impl Pallet { } // single asset also marked as fee item if assets.len() == 1 { - assets_transfer_type = fees_transfer_type + assets_transfer_type = fees_transfer_type.clone() } Ok(( fees_transfer_type.ok_or(Error::::Empty)?, @@ -1512,17 +1497,17 @@ impl Pallet { fn do_reserve_transfer_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::do_reserve_transfer_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}", @@ -1558,17 +1543,17 @@ impl Pallet { fn do_teleport_assets( origin: OriginFor, - dest: Box, - beneficiary: Box, - assets: Box, + dest: Box, + beneficiary: Box, + assets: Box, fee_asset_item: u32, weight_limit: WeightLimit, ) -> DispatchResult { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; let dest = (*dest).try_into().map_err(|()| Error::::BadVersion)?; - let beneficiary: MultiLocation = + let beneficiary: Location = (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; - let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; log::debug!( target: "xcm::pallet_xcm::do_teleport_assets", "origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}, weight_limit {:?}", @@ -1598,10 +1583,10 @@ impl Pallet { } fn build_and_execute_xcm_transfer_type( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, transfer_type: TransferType, fees: FeesHandling, weight_limit: WeightLimit, @@ -1615,8 +1600,8 @@ impl Pallet { let (mut local_xcm, remote_xcm) = match transfer_type { TransferType::LocalReserve => { let (local, remote) = Self::local_reserve_transfer_programs( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1626,8 +1611,8 @@ impl Pallet { }, TransferType::DestinationReserve => { let (local, remote) = Self::destination_reserve_transfer_programs( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1641,9 +1626,9 @@ impl Pallet { _ => return Err(Error::::InvalidAssetUnsupportedReserve.into()), }; let local = Self::remote_reserve_transfer_program( - origin, + origin.clone(), reserve, - dest, + dest.clone(), beneficiary, assets, fees, @@ -1653,8 +1638,8 @@ impl Pallet { }, TransferType::Teleport => { let (local, remote) = Self::teleport_assets_program( - origin, - dest, + origin.clone(), + dest.clone(), beneficiary, assets, fees, @@ -1665,9 +1650,14 @@ impl Pallet { }; let weight = T::Weigher::weight(&mut local_xcm).map_err(|()| Error::::UnweighableMessage)?; - let hash = local_xcm.using_encoded(sp_io::hashing::blake2_256); - let outcome = - T::XcmExecutor::execute_xcm_in_credit(origin, local_xcm, hash, weight, weight); + let mut hash = local_xcm.using_encoded(sp_io::hashing::blake2_256); + let outcome = T::XcmExecutor::prepare_and_execute( + origin.clone(), + local_xcm, + &mut hash, + weight, + weight, + ); Self::deposit_event(Event::Attempted { outcome: outcome.clone() }); outcome.ensure_complete().map_err(|error| { log::error!( @@ -1678,10 +1668,10 @@ impl Pallet { })?; if let Some(remote_xcm) = remote_xcm { - let (ticket, price) = validate_send::(dest, remote_xcm.clone()) + let (ticket, price) = validate_send::(dest.clone(), remote_xcm.clone()) .map_err(Error::::from)?; if origin != Here.into_location() { - Self::charge_fees(origin, price).map_err(|error| { + Self::charge_fees(origin.clone(), price).map_err(|error| { log::error!( target: "xcm::pallet_xcm::build_and_execute_xcm_transfer_type", "Unable to charge fee with error {:?}", error @@ -1698,7 +1688,7 @@ impl Pallet { } fn add_fees_to_xcm( - dest: MultiLocation, + dest: Location, fees: FeesHandling, weight_limit: WeightLimit, local: &mut Xcm<::RuntimeCall>, @@ -1710,7 +1700,7 @@ impl Pallet { // no custom fees instructions, they are batched together with `assets` transfer; // BuyExecution happens after receiving all `assets` let reanchored_fees = - fees.reanchored(&dest, context).map_err(|_| Error::::CannotReanchor)?; + fees.reanchored(&dest, &context).map_err(|_| Error::::CannotReanchor)?; // buy execution using `fees` batched together with above `reanchored_assets` remote.inner_mut().push(BuyExecution { fees: reanchored_fees, weight_limit }); }, @@ -1728,9 +1718,9 @@ impl Pallet { } fn local_reserve_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1739,7 +1729,7 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; let local_execute_xcm = Xcm(vec![ @@ -1756,10 +1746,10 @@ impl Pallet { } fn local_reserve_transfer_programs( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1770,17 +1760,17 @@ impl Pallet { // max assets is `assets` (+ potentially separately handled fee) let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let context = T::UniversalLocation::get(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XCM instructions to be executed on local chain let mut local_execute_xcm = Xcm(vec![ // locally move `assets` to `dest`s local sovereign account - TransferAsset { assets, beneficiary: dest }, + TransferAsset { assets, beneficiary: dest.clone() }, ]); // XCM instructions to be executed on destination chain let mut xcm_on_dest = Xcm(vec![ @@ -1800,9 +1790,9 @@ impl Pallet { } fn destination_reserve_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1811,9 +1801,9 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; - let fees: MultiAssets = fees.into(); + let fees: Assets = fees.into(); let local_execute_xcm = Xcm(vec![ // withdraw reserve-based fees (derivatives) @@ -1831,10 +1821,10 @@ impl Pallet { } fn destination_reserve_transfer_programs( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1845,11 +1835,11 @@ impl Pallet { // max assets is `assets` (+ potentially separately handled fee) let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let context = T::UniversalLocation::get(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XCM instructions to be executed on local chain @@ -1878,12 +1868,12 @@ impl Pallet { // function assumes fees and assets have the same remote reserve fn remote_reserve_transfer_program( - origin: MultiLocation, - reserve: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, - fees: MultiAsset, + origin: Location, + reserve: Location, + dest: Location, + beneficiary: Location, + assets: Vec, + fees: Asset, weight_limit: WeightLimit, ) -> Result::RuntimeCall>, Error> { let value = (origin, assets); @@ -1897,13 +1887,14 @@ impl Pallet { let (fees_half_1, fees_half_2) = Self::halve_fees(fees)?; // identifies fee item as seen by `reserve` - to be used at reserve chain let reserve_fees = fees_half_1 - .reanchored(&reserve, context) + .reanchored(&reserve, &context) .map_err(|_| Error::::CannotReanchor)?; // identifies fee item as seen by `dest` - to be used at destination chain - let dest_fees = - fees_half_2.reanchored(&dest, context).map_err(|_| Error::::CannotReanchor)?; + let dest_fees = fees_half_2 + .reanchored(&dest, &context) + .map_err(|_| Error::::CannotReanchor)?; // identifies `dest` as seen by `reserve` - let dest = dest.reanchored(&reserve, context).map_err(|_| Error::::CannotReanchor)?; + let dest = dest.reanchored(&reserve, &context).map_err(|_| Error::::CannotReanchor)?; // xcm to be executed at dest let xcm_on_dest = Xcm(vec![ BuyExecution { fees: dest_fees, weight_limit: weight_limit.clone() }, @@ -1925,9 +1916,9 @@ impl Pallet { } fn teleport_fees_instructions( - origin: MultiLocation, - dest: MultiLocation, - fees: MultiAsset, + origin: Location, + dest: Location, + fees: Asset, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { let value = (origin, vec![fees.clone()]); @@ -1936,7 +1927,7 @@ impl Pallet { let context = T::UniversalLocation::get(); let reanchored_fees = fees .clone() - .reanchored(&dest, context) + .reanchored(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XcmContext irrelevant in teleports checks @@ -1960,7 +1951,7 @@ impl Pallet { &dummy_context, ); - let fees: MultiAssets = fees.into(); + let fees: Assets = fees.into(); let local_execute_xcm = Xcm(vec![ // withdraw fees WithdrawAsset(fees.clone()), @@ -1977,10 +1968,10 @@ impl Pallet { } fn teleport_assets_program( - origin: MultiLocation, - dest: MultiLocation, - beneficiary: MultiLocation, - assets: Vec, + origin: Location, + dest: Location, + beneficiary: Location, + assets: Vec, fees: FeesHandling, weight_limit: WeightLimit, ) -> Result<(Xcm<::RuntimeCall>, Xcm<()>), Error> { @@ -1992,10 +1983,10 @@ impl Pallet { let max_assets = assets.len() as u32 + if matches!(&fees, FeesHandling::Batched { .. }) { 0 } else { 1 }; let context = T::UniversalLocation::get(); - let assets: MultiAssets = assets.into(); + let assets: Assets = assets.into(); let mut reanchored_assets = assets.clone(); reanchored_assets - .reanchor(&dest, context) + .reanchor(&dest, &context) .map_err(|_| Error::::CannotReanchor)?; // XcmContext irrelevant in teleports checks @@ -2048,14 +2039,14 @@ impl Pallet { } /// Halve `fees` fungible amount. - pub(crate) fn halve_fees(fees: MultiAsset) -> Result<(MultiAsset, MultiAsset), Error> { + pub(crate) fn halve_fees(fees: Asset) -> Result<(Asset, Asset), Error> { match fees.fun { Fungible(amount) => { let fee1 = amount.saturating_div(2); let fee2 = amount.saturating_sub(fee1); ensure!(fee1 > 0, Error::::FeesNotMet); ensure!(fee2 > 0, Error::::FeesNotMet); - Ok((MultiAsset::from((fees.id, fee1)), MultiAsset::from((fees.id, fee2)))) + Ok((Asset::from((fees.id.clone(), fee1)), Asset::from((fees.id.clone(), fee2)))) }, NonFungible(_) => Err(Error::::FeesNotMet), } @@ -2119,7 +2110,7 @@ impl Pallet { }; while let Some((key, value)) = iter.next() { let (query_id, max_weight, target_xcm_version) = value; - let new_key: MultiLocation = match key.clone().try_into() { + let new_key: Location = match key.clone().try_into() { Ok(k) if target_xcm_version != xcm_version => k, _ => { // We don't early return here since we need to be certain that we @@ -2131,7 +2122,7 @@ impl Pallet { let response = Response::Version(xcm_version); let message = Xcm(vec![QueryResponse { query_id, response, max_weight, querier: None }]); - let event = match send_xcm::(new_key, message) { + let event = match send_xcm::(new_key.clone(), message) { Ok((message_id, cost)) => { let value = (query_id, max_weight, xcm_version); VersionNotifyTargets::::insert(XCM_VERSION, key, value); @@ -2160,7 +2151,7 @@ impl Pallet { for v in 0..XCM_VERSION { for (old_key, value) in VersionNotifyTargets::::drain_prefix(v) { let (query_id, max_weight, target_xcm_version) = value; - let new_key = match MultiLocation::try_from(old_key.clone()) { + let new_key = match Location::try_from(old_key.clone()) { Ok(k) => k, Err(()) => { Self::deposit_event(Event::NotifyTargetMigrationFail { @@ -2175,7 +2166,7 @@ impl Pallet { }, }; - let versioned_key = LatestVersionedMultiLocation(&new_key); + let versioned_key = LatestVersionedLocation(&new_key); if target_xcm_version == xcm_version { VersionNotifyTargets::::insert(XCM_VERSION, versioned_key, value); weight_used.saturating_accrue(vnt_migrate_weight); @@ -2188,7 +2179,7 @@ impl Pallet { max_weight, querier: None, }]); - let event = match send_xcm::(new_key, message) { + let event = match send_xcm::(new_key.clone(), message) { Ok((message_id, cost)) => { VersionNotifyTargets::::insert( XCM_VERSION, @@ -2221,9 +2212,9 @@ impl Pallet { } /// Request that `dest` informs us of its version. - pub fn request_version_notify(dest: impl Into) -> XcmResult { + pub fn request_version_notify(dest: impl Into) -> XcmResult { let dest = dest.into(); - let versioned_dest = VersionedMultiLocation::from(dest); + let versioned_dest = VersionedLocation::from(dest.clone()); let already = VersionNotifiers::::contains_key(XCM_VERSION, &versioned_dest); ensure!(!already, XcmError::InvalidLocation); let query_id = QueryCounter::::mutate(|q| { @@ -2233,7 +2224,7 @@ impl Pallet { }); // TODO #3735: Correct weight. let instruction = SubscribeVersion { query_id, max_response_weight: Weight::zero() }; - let (message_id, cost) = send_xcm::(dest, Xcm(vec![instruction]))?; + let (message_id, cost) = send_xcm::(dest.clone(), Xcm(vec![instruction]))?; Self::deposit_event(Event::VersionNotifyRequested { destination: dest, cost, message_id }); VersionNotifiers::::insert(XCM_VERSION, &versioned_dest, query_id); let query_status = @@ -2243,12 +2234,13 @@ impl Pallet { } /// Request that `dest` ceases informing us of its version. - pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { + pub fn unrequest_version_notify(dest: impl Into) -> XcmResult { let dest = dest.into(); - let versioned_dest = LatestVersionedMultiLocation(&dest); + let versioned_dest = LatestVersionedLocation(&dest); let query_id = VersionNotifiers::::take(XCM_VERSION, versioned_dest) .ok_or(XcmError::InvalidLocation)?; - let (message_id, cost) = send_xcm::(dest, Xcm(vec![UnsubscribeVersion]))?; + let (message_id, cost) = + send_xcm::(dest.clone(), Xcm(vec![UnsubscribeVersion]))?; Self::deposit_event(Event::VersionNotifyUnrequested { destination: dest, cost, @@ -2263,13 +2255,13 @@ impl Pallet { /// are not charged (and instead borne by the chain). pub fn send_xcm( interior: impl Into, - dest: impl Into, + dest: impl Into, mut message: Xcm<()>, ) -> Result { let interior = interior.into(); let dest = dest.into(); let maybe_fee_payer = if interior != Junctions::Here { - message.0.insert(0, DescendOrigin(interior)); + message.0.insert(0, DescendOrigin(interior.clone())); Some(interior.into()) } else { None @@ -2289,10 +2281,10 @@ impl Pallet { /// Create a new expectation of a query response with the querier being here. fn do_new_query( - responder: impl Into, + responder: impl Into, maybe_notify: Option<(u8, u8)>, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> u64 { QueryCounter::::mutate(|q| { let r = *q; @@ -2334,7 +2326,7 @@ impl Pallet { /// may be put in the overweight queue and need to be manually executed. pub fn report_outcome_notify( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, notify: impl Into<::RuntimeCall>, timeout: BlockNumberFor, ) -> Result<(), XcmError> { @@ -2354,10 +2346,10 @@ impl Pallet { /// Attempt to create a new query ID and register it as a query that is yet to respond, and /// which will call a dispatchable when a response happens. pub fn new_notify_query( - responder: impl Into, + responder: impl Into, notify: impl Into<::RuntimeCall>, timeout: BlockNumberFor, - match_querier: impl Into, + match_querier: impl Into, ) -> u64 { let notify = notify.into().using_encoded(|mut bytes| Decode::decode(&mut bytes)).expect( "decode input is output of Call encode; Call guaranteed to have two enums; qed", @@ -2367,13 +2359,13 @@ impl Pallet { /// Note that a particular destination to whom we would like to send a message is unknown /// and queue it for version discovery. - fn note_unknown_version(dest: &MultiLocation) { + fn note_unknown_version(dest: &Location) { log::trace!( target: "xcm::pallet_xcm::note_unknown_version", "XCM version is unknown for destination: {:?}", dest, ); - let versioned_dest = VersionedMultiLocation::from(*dest); + let versioned_dest = VersionedLocation::from(dest.clone()); VersionDiscoveryQueue::::mutate(|q| { if let Some(index) = q.iter().position(|i| &i.0 == &versioned_dest) { // exists - just bump the count. @@ -2389,8 +2381,8 @@ impl Pallet { /// Fails if: /// - the `assets` are not known on this chain; /// - the `assets` cannot be withdrawn with that location as the Origin. - fn charge_fees(location: MultiLocation, assets: MultiAssets) -> DispatchResult { - T::XcmExecutor::charge_fees(location, assets.clone()) + fn charge_fees(location: Location, assets: Assets) -> DispatchResult { + T::XcmExecutor::charge_fees(location.clone(), assets.clone()) .map_err(|_| Error::::FeesNotMet)?; Self::deposit_event(Event::FeesPaid { paying: location, fees: assets }); Ok(()) @@ -2400,7 +2392,7 @@ impl Pallet { pub struct LockTicket { sovereign_account: T::AccountId, amount: BalanceOf, - unlocker: MultiLocation, + unlocker: Location, item_index: Option, } @@ -2434,7 +2426,7 @@ impl xcm_executor::traits::Enact for LockTicket { pub struct UnlockTicket { sovereign_account: T::AccountId, amount: BalanceOf, - unlocker: MultiLocation, + unlocker: Location, } impl xcm_executor::traits::Enact for UnlockTicket { @@ -2471,8 +2463,8 @@ impl xcm_executor::traits::Enact for UnlockTicket { pub struct ReduceTicket { key: (u32, T::AccountId, VersionedAssetId), amount: u128, - locker: VersionedMultiLocation, - owner: VersionedMultiLocation, + locker: VersionedLocation, + owner: VersionedLocation, } impl xcm_executor::traits::Enact for ReduceTicket { @@ -2498,9 +2490,9 @@ impl xcm_executor::traits::AssetLock for Pallet { type ReduceTicket = ReduceTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result, xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; @@ -2513,9 +2505,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result, xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?; @@ -2529,9 +2521,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - mut owner: MultiLocation, + locker: Location, + asset: Asset, + mut owner: Location, ) -> Result<(), xcm_executor::traits::LockError> { use xcm_executor::traits::LockError::*; ensure!(T::TrustedLockers::contains(&locker, &asset), NotTrusted); @@ -2558,9 +2550,9 @@ impl xcm_executor::traits::AssetLock for Pallet { } fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - mut owner: MultiLocation, + locker: Location, + asset: Asset, + mut owner: Location, ) -> Result { use xcm_executor::traits::LockError::*; let amount = match asset.fun { @@ -2588,7 +2580,7 @@ impl xcm_executor::traits::AssetLock for Pallet { impl WrapVersion for Pallet { fn wrap_version( - dest: &MultiLocation, + dest: &Location, xcm: impl Into>, ) -> Result, ()> { Self::get_version_for(dest) @@ -2609,8 +2601,8 @@ impl WrapVersion for Pallet { } impl GetVersion for Pallet { - fn get_version_for(dest: &MultiLocation) -> Option { - SupportedVersion::::get(XCM_VERSION, LatestVersionedMultiLocation(dest)) + fn get_version_for(dest: &Location) -> Option { + SupportedVersion::::get(XCM_VERSION, LatestVersionedLocation(dest)) } } @@ -2624,21 +2616,21 @@ impl VersionChangeNotifier for Pallet { /// If the `location` has an ongoing notification and when this function is called, then an /// error should be returned. fn start( - dest: &MultiLocation, + dest: &Location, query_id: QueryId, max_weight: Weight, _context: &XcmContext, ) -> XcmResult { - let versioned_dest = LatestVersionedMultiLocation(dest); + let versioned_dest = LatestVersionedLocation(dest); let already = VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest); ensure!(!already, XcmError::InvalidLocation); let xcm_version = T::AdvertisedXcmVersion::get(); let response = Response::Version(xcm_version); let instruction = QueryResponse { query_id, response, max_weight, querier: None }; - let (message_id, cost) = send_xcm::(*dest, Xcm(vec![instruction]))?; + let (message_id, cost) = send_xcm::(dest.clone(), Xcm(vec![instruction]))?; Self::deposit_event(Event::::VersionNotifyStarted { - destination: *dest, + destination: dest.clone(), cost, message_id, }); @@ -2650,27 +2642,31 @@ impl VersionChangeNotifier for Pallet { /// Stop notifying `location` should the XCM change. This is a no-op if there was never a /// subscription. - fn stop(dest: &MultiLocation, _context: &XcmContext) -> XcmResult { - VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedMultiLocation(dest)); + fn stop(dest: &Location, _context: &XcmContext) -> XcmResult { + VersionNotifyTargets::::remove(XCM_VERSION, LatestVersionedLocation(dest)); Ok(()) } /// Return true if a location is subscribed to XCM version changes. - fn is_subscribed(dest: &MultiLocation) -> bool { - let versioned_dest = LatestVersionedMultiLocation(dest); + fn is_subscribed(dest: &Location) -> bool { + let versioned_dest = LatestVersionedLocation(dest); VersionNotifyTargets::::contains_key(XCM_VERSION, versioned_dest) } } impl DropAssets for Pallet { - fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { + fn drop_assets(origin: &Location, assets: AssetsInHolding, _context: &XcmContext) -> Weight { if assets.is_empty() { return Weight::zero() } - let versioned = VersionedMultiAssets::from(MultiAssets::from(assets)); + let versioned = VersionedAssets::from(Assets::from(assets)); let hash = BlakeTwo256::hash_of(&(&origin, &versioned)); AssetTraps::::mutate(hash, |n| *n += 1); - Self::deposit_event(Event::AssetsTrapped { hash, origin: *origin, assets: versioned }); + Self::deposit_event(Event::AssetsTrapped { + hash, + origin: origin.clone(), + assets: versioned, + }); // TODO #3735: Put the real weight in there. Weight::zero() } @@ -2678,71 +2674,75 @@ impl DropAssets for Pallet { impl ClaimAssets for Pallet { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - assets: &MultiAssets, + origin: &Location, + ticket: &Location, + assets: &Assets, _context: &XcmContext, ) -> bool { - let mut versioned = VersionedMultiAssets::from(assets.clone()); - match (ticket.parents, &ticket.interior) { - (0, X1(GeneralIndex(i))) => + let mut versioned = VersionedAssets::from(assets.clone()); + match ticket.unpack() { + (0, [GeneralIndex(i)]) => versioned = match versioned.into_version(*i as u32) { Ok(v) => v, Err(()) => return false, }, - (0, Here) => (), + (0, []) => (), _ => return false, }; - let hash = BlakeTwo256::hash_of(&(origin, versioned.clone())); + let hash = BlakeTwo256::hash_of(&(origin.clone(), versioned.clone())); match AssetTraps::::get(hash) { 0 => return false, 1 => AssetTraps::::remove(hash), n => AssetTraps::::insert(hash, n - 1), } - Self::deposit_event(Event::AssetsClaimed { hash, origin: *origin, assets: versioned }); + Self::deposit_event(Event::AssetsClaimed { + hash, + origin: origin.clone(), + assets: versioned, + }); return true } } impl OnResponse for Pallet { fn expecting_response( - origin: &MultiLocation, + origin: &Location, query_id: QueryId, - querier: Option<&MultiLocation>, + querier: Option<&Location>, ) -> bool { match Queries::::get(query_id) { Some(QueryStatus::Pending { responder, maybe_match_querier, .. }) => - MultiLocation::try_from(responder).map_or(false, |r| origin == &r) && + Location::try_from(responder).map_or(false, |r| origin == &r) && maybe_match_querier.map_or(true, |match_querier| { - MultiLocation::try_from(match_querier).map_or(false, |match_querier| { + Location::try_from(match_querier).map_or(false, |match_querier| { querier.map_or(false, |q| q == &match_querier) }) }), Some(QueryStatus::VersionNotifier { origin: r, .. }) => - MultiLocation::try_from(r).map_or(false, |r| origin == &r), + Location::try_from(r).map_or(false, |r| origin == &r), _ => false, } } fn on_response( - origin: &MultiLocation, + origin: &Location, query_id: QueryId, - querier: Option<&MultiLocation>, + querier: Option<&Location>, response: Response, max_weight: Weight, _context: &XcmContext, ) -> Weight { - let origin = *origin; + let origin = origin.clone(); match (response, Queries::::get(query_id)) { ( Response::Version(v), Some(QueryStatus::VersionNotifier { origin: expected_origin, is_active }), ) => { - let origin: MultiLocation = match expected_origin.try_into() { + let origin: Location = match expected_origin.try_into() { Ok(o) if o == origin => o, Ok(o) => { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: Some(o), }); @@ -2750,7 +2750,7 @@ impl OnResponse for Pallet { }, _ => { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: None, }); @@ -2762,15 +2762,14 @@ impl OnResponse for Pallet { if !is_active { Queries::::insert( query_id, - QueryStatus::VersionNotifier { origin: origin.into(), is_active: true }, + QueryStatus::VersionNotifier { + origin: origin.clone().into(), + is_active: true, + }, ); } // We're being notified of a version change. - SupportedVersion::::insert( - XCM_VERSION, - LatestVersionedMultiLocation(&origin), - v, - ); + SupportedVersion::::insert(XCM_VERSION, LatestVersionedLocation(&origin), v); Self::deposit_event(Event::SupportedVersionChanged { location: origin, version: v, @@ -2782,16 +2781,19 @@ impl OnResponse for Pallet { Some(QueryStatus::Pending { responder, maybe_notify, maybe_match_querier, .. }), ) => { if let Some(match_querier) = maybe_match_querier { - let match_querier = match MultiLocation::try_from(match_querier) { + let match_querier = match Location::try_from(match_querier) { Ok(mq) => mq, Err(_) => { - Self::deposit_event(Event::InvalidQuerierVersion { origin, query_id }); + Self::deposit_event(Event::InvalidQuerierVersion { + origin: origin.clone(), + query_id, + }); return Weight::zero() }, }; if querier.map_or(true, |q| q != &match_querier) { Self::deposit_event(Event::InvalidQuerier { - origin, + origin: origin.clone(), query_id, expected_querier: match_querier, maybe_actual_querier: querier.cloned(), @@ -2799,16 +2801,19 @@ impl OnResponse for Pallet { return Weight::zero() } } - let responder = match MultiLocation::try_from(responder) { + let responder = match Location::try_from(responder) { Ok(r) => r, Err(_) => { - Self::deposit_event(Event::InvalidResponderVersion { origin, query_id }); + Self::deposit_event(Event::InvalidResponderVersion { + origin: origin.clone(), + query_id, + }); return Weight::zero() }, }; if origin != responder { Self::deposit_event(Event::InvalidResponder { - origin, + origin: origin.clone(), query_id, expected_location: Some(responder), }); @@ -2836,7 +2841,7 @@ impl OnResponse for Pallet { Self::deposit_event(e); return Weight::zero() } - let dispatch_origin = Origin::Response(origin).into(); + let dispatch_origin = Origin::Response(origin.clone()).into(); match call.dispatch(dispatch_origin) { Ok(post_info) => { let e = Event::Notified { query_id, pallet_index, call_index }; @@ -2874,7 +2879,7 @@ impl OnResponse for Pallet { } }, _ => { - let e = Event::UnexpectedResponse { origin, query_id }; + let e = Event::UnexpectedResponse { origin: origin.clone(), query_id }; Self::deposit_event(e); Weight::zero() }, @@ -2884,7 +2889,7 @@ impl OnResponse for Pallet { impl CheckSuspension for Pallet { fn is_suspended( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -2896,7 +2901,7 @@ impl CheckSuspension for Pallet { /// Ensure that the origin `o` represents an XCM (`Transact`) origin. /// /// Returns `Ok` with the location of the XCM sender or an `Err` otherwise. -pub fn ensure_xcm(o: OuterOrigin) -> Result +pub fn ensure_xcm(o: OuterOrigin) -> Result where OuterOrigin: Into>, { @@ -2909,7 +2914,7 @@ where /// Ensure that the origin `o` represents an XCM response origin. /// /// Returns `Ok` with the location of the responder or an `Err` otherwise. -pub fn ensure_response(o: OuterOrigin) -> Result +pub fn ensure_response(o: OuterOrigin) -> Result where OuterOrigin: Into>, { @@ -2919,46 +2924,50 @@ where } } -/// Filter for `MultiLocation` to find those which represent a strict majority approval of an +/// Filter for `Location` to find those which represent a strict majority approval of an /// identified plurality. /// /// May reasonably be used with `EnsureXcm`. pub struct IsMajorityOfBody(PhantomData<(Prefix, Body)>); -impl, Body: Get> Contains +impl, Body: Get> Contains for IsMajorityOfBody { - fn contains(l: &MultiLocation) -> bool { + fn contains(l: &Location) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority()) } } -/// Filter for `MultiLocation` to find those which represent a voice of an identified plurality. +/// Filter for `Location` to find those which represent a voice of an identified plurality. /// /// May reasonably be used with `EnsureXcm`. pub struct IsVoiceOfBody(PhantomData<(Prefix, Body)>); -impl, Body: Get> Contains - for IsVoiceOfBody -{ - fn contains(l: &MultiLocation) -> bool { +impl, Body: Get> Contains for IsVoiceOfBody { + fn contains(l: &Location) -> bool { let maybe_suffix = l.match_and_split(&Prefix::get()); matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part == &BodyPart::Voice) } } -/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and filter /// the `Origin::Xcm` item. -pub struct EnsureXcm(PhantomData); -impl, F: Contains> EnsureOrigin for EnsureXcm +pub struct EnsureXcm(PhantomData<(F, L)>); +impl< + O: OriginTrait + From, + F: Contains, + L: TryFrom + TryInto + Clone, + > EnsureOrigin for EnsureXcm where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = L; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { caller.try_into().and_then(|o| match o { - Origin::Xcm(location) if F::contains(&location) => Ok(location), + Origin::Xcm(ref location) + if F::contains(&location.clone().try_into().map_err(|_| o.clone().into())?) => + Ok(location.clone().try_into().map_err(|_| o.clone().into())?), Origin::Xcm(location) => Err(Origin::Xcm(location).into()), o => Err(o.into()), }) @@ -2971,15 +2980,14 @@ where } } -/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter +/// `EnsureOrigin` implementation succeeding with a `Location` value to recognize and filter /// the `Origin::Response` item. pub struct EnsureResponse(PhantomData); -impl, F: Contains> EnsureOrigin - for EnsureResponse +impl, F: Contains> EnsureOrigin for EnsureResponse where O::PalletsOrigin: From + TryInto, { - type Success = MultiLocation; + type Success = Location; fn try_origin(outer: O) -> Result { outer.try_with_caller(|caller| { @@ -2996,16 +3004,16 @@ where } } -/// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of +/// A simple passthrough where we reuse the `Location`-typed XCM origin as the inner value of /// this crate's `Origin::Xcm` value. pub struct XcmPassthrough(PhantomData); impl> ConvertOrigin for XcmPassthrough { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); match kind { OriginKind::Xcm => Ok(crate::Origin::Xcm(origin).into()), diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 0ac4205ed94..3ce32fa46d3 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -16,7 +16,7 @@ use codec::Encode; use frame_support::{ - construct_runtime, derive_impl, match_types, parameter_types, + construct_runtime, derive_impl, parameter_types, traits::{ AsEnsureOriginWithArg, ConstU128, ConstU32, Contains, Equals, Everything, EverythingBut, Nothing, @@ -76,7 +76,7 @@ pub mod pallet_test_notifier { pub enum Event { QueryPrepared(QueryId), NotifyQueryPrepared(QueryId), - ResponseReceived(MultiLocation, QueryId, Response), + ResponseReceived(Location, QueryId, Response), } #[pallet::error] @@ -89,7 +89,7 @@ pub mod pallet_test_notifier { impl Pallet { #[pallet::call_index(0)] #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] - pub fn prepare_new_query(origin: OriginFor, querier: MultiLocation) -> DispatchResult { + pub fn prepare_new_query(origin: OriginFor, querier: Location) -> DispatchResult { let who = ensure_signed(origin)?; let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) @@ -105,10 +105,7 @@ pub mod pallet_test_notifier { #[pallet::call_index(1)] #[pallet::weight(Weight::from_parts(1_000_000, 1_000_000))] - pub fn prepare_new_notify_query( - origin: OriginFor, - querier: MultiLocation, - ) -> DispatchResult { + pub fn prepare_new_notify_query(origin: OriginFor, querier: Location) -> DispatchResult { let who = ensure_signed(origin)?; let id = who .using_encoded(|mut d| <[u8; 32]>::decode(&mut d)) @@ -144,7 +141,7 @@ construct_runtime!( { System: frame_system::{Pallet, Call, Storage, Config, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Config, Event}, + AssetsPallet: pallet_assets::{Pallet, Call, Storage, Config, Event}, ParasOrigin: origin::{Pallet, Origin}, XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config}, TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, @@ -152,13 +149,13 @@ construct_runtime!( ); thread_local! { - pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell)>> = RefCell::new(Vec::new()); pub static FAIL_SEND_XCM: RefCell = RefCell::new(false); } -pub(crate) fn sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { +pub(crate) fn sent_xcm() -> Vec<(Location, Xcm<()>)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } -pub(crate) fn take_sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> { +pub(crate) fn take_sent_xcm() -> Vec<(Location, Xcm<()>)> { SENT_XCM.with(|q| { let mut r = Vec::new(); std::mem::swap(&mut r, &mut *q.borrow_mut()); @@ -171,18 +168,18 @@ pub(crate) fn set_send_xcm_artificial_failure(should_fail: bool) { /// Sender that never returns error. pub struct TestSendXcm; impl SendXcm for TestSendXcm { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if FAIL_SEND_XCM.with(|q| *q.borrow()) { return Err(SendError::Transport("Intentional send failure used in tests")) } let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, MultiAssets::new())) + Ok((pair, Assets::new())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -191,11 +188,11 @@ impl SendXcm for TestSendXcm { /// Sender that returns error if `X8` junction and stops routing pub struct TestSendXcmErrX8; impl SendXcm for TestSendXcmErrX8 { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, _: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if dest.as_ref().unwrap().len() == 8 { dest.take(); Err(SendError::Transport("Destination location full")) @@ -203,7 +200,7 @@ impl SendXcm for TestSendXcmErrX8 { Err(SendError::NotApplicable) } } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -212,18 +209,18 @@ impl SendXcm for TestSendXcmErrX8 { parameter_types! { pub Para3000: u32 = 3000; - pub Para3000Location: MultiLocation = Parachain(Para3000::get()).into(); + pub Para3000Location: Location = Parachain(Para3000::get()).into(); pub Para3000PaymentAmount: u128 = 1; - pub Para3000PaymentMultiAssets: MultiAssets = MultiAssets::from(MultiAsset::from((Here, Para3000PaymentAmount::get()))); + pub Para3000PaymentAssets: Assets = Assets::from(Asset::from((Here, Para3000PaymentAmount::get()))); } /// Sender only sends to `Parachain(3000)` destination requiring payment. pub struct TestPaidForPara3000SendXcm; impl SendXcm for TestPaidForPara3000SendXcm { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { if let Some(dest) = dest.as_ref() { if !dest.eq(&Para3000Location::get()) { return Err(SendError::NotApplicable) @@ -233,9 +230,9 @@ impl SendXcm for TestPaidForPara3000SendXcm { } let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, Para3000PaymentMultiAssets::get())) + Ok((pair, Para3000PaymentAssets::get())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_message_hash(&pair.1); SENT_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) @@ -300,17 +297,17 @@ impl pallet_balances::Config for Test { /// Simple conversion of `u32` into an `AssetId` for use in benchmarking. pub struct XcmBenchmarkHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { - fn create_asset_id_parameter(id: u32) -> MultiLocation { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } +impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { + fn create_asset_id_parameter(id: u32) -> Location { + Location::new(1, [Parachain(id)]) } } impl pallet_assets::Config for Test { type RuntimeEvent = RuntimeEvent; type Balance = Balance; - type AssetId = MultiLocation; - type AssetIdParameter = MultiLocation; + type AssetId = Location; + type AssetIdParameter = Location; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; @@ -354,61 +351,61 @@ pub const OTHER_PARA_ID: u32 = 2009; pub const FILTERED_PARA_ID: u32 = 2010; parameter_types! { - pub const RelayLocation: MultiLocation = Here.into_location(); - pub const NativeAsset: MultiAsset = MultiAsset { + pub const RelayLocation: Location = Here.into_location(); + pub const NativeAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(Here.into_location()), - }; - pub const SystemParachainLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(SOME_SYSTEM_PARA)) - }; - pub const ForeignReserveLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID)) + id: AssetId(Here.into_location()), }; - pub const ForeignAsset: MultiAsset = MultiAsset { + pub SystemParachainLocation: Location = Location::new( + 0, + [Parachain(SOME_SYSTEM_PARA)] + ); + pub ForeignReserveLocation: Location = Location::new( + 0, + [Parachain(FOREIGN_ASSET_RESERVE_PARA_ID)] + ); + pub ForeignAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X2(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION), - }), + id: AssetId(Location::new( + 0, + [Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION], + )), }; - pub const UsdcReserveLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(USDC_RESERVE_PARA_ID)) - }; - pub const Usdc: MultiAsset = MultiAsset { + pub UsdcReserveLocation: Location = Location::new( + 0, + [Parachain(USDC_RESERVE_PARA_ID)] + ); + pub Usdc: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X2(Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION), - }), + id: AssetId(Location::new( + 0, + [Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION], + )), }; - pub const UsdtTeleportLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(USDT_PARA_ID)) - }; - pub const Usdt: MultiAsset = MultiAsset { + pub UsdtTeleportLocation: Location = Location::new( + 0, + [Parachain(USDT_PARA_ID)] + ); + pub Usdt: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X1(Parachain(USDT_PARA_ID)), - }), + id: AssetId(Location::new( + 0, + [Parachain(USDT_PARA_ID)], + )), }; - pub const FilteredTeleportLocation: MultiLocation = MultiLocation { - parents: 0, - interior: X1(Parachain(FILTERED_PARA_ID)) - }; - pub const FilteredTeleportAsset: MultiAsset = MultiAsset { + pub FilteredTeleportLocation: Location = Location::new( + 0, + [Parachain(FILTERED_PARA_ID)] + ); + pub FilteredTeleportAsset: Asset = Asset { fun: Fungible(10), - id: Concrete(MultiLocation { - parents: 0, - interior: X1(Parachain(FILTERED_PARA_ID)), - }), + id: AssetId(Location::new( + 0, + [Parachain(FILTERED_PARA_ID)], + )), }; pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; pub CheckingAccount: AccountId = XcmPallet::check_account(); } @@ -420,7 +417,7 @@ pub type SovereignAccountOf = ( ); pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId< - MultiLocation, + Location, Balance, // Excludes relay/parent chain currency EverythingBut<(Equals,)>, @@ -432,7 +429,7 @@ pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId< pub type AssetTransactors = ( XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>, FungiblesAdapter< - Assets, + AssetsPallet, ForeignAssetsConvertedConcreteId, SovereignAccountOf, AccountId, @@ -450,24 +447,29 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); - pub TrustedLocal: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); - pub TrustedSystemPara: (MultiAssetFilter, MultiLocation) = (NativeAsset::get().into(), SystemParachainLocation::get()); - pub TrustedUsdt: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), UsdtTeleportLocation::get()); - pub TrustedFilteredTeleport: (MultiAssetFilter, MultiLocation) = (FilteredTeleportAsset::get().into(), FilteredTeleportLocation::get()); - pub TeleportUsdtToForeign: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), ForeignReserveLocation::get()); - pub TrustedForeign: (MultiAssetFilter, MultiLocation) = (ForeignAsset::get().into(), ForeignReserveLocation::get()); - pub TrustedUsdc: (MultiAssetFilter, MultiLocation) = (Usdc::get().into(), UsdcReserveLocation::get()); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (AssetId(RelayLocation::get()), 1, 1); + pub TrustedLocal: (AssetFilter, Location) = (All.into(), Here.into()); + pub TrustedSystemPara: (AssetFilter, Location) = (NativeAsset::get().into(), SystemParachainLocation::get()); + pub TrustedUsdt: (AssetFilter, Location) = (Usdt::get().into(), UsdtTeleportLocation::get()); + pub TrustedFilteredTeleport: (AssetFilter, Location) = (FilteredTeleportAsset::get().into(), FilteredTeleportLocation::get()); + pub TeleportUsdtToForeign: (AssetFilter, Location) = (Usdt::get().into(), ForeignReserveLocation::get()); + pub TrustedForeign: (AssetFilter, Location) = (ForeignAsset::get().into(), ForeignReserveLocation::get()); + pub TrustedUsdc: (AssetFilter, Location) = (Usdc::get().into(), UsdcReserveLocation::get()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub XcmFeesTargetAccount: AccountId = AccountId::new([167u8; 32]); } pub const XCM_FEES_NOT_WAIVED_USER_ACCOUNT: [u8; 32] = [37u8; 32]; -match_types! { - pub type XcmFeesNotWaivedLocations: impl Contains = { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 {network: None, id: XCM_FEES_NOT_WAIVED_USER_ACCOUNT})} - }; + +pub struct XcmFeesNotWaivedLocations; +impl Contains for XcmFeesNotWaivedLocations { + fn contains(location: &Location) -> bool { + matches!( + location.unpack(), + (0, [Junction::AccountId32 { network: None, id: XCM_FEES_NOT_WAIVED_USER_ACCOUNT }]) + ) + } } pub type Barrier = ( @@ -519,12 +521,12 @@ impl xcm_executor::Config for XcmConfig { pub type LocalOriginToLocation = SignedToAccountId32; parameter_types! { - pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 3; + pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 4; } pub struct XcmTeleportFiltered; -impl Contains<(MultiLocation, Vec)> for XcmTeleportFiltered { - fn contains(t: &(MultiLocation, Vec)) -> bool { +impl Contains<(Location, Vec)> for XcmTeleportFiltered { + fn contains(t: &(Location, Vec)) -> bool { let filtered = FilteredTeleportAsset::get(); t.1.iter().any(|asset| asset == &filtered) } @@ -566,24 +568,23 @@ impl pallet_test_notifier::Config for Test { #[cfg(feature = "runtime-benchmarks")] impl super::benchmarking::Config for Test { - fn reachable_dest() -> Option { + fn reachable_dest() -> Option { Some(Parachain(1000).into()) } - fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn teleportable_asset_and_dest() -> Option<(Asset, Location)> { Some((NativeAsset::get(), SystemParachainLocation::get())) } - fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> { + fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { Some(( - MultiAsset { fun: Fungible(10), id: Concrete(Here.into_location()) }, + Asset { fun: Fungible(10), id: AssetId(Here.into_location()) }, Parachain(OTHER_PARA_ID).into(), )) } - fn set_up_complex_asset_transfer( - ) -> Option<(MultiAssets, u32, MultiLocation, Box)> { - use crate::tests::assets_transfer::{into_multiassets_checked, set_up_foreign_asset}; + fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { + use crate::tests::assets_transfer::{into_assets_checked, set_up_foreign_asset}; // Transfer native asset (local reserve) to `USDT_PARA_ID`. Using teleport-trusted USDT for // fees. @@ -600,7 +601,7 @@ impl super::benchmarking::Config for Test { ); // create sufficient foreign asset USDT let usdt_initial_local_amount = fee_amount * 10; - let (usdt_chain, _, usdt_id_multilocation) = set_up_foreign_asset( + let (usdt_chain, _, usdt_id_location) = set_up_foreign_asset( USDT_PARA_ID, None, caller.clone(), @@ -610,22 +611,25 @@ impl super::benchmarking::Config for Test { // native assets transfer destination is USDT chain (teleport trust only for USDT) let dest = usdt_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, fee_amount).into(), + (usdt_id_location.clone(), fee_amount).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), asset_amount).into(), + (Location::here(), asset_amount).into(), ); // verify initial balances assert_eq!(Balances::free_balance(&caller), balance); - assert_eq!(Assets::balance(usdt_id_multilocation, &caller), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), &caller), + usdt_initial_local_amount + ); // verify transferred successfully let verify = Box::new(move || { // verify balances after transfer, decreased by transferred amounts assert_eq!(Balances::free_balance(&caller), balance - asset_amount); assert_eq!( - Assets::balance(usdt_id_multilocation, &caller), + AssetsPallet::balance(usdt_id_location, &caller), usdt_initial_local_amount - fee_amount ); }); @@ -641,13 +645,13 @@ pub(crate) fn last_events(n: usize) -> Vec { System::events().into_iter().map(|e| e.event).rev().take(n).rev().collect() } -pub(crate) fn buy_execution(fees: impl Into) -> Instruction { +pub(crate) fn buy_execution(fees: impl Into) -> Instruction { use xcm::latest::prelude::*; BuyExecution { fees: fees.into(), weight_limit: Unlimited } } pub(crate) fn buy_limited_execution( - fees: impl Into, + fees: impl Into, weight_limit: WeightLimit, ) -> Instruction { use xcm::latest::prelude::*; diff --git a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs index 6893bae2b6c..27be5cce145 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/assets_transfer.rs @@ -33,8 +33,8 @@ use xcm_executor::traits::ConvertLocation; // Helper function to deduplicate testing different teleport types. fn do_test_and_verify_teleport_assets( - origin_location: MultiLocation, - expected_beneficiary: MultiLocation, + origin_location: Location, + expected_beneficiary: Location, call: Call, expected_weight_limit: WeightLimit, ) { @@ -70,13 +70,15 @@ fn do_test_and_verify_teleport_assets( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -92,11 +94,11 @@ fn do_test_and_verify_teleport_assets( /// local effects. #[test] fn teleport_assets_works() { - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); do_test_and_verify_teleport_assets( - origin_location, - beneficiary, + origin_location.clone(), + beneficiary.clone(), || { assert_ok!(XcmPallet::teleport_assets( RuntimeOrigin::signed(ALICE), @@ -116,13 +118,13 @@ fn teleport_assets_works() { /// local effects. #[test] fn limited_teleport_assets_works() { - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); let weight_limit = WeightLimit::Limited(Weight::from_parts(5000, 5000)); let expected_weight_limit = weight_limit.clone(); do_test_and_verify_teleport_assets( - origin_location, - beneficiary, + origin_location.clone(), + beneficiary.clone(), || { assert_ok!(XcmPallet::limited_teleport_assets( RuntimeOrigin::signed(ALICE), @@ -140,7 +142,7 @@ fn limited_teleport_assets_works() { /// `limited_teleport_assets` should fail for filtered assets #[test] fn limited_teleport_filtered_assets_disallowed() { - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); new_test_ext_with_balances(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { let result = XcmPallet::limited_teleport_assets( RuntimeOrigin::signed(ALICE), @@ -165,7 +167,7 @@ fn limited_teleport_filtered_assets_disallowed() { /// /// Asserts that the sender's balance is decreased and the beneficiary's balance /// is increased. Verifies the correct message is sent and event is emitted. -/// Verifies that XCM router fees (`SendXcm::validate` -> `MultiAssets`) are withdrawn from correct +/// Verifies that XCM router fees (`SendXcm::validate` -> `Assets`) are withdrawn from correct /// user account and deposited to a correct target account (`XcmFeesTargetAccount`). #[test] fn reserve_transfer_assets_with_paid_router_works() { @@ -179,13 +181,13 @@ fn reserve_transfer_assets_with_paid_router_works() { new_test_ext_with_balances(balances).execute_with(|| { let xcm_router_fee_amount = Para3000PaymentAmount::get(); let weight = BaseXcmWeight::get(); - let dest: MultiLocation = - AccountId32 { network: None, id: user_account.clone().into() }.into(); + let dest: Location = + Junction::AccountId32 { network: None, id: user_account.clone().into() }.into(); assert_eq!(Balances::total_balance(&user_account), INITIAL_BALANCE); assert_ok!(XcmPallet::reserve_transfer_assets( RuntimeOrigin::signed(user_account.clone()), Box::new(Parachain(paid_para_id).into()), - Box::new(dest.into()), + Box::new(dest.clone().into()), Box::new((Here, SEND_AMOUNT).into()), 0, )); @@ -206,7 +208,7 @@ fn reserve_transfer_assets_with_paid_router_works() { INITIAL_BALANCE + xcm_router_fee_amount ); - let dest_para: MultiLocation = Parachain(paid_para_id).into(); + let dest_para: Location = Parachain(paid_para_id).into(); assert_eq!( sent_xcm(), vec![( @@ -215,14 +217,16 @@ fn reserve_transfer_assets_with_paid_router_works() { ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, buy_execution((Parent, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]), )] ); let mut last_events = last_events(5).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // balances events last_events.next().unwrap(); @@ -231,7 +235,7 @@ fn reserve_transfer_assets_with_paid_router_works() { last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: dest, - fees: Para3000PaymentMultiAssets::get(), + fees: Para3000PaymentAssets::get(), }) ); assert!(matches!( @@ -247,45 +251,45 @@ pub(crate) fn set_up_foreign_asset( benficiary: AccountId, initial_amount: u128, is_sufficient: bool, -) -> (MultiLocation, AccountId, MultiLocation) { +) -> (Location, AccountId, Location) { let reserve_location = RelayLocation::get().pushed_with_interior(Parachain(reserve_para_id)).unwrap(); let reserve_sovereign_account = SovereignAccountOf::convert_location(&reserve_location).unwrap(); - let foreign_asset_id_multilocation = if let Some(junction) = inner_junction { - reserve_location.pushed_with_interior(junction).unwrap() + let foreign_asset_id_location = if let Some(junction) = inner_junction { + reserve_location.clone().pushed_with_interior(junction).unwrap() } else { - reserve_location + reserve_location.clone() }; - // create sufficient (to be used as fees as well) foreign asset - assert_ok!(Assets::force_create( + // create sufficient (to be used as fees as well) foreign asset (0 total issuance) + assert_ok!(AssetsPallet::force_create( RuntimeOrigin::root(), - foreign_asset_id_multilocation, + foreign_asset_id_location.clone(), BOB, is_sufficient, 1 )); // this asset should have been teleported/reserve-transferred in, but for this test we just // mint it locally. - assert_ok!(Assets::mint( + assert_ok!(AssetsPallet::mint( RuntimeOrigin::signed(BOB), - foreign_asset_id_multilocation, + foreign_asset_id_location.clone(), benficiary, initial_amount )); - (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) + (reserve_location, reserve_sovereign_account, foreign_asset_id_location) } // Helper function that provides correct `fee_index` after `sort()` done by -// `vec![MultiAsset, MultiAsset].into()`. -pub(crate) fn into_multiassets_checked( - fee_asset: MultiAsset, - transfer_asset: MultiAsset, -) -> (MultiAssets, usize, MultiAsset, MultiAsset) { - let assets: MultiAssets = vec![fee_asset.clone(), transfer_asset.clone()].into(); +// `vec![Asset, Asset].into()`. +pub(crate) fn into_assets_checked( + fee_asset: Asset, + transfer_asset: Asset, +) -> (Assets, usize, Asset, Asset) { + let assets: Assets = vec![fee_asset.clone(), transfer_asset.clone()].into(); let fee_index = if assets.get(0).unwrap().eq(&fee_asset) { 0 } else { 1 }; (assets, fee_index, fee_asset, transfer_asset) } @@ -302,9 +306,9 @@ fn local_asset_reserve_and_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, @@ -313,12 +317,14 @@ fn local_asset_reserve_and_local_fee_reserve_call( (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let weight_limit = WeightLimit::Limited(Weight::from_parts(5000, 5000)); let expected_weight_limit = weight_limit.clone(); - let expected_beneficiary = beneficiary; - let dest: MultiLocation = Parachain(OTHER_PARA_ID).into(); + let expected_beneficiary = beneficiary.clone(); + let dest: Location = Parachain(OTHER_PARA_ID).into(); new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get(); @@ -326,8 +332,8 @@ fn local_asset_reserve_and_local_fee_reserve_call( // call extrinsic let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new((Here, SEND_AMOUNT).into()), 0, weight_limit, @@ -352,7 +358,7 @@ fn local_asset_reserve_and_local_fee_reserve_call( buy_limited_execution((Parent, SEND_AMOUNT), expected_weight_limit), DepositAsset { assets: AllCounted(1).into(), - beneficiary: expected_beneficiary + beneficiary: expected_beneficiary.clone() }, ]), )] @@ -360,13 +366,15 @@ fn local_asset_reserve_and_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -423,21 +431,22 @@ fn destination_asset_reserve_and_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let weight = BaseXcmWeight::get() * 3; let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -449,27 +458,30 @@ fn destination_asset_reserve_and_local_fee_reserve_call( // transfer destination is reserve location (no teleport trust) let dest = reserve_location; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -483,24 +495,32 @@ fn destination_asset_reserve_and_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // Alice spent (transferred) amount assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Alice used native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - FEE_AMOUNT); // Destination account (parachain account) added native reserve used as fee to balances assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), FEE_AMOUNT); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -514,7 +534,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( buy_limited_execution(expected_fee, Unlimited), WithdrawAsset(expected_asset.into()), ClearOrigin, - DepositAsset { assets: AllCounted(2).into(), beneficiary }, + DepositAsset { assets: AllCounted(2).into(), beneficiary: beneficiary.clone() }, ]) )] ); @@ -522,7 +542,7 @@ fn destination_asset_reserve_and_local_fee_reserve_call( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -582,19 +602,19 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, _, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, _, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -606,15 +626,18 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( // chain) let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // foreign asset to transfer - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // try the transfer @@ -629,14 +652,20 @@ fn remote_asset_reserve_and_local_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice transferred nothing - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); // Alice spent native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); }); } @@ -698,20 +727,21 @@ fn local_asset_reserve_and_destination_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (usdc_reserve_location, usdc_chain_sovereign_account, usdc_id_multilocation) = + let (usdc_reserve_location, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), @@ -723,27 +753,30 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // native assets transfer to fee reserve location (no teleport trust) let dest = usdc_reserve_location; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // usdc for fees (is sufficient on local chain too) - destination reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -758,13 +791,15 @@ fn local_asset_reserve_and_destination_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -774,18 +809,21 @@ fn local_asset_reserve_and_destination_fee_reserve_call( // Alice spent (fees) amount assert_eq!( - Assets::balance(usdc_id_multilocation, ALICE), + AssetsPallet::balance(usdc_id_location.clone(), ALICE), usdc_initial_local_amount - FEE_AMOUNT ); // Alice used native asset for transfer assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); // Sovereign account of dest parachain holds `SEND_AMOUNT` native asset in local reserve assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), SEND_AMOUNT); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC have decreased (burned on reserve-withdraw) let expected_issuance = usdc_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -856,21 +894,22 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // we'll send just this foreign asset back to its reserve location and use it for fees as // well let foreign_initial_amount = 142; - let (reserve_location, reserve_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -881,22 +920,25 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // transfer destination is reserve location let dest = reserve_location; - let assets: MultiAssets = vec![(foreign_asset_id_multilocation, SEND_AMOUNT).into()].into(); + let assets: Assets = vec![(foreign_asset_id_location.clone(), SEND_AMOUNT).into()].into(); let fee_index = 0; // reanchor according to test-case let mut expected_assets = assets.clone(); - expected_assets.reanchor(&dest, UniversalLocation::get()).unwrap(); + expected_assets.reanchor(&dest, &UniversalLocation::get()).unwrap(); // balances checks before - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index, Unlimited, @@ -911,13 +953,15 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -927,19 +971,25 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( // Alice spent (transferred) amount assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Alice's native asset balance is untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Reserve sovereign account has same balances assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -950,7 +1000,7 @@ fn destination_asset_reserve_and_destination_fee_reserve_call( WithdrawAsset(expected_assets.clone()), ClearOrigin, buy_limited_execution(expected_assets.get(0).unwrap().clone(), Unlimited), - DepositAsset { assets: AllCounted(1).into(), beneficiary }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: beneficiary.clone() }, ]), )] ); @@ -1003,19 +1053,19 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 42; - let (usdc_chain, _, usdc_id_multilocation) = set_up_foreign_asset( + let (usdc_chain, _, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1025,7 +1075,7 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, _, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, _, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -1037,16 +1087,22 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // reserve chain) let dest = usdc_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - destination reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1062,14 +1118,23 @@ fn remote_asset_reserve_and_destination_fee_reserve_call_disallowed( // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1127,19 +1192,19 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1151,15 +1216,18 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); let dest_sovereign_account = SovereignAccountOf::convert_location(&dest).unwrap(); - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1172,15 +1240,21 @@ fn local_asset_reserve_and_remote_fee_reserve_call_disallowed( Unlimited, ); assert_eq!(result, expected_result); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Sovereign account of reserve parachain is unchanged assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(dest_sovereign_account), 0); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), expected_usdc_issuance); }); } @@ -1237,19 +1311,19 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 42; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -1259,7 +1333,7 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -1272,15 +1346,18 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDC for fees (is sufficient on local chain too) - remote reserve - (usdc_id_multilocation, FEE_AMOUNT).into(), + (usdc_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1295,18 +1372,33 @@ fn destination_asset_reserve_and_remote_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); let expected_usdc_issuance = usdc_initial_local_amount; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1377,52 +1469,54 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (usdc_chain, usdc_chain_sovereign_account, usdc_id_multilocation) = - set_up_foreign_asset( - USDC_RESERVE_PARA_ID, - Some(USDC_INNER_JUNCTION), - ALICE, - usdc_initial_local_amount, - true, - ); + let (usdc_chain, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( + USDC_RESERVE_PARA_ID, + Some(USDC_INNER_JUNCTION), + ALICE, + usdc_initial_local_amount, + true, + ); // transfer destination is some other parachain let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let assets: MultiAssets = vec![(usdc_id_multilocation, SEND_AMOUNT).into()].into(); - let fee_index = 0u32; + let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); + let fee_index = 0; // reanchor according to test-case let context = UniversalLocation::get(); - let expected_dest_on_reserve = dest.reanchored(&usdc_chain, context).unwrap(); + let expected_dest_on_reserve = dest.clone().reanchored(&usdc_chain, &context).unwrap(); let fees = assets.get(fee_index as usize).unwrap().clone(); let (fees_half_1, fees_half_2) = XcmPallet::halve_fees(fees).unwrap(); let mut expected_assets_on_reserve = assets.clone(); - expected_assets_on_reserve.reanchor(&usdc_chain, context).unwrap(); - let expected_fee_on_reserve = fees_half_1.reanchored(&usdc_chain, context).unwrap(); - let expected_fee_on_dest = fees_half_2.reanchored(&dest, context).unwrap(); + expected_assets_on_reserve.reanchor(&usdc_chain, &context).unwrap(); + let expected_fee_on_reserve = fees_half_1.reanchored(&usdc_chain, &context).unwrap(); + let expected_fee_on_dest = fees_half_2.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index, Unlimited, @@ -1435,23 +1529,26 @@ fn remote_asset_reserve_and_remote_fee_reserve_call( assert!(matches!( last_event(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(_) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete { .. } }) )); // Alice spent (transferred) amount assert_eq!( - Assets::balance(usdc_id_multilocation, ALICE), + AssetsPallet::balance(usdc_id_location.clone(), ALICE), usdc_initial_local_amount - SEND_AMOUNT ); // Alice's native asset balance is untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Destination account (parachain account) has expected (same) balances assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC have decreased (burned on reserve-withdraw) let expected_usdc_issuance = usdc_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdc_id_multilocation), expected_usdc_issuance); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), expected_usdc_issuance); + assert_eq!(AssetsPallet::total_issuance(usdc_id_location.clone()), expected_usdc_issuance); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location.clone()), expected_usdc_issuance); // Verify sent XCM program assert_eq!( @@ -1523,46 +1620,50 @@ fn local_asset_reserve_and_teleported_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // native assets transfer destination is USDT chain (teleport trust only for USDT) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -1577,13 +1678,15 @@ fn local_asset_reserve_and_teleported_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -1592,18 +1695,21 @@ fn local_asset_reserve_and_teleported_fee_call( )); // Alice spent (fees) amount assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - FEE_AMOUNT ); // Alice used native asset for transfer assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT); // Sovereign account of dest parachain holds `SEND_AMOUNT` native asset in local reserve assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), SEND_AMOUNT); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_usdt_issuance); // Verify sent XCM program assert_eq!( @@ -1672,25 +1778,26 @@ fn destination_asset_reserve_and_teleported_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = + Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (_, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (_, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -1703,27 +1810,30 @@ fn destination_asset_reserve_and_teleported_fee_call( let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - destination reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -1738,13 +1848,15 @@ fn destination_asset_reserve_and_teleported_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { - paying: origin_location, - fees: MultiAssets::new(), + paying: origin_location.clone(), + fees: Assets::new(), }) ); assert!(matches!( @@ -1755,29 +1867,38 @@ fn destination_asset_reserve_and_teleported_fee_call( assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice spent USDT for fees assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - FEE_AMOUNT ); // Alice transferred BLA assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - SEND_AMOUNT ); // Verify balances of USDT reserve parachain assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify balances of transferred-asset reserve parachain assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); // Verify total and active issuance of USDT have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location.clone()), expected_usdt_issuance); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_bla_issuance = foreign_initial_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); // Verify sent XCM program assert_eq!( @@ -1844,24 +1965,24 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // create non-sufficient foreign asset BLA let foreign_initial_amount = 142; - let (_, reserve_sovereign_account, foreign_asset_id_multilocation) = set_up_foreign_asset( + let (_, reserve_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), ALICE, @@ -1872,15 +1993,18 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // USDT for fees (is sufficient on local chain too) - teleported - (usdt_id_multilocation, FEE_AMOUNT).into(), + (usdt_id_location.clone(), FEE_AMOUNT).into(), // foreign asset to transfer (not used for fees) - remote reserve - (foreign_asset_id_multilocation, SEND_AMOUNT).into(), + (foreign_asset_id_location.clone(), SEND_AMOUNT).into(), ); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // try the transfer @@ -1895,18 +2019,33 @@ fn remote_asset_reserve_and_teleported_fee_reserve_call_disallowed( assert_eq!(result, expected_result); // Alice native asset untouched assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, ALICE), foreign_initial_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), + foreign_initial_amount + ); assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); assert_eq!(Balances::free_balance(reserve_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, reserve_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), reserve_sovereign_account), + 0 + ); let expected_usdt_issuance = usdt_initial_local_amount; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location.clone()), expected_usdt_issuance); let expected_bla_issuance = foreign_initial_amount; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); }); } @@ -1959,21 +2098,24 @@ fn teleport_assets_with_remote_asset_reserve_and_teleported_fee_disallowed() { #[test] fn reserve_transfer_assets_with_teleportable_asset_disallowed() { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, true); // transfer destination is USDT chain (foreign asset needs to go through its reserve chain) let dest = usdt_chain; - let assets: MultiAssets = vec![(usdt_id_multilocation, FEE_AMOUNT).into()].into(); + let assets: Assets = vec![(usdt_id_location.clone(), FEE_AMOUNT).into()].into(); let fee_index = 0; // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer @@ -1996,25 +2138,34 @@ fn reserve_transfer_assets_with_teleportable_asset_disallowed() { // Alice native asset is still same assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice USDT balance is still same - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); // No USDT moved to sovereign account of reserve parachain - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDT are still the same - assert_eq!(Assets::total_issuance(usdt_id_multilocation), usdt_initial_local_amount); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::total_issuance(usdt_id_location.clone()), + usdt_initial_local_amount + ); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), usdt_initial_local_amount); }); } /// Test `transfer_assets` with teleportable fee that is filtered - should fail. #[test] fn transfer_assets_with_filtered_teleported_fee_disallowed() { - let beneficiary: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: BOB.into() }.into(); new_test_ext_with_balances(vec![(ALICE, INITIAL_BALANCE)]).execute_with(|| { - let (assets, fee_index, _, _) = into_multiassets_checked( + let (assets, fee_index, _, _) = into_assets_checked( // FilteredTeleportAsset for fees - teleportable but filtered FilteredTeleportAsset::get().into(), // native asset to transfer (not used for fees) - local reserve - (MultiLocation::here(), SEND_AMOUNT).into(), + (Location::here(), SEND_AMOUNT).into(), ); let result = XcmPallet::transfer_assets( RuntimeOrigin::signed(ALICE), @@ -2043,11 +2194,11 @@ fn transfer_assets_with_filtered_teleported_fee_disallowed() { #[test] fn intermediary_error_reverts_side_effects() { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset USDC let usdc_initial_local_amount = 142; - let (_, usdc_chain_sovereign_account, usdc_id_multilocation) = set_up_foreign_asset( + let (_, usdc_chain_sovereign_account, usdc_id_location) = set_up_foreign_asset( USDC_RESERVE_PARA_ID, Some(USDC_INNER_JUNCTION), ALICE, @@ -2058,11 +2209,14 @@ fn intermediary_error_reverts_side_effects() { // transfer destination is some other parachain let dest = RelayLocation::get().pushed_with_interior(Parachain(OTHER_PARA_ID)).unwrap(); - let assets: MultiAssets = vec![(usdc_id_multilocation, SEND_AMOUNT).into()].into(); + let assets: Assets = vec![(usdc_id_location.clone(), SEND_AMOUNT).into()].into(); let fee_index = 0; // balances checks before - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // introduce artificial error in sending outbound XCM @@ -2080,14 +2234,23 @@ fn intermediary_error_reverts_side_effects() { .is_err()); // Alice no changes - assert_eq!(Assets::balance(usdc_id_multilocation, ALICE), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), ALICE), + usdc_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Destination account (parachain account) no changes assert_eq!(Balances::free_balance(usdc_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdc_id_multilocation, usdc_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdc_id_location.clone(), usdc_chain_sovereign_account), + 0 + ); // Verify total and active issuance of USDC has not changed - assert_eq!(Assets::total_issuance(usdc_id_multilocation), usdc_initial_local_amount); - assert_eq!(Assets::active_issuance(usdc_id_multilocation), usdc_initial_local_amount); + assert_eq!( + AssetsPallet::total_issuance(usdc_id_location.clone()), + usdc_initial_local_amount + ); + assert_eq!(AssetsPallet::active_issuance(usdc_id_location), usdc_initial_local_amount); // Verify no XCM program sent assert_eq!(sent_xcm(), vec![]); }); @@ -2105,47 +2268,50 @@ fn teleport_asset_using_local_fee_reserve_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let weight = BaseXcmWeight::get() * 3; let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create non-sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (usdt_chain, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (usdt_chain, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, false); // transfer destination is reserve location (no teleport trust) let dest = usdt_chain; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // native asset for fee - local reserve - (MultiLocation::here(), FEE_AMOUNT).into(), + (Location::here(), FEE_AMOUNT).into(), // USDT to transfer - destination reserve - (usdt_id_multilocation, SEND_AMOUNT).into(), + (usdt_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -2159,24 +2325,29 @@ fn teleport_asset_using_local_fee_reserve_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); // Alice spent (transferred) amount assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - SEND_AMOUNT ); // Alice used native asset for fees assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - FEE_AMOUNT); // Destination account (parachain account) added native reserve to balances assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), FEE_AMOUNT); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify total and active issuance of foreign BLA have decreased (burned on // reserve-withdraw) let expected_issuance = usdt_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_issuance); // Verify sent XCM program assert_eq!( @@ -2198,7 +2369,7 @@ fn teleport_asset_using_local_fee_reserve_call( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -2255,20 +2426,20 @@ fn teleported_asset_using_destination_reserve_fee_call( ) where Call: FnOnce( OriginFor, - Box, - Box, - Box, + Box, + Box, + Box, u32, WeightLimit, ) -> DispatchResult, { let balances = vec![(ALICE, INITIAL_BALANCE)]; - let origin_location: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let beneficiary: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let origin_location: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let beneficiary: Location = AccountId32 { network: None, id: ALICE.into() }.into(); new_test_ext_with_balances(balances).execute_with(|| { // create sufficient foreign asset BLA to be used for fees let foreign_initial_amount = 142; - let (reserve_location, foreign_sovereign_account, foreign_asset_id_multilocation) = + let (reserve_location, foreign_sovereign_account, foreign_asset_id_location) = set_up_foreign_asset( FOREIGN_ASSET_RESERVE_PARA_ID, Some(FOREIGN_ASSET_INNER_JUNCTION), @@ -2279,34 +2450,37 @@ fn teleported_asset_using_destination_reserve_fee_call( // create non-sufficient foreign asset USDT let usdt_initial_local_amount = 42; - let (_, usdt_chain_sovereign_account, usdt_id_multilocation) = + let (_, usdt_chain_sovereign_account, usdt_id_location) = set_up_foreign_asset(USDT_PARA_ID, None, ALICE, usdt_initial_local_amount, false); // transfer destination is BLA reserve location let dest = reserve_location; let dest_sovereign_account = foreign_sovereign_account; - let (assets, fee_index, fee_asset, xfer_asset) = into_multiassets_checked( + let (assets, fee_index, fee_asset, xfer_asset) = into_assets_checked( // foreign asset BLA used for fees - destination reserve - (foreign_asset_id_multilocation, FEE_AMOUNT).into(), + (foreign_asset_id_location.clone(), FEE_AMOUNT).into(), // USDT to transfer - teleported - (usdt_id_multilocation, SEND_AMOUNT).into(), + (usdt_id_location.clone(), SEND_AMOUNT).into(), ); // reanchor according to test-case let context = UniversalLocation::get(); - let expected_fee = fee_asset.reanchored(&dest, context).unwrap(); - let expected_asset = xfer_asset.reanchored(&dest, context).unwrap(); + let expected_fee = fee_asset.reanchored(&dest, &context).unwrap(); + let expected_asset = xfer_asset.reanchored(&dest, &context).unwrap(); // balances checks before - assert_eq!(Assets::balance(usdt_id_multilocation, ALICE), usdt_initial_local_amount); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), ALICE), + usdt_initial_local_amount + ); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // do the transfer let result = tested_call( RuntimeOrigin::signed(ALICE), - Box::new(dest.into()), - Box::new(beneficiary.into()), + Box::new(dest.clone().into()), + Box::new(beneficiary.clone().into()), Box::new(assets.into()), fee_index as u32, Unlimited, @@ -2321,13 +2495,15 @@ fn teleported_asset_using_destination_reserve_fee_call( let mut last_events = last_events(3).into_iter(); assert_eq!( last_events.next().unwrap(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); assert_eq!( last_events.next().unwrap(), RuntimeEvent::XcmPallet(crate::Event::FeesPaid { paying: origin_location, - fees: MultiAssets::new(), + fees: Assets::new(), }) ); assert!(matches!( @@ -2338,29 +2514,38 @@ fn teleported_asset_using_destination_reserve_fee_call( assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE); // Alice spent USDT for fees assert_eq!( - Assets::balance(usdt_id_multilocation, ALICE), + AssetsPallet::balance(usdt_id_location.clone(), ALICE), usdt_initial_local_amount - SEND_AMOUNT ); // Alice transferred BLA assert_eq!( - Assets::balance(foreign_asset_id_multilocation, ALICE), + AssetsPallet::balance(foreign_asset_id_location.clone(), ALICE), foreign_initial_amount - FEE_AMOUNT ); // Verify balances of USDT reserve parachain assert_eq!(Balances::free_balance(usdt_chain_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(usdt_id_multilocation, usdt_chain_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(usdt_id_location.clone(), usdt_chain_sovereign_account), + 0 + ); // Verify balances of transferred-asset reserve parachain assert_eq!(Balances::free_balance(dest_sovereign_account.clone()), 0); - assert_eq!(Assets::balance(foreign_asset_id_multilocation, dest_sovereign_account), 0); + assert_eq!( + AssetsPallet::balance(foreign_asset_id_location.clone(), dest_sovereign_account), + 0 + ); // Verify total and active issuance of USDT have decreased (teleported) let expected_usdt_issuance = usdt_initial_local_amount - SEND_AMOUNT; - assert_eq!(Assets::total_issuance(usdt_id_multilocation), expected_usdt_issuance); - assert_eq!(Assets::active_issuance(usdt_id_multilocation), expected_usdt_issuance); + assert_eq!(AssetsPallet::total_issuance(usdt_id_location.clone()), expected_usdt_issuance); + assert_eq!(AssetsPallet::active_issuance(usdt_id_location), expected_usdt_issuance); // Verify total and active issuance of foreign BLA asset have decreased (burned on // reserve-withdraw) let expected_bla_issuance = foreign_initial_amount - FEE_AMOUNT; - assert_eq!(Assets::total_issuance(foreign_asset_id_multilocation), expected_bla_issuance); - assert_eq!(Assets::active_issuance(foreign_asset_id_multilocation), expected_bla_issuance); + assert_eq!( + AssetsPallet::total_issuance(foreign_asset_id_location.clone()), + expected_bla_issuance + ); + assert_eq!(AssetsPallet::active_issuance(foreign_asset_id_location), expected_bla_issuance); // Verify sent XCM program assert_eq!( diff --git a/polkadot/xcm/pallet-xcm/src/tests/mod.rs b/polkadot/xcm/pallet-xcm/src/tests/mod.rs index e7a6fdc9dce..5f9c86ed7b3 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/mod.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/mod.rs @@ -19,9 +19,8 @@ pub(crate) mod assets_transfer; use crate::{ - mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedMultiLocation, Queries, - QueryStatus, VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, - VersionNotifyTargets, + mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedLocation, Queries, QueryStatus, + VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers, VersionNotifyTargets, }; use frame_support::{ assert_noop, assert_ok, @@ -49,9 +48,11 @@ fn report_outcome_notify_works() { (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let mut message = - Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = Xcm(vec![TransferAsset { + assets: (Here, SEND_AMOUNT).into(), + beneficiary: sender.clone(), + }]); let call = pallet_test_notifier::Call::notification_received { query_id: 0, response: Default::default(), @@ -76,12 +77,12 @@ fn report_outcome_notify_works() { TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, ]) ); - let querier: MultiLocation = Here.into(); + let querier: Location = Here.into(); let status = QueryStatus::Pending { - responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(), + responder: Location::from(Parachain(OTHER_PARA_ID)).into(), maybe_notify: Some((5, 2)), timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -91,14 +92,15 @@ fn report_outcome_notify_works() { max_weight: Weight::from_parts(1_000_000, 1_000_000), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(OTHER_PARA_ID), message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_events(2), vec![ @@ -124,9 +126,11 @@ fn report_outcome_works() { (ALICE, INITIAL_BALANCE), (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); - let mut message = - Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); + let mut message = Xcm(vec![TransferAsset { + assets: (Here, SEND_AMOUNT).into(), + beneficiary: sender.clone(), + }]); new_test_ext_with_balances(balances).execute_with(|| { XcmPallet::report_outcome(&mut message, Parachain(OTHER_PARA_ID).into_location(), 100) .unwrap(); @@ -141,12 +145,12 @@ fn report_outcome_works() { TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }, ]) ); - let querier: MultiLocation = Here.into(); + let querier: Location = Here.into(); let status = QueryStatus::Pending { - responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(), + responder: Location::from(Parachain(OTHER_PARA_ID)).into(), maybe_notify: None, timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -156,14 +160,15 @@ fn report_outcome_works() { max_weight: Weight::zero(), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(OTHER_PARA_ID), message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::ResponseReady { @@ -185,16 +190,15 @@ fn custom_querier_works() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let querier: MultiLocation = - (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); + let querier: Location = (Parent, AccountId32 { network: None, id: ALICE.into() }).into(); - let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier); + let r = TestNotifier::prepare_new_query(RuntimeOrigin::signed(ALICE), querier.clone()); assert_eq!(r, Ok(())); let status = QueryStatus::Pending { - responder: MultiLocation::from(AccountId32 { network: None, id: ALICE.into() }).into(), + responder: Location::from(AccountId32 { network: None, id: ALICE.into() }).into(), maybe_notify: None, timeout: 100, - maybe_match_querier: Some(querier.into()), + maybe_match_querier: Some(querier.clone().into()), }; assert_eq!(crate::Queries::::iter().collect::>(), vec![(0, status)]); @@ -205,21 +209,21 @@ fn custom_querier_works() { max_weight: Weight::zero(), querier: None, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), Weight::from_parts(1_000, 1_000), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { origin: AccountId32 { network: None, id: ALICE.into() }.into(), query_id: 0, - expected_querier: querier, + expected_querier: querier.clone(), maybe_actual_querier: None, }), ); @@ -229,24 +233,24 @@ fn custom_querier_works() { query_id: 0, response: Response::ExecutionResult(None), max_weight: Weight::zero(), - querier: Some(MultiLocation::here()), + querier: Some(Location::here()), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), Weight::from_parts(1_000, 1_000), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::InvalidQuerier { origin: AccountId32 { network: None, id: ALICE.into() }.into(), query_id: 0, - expected_querier: querier, - maybe_actual_querier: Some(MultiLocation::here()), + expected_querier: querier.clone(), + maybe_actual_querier: Some(Location::here()), }), ); @@ -257,14 +261,15 @@ fn custom_querier_works() { max_weight: Weight::zero(), querier: Some(querier), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, Weight::from_parts(1_000_000_000, 1_000_000_000), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(1_000, 1_000))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(1_000, 1_000) }); assert_eq!( last_event(), RuntimeEvent::XcmPallet(crate::Event::ResponseReady { @@ -289,12 +294,12 @@ fn send_works() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into(); + let sender: Location = AccountId32 { network: None, id: ALICE.into() }.into(); let message = Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), ClearOrigin, buy_execution((Parent, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: sender }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: sender.clone() }, ]); let versioned_dest = Box::new(RelayLocation::get().into()); @@ -304,7 +309,7 @@ fn send_works() { versioned_dest, versioned_message )); - let sent_message = Xcm(Some(DescendOrigin(sender.try_into().unwrap())) + let sent_message = Xcm(Some(DescendOrigin(sender.clone().try_into().unwrap())) .into_iter() .chain(message.0.clone().into_iter()) .collect()); @@ -333,8 +338,7 @@ fn send_fails_when_xcm_router_blocks() { (ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let sender: MultiLocation = - Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let sender: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let message = Xcm(vec![ ReserveAssetDeposited((Parent, SEND_AMOUNT).into()), buy_execution((Parent, SEND_AMOUNT)), @@ -343,7 +347,7 @@ fn send_fails_when_xcm_router_blocks() { assert_noop!( XcmPallet::send( RuntimeOrigin::signed(ALICE), - Box::new(MultiLocation::ancestor(8).into()), + Box::new(Location::ancestor(8).into()), Box::new(VersionedXcm::from(message.clone())), ), crate::Error::::SendFailure @@ -363,7 +367,7 @@ fn execute_withdraw_to_deposit_works() { ]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 3; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); assert_ok!(XcmPallet::execute( RuntimeOrigin::signed(ALICE), @@ -378,7 +382,9 @@ fn execute_withdraw_to_deposit_works() { assert_eq!(Balances::total_balance(&BOB), SEND_AMOUNT); assert_eq!( last_event(), - RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) }) + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: weight } + }) ); }); } @@ -389,7 +395,7 @@ fn trapped_assets_can_be_claimed() { let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 6; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_ok!(XcmPallet::execute( RuntimeOrigin::signed(ALICE), @@ -401,15 +407,14 @@ fn trapped_assets_can_be_claimed() { // This will make an error. Trap(0), // This would succeed, but we never get to it. - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]))), weight )); - let source: MultiLocation = - Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let source: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); let trapped = AssetTraps::::iter().collect::>(); - let vma = VersionedMultiAssets::from(MultiAssets::from((Here, SEND_AMOUNT))); - let hash = BlakeTwo256::hash_of(&(source, vma.clone())); + let vma = VersionedAssets::from(Assets::from((Here, SEND_AMOUNT))); + let hash = BlakeTwo256::hash_of(&(source.clone(), vma.clone())); assert_eq!( last_events(2), vec![ @@ -419,7 +424,7 @@ fn trapped_assets_can_be_claimed() { assets: vma }), RuntimeEvent::XcmPallet(crate::Event::Attempted { - outcome: Outcome::Complete(BaseXcmWeight::get() * 5) + outcome: Outcome::Complete { used: BaseXcmWeight::get() * 5 } }), ] ); @@ -435,7 +440,7 @@ fn trapped_assets_can_be_claimed() { Box::new(VersionedXcm::from(Xcm(vec![ ClaimAsset { assets: (Here, SEND_AMOUNT).into(), ticket: Here.into() }, buy_execution((Here, SEND_AMOUNT)), - DepositAsset { assets: AllCounted(1).into(), beneficiary: dest }, + DepositAsset { assets: AllCounted(1).into(), beneficiary: dest.clone() }, ]))), weight )); @@ -454,7 +459,8 @@ fn trapped_assets_can_be_claimed() { ]))), weight )); - let outcome = Outcome::Incomplete(BaseXcmWeight::get(), XcmError::UnknownClaim); + let outcome = + Outcome::Incomplete { used: BaseXcmWeight::get(), error: XcmError::UnknownClaim }; assert_eq!(last_event(), RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome })); }); } @@ -468,10 +474,10 @@ fn incomplete_execute_reverts_side_effects() { let balances = vec![(ALICE, INITIAL_BALANCE), (BOB, INITIAL_BALANCE)]; new_test_ext_with_balances(balances).execute_with(|| { let weight = BaseXcmWeight::get() * 4; - let dest: MultiLocation = Junction::AccountId32 { network: None, id: BOB.into() }.into(); + let dest: Location = Junction::AccountId32 { network: None, id: BOB.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); let amount_to_send = INITIAL_BALANCE - ExistentialDeposit::get(); - let assets: MultiAssets = (Here, amount_to_send).into(); + let assets: Assets = (Here, amount_to_send).into(); let result = XcmPallet::execute( RuntimeOrigin::signed(ALICE), Box::new(VersionedXcm::from(Xcm(vec![ @@ -506,35 +512,38 @@ fn incomplete_execute_reverts_side_effects() { } #[test] -fn fake_latest_versioned_multilocation_works() { +fn fake_latest_versioned_location_works() { use codec::Encode; - let remote: MultiLocation = Parachain(1000).into(); - let versioned_remote = LatestVersionedMultiLocation(&remote); + let remote: Location = Parachain(1000).into(); + let versioned_remote = LatestVersionedLocation(&remote); assert_eq!(versioned_remote.encode(), remote.into_versioned().encode()); } #[test] fn basic_subscription_works() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_eq!( Queries::::iter().collect::>(), - vec![(0, QueryStatus::VersionNotifier { origin: remote.into(), is_active: false })] + vec![( + 0, + QueryStatus::VersionNotifier { origin: remote.clone().into(), is_active: false } + )] ); assert_eq!( VersionNotifiers::::iter().collect::>(), - vec![(XCM_VERSION, remote.into(), 0)] + vec![(XCM_VERSION, remote.clone().into(), 0)] ); assert_eq!( take_sent_xcm(), vec![( - remote, + remote.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), ),] ); @@ -561,16 +570,16 @@ fn basic_subscription_works() { #[test] fn subscriptions_increment_id() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); - let remote2: MultiLocation = Parachain(1001).into(); + let remote2: Location = Parachain(1001).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote2.into()), + Box::new(remote2.clone().into()), )); assert_eq!( @@ -598,10 +607,10 @@ fn subscriptions_increment_id() { #[test] fn double_subscription_fails() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_noop!( XcmPallet::force_subscribe_version_notify( @@ -616,19 +625,19 @@ fn double_subscription_fails() { #[test] fn unsubscribe_works() { new_test_ext_with_balances(vec![]).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_ok!(XcmPallet::force_unsubscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()) + Box::new(remote.clone().into()) )); assert_noop!( XcmPallet::force_unsubscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()) + Box::new(remote.clone().into()) ), Error::::NoSubscription, ); @@ -637,13 +646,13 @@ fn unsubscribe_works() { take_sent_xcm(), vec![ ( - remote, + remote.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), ), - (remote, Xcm(vec![UnsubscribeVersion]),), + (remote.clone(), Xcm(vec![UnsubscribeVersion]),), ] ); }); @@ -655,13 +664,19 @@ fn subscription_side_works() { new_test_ext_with_balances(vec![]).execute_with(|| { AdvertisedXcmVersion::set(1); - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); let weight = BaseXcmWeight::get(); let message = Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let instr = QueryResponse { query_id: 0, @@ -669,7 +684,7 @@ fn subscription_side_works() { response: Response::Version(1), querier: None, }; - assert_eq!(take_sent_xcm(), vec![(remote, Xcm(vec![instr]))]); + assert_eq!(take_sent_xcm(), vec![(remote.clone(), Xcm(vec![instr]))]); // A runtime upgrade which doesn't alter the version sends no notifications. CurrentMigration::::put(VersionMigrationStage::default()); @@ -698,7 +713,7 @@ fn subscription_side_upgrades_work_with_notify() { AdvertisedXcmVersion::set(1); // An entry from a previous runtime with v2 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); @@ -751,7 +766,7 @@ fn subscription_side_upgrades_work_with_notify() { fn subscription_side_upgrades_work_without_notify() { new_test_ext_with_balances(vec![]).execute_with(|| { // An entry from a previous runtime with v2 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 2)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 2)); @@ -765,8 +780,8 @@ fn subscription_side_upgrades_work_without_notify() { assert_eq!( contents, vec![ - (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 3)), - (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 3)), + (XCM_VERSION, Parachain(1001).into_versioned(), (70, Weight::zero(), 4)), + (XCM_VERSION, Parachain(1003).into_versioned(), (72, Weight::zero(), 4)), ] ); }); @@ -775,10 +790,10 @@ fn subscription_side_upgrades_work_without_notify() { #[test] fn subscriber_side_subscription_works() { new_test_ext_with_balances_and_xcm_version(vec![], Some(XCM_VERSION)).execute_with(|| { - let remote: MultiLocation = Parachain(1000).into(); + let remote: Location = Parachain(1000).into(); assert_ok!(XcmPallet::force_subscribe_version_notify( RuntimeOrigin::root(), - Box::new(remote.into()), + Box::new(remote.clone().into()), )); assert_eq!(XcmPallet::get_version_for(&remote), None); take_sent_xcm(); @@ -795,9 +810,15 @@ fn subscriber_side_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(take_sent_xcm(), vec![]); assert_eq!(XcmPallet::get_version_for(&remote), Some(1)); @@ -814,9 +835,15 @@ fn subscriber_side_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(take_sent_xcm(), vec![]); assert_eq!(XcmPallet::get_version_for(&remote), Some(2)); @@ -832,73 +859,79 @@ fn subscriber_side_subscription_works() { #[test] fn auto_subscription_works() { new_test_ext_with_balances_and_xcm_version(vec![], None).execute_with(|| { - let remote_v2: MultiLocation = Parachain(1000).into(); - let remote_v3: MultiLocation = Parachain(1001).into(); + let remote_v2: Location = Parachain(1000).into(); + let remote_v4: Location = Parachain(1001).into(); assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(2))); // Wrapping a version for a destination we don't know elicits a subscription. let msg_v2 = xcm::v2::Xcm::<()>(vec![xcm::v2::Instruction::Trap(0)]); - let msg_v3 = xcm::v3::Xcm::<()>(vec![xcm::v3::Instruction::ClearTopic]); + let msg_v4 = xcm::v4::Xcm::<()>(vec![xcm::v4::Instruction::ClearTopic]); assert_eq!( XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), Ok(VersionedXcm::from(msg_v2.clone())), ); - assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v4.clone()), Err(())); - let expected = vec![(remote_v2.into(), 2)]; + let expected = vec![(remote_v2.clone().into(), 2)]; assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), + XcmPallet::wrap_version(&remote_v4, msg_v2.clone()), Ok(VersionedXcm::from(msg_v2.clone())), ); - assert_eq!(XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v4, msg_v4.clone()), Err(())); - let expected = vec![(remote_v2.into(), 2), (remote_v3.into(), 2)]; + let expected = vec![(remote_v2.clone().into(), 2), (remote_v4.clone().into(), 2)]; assert_eq!(VersionDiscoveryQueue::::get().into_inner(), expected); XcmPallet::on_initialize(1); assert_eq!( take_sent_xcm(), vec![( - remote_v3, + remote_v4.clone(), Xcm(vec![SubscribeVersion { query_id: 0, max_response_weight: Weight::zero() }]), )] ); - // Assume remote_v3 is working ok and XCM version 3. + // Assume remote_v4 is working ok and XCM version 4. let weight = BaseXcmWeight::get(); let message = Xcm(vec![ - // Remote supports XCM v3 + // Remote supports XCM v4 QueryResponse { query_id: 0, max_weight: Weight::zero(), - response: Response::Version(3), + response: Response::Version(4), querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote_v3, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote_v4.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); - // V2 messages can be sent to remote_v3 under XCM v3. + // V2 messages can be sent to remote_v4 under XCM v4. assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v2.clone()), - Ok(VersionedXcm::from(msg_v2.clone()).into_version(3).unwrap()), + XcmPallet::wrap_version(&remote_v4, msg_v2.clone()), + Ok(VersionedXcm::from(msg_v2.clone()).into_version(4).unwrap()), ); - // This message can now be sent to remote_v3 as it's v3. + // This message can now be sent to remote_v4 as it's v4. assert_eq!( - XcmPallet::wrap_version(&remote_v3, msg_v3.clone()), - Ok(VersionedXcm::from(msg_v3.clone())) + XcmPallet::wrap_version(&remote_v4, msg_v4.clone()), + Ok(VersionedXcm::from(msg_v4.clone())) ); XcmPallet::on_initialize(2); assert_eq!( take_sent_xcm(), vec![( - remote_v2, + remote_v2.clone(), Xcm(vec![SubscribeVersion { query_id: 1, max_response_weight: Weight::zero() }]), )] ); @@ -915,16 +948,22 @@ fn auto_subscription_works() { querier: None, }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(remote_v2, message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + remote_v2.clone(), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); - // v3 messages cannot be sent to remote_v2... + // v4 messages cannot be sent to remote_v2... assert_eq!( XcmPallet::wrap_version(&remote_v2, msg_v2.clone()), Ok(VersionedXcm::V2(msg_v2)) ); - assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v3.clone()), Err(())); + assert_eq!(XcmPallet::wrap_version(&remote_v2, msg_v4.clone()), Err(())); }) } @@ -934,9 +973,9 @@ fn subscription_side_upgrades_work_with_multistage_notify() { AdvertisedXcmVersion::set(1); // An entry from a previous runtime with v0 XCM. - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1001).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1001).into()); VersionNotifyTargets::::insert(1, v2_location, (70, Weight::zero(), 1)); - let v2_location = VersionedMultiLocation::V2(xcm::v2::Junction::Parachain(1002).into()); + let v2_location = VersionedLocation::V2(xcm::v2::Junction::Parachain(1002).into()); VersionNotifyTargets::::insert(2, v2_location, (71, Weight::zero(), 1)); let v3_location = Parachain(1003).into_versioned(); VersionNotifyTargets::::insert(3, v3_location, (72, Weight::zero(), 1)); @@ -1003,9 +1042,9 @@ fn subscription_side_upgrades_work_with_multistage_notify() { #[test] fn get_and_wrap_version_works() { new_test_ext_with_balances_and_xcm_version(vec![], None).execute_with(|| { - let remote_a: MultiLocation = Parachain(1000).into(); - let remote_b: MultiLocation = Parachain(1001).into(); - let remote_c: MultiLocation = Parachain(1002).into(); + let remote_a: Location = Parachain(1000).into(); + let remote_b: Location = Parachain(1001).into(); + let remote_c: Location = Parachain(1002).into(); // no `safe_xcm_version` version at `GenesisConfig` assert_eq!(XcmPallet::get_version_for(&remote_a), None); @@ -1023,7 +1062,7 @@ fn get_and_wrap_version_works() { // set XCM version only for `remote_a` assert_ok!(XcmPallet::force_xcm_version( RuntimeOrigin::root(), - Box::new(remote_a), + Box::new(remote_a.clone()), XCM_VERSION )); assert_eq!(XcmPallet::get_version_for(&remote_a), Some(XCM_VERSION)); @@ -1041,7 +1080,10 @@ fn get_and_wrap_version_works() { // does not work because remote_b has unknown version and default is set to 1, and // `XCM_VERSION` cannot be wrapped to the `1` assert_eq!(XcmPallet::wrap_version(&remote_b, xcm.clone()), Err(())); - assert_eq!(VersionDiscoveryQueue::::get().into_inner(), vec![(remote_b.into(), 1)]); + assert_eq!( + VersionDiscoveryQueue::::get().into_inner(), + vec![(remote_b.clone().into(), 1)] + ); // set default to the `XCM_VERSION` assert_ok!(XcmPallet::force_default_xcm_version(RuntimeOrigin::root(), Some(XCM_VERSION))); @@ -1053,10 +1095,17 @@ fn get_and_wrap_version_works() { XcmPallet::wrap_version(&remote_b, xcm.clone()), Ok(VersionedXcm::from(xcm.clone())) ); - assert_eq!(VersionDiscoveryQueue::::get().into_inner(), vec![(remote_b.into(), 2)]); + assert_eq!( + VersionDiscoveryQueue::::get().into_inner(), + vec![(remote_b.clone().into(), 2)] + ); // change remote_c to `1` - assert_ok!(XcmPallet::force_xcm_version(RuntimeOrigin::root(), Box::new(remote_c), 1)); + assert_ok!(XcmPallet::force_xcm_version( + RuntimeOrigin::root(), + Box::new(remote_c.clone()), + 1 + )); // does not work because remote_c has `1` and default is `XCM_VERSION` which cannot be // wrapped to the `1` diff --git a/polkadot/xcm/procedural/src/lib.rs b/polkadot/xcm/procedural/src/lib.rs index 7600e817d0e..4980d84d328 100644 --- a/polkadot/xcm/procedural/src/lib.rs +++ b/polkadot/xcm/procedural/src/lib.rs @@ -22,6 +22,7 @@ use syn::{parse_macro_input, DeriveInput}; mod builder_pattern; mod v2; mod v3; +mod v4; mod weight_info; #[proc_macro] @@ -31,6 +32,13 @@ pub fn impl_conversion_functions_for_multilocation_v2(input: TokenStream) -> Tok .into() } +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v2(input: TokenStream) -> TokenStream { + v2::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + #[proc_macro_derive(XcmWeightInfoTrait)] pub fn derive_xcm_weight_info(item: TokenStream) -> TokenStream { weight_info::derive(item) @@ -50,6 +58,20 @@ pub fn impl_conversion_functions_for_junctions_v3(input: TokenStream) -> TokenSt .into() } +#[proc_macro] +pub fn impl_conversion_functions_for_location_v4(input: TokenStream) -> TokenStream { + v4::location::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn impl_conversion_functions_for_junctions_v4(input: TokenStream) -> TokenStream { + v4::junctions::generate_conversion_functions(input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + /// This is called on the `Instruction` enum, not on the `Xcm` struct, /// and allows for the following syntax for building XCMs: /// let message = Xcm::builder() diff --git a/polkadot/xcm/procedural/src/v2.rs b/polkadot/xcm/procedural/src/v2.rs index dc2694a666f..1a2f281a498 100644 --- a/polkadot/xcm/procedural/src/v2.rs +++ b/polkadot/xcm/procedural/src/v2.rs @@ -14,10 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + pub mod multilocation { - use proc_macro2::{Span, TokenStream}; - use quote::{format_ident, quote}; - use syn::{Result, Token}; + use super::*; pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { if !input.is_empty() { @@ -181,3 +183,44 @@ pub mod multilocation { } } } + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")); + } + + let from_slice_syntax = generate_conversion_from_slice_syntax(); + + Ok(quote! { + #from_slice_syntax + }) + } + + fn generate_conversion_from_slice_syntax() -> TokenStream { + quote! { + macro_rules! impl_junction { + ($count:expr, $variant:ident, ($($index:literal),+)) => { + /// Additional helper for building junctions + /// Useful for converting to future XCM versions + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant($(junctions[$index].clone()),*) + } + } + }; + } + + impl_junction!(1, X1, (0)); + impl_junction!(2, X2, (0, 1)); + impl_junction!(3, X3, (0, 1, 2)); + impl_junction!(4, X4, (0, 1, 2, 3)); + impl_junction!(5, X5, (0, 1, 2, 3, 4)); + impl_junction!(6, X6, (0, 1, 2, 3, 4, 5)); + impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6)); + impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7)); + } + } +} diff --git a/polkadot/xcm/procedural/src/v3.rs b/polkadot/xcm/procedural/src/v3.rs index 246f90a46a3..f0556d5a8d4 100644 --- a/polkadot/xcm/procedural/src/v3.rs +++ b/polkadot/xcm/procedural/src/v3.rs @@ -45,9 +45,8 @@ pub mod multilocation { let interior = if num_junctions == 0 { quote!(Junctions::Here) } else { - let variant = format_ident!("X{}", num_junctions); quote! { - Junctions::#variant( #(#idents .into()),* ) + [#(#idents .into()),*].into() } }; @@ -110,7 +109,7 @@ pub mod multilocation { impl From for MultiLocation { fn from(x: Junction) -> Self { - MultiLocation { parents: 0, interior: Junctions::X1(x) } + MultiLocation { parents: 0, interior: [x].into() } } } @@ -129,10 +128,12 @@ pub mod junctions { // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. let from_v2 = generate_conversion_from_v2(MAX_JUNCTIONS); + let from_v4 = generate_conversion_from_v4(); let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); Ok(quote! { #from_v2 + #from_v4 #from_tuples }) } @@ -143,12 +144,11 @@ pub mod junctions { let idents = (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); - let variant = &format_ident!("X{}", num_junctions); quote! { impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { - Self::#variant( #(#idents .into()),* ) + [#(#idents .into()),*].into() } } } @@ -156,6 +156,45 @@ pub mod junctions { .collect() } + fn generate_conversion_from_v4() -> TokenStream { + let match_variants = (0..8u8) + .map(|current_number| { + let number_ancestors = current_number + 1; + let variant = format_ident!("X{}", number_ancestors); + let idents = + (0..=current_number).map(|i| format_ident!("j{}", i)).collect::>(); + let convert = idents + .iter() + .map(|ident| { + quote! { let #ident = core::convert::TryInto::try_into(#ident.clone())?; } + }) + .collect::>(); + + quote! { + crate::v4::Junctions::#variant( junctions ) => { + let [#(#idents),*] = &*junctions; + #(#convert);* + [#(#idents),*].into() + }, + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + + fn try_from(mut new: crate::v4::Junctions) -> core::result::Result { + use Junctions::*; + Ok(match new { + crate::v4::Junctions::Here => Here, + #match_variants + }) + } + } + } + } + fn generate_conversion_from_v2(max_junctions: usize) -> TokenStream { let match_variants = (0..max_junctions) .map(|cur_num| { diff --git a/polkadot/xcm/procedural/src/v4.rs b/polkadot/xcm/procedural/src/v4.rs new file mode 100644 index 00000000000..5f5e10d3081 --- /dev/null +++ b/polkadot/xcm/procedural/src/v4.rs @@ -0,0 +1,196 @@ +// 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 . + +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{Result, Token}; + +const MAX_JUNCTIONS: usize = 8; + +pub mod location { + use super::*; + + /// Generates conversion functions from other types to the `Location` type: + /// - [PalletInstance(50), GeneralIndex(1984)].into() + /// - (Parent, Parachain(1000), AccountId32 { .. }).into() + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + let from_tuples = generate_conversion_from_tuples(8, 8); + + Ok(quote! { + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize, max_parents: usize) -> TokenStream { + let mut from_tuples = (0..=max_junctions) + .map(|num_junctions| { + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let array_size = num_junctions; + let interior = if num_junctions == 0 { + quote!(Junctions::Here) + } else { + let variant = format_ident!("X{}", num_junctions); + quote! { + Junctions::#variant( alloc::sync::Arc::new( [#(#idents .into()),*] ) ) + } + }; + + let mut from_tuple = quote! { + impl< #(#types : Into,)* > From<( Ancestor, #( #types ),* )> for Location { + fn from( ( Ancestor(parents), #(#idents),* ): ( Ancestor, #( #types ),* ) ) -> Self { + Location { parents, interior: #interior } + } + } + + impl From<[Junction; #array_size]> for Location { + fn from(j: [Junction; #array_size]) -> Self { + let [#(#idents),*] = j; + Location { parents: 0, interior: #interior } + } + } + }; + + let from_parent_tuples = (0..=max_parents).map(|cur_parents| { + let parents = + (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl< #(#types : Into,)* > From<( #( #parents , )* #( #types , )* )> for Location { + fn from( ( #(#underscores,)* #(#idents,)* ): ( #(#parents,)* #(#types,)* ) ) -> Self { + Self { parents: #cur_parents as u8, interior: #interior } + } + } + } + }); + + from_tuple.extend(from_parent_tuples); + from_tuple + }) + .collect::(); + + let from_parent_junctions_tuples = (0..=max_parents).map(|cur_parents| { + let parents = (0..cur_parents).map(|_| format_ident!("Parent")).collect::>(); + let underscores = + (0..cur_parents).map(|_| Token![_](Span::call_site())).collect::>(); + + quote! { + impl From<( #(#parents,)* Junctions )> for Location { + fn from( (#(#underscores,)* junctions): ( #(#parents,)* Junctions ) ) -> Self { + Location { parents: #cur_parents as u8, interior: junctions } + } + } + } + }); + from_tuples.extend(from_parent_junctions_tuples); + + quote! { + impl From<(Ancestor, Junctions)> for Location { + fn from((Ancestor(parents), interior): (Ancestor, Junctions)) -> Self { + Location { parents, interior } + } + } + + impl From for Location { + fn from(x: Junction) -> Self { + Location { parents: 0, interior: [x].into() } + } + } + + #from_tuples + } + } +} + +pub mod junctions { + use super::*; + + pub fn generate_conversion_functions(input: proc_macro::TokenStream) -> Result { + if !input.is_empty() { + return Err(syn::Error::new(Span::call_site(), "No arguments expected")) + } + + // Support up to 8 Parents in a tuple, assuming that most use cases don't go past 8 parents. + let from_v3 = generate_conversion_from_v3(MAX_JUNCTIONS); + let from_tuples = generate_conversion_from_tuples(MAX_JUNCTIONS); + + Ok(quote! { + #from_v3 + #from_tuples + }) + } + + fn generate_conversion_from_tuples(max_junctions: usize) -> TokenStream { + (1..=max_junctions) + .map(|num_junctions| { + let idents = + (0..num_junctions).map(|i| format_ident!("j{}", i)).collect::>(); + let types = (0..num_junctions).map(|i| format_ident!("J{}", i)).collect::>(); + + quote! { + impl<#(#types : Into,)*> From<( #(#types,)* )> for Junctions { + fn from( ( #(#idents,)* ): ( #(#types,)* ) ) -> Self { + [#(#idents .into()),*].into() + } + } + } + }) + .collect() + } + + fn generate_conversion_from_v3(max_junctions: usize) -> TokenStream { + let match_variants = (0..max_junctions) + .map(|cur_num| { + let num_ancestors = cur_num + 1; + let variant = format_ident!("X{}", num_ancestors); + let idents = (0..=cur_num).map(|i| format_ident!("j{}", i)).collect::>(); + let convert = idents + .iter() + .map(|ident| { + quote! { let #ident = core::convert::TryInto::try_into(#ident.clone())?; } + }) + .collect::>(); + + quote! { + crate::v3::Junctions::#variant( #(#idents),* ) => { + #(#convert);*; + let junctions: Junctions = [#(#idents),*].into(); + junctions + }, + } + }) + .collect::(); + + quote! { + impl core::convert::TryFrom for Junctions { + type Error = (); + fn try_from(mut old: crate::v3::Junctions) -> core::result::Result { + Ok(match old { + crate::v3::Junctions::Here => Junctions::Here, + #match_variants + }) + } + } + } + } +} diff --git a/polkadot/xcm/procedural/tests/builder_pattern.rs b/polkadot/xcm/procedural/tests/builder_pattern.rs index eab9d67121f..a9a30611dc0 100644 --- a/polkadot/xcm/procedural/tests/builder_pattern.rs +++ b/polkadot/xcm/procedural/tests/builder_pattern.rs @@ -21,12 +21,12 @@ use xcm::latest::prelude::*; #[test] fn builder_pattern_works() { - let asset: MultiAsset = (Here, 100u128).into(); - let beneficiary: MultiLocation = AccountId32 { id: [0u8; 32], network: None }.into(); + let asset: Asset = (Here, 100u128).into(); + let beneficiary: Location = AccountId32 { id: [0u8; 32], network: None }.into(); let message: Xcm<()> = Xcm::builder() .receive_teleported_asset(asset.clone().into()) .buy_execution(asset.clone(), Unlimited) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); assert_eq!( message, @@ -40,8 +40,8 @@ fn builder_pattern_works() { #[test] fn default_builder_requires_buy_execution() { - let asset: MultiAsset = (Here, 100u128).into(); - let beneficiary: MultiLocation = AccountId32 { id: [0u8; 32], network: None }.into(); + let asset: Asset = (Here, 100u128).into(); + let beneficiary: Location = AccountId32 { id: [0u8; 32], network: None }.into(); // This is invalid, since it doesn't pay for fees. // This is enforced by the runtime, because the build() method doesn't exist // on the resulting type. @@ -54,14 +54,14 @@ fn default_builder_requires_buy_execution() { let message: Xcm<()> = Xcm::builder_unpaid() .unpaid_execution(Unlimited, None) .withdraw_asset(asset.clone().into()) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); // This works assert_eq!( message, Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, WithdrawAsset(asset.clone().into()), - DepositAsset { assets: asset.clone().into(), beneficiary }, + DepositAsset { assets: asset.clone().into(), beneficiary: beneficiary.clone() }, ]) ); @@ -69,7 +69,7 @@ fn default_builder_requires_buy_execution() { // only be used when you really know what you're doing. let message: Xcm<()> = Xcm::builder_unsafe() .withdraw_asset(asset.clone().into()) - .deposit_asset(asset.clone().into(), beneficiary) + .deposit_asset(asset.clone().into(), beneficiary.clone()) .build(); assert_eq!( message, diff --git a/polkadot/xcm/procedural/tests/conversion_functions.rs b/polkadot/xcm/procedural/tests/conversion_functions.rs new file mode 100644 index 00000000000..5b6965167fc --- /dev/null +++ b/polkadot/xcm/procedural/tests/conversion_functions.rs @@ -0,0 +1,24 @@ +// 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 . + +use xcm::v2::prelude::*; + +#[test] +fn slice_syntax_in_v2_works() { + let old_junctions = Junctions::X2(Parachain(1), PalletInstance(1)); + let new_junctions = Junctions::from([Parachain(1), PalletInstance(1)]); + assert_eq!(old_junctions, new_junctions); +} diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs index ddad0b5303b..f0cbe985331 100644 --- a/polkadot/xcm/src/lib.rs +++ b/polkadot/xcm/src/lib.rs @@ -30,13 +30,14 @@ use scale_info::TypeInfo; pub mod v2; pub mod v3; +pub mod v4; pub mod lts { - pub use super::v3::*; + pub use super::v4::*; } pub mod latest { - pub use super::v3::*; + pub use super::v4::*; } mod double_encoded; @@ -79,6 +80,8 @@ macro_rules! versioned_type { ($(#[$attr:meta])* pub enum $n:ident { $(#[$index3:meta])+ V3($v3:ty), + $(#[$index4:meta])+ + V4($v4:ty), }) => { #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative( @@ -94,6 +97,8 @@ macro_rules! versioned_type { pub enum $n { $(#[$index3])* V3($v3), + $(#[$index4])* + V4($v4), } impl $n { pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { @@ -104,6 +109,15 @@ macro_rules! versioned_type { fn try_as(&self) -> Result<&$v3, ()> { match &self { Self::V3(ref x) => Ok(x), + _ => Err(()), + } + } + } + impl TryAs<$v4> for $n { + fn try_as(&self) -> Result<&$v4, ()> { + match &self { + Self::V4(ref x) => Ok(x), + _ => Err(()), } } } @@ -111,21 +125,38 @@ macro_rules! versioned_type { fn into_version(self, n: Version) -> Result { Ok(match n { 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } } - impl> From for $n { - fn from(x: T) -> Self { + impl From<$v3> for $n { + fn from(x: $v3) -> Self { $n::V3(x.into()) } } + impl From<$v4> for $n { + fn from(x: $v4) -> Self { + $n::V4(x.into()) + } + } impl TryFrom<$n> for $v3 { type Error = (); fn try_from(x: $n) -> Result { use $n::*; match x { V3(x) => Ok(x), + V4(x) => x.try_into(), + } + } + } + impl TryFrom<$n> for $v4 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V3(x) => x.try_into().map_err(|_| ()), + V4(x) => Ok(x), } } } @@ -141,6 +172,8 @@ macro_rules! versioned_type { V2($v2:ty), $(#[$index3:meta])+ V3($v3:ty), + $(#[$index4:meta])+ + V4($v4:ty), }) => { #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative( @@ -158,6 +191,8 @@ macro_rules! versioned_type { V2($v2), $(#[$index3])* V3($v3), + $(#[$index4])* + V4($v4), } impl $n { pub fn try_as(&self) -> Result<&T, ()> where Self: TryAs { @@ -180,11 +215,20 @@ macro_rules! versioned_type { } } } + impl TryAs<$v4> for $n { + fn try_as(&self) -> Result<&$v4, ()> { + match &self { + Self::V4(ref x) => Ok(x), + _ => Err(()), + } + } + } impl IntoVersion for $n { fn into_version(self, n: Version) -> Result { Ok(match n { 1 | 2 => Self::V2(self.try_into()?), 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } @@ -194,9 +238,9 @@ macro_rules! versioned_type { $n::V2(x) } } - impl> From for $n { + impl> From for $n { fn from(x: T) -> Self { - $n::V3(x.into()) + $n::V4(x.into()) } } impl TryFrom<$n> for $v2 { @@ -206,6 +250,10 @@ macro_rules! versioned_type { match x { V2(x) => Ok(x), V3(x) => x.try_into(), + V4(x) => { + let v3: $v3 = x.try_into().map_err(|_| ())?; + v3.try_into() + }, } } } @@ -216,6 +264,21 @@ macro_rules! versioned_type { match x { V2(x) => x.try_into(), V3(x) => Ok(x), + V4(x) => x.try_into().map_err(|_| ()), + } + } + } + impl TryFrom<$n> for $v4 { + type Error = (); + fn try_from(x: $n) -> Result { + use $n::*; + match x { + V2(x) => { + let v3: $v3 = x.try_into().map_err(|_| ())?; + v3.try_into().map_err(|_| ()) + }, + V3(x) => x.try_into().map_err(|_| ()), + V4(x) => Ok(x), } } } @@ -228,10 +291,12 @@ macro_rules! versioned_type { } versioned_type! { - /// A single version's `Response` value, together with its version code. + /// A single version's `AssetId` value, together with its version code. pub enum VersionedAssetId { #[codec(index = 3)] V3(v3::AssetId), + #[codec(index = 4)] + V4(v4::AssetId), } } @@ -242,6 +307,8 @@ versioned_type! { V2(v2::Response), #[codec(index = 3)] V3(v3::Response), + #[codec(index = 4)] + V4(v4::Response), } } @@ -252,6 +319,8 @@ versioned_type! { V2(v2::NetworkId), #[codec(index = 3)] V3(v3::NetworkId), + #[codec(index = 4)] + V4(v4::NetworkId), } } @@ -262,50 +331,72 @@ versioned_type! { V2(v2::Junction), #[codec(index = 3)] V3(v3::Junction), + #[codec(index = 4)] + V4(v4::Junction), } } versioned_type! { - /// A single `MultiLocation` value, together with its version code. + /// A single `Location` value, together with its version code. #[derive(Ord, PartialOrd)] - pub enum VersionedMultiLocation { + pub enum VersionedLocation { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiLocation), #[codec(index = 3)] V3(v3::MultiLocation), + #[codec(index = 4)] + V4(v4::Location), } } +#[deprecated(note = "Use `VersionedLocation` instead")] +pub type VersionedMultiLocation = VersionedLocation; + versioned_type! { - /// A single `InteriorMultiLocation` value, together with its version code. - pub enum VersionedInteriorMultiLocation { - #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorMultiLocation is introduced in v3 + /// A single `InteriorLocation` value, together with its version code. + pub enum VersionedInteriorLocation { + #[codec(index = 2)] // while this is same as v1::Junctions, VersionedInteriorLocation is introduced in v3 V2(v2::InteriorMultiLocation), #[codec(index = 3)] V3(v3::InteriorMultiLocation), + #[codec(index = 4)] + V4(v4::InteriorLocation), } } +#[deprecated(note = "Use `VersionedInteriorLocation` instead")] +pub type VersionedInteriorMultiLocation = VersionedInteriorLocation; + versioned_type! { - /// A single `MultiAsset` value, together with its version code. - pub enum VersionedMultiAsset { + /// A single `Asset` value, together with its version code. + pub enum VersionedAsset { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiAsset), #[codec(index = 3)] V3(v3::MultiAsset), + #[codec(index = 4)] + V4(v4::Asset), } } +#[deprecated(note = "Use `VersionedAsset` instead")] +pub type VersionedMultiAsset = VersionedAsset; + versioned_type! { /// A single `MultiAssets` value, together with its version code. - pub enum VersionedMultiAssets { + pub enum VersionedAssets { #[codec(index = 1)] // v2 is same as v1 and therefore re-using the v1 index V2(v2::MultiAssets), #[codec(index = 3)] V3(v3::MultiAssets), + #[codec(index = 4)] + V4(v4::Assets), } } +#[deprecated(note = "Use `VersionedAssets` instead")] +pub type VersionedMultiAssets = VersionedAssets; + /// A single XCM message, together with its version code. #[derive(Derivative, Encode, Decode, TypeInfo)] #[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] @@ -318,6 +409,8 @@ pub enum VersionedXcm { V2(v2::Xcm), #[codec(index = 3)] V3(v3::Xcm), + #[codec(index = 4)] + V4(v4::Xcm), } impl IntoVersion for VersionedXcm { @@ -325,6 +418,7 @@ impl IntoVersion for VersionedXcm { Ok(match n { 2 => Self::V2(self.try_into()?), 3 => Self::V3(self.try_into()?), + 4 => Self::V4(self.try_into()?), _ => return Err(()), }) } @@ -342,6 +436,12 @@ impl From> for VersionedXcm { } } +impl From> for VersionedXcm { + fn from(x: v4::Xcm) -> Self { + VersionedXcm::V4(x) + } +} + impl TryFrom> for v2::Xcm { type Error = (); fn try_from(x: VersionedXcm) -> Result { @@ -349,6 +449,10 @@ impl TryFrom> for v2::Xcm { match x { V2(x) => Ok(x), V3(x) => x.try_into(), + V4(x) => { + let v3: v3::Xcm = x.try_into()?; + v3.try_into() + }, } } } @@ -360,15 +464,31 @@ impl TryFrom> for v3::Xcm { match x { V2(x) => x.try_into(), V3(x) => Ok(x), + V4(x) => x.try_into(), + } + } +} + +impl TryFrom> for v4::Xcm { + type Error = (); + fn try_from(x: VersionedXcm) -> Result { + use VersionedXcm::*; + match x { + V2(x) => { + let v3: v3::Xcm = x.try_into()?; + v3.try_into() + }, + V3(x) => x.try_into(), + V4(x) => Ok(x), } } } -/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will +/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `Location` which will /// interpret it. pub trait WrapVersion { fn wrap_version( - dest: &latest::MultiLocation, + dest: &latest::Location, xcm: impl Into>, ) -> Result, ()>; } @@ -376,14 +496,14 @@ pub trait WrapVersion { /// Check and return the `Version` that should be used for the `Xcm` datum for the destination /// `MultiLocation`, which will interpret it. pub trait GetVersion { - fn get_version_for(dest: &latest::MultiLocation) -> Option; + fn get_version_for(dest: &latest::Location) -> Option; } /// `()` implementation does nothing with the XCM, just sending with whatever version it was /// authored as. impl WrapVersion for () { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(xcm.into()) @@ -395,14 +515,14 @@ impl WrapVersion for () { pub struct AlwaysV2; impl WrapVersion for AlwaysV2 { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(VersionedXcm::::V2(xcm.into().try_into()?)) } } impl GetVersion for AlwaysV2 { - fn get_version_for(_dest: &latest::MultiLocation) -> Option { + fn get_version_for(_dest: &latest::Location) -> Option { Some(v2::VERSION) } } @@ -412,31 +532,48 @@ impl GetVersion for AlwaysV2 { pub struct AlwaysV3; impl WrapVersion for AlwaysV3 { fn wrap_version( - _: &latest::MultiLocation, + _: &latest::Location, xcm: impl Into>, ) -> Result, ()> { Ok(VersionedXcm::::V3(xcm.into().try_into()?)) } } impl GetVersion for AlwaysV3 { - fn get_version_for(_dest: &latest::MultiLocation) -> Option { + fn get_version_for(_dest: &latest::Location) -> Option { Some(v3::VERSION) } } +/// `WrapVersion` implementation which attempts to always convert the XCM to version 3 before +/// wrapping it. +pub struct AlwaysV4; +impl WrapVersion for AlwaysV4 { + fn wrap_version( + _: &latest::Location, + xcm: impl Into>, + ) -> Result, ()> { + Ok(VersionedXcm::::V4(xcm.into().try_into()?)) + } +} +impl GetVersion for AlwaysV4 { + fn get_version_for(_dest: &latest::Location) -> Option { + Some(v4::VERSION) + } +} + /// `WrapVersion` implementation which attempts to always convert the XCM to the latest version /// before wrapping it. -pub type AlwaysLatest = AlwaysV3; +pub type AlwaysLatest = AlwaysV4; /// `WrapVersion` implementation which attempts to always convert the XCM to the most recent Long- /// Term-Support version before wrapping it. -pub type AlwaysLts = AlwaysV3; +pub type AlwaysLts = AlwaysV4; pub mod prelude { pub use super::{ - latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, GetVersion, IntoVersion, - Unsupported, Version as XcmVersion, VersionedAssetId, VersionedInteriorMultiLocation, - VersionedMultiAsset, VersionedMultiAssets, VersionedMultiLocation, VersionedResponse, + latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, AlwaysV4, GetVersion, + IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, VersionedAssetId, + VersionedAssets, VersionedInteriorLocation, VersionedLocation, VersionedResponse, VersionedXcm, WrapVersion, }; } @@ -454,13 +591,19 @@ pub mod opaque { // Then override with the opaque types in v3 pub use crate::v3::opaque::{Instruction, Xcm}; } + pub mod v4 { + // Everything from v4 + pub use crate::v4::*; + // Then override with the opaque types in v4 + pub use crate::v4::opaque::{Instruction, Xcm}; + } pub mod latest { - pub use super::v3::*; + pub use super::v4::*; } pub mod lts { - pub use super::v3::*; + pub use super::v4::*; } /// The basic `VersionedXcm` type which just uses the `Vec` as an encoded call. @@ -470,5 +613,56 @@ pub mod opaque { #[test] fn conversion_works() { use latest::prelude::*; - let _: VersionedMultiAssets = (Here, 1u128).into(); + let assets: Assets = (Here, 1u128).into(); + let _: VersionedAssets = assets.into(); +} + +#[test] +fn size_limits() { + extern crate std; + + let mut test_failed = false; + macro_rules! check_sizes { + ($(($kind:ty, $expected:expr),)+) => { + $({ + let s = core::mem::size_of::<$kind>(); + // Since the types often affect the size of other types in which they're included + // it is more convenient to check multiple types at the same time and only fail + // the test at the end. For debugging it's also useful to print out all of the sizes, + // even if they're within the expected range. + if s > $expected { + test_failed = true; + std::eprintln!( + "assertion failed: size of '{}' is {} (which is more than the expected {})", + stringify!($kind), + s, + $expected + ); + } else { + std::println!( + "type '{}' is of size {} which is within the expected {}", + stringify!($kind), + s, + $expected + ); + } + })+ + } + } + + check_sizes! { + (crate::latest::Instruction<()>, 112), + (crate::latest::Asset, 80), + (crate::latest::Location, 24), + (crate::latest::AssetId, 40), + (crate::latest::Junctions, 16), + (crate::latest::Junction, 88), + (crate::latest::Response, 40), + (crate::latest::AssetInstance, 40), + (crate::latest::NetworkId, 48), + (crate::latest::BodyId, 32), + (crate::latest::Assets, 24), + (crate::latest::BodyPart, 12), + } + assert!(!test_failed); } diff --git a/polkadot/xcm/src/tests.rs b/polkadot/xcm/src/tests.rs index a3a60f6477c..1aabbcef281 100644 --- a/polkadot/xcm/src/tests.rs +++ b/polkadot/xcm/src/tests.rs @@ -59,79 +59,79 @@ fn encode_decode_versioned_response_v3() { #[test] fn encode_decode_versioned_multi_location_v2() { - let location = VersionedMultiLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); + let location = VersionedLocation::V2(v2::MultiLocation::new(0, v2::Junctions::Here)); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("010000"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); // this is introduced in v1 - let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_multi_location_v3() { - let location = VersionedMultiLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); + let location = VersionedLocation::V3(v3::MultiLocation::new(0, v3::Junctions::Here)); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("030000"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_interior_multi_location_v2() { - let location = VersionedInteriorMultiLocation::V2(v2::InteriorMultiLocation::Here); + let location = VersionedInteriorLocation::V2(v2::InteriorMultiLocation::Here); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("0200"), "encode format changed"); assert_eq!(encoded[0], 2, "bad version number"); - let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedInteriorLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_interior_multi_location_v3() { - let location = VersionedInteriorMultiLocation::V3(v3::InteriorMultiLocation::Here); + let location = VersionedInteriorLocation::V3(v3::InteriorMultiLocation::Here); let encoded = location.encode(); assert_eq!(encoded, hex_literal::hex!("0300"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedInteriorMultiLocation::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedInteriorLocation::decode(&mut &encoded[..]).unwrap(); assert_eq!(location, decoded); } #[test] fn encode_decode_versioned_multi_asset_v2() { - let asset = VersionedMultiAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); + let asset = VersionedAsset::V2(v2::MultiAsset::from(((0, v2::Junctions::Here), 1))); let encoded = asset.encode(); assert_eq!(encoded, hex_literal::hex!("010000000004"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); - let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAsset::decode(&mut &encoded[..]).unwrap(); assert_eq!(asset, decoded); } #[test] fn encode_decode_versioned_multi_asset_v3() { - let asset = VersionedMultiAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); + let asset = VersionedAsset::V3(v3::MultiAsset::from((v3::MultiLocation::default(), 1))); let encoded = asset.encode(); assert_eq!(encoded, hex_literal::hex!("030000000004"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiAsset::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAsset::decode(&mut &encoded[..]).unwrap(); assert_eq!(asset, decoded); } #[test] fn encode_decode_versioned_multi_assets_v2() { - let assets = VersionedMultiAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( + let assets = VersionedAssets::V2(v2::MultiAssets::from(vec![v2::MultiAsset::from(( (0, v2::Junctions::Here), 1, ))])); @@ -140,13 +140,13 @@ fn encode_decode_versioned_multi_assets_v2() { assert_eq!(encoded, hex_literal::hex!("01040000000004"), "encode format changed"); assert_eq!(encoded[0], 1, "bad version number"); - let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAssets::decode(&mut &encoded[..]).unwrap(); assert_eq!(assets, decoded); } #[test] fn encode_decode_versioned_multi_assets_v3() { - let assets = VersionedMultiAssets::V3(v3::MultiAssets::from(vec![ + let assets = VersionedAssets::V3(v3::MultiAssets::from(vec![ (v3::MultiAsset::from((v3::MultiLocation::default(), 1))), ])); let encoded = assets.encode(); @@ -154,7 +154,7 @@ fn encode_decode_versioned_multi_assets_v3() { assert_eq!(encoded, hex_literal::hex!("03040000000004"), "encode format changed"); assert_eq!(encoded[0], 3, "bad version number"); - let decoded = VersionedMultiAssets::decode(&mut &encoded[..]).unwrap(); + let decoded = VersionedAssets::decode(&mut &encoded[..]).unwrap(); assert_eq!(assets, decoded); } @@ -187,6 +187,8 @@ fn encode_decode_versioned_xcm_v3() { #[test] fn ensure_type_info_is_correct() { let type_info = VersionedXcm::<()>::type_info(); - assert_eq!(type_info.path.segments, vec!["xcm", "VersionedXcm"]); + + let type_info = VersionedAssetId::type_info(); + assert_eq!(type_info.path.segments, vec!["xcm", "VersionedAssetId"]); } diff --git a/polkadot/xcm/src/v2/multilocation.rs b/polkadot/xcm/src/v2/multilocation.rs index 81b67eee974..60aa1f6cead 100644 --- a/polkadot/xcm/src/v2/multilocation.rs +++ b/polkadot/xcm/src/v2/multilocation.rs @@ -75,8 +75,8 @@ impl MultiLocation { MultiLocation { parents, interior: junctions } } - /// Consume `self` and return the equivalent `VersionedMultiLocation` value. - pub fn versioned(self) -> crate::VersionedMultiLocation { + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub fn versioned(self) -> crate::VersionedLocation { self.into() } @@ -240,9 +240,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)); + /// let mut m = MultiLocation::new(1, [PalletInstance(3), OnlyChild].into()); /// assert_eq!( - /// m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3)))), + /// m.match_and_split(&MultiLocation::new(1, [PalletInstance(3)].into())), /// Some(&OnlyChild), /// ); /// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here)), None); @@ -260,10 +260,10 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let m = MultiLocation::new(1, X3(PalletInstance(3), OnlyChild, OnlyChild)); - /// assert!(m.starts_with(&MultiLocation::new(1, X1(PalletInstance(3))))); - /// assert!(!m.starts_with(&MultiLocation::new(1, X1(GeneralIndex(99))))); - /// assert!(!m.starts_with(&MultiLocation::new(0, X1(PalletInstance(3))))); + /// let m = MultiLocation::new(1, [PalletInstance(3), OnlyChild, OnlyChild].into()); + /// assert!(m.starts_with(&MultiLocation::new(1, [PalletInstance(3)].into()))); + /// assert!(!m.starts_with(&MultiLocation::new(1, [GeneralIndex(99)].into()))); + /// assert!(!m.starts_with(&MultiLocation::new(0, [PalletInstance(3)].into()))); /// ``` pub fn starts_with(&self, prefix: &MultiLocation) -> bool { if self.parents != prefix.parents { @@ -279,9 +279,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(1, X1(Parachain(21))); - /// assert_eq!(m.append_with(X1(PalletInstance(3))), Ok(())); - /// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3)))); + /// let mut m = MultiLocation::new(1, [Parachain(21)].into()); + /// assert_eq!(m.append_with([PalletInstance(3)].into()), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, [Parachain(21), PalletInstance(3)].into())); /// ``` pub fn append_with(&mut self, suffix: Junctions) -> Result<(), Junctions> { if self.interior.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { @@ -300,9 +300,9 @@ impl MultiLocation { /// # Example /// ```rust /// # use staging_xcm::v2::{Junctions::*, Junction::*, MultiLocation}; - /// let mut m = MultiLocation::new(2, X1(PalletInstance(3))); - /// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild))), Ok(())); - /// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3)))); + /// let mut m = MultiLocation::new(2, [PalletInstance(3)].into()); + /// assert_eq!(m.prepend_with(MultiLocation::new(1, [Parachain(21), OnlyChild].into())), Ok(())); + /// assert_eq!(m, MultiLocation::new(1, [PalletInstance(3)].into())); /// ``` pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> { // prefix self (suffix) @@ -455,6 +455,7 @@ impl> From> for MultiLocation { } xcm_procedural::impl_conversion_functions_for_multilocation_v2!(); +xcm_procedural::impl_conversion_functions_for_junctions_v2!(); /// Maximum number of `Junction`s that a `Junctions` can contain. const MAX_JUNCTIONS: usize = 8; diff --git a/polkadot/xcm/src/v2/traits.rs b/polkadot/xcm/src/v2/traits.rs index 6453f91a1f1..9cfb9b051ab 100644 --- a/polkadot/xcm/src/v2/traits.rs +++ b/polkadot/xcm/src/v2/traits.rs @@ -292,11 +292,12 @@ pub type SendResult = result::Result<(), SendError>; /// } /// } /// -/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing. +/// /// A sender that accepts a message that has two junctions, otherwise stops the routing. /// struct Sender2; /// impl SendXcm for Sender2 { /// fn send_xcm(destination: impl Into, message: Xcm<()>) -> SendResult { -/// if let MultiLocation { parents: 0, interior: X2(j1, j2) } = destination.into() { +/// let destination = destination.into(); +/// if destination.parents == 0 && destination.interior.len() == 2 { /// Ok(()) /// } else { /// Err(SendError::Unroutable) diff --git a/polkadot/xcm/src/v3/junction.rs b/polkadot/xcm/src/v3/junction.rs index 6ae339db2ae..e9e51941b1a 100644 --- a/polkadot/xcm/src/v3/junction.rs +++ b/polkadot/xcm/src/v3/junction.rs @@ -22,7 +22,8 @@ use crate::{ BodyId as OldBodyId, BodyPart as OldBodyPart, Junction as OldJunction, NetworkId as OldNetworkId, }, - VersionedMultiLocation, + v4::{Junction as NewJunction, NetworkId as NewNetworkId}, + VersionedLocation, }; use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; use core::convert::{TryFrom, TryInto}; @@ -104,6 +105,31 @@ impl TryFrom for NetworkId { } } +impl From for Option { + fn from(new: NewNetworkId) -> Self { + Some(NetworkId::from(new)) + } +} + +impl From for NetworkId { + fn from(new: NewNetworkId) -> Self { + use NewNetworkId::*; + match new { + ByGenesis(hash) => Self::ByGenesis(hash), + ByFork { block_number, block_hash } => Self::ByFork { block_number, block_hash }, + Polkadot => Self::Polkadot, + Kusama => Self::Kusama, + Westend => Self::Westend, + Rococo => Self::Rococo, + Wococo => Self::Wococo, + Ethereum { chain_id } => Self::Ethereum { chain_id }, + BitcoinCore => Self::BitcoinCore, + BitcoinCash => Self::BitcoinCash, + PolkadotBulletin => Self::PolkadotBulletin, + } + } +} + /// An identifier of a pluralistic body. #[derive( Copy, @@ -414,6 +440,29 @@ impl TryFrom for Junction { } } +impl TryFrom for Junction { + type Error = (); + + fn try_from(value: NewJunction) -> Result { + use NewJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network: maybe_network, id } => + Self::AccountId32 { network: maybe_network.map(|network| network.into()), id }, + AccountIndex64 { network: maybe_network, index } => + Self::AccountIndex64 { network: maybe_network.map(|network| network.into()), index }, + AccountKey20 { network: maybe_network, key } => + Self::AccountKey20 { network: maybe_network.map(|network| network.into()), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey { length, data }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id, part }, + GlobalConsensus(network) => Self::GlobalConsensus(network.into()), + }) + } +} + impl Junction { /// Convert `self` into a `MultiLocation` containing 0 parents. /// @@ -430,10 +479,10 @@ impl Junction { MultiLocation { parents: n, interior: Junctions::X1(self) } } - /// Convert `self` into a `VersionedMultiLocation` containing 0 parents. + /// Convert `self` into a `VersionedLocation` containing 0 parents. /// /// Similar to `Into::into`, except that this method can be used in a const evaluation context. - pub const fn into_versioned(self) -> VersionedMultiLocation { + pub const fn into_versioned(self) -> VersionedLocation { self.into_location().into_versioned() } diff --git a/polkadot/xcm/src/v3/junctions.rs b/polkadot/xcm/src/v3/junctions.rs index 88da20cb1a1..9748e81fa55 100644 --- a/polkadot/xcm/src/v3/junctions.rs +++ b/polkadot/xcm/src/v3/junctions.rs @@ -67,6 +67,27 @@ pub enum Junctions { X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction), } +macro_rules! impl_junction { + ($count:expr, $variant:ident, ($($index:literal),+)) => { + /// Additional helper for building junctions + /// Useful for converting to future XCM versions + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant($(junctions[$index]),*) + } + } + }; +} + +impl_junction!(1, X1, (0)); +impl_junction!(2, X2, (0, 1)); +impl_junction!(3, X3, (0, 1, 2)); +impl_junction!(4, X4, (0, 1, 2, 3)); +impl_junction!(5, X5, (0, 1, 2, 3, 4)); +impl_junction!(6, X6, (0, 1, 2, 3, 4, 5)); +impl_junction!(7, X7, (0, 1, 2, 3, 4, 5, 6)); +impl_junction!(8, X8, (0, 1, 2, 3, 4, 5, 6, 7)); + pub struct JunctionsIterator(Junctions); impl Iterator for JunctionsIterator { type Item = Junction; diff --git a/polkadot/xcm/src/v3/mod.rs b/polkadot/xcm/src/v3/mod.rs index 50b7a539122..1172cbf43e6 100644 --- a/polkadot/xcm/src/v3/mod.rs +++ b/polkadot/xcm/src/v3/mod.rs @@ -16,9 +16,15 @@ //! Version 3 of the Cross-Consensus Message format data structures. -use super::v2::{ - Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, - Xcm as OldXcm, +use super::{ + v2::{ + Instruction as OldInstruction, Response as OldResponse, WeightLimit as OldWeightLimit, + Xcm as OldXcm, + }, + v4::{ + Instruction as NewInstruction, PalletInfo as NewPalletInfo, + QueryResponseInfo as NewQueryResponseInfo, Response as NewResponse, Xcm as NewXcm, + }, }; use crate::DoubleEncoded; use alloc::{vec, vec::Vec}; @@ -48,7 +54,7 @@ pub use multiasset::{ WildFungibility, WildMultiAsset, MAX_ITEMS_IN_MULTIASSETS, }; pub use multilocation::{ - Ancestor, AncestorThen, InteriorMultiLocation, MultiLocation, Parent, ParentThen, + Ancestor, AncestorThen, InteriorMultiLocation, Location, MultiLocation, Parent, ParentThen, }; pub use traits::{ send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Result, SendError, @@ -209,7 +215,7 @@ pub mod prelude { InteriorMultiLocation, Junction::{self, *}, Junctions::{self, *}, - MaybeErrorCode, MultiAsset, + Location, MaybeErrorCode, MultiAsset, MultiAssetFilter::{self, *}, MultiAssets, MultiLocation, NetworkId::{self, *}, @@ -275,6 +281,22 @@ impl PalletInfo { } } +impl TryInto for PalletInfo { + type Error = (); + + fn try_into(self) -> result::Result { + NewPalletInfo::new( + self.index, + self.name.into_inner(), + self.module_name.into_inner(), + self.major, + self.minor, + self.patch, + ) + .map_err(|_| ()) + } +} + #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] #[scale_info(replace_segment("staging_xcm", "xcm"))] #[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))] @@ -324,6 +346,32 @@ impl Default for Response { } } +impl TryFrom for Response { + type Error = (); + + fn try_from(new: NewResponse) -> result::Result { + use NewResponse::*; + Ok(match new { + Null => Self::Null, + Assets(assets) => Self::Assets(assets.try_into()?), + ExecutionResult(result) => + Self::ExecutionResult(result.map(|(num, old_error)| (num, old_error.into()))), + Version(version) => Self::Version(version), + PalletsInfo(pallet_info) => { + let inner = pallet_info + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + Self::PalletsInfo( + BoundedVec::::try_from(inner).map_err(|_| ())?, + ) + }, + DispatchResult(maybe_error) => + Self::DispatchResult(maybe_error.try_into().map_err(|_| ())?), + }) + } +} + /// Information regarding the composition of a query response. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -338,6 +386,18 @@ pub struct QueryResponseInfo { pub max_weight: Weight, } +impl TryFrom for QueryResponseInfo { + type Error = (); + + fn try_from(new: NewQueryResponseInfo) -> result::Result { + Ok(Self { + destination: new.destination.try_into()?, + query_id: new.query_id, + max_weight: new.max_weight, + }) + } +} + /// An optional weight limit. #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -367,13 +427,12 @@ impl From for Option { } } -impl TryFrom for WeightLimit { - type Error = (); - fn try_from(x: OldWeightLimit) -> result::Result { +impl From for WeightLimit { + fn from(x: OldWeightLimit) -> Self { use OldWeightLimit::*; match x { - Limited(w) => Ok(Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE))), - Unlimited => Ok(Self::Unlimited), + Limited(w) => Self::Limited(Weight::from_parts(w, DEFAULT_PROOF_SIZE)), + Unlimited => Self::Unlimited, } } } @@ -1263,6 +1322,155 @@ impl TryFrom> for Xcm { } } +// Convert from a v4 XCM to a v3 XCM. +impl TryFrom> for Xcm { + type Error = (); + fn try_from(new_xcm: NewXcm) -> result::Result { + Ok(Xcm(new_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v4 instruction to a v3 instruction. +impl TryFrom> for Instruction { + type Error = (); + fn try_from(new_instruction: NewInstruction) -> result::Result { + use NewInstruction::*; + Ok(match new_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, querier: Some(querier) } => + Self::QueryResponse { + query_id, + querier: querier.try_into()?, + response: response.try_into()?, + max_weight, + }, + QueryResponse { query_id, response, max_weight, querier: None } => + Self::QueryResponse { + query_id, + querier: None, + response: response.try_into()?, + max_weight, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Self::Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => Self::ReportError(QueryResponseInfo { + query_id: response_info.query_id, + destination: response_info.destination.try_into().map_err(|_| ())?, + max_weight: response_info.max_weight, + }), + DepositAsset { assets, beneficiary } => { + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, dest, xcm } + }, + ExchangeAsset { give, want, maximal } => { + let give = give.try_into()?; + let want = want.try_into()?; + Self::ExchangeAsset { give, want, maximal } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + // No `max_assets` here, so if there's a connt, then we cannot translate. + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => { + let response_info = QueryResponseInfo { + destination: response_info.destination.try_into().map_err(|_| ())?, + query_id: response_info.query_id, + max_weight: response_info.max_weight, + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.into(); + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => + Self::SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => Self::UnsubscribeVersion, + BurnAsset(assets) => Self::BurnAsset(assets.try_into()?), + ExpectAsset(assets) => Self::ExpectAsset(assets.try_into()?), + ExpectOrigin(maybe_origin) => + Self::ExpectOrigin(maybe_origin.map(|origin| origin.try_into()).transpose()?), + ExpectError(maybe_error) => Self::ExpectError(maybe_error), + ExpectTransactStatus(maybe_error_code) => Self::ExpectTransactStatus(maybe_error_code), + QueryPallet { module_name, response_info } => + Self::QueryPallet { module_name, response_info: response_info.try_into()? }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + Self::ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => + Self::ReportTransactStatus(response_info.try_into()?), + ClearTransactStatus => Self::ClearTransactStatus, + UniversalOrigin(junction) => Self::UniversalOrigin(junction.try_into()?), + ExportMessage { network, destination, xcm } => Self::ExportMessage { + network: network.into(), + destination: destination.try_into()?, + xcm: xcm.try_into()?, + }, + LockAsset { asset, unlocker } => + Self::LockAsset { asset: asset.try_into()?, unlocker: unlocker.try_into()? }, + UnlockAsset { asset, target } => + Self::UnlockAsset { asset: asset.try_into()?, target: target.try_into()? }, + NoteUnlockable { asset, owner } => + Self::NoteUnlockable { asset: asset.try_into()?, owner: owner.try_into()? }, + RequestUnlock { asset, locker } => + Self::RequestUnlock { asset: asset.try_into()?, locker: locker.try_into()? }, + SetFeesMode { jit_withdraw } => Self::SetFeesMode { jit_withdraw }, + SetTopic(topic) => Self::SetTopic(topic), + ClearTopic => Self::ClearTopic, + AliasOrigin(location) => Self::AliasOrigin(location.try_into()?), + UnpaidExecution { weight_limit, check_origin } => Self::UnpaidExecution { + weight_limit, + check_origin: check_origin.map(|origin| origin.try_into()).transpose()?, + }, + }) + } +} + /// Default value for the proof size weight component when converting from V2. Set at 64 KB. /// NOTE: Make sure this is removed after we properly account for PoV weights. const DEFAULT_PROOF_SIZE: u64 = 64 * 1024; @@ -1343,10 +1551,8 @@ impl TryFrom> for Instruction { }; Self::ReportHolding { response_info, assets: assets.try_into()? } }, - BuyExecution { fees, weight_limit } => Self::BuyExecution { - fees: fees.try_into()?, - weight_limit: weight_limit.try_into()?, - }, + BuyExecution { fees, weight_limit } => + Self::BuyExecution { fees: fees.try_into()?, weight_limit: weight_limit.into() }, ClearOrigin => Self::ClearOrigin, DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), RefundSurplus => Self::RefundSurplus, diff --git a/polkadot/xcm/src/v3/multiasset.rs b/polkadot/xcm/src/v3/multiasset.rs index c8801f5a461..557ffa568a4 100644 --- a/polkadot/xcm/src/v3/multiasset.rs +++ b/polkadot/xcm/src/v3/multiasset.rs @@ -27,11 +27,18 @@ //! filtering an XCM holding account. use super::{InteriorMultiLocation, MultiLocation}; -use crate::v2::{ - AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, - MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, - MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, - WildMultiAsset as OldWildMultiAsset, +use crate::{ + v2::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldMultiAsset, MultiAssetFilter as OldMultiAssetFilter, + MultiAssets as OldMultiAssets, WildFungibility as OldWildFungibility, + WildMultiAsset as OldWildMultiAsset, + }, + v4::{ + Asset as NewMultiAsset, AssetFilter as NewMultiAssetFilter, AssetId as NewAssetId, + AssetInstance as NewAssetInstance, Assets as NewMultiAssets, Fungibility as NewFungibility, + WildAsset as NewWildMultiAsset, WildFungibility as NewWildFungibility, + }, }; use alloc::{vec, vec::Vec}; use bounded_collections::{BoundedVec, ConstU32}; @@ -86,6 +93,21 @@ impl TryFrom for AssetInstance { } } +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: NewAssetInstance) -> Result { + use NewAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + impl From<()> for AssetInstance { fn from(_: ()) -> Self { Self::Undefined @@ -310,6 +332,17 @@ impl TryFrom for Fungibility { } } +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: NewFungibility) -> Result { + use NewFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + /// Classification of whether an asset is fungible or not. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, @@ -335,6 +368,17 @@ impl TryFrom for WildFungibility { } } +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: NewWildFungibility) -> Result { + use NewWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + /// Classification of an asset being concrete or abstract. #[derive( Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, @@ -378,6 +422,13 @@ impl TryFrom for AssetId { } } +impl TryFrom for AssetId { + type Error = (); + fn try_from(new: NewAssetId) -> Result { + Ok(Self::Concrete(new.0.try_into()?)) + } +} + impl AssetId { /// Prepend a `MultiLocation` to a concrete asset, giving it a new root location. pub fn prepend_with(&mut self, prepend: &MultiLocation) -> Result<(), ()> { @@ -506,6 +557,13 @@ impl TryFrom for MultiAsset { } } +impl TryFrom for MultiAsset { + type Error = (); + fn try_from(new: NewMultiAsset) -> Result { + Ok(Self { id: new.id.try_into()?, fun: new.fun.try_into()? }) + } +} + /// A `Vec` of `MultiAsset`s. /// /// There are a number of invariants which the construction and mutation functions must ensure are @@ -549,6 +607,18 @@ impl TryFrom for MultiAssets { } } +impl TryFrom for MultiAssets { + type Error = (); + fn try_from(new: NewMultiAssets) -> Result { + let v = new + .into_inner() + .into_iter() + .map(MultiAsset::try_from) + .collect::, ()>>()?; + Ok(MultiAssets(v)) + } +} + impl From> for MultiAssets { fn from(mut assets: Vec) -> Self { let mut res = Vec::with_capacity(assets.len()); @@ -747,6 +817,20 @@ impl TryFrom for WildMultiAsset { } } +impl TryFrom for WildMultiAsset { + type Error = (); + fn try_from(new: NewWildMultiAsset) -> Result { + use NewWildMultiAsset::*; + Ok(match new { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + AllOfCounted { id, fun, count } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + All => Self::All, + AllCounted(count) => Self::AllCounted(count), + }) + } +} + impl TryFrom<(OldWildMultiAsset, u32)> for WildMultiAsset { type Error = (); fn try_from(old: (OldWildMultiAsset, u32)) -> Result { @@ -917,6 +1001,17 @@ impl TryFrom for MultiAssetFilter { } } +impl TryFrom for MultiAssetFilter { + type Error = (); + fn try_from(new: NewMultiAssetFilter) -> Result { + use NewMultiAssetFilter::*; + Ok(match new { + Definite(x) => Self::Definite(x.try_into()?), + Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + impl TryFrom<(OldMultiAssetFilter, u32)> for MultiAssetFilter { type Error = (); fn try_from(old: (OldMultiAssetFilter, u32)) -> Result { diff --git a/polkadot/xcm/src/v3/multilocation.rs b/polkadot/xcm/src/v3/multilocation.rs index 9649b1b3207..c588b924ac7 100644 --- a/polkadot/xcm/src/v3/multilocation.rs +++ b/polkadot/xcm/src/v3/multilocation.rs @@ -17,7 +17,9 @@ //! XCM `MultiLocation` datatype. use super::{Junction, Junctions}; -use crate::{v2::MultiLocation as OldMultiLocation, VersionedMultiLocation}; +use crate::{ + v2::MultiLocation as OldMultiLocation, v4::Location as NewMultiLocation, VersionedLocation, +}; use core::{ convert::{TryFrom, TryInto}, result, @@ -74,6 +76,9 @@ pub struct MultiLocation { pub interior: Junctions, } +/// Type alias for a better transition to V4. +pub type Location = MultiLocation; + impl Default for MultiLocation { fn default() -> Self { Self { parents: 0, interior: Junctions::Here } @@ -91,9 +96,9 @@ impl MultiLocation { MultiLocation { parents, interior: interior.into() } } - /// Consume `self` and return the equivalent `VersionedMultiLocation` value. - pub const fn into_versioned(self) -> VersionedMultiLocation { - VersionedMultiLocation::V3(self) + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub const fn into_versioned(self) -> VersionedLocation { + VersionedLocation::V3(self) } /// Creates a new `MultiLocation` with 0 parents and a `Here` interior. @@ -469,6 +474,23 @@ impl TryFrom for MultiLocation { } } +impl TryFrom for Option { + type Error = (); + fn try_from(new: NewMultiLocation) -> result::Result { + Ok(Some(MultiLocation::try_from(new)?)) + } +} + +impl TryFrom for MultiLocation { + type Error = (); + fn try_from(new: NewMultiLocation) -> result::Result { + Ok(MultiLocation { + parents: new.parent_count(), + interior: new.interior().clone().try_into()?, + }) + } +} + /// A unit struct which can be converted into a `MultiLocation` of `parents` value 1. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct Parent; diff --git a/polkadot/xcm/src/v3/traits.rs b/polkadot/xcm/src/v3/traits.rs index 29bd40a6a2d..9e9b983fdf8 100644 --- a/polkadot/xcm/src/v3/traits.rs +++ b/polkadot/xcm/src/v3/traits.rs @@ -216,52 +216,6 @@ impl From for Error { pub type Result = result::Result<(), Error>; -/* -TODO: XCMv4 -/// Outcome of an XCM execution. -#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] -pub enum Outcome { - /// Execution completed successfully; given weight was used. - Complete { used: Weight }, - /// Execution started, but did not complete successfully due to the given error; given weight - /// was used. - Incomplete { used: Weight, error: Error }, - /// Execution did not start due to the given error. - Error { error: Error }, -} - -impl Outcome { - pub fn ensure_complete(self) -> Result { - match self { - Outcome::Complete { .. } => Ok(()), - Outcome::Incomplete { error, .. } => Err(error), - Outcome::Error { error, .. } => Err(error), - } - } - pub fn ensure_execution(self) -> result::Result { - match self { - Outcome::Complete { used, .. } => Ok(used), - Outcome::Incomplete { used, .. } => Ok(used), - Outcome::Error { error, .. } => Err(error), - } - } - /// How much weight was used by the XCM execution attempt. - pub fn weight_used(&self) -> Weight { - match self { - Outcome::Complete { used, .. } => *used, - Outcome::Incomplete { used, .. } => *used, - Outcome::Error { .. } => Weight::zero(), - } - } -} - -impl From for Outcome { - fn from(error: Error) -> Self { - Self::Error { error, maybe_id: None } - } -} -*/ - /// Outcome of an XCM execution. #[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] #[scale_info(replace_segment("staging_xcm", "xcm"))] @@ -337,8 +291,6 @@ pub trait ExecuteXcm { /// /// The weight limit is a basic hard-limit and the implementation may place further /// restrictions or requirements on weight and other aspects. - // TODO: XCMv4 - // #[deprecated = "Use `prepare_and_execute` instead"] fn execute_xcm( origin: impl Into, message: Xcm, @@ -361,8 +313,6 @@ pub trait ExecuteXcm { /// /// Some amount of `weight_credit` may be provided which, depending on the implementation, may /// allow execution without associated payment. - // TODO: XCMv4 - // #[deprecated = "Use `prepare_and_execute` instead"] fn execute_xcm_in_credit( origin: impl Into, message: Xcm, diff --git a/polkadot/xcm/src/v4/asset.rs b/polkadot/xcm/src/v4/asset.rs new file mode 100644 index 00000000000..8aa1cc61437 --- /dev/null +++ b/polkadot/xcm/src/v4/asset.rs @@ -0,0 +1,915 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate 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. + +// Substrate 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 . + +//! Cross-Consensus Message format asset data structures. +//! +//! This encompasses four types for representing assets: +//! - `Asset`: A description of a single asset, either an instance of a non-fungible or some amount +//! of a fungible. +//! - `Assets`: A collection of `Asset`s. These are stored in a `Vec` and sorted with fungibles +//! first. +//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific +//! kind. +//! - `AssetFilter`: A combination of `Wild` and `Assets` designed for efficiently filtering an XCM +//! holding account. + +use super::{InteriorLocation, Location, Reanchorable}; +use crate::v3::{ + AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility, + MultiAsset as OldAsset, MultiAssetFilter as OldAssetFilter, MultiAssets as OldAssets, + WildFungibility as OldWildFungibility, WildMultiAsset as OldWildAsset, +}; +use alloc::{vec, vec::Vec}; +use core::{ + cmp::Ordering, + convert::{TryFrom, TryInto}, +}; +use parity_scale_codec::{self as codec, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A general identifier for an instance of a non-fungible asset class. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetInstance { + /// Undefined - used if the non-fungible asset class has only one instance. + Undefined, + + /// A compact index. Technically this could be greater than `u128`, but this implementation + /// supports only values up to `2**128 - 1`. + Index(#[codec(compact)] u128), + + /// A 4-byte fixed-length datum. + Array4([u8; 4]), + + /// An 8-byte fixed-length datum. + Array8([u8; 8]), + + /// A 16-byte fixed-length datum. + Array16([u8; 16]), + + /// A 32-byte fixed-length datum. + Array32([u8; 32]), +} + +impl TryFrom for AssetInstance { + type Error = (); + fn try_from(value: OldAssetInstance) -> Result { + use OldAssetInstance::*; + Ok(match value { + Undefined => Self::Undefined, + Index(n) => Self::Index(n), + Array4(n) => Self::Array4(n), + Array8(n) => Self::Array8(n), + Array16(n) => Self::Array16(n), + Array32(n) => Self::Array32(n), + }) + } +} + +impl From<()> for AssetInstance { + fn from(_: ()) -> Self { + Self::Undefined + } +} + +impl From<[u8; 4]> for AssetInstance { + fn from(x: [u8; 4]) -> Self { + Self::Array4(x) + } +} + +impl From<[u8; 8]> for AssetInstance { + fn from(x: [u8; 8]) -> Self { + Self::Array8(x) + } +} + +impl From<[u8; 16]> for AssetInstance { + fn from(x: [u8; 16]) -> Self { + Self::Array16(x) + } +} + +impl From<[u8; 32]> for AssetInstance { + fn from(x: [u8; 32]) -> Self { + Self::Array32(x) + } +} + +impl From for AssetInstance { + fn from(x: u8) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u16) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u32) -> Self { + Self::Index(x as u128) + } +} + +impl From for AssetInstance { + fn from(x: u64) -> Self { + Self::Index(x as u128) + } +} + +impl TryFrom for () { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Undefined => Ok(()), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 4] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array4(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 8] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array8(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 16] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array16(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for [u8; 32] { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Array32(x) => Ok(x), + _ => Err(()), + } + } +} + +impl TryFrom for u8 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u16 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u32 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u64 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => x.try_into().map_err(|_| ()), + _ => Err(()), + } + } +} + +impl TryFrom for u128 { + type Error = (); + fn try_from(x: AssetInstance) -> Result { + match x { + AssetInstance::Index(x) => Ok(x), + _ => Err(()), + } + } +} + +/// Classification of whether an asset is fungible or not, along with a mandatory amount or +/// instance. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum Fungibility { + /// A fungible asset; we record a number of units, as a `u128` in the inner item. + Fungible(#[codec(compact)] u128), + /// A non-fungible asset. We record the instance identifier in the inner item. Only one asset + /// of each instance identifier may ever be in existence at once. + NonFungible(AssetInstance), +} + +#[derive(Decode)] +enum UncheckedFungibility { + Fungible(#[codec(compact)] u128), + NonFungible(AssetInstance), +} + +impl Decode for Fungibility { + fn decode(input: &mut I) -> Result { + match UncheckedFungibility::decode(input)? { + UncheckedFungibility::Fungible(a) if a != 0 => Ok(Self::Fungible(a)), + UncheckedFungibility::NonFungible(i) => Ok(Self::NonFungible(i)), + UncheckedFungibility::Fungible(_) => + Err("Fungible asset of zero amount is not allowed".into()), + } + } +} + +impl Fungibility { + pub fn is_kind(&self, w: WildFungibility) -> bool { + use Fungibility::*; + use WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}; + matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible)) + } +} + +impl From for Fungibility { + fn from(amount: i32) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount as u128) + } +} + +impl From for Fungibility { + fn from(amount: u128) -> Fungibility { + debug_assert_ne!(amount, 0); + Fungibility::Fungible(amount) + } +} + +impl> From for Fungibility { + fn from(instance: T) -> Fungibility { + Fungibility::NonFungible(instance.into()) + } +} + +impl TryFrom for Fungibility { + type Error = (); + fn try_from(value: OldFungibility) -> Result { + use OldFungibility::*; + Ok(match value { + Fungible(n) => Self::Fungible(n), + NonFungible(i) => Self::NonFungible(i.try_into()?), + }) + } +} + +/// Classification of whether an asset is fungible or not. +#[derive( + Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildFungibility { + /// The asset is fungible. + Fungible, + /// The asset is not fungible. + NonFungible, +} + +impl TryFrom for WildFungibility { + type Error = (); + fn try_from(value: OldWildFungibility) -> Result { + use OldWildFungibility::*; + Ok(match value { + Fungible => Self::Fungible, + NonFungible => Self::NonFungible, + }) + } +} + +/// Location to identify an asset. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct AssetId(pub Location); + +impl> From for AssetId { + fn from(x: T) -> Self { + Self(x.into()) + } +} + +impl TryFrom for AssetId { + type Error = (); + fn try_from(old: OldAssetId) -> Result { + use OldAssetId::*; + Ok(match old { + Concrete(l) => Self(l.try_into()?), + Abstract(_) => return Err(()), + }) + } +} + +impl AssetId { + /// Prepend a `Location` to an asset id, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &Location) -> Result<(), ()> { + self.0.prepend_with(prepend.clone()).map_err(|_| ())?; + Ok(()) + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `Asset` value. + pub fn into_asset(self, fun: Fungibility) -> Asset { + Asset { fun, id: self } + } + + /// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding + /// `WildAsset` wildcard (`AllOf`) value. + pub fn into_wild(self, fun: WildFungibility) -> WildAsset { + WildAsset::AllOf { fun, id: self } + } +} + +impl Reanchorable for AssetId { + type Error = (); + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.0.reanchor(target, context)?; + Ok(()) + } + + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(()), + } + } +} + +/// Either an amount of a single fungible asset, or a single well-identified non-fungible asset. +#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Asset { + /// The overall asset identity (aka *class*, in the case of a non-fungible). + pub id: AssetId, + /// The fungibility of the asset, which contains either the amount (in the case of a fungible + /// asset) or the *instance ID*, the secondary asset identifier. + pub fun: Fungibility, +} + +impl PartialOrd for Asset { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Asset { + fn cmp(&self, other: &Self) -> Ordering { + match (&self.fun, &other.fun) { + (Fungibility::Fungible(..), Fungibility::NonFungible(..)) => Ordering::Less, + (Fungibility::NonFungible(..), Fungibility::Fungible(..)) => Ordering::Greater, + _ => (&self.id, &self.fun).cmp(&(&other.id, &other.fun)), + } + } +} + +impl, B: Into> From<(A, B)> for Asset { + fn from((id, fun): (A, B)) -> Asset { + Asset { fun: fun.into(), id: id.into() } + } +} + +impl Asset { + pub fn is_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + pub fn is_non_fungible(&self, maybe_id: Option) -> bool { + use Fungibility::*; + matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id) + } + + /// Prepend a `Location` to a concrete asset, giving it a new root location. + pub fn prepend_with(&mut self, prepend: &Location) -> Result<(), ()> { + self.id.prepend_with(prepend) + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + use Fungibility::*; + if self.id == inner.id { + match (&self.fun, &inner.fun) { + (Fungible(a), Fungible(i)) if a >= i => return true, + (NonFungible(a), NonFungible(i)) if a == i => return true, + _ => (), + } + } + false + } +} + +impl Reanchorable for Asset { + type Error = (); + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.id.reanchor(target, context) + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + self.id.reanchor(target, context)?; + Ok(self) + } +} + +impl TryFrom for Asset { + type Error = (); + fn try_from(old: OldAsset) -> Result { + Ok(Self { id: old.id.try_into()?, fun: old.fun.try_into()? }) + } +} + +/// A `Vec` of `Asset`s. +/// +/// There are a number of invariants which the construction and mutation functions must ensure are +/// maintained: +/// - It may contain no items of duplicate asset class; +/// - All items must be ordered; +/// - The number of items should grow no larger than `MAX_ITEMS_IN_ASSETS`. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, Default)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Assets(Vec); + +/// Maximum number of items we expect in a single `Assets` value. Note this is not (yet) +/// enforced, and just serves to provide a sensible `max_encoded_len` for `Assets`. +pub const MAX_ITEMS_IN_ASSETS: usize = 20; + +impl MaxEncodedLen for Assets { + fn max_encoded_len() -> usize { + Asset::max_encoded_len() * MAX_ITEMS_IN_ASSETS + } +} + +impl Decode for Assets { + fn decode(input: &mut I) -> Result { + Self::from_sorted_and_deduplicated(Vec::::decode(input)?) + .map_err(|()| "Out of order".into()) + } +} + +impl TryFrom for Assets { + type Error = (); + fn try_from(old: OldAssets) -> Result { + let v = old + .into_inner() + .into_iter() + .map(Asset::try_from) + .collect::, ()>>()?; + Ok(Assets(v)) + } +} + +impl From> for Assets { + fn from(mut assets: Vec) -> Self { + let mut res = Vec::with_capacity(assets.len()); + if !assets.is_empty() { + assets.sort(); + let mut iter = assets.into_iter(); + if let Some(first) = iter.next() { + let last = iter.fold(first, |a, b| -> Asset { + match (a, b) { + ( + Asset { fun: Fungibility::Fungible(a_amount), id: a_id }, + Asset { fun: Fungibility::Fungible(b_amount), id: b_id }, + ) if a_id == b_id => Asset { + id: a_id, + fun: Fungibility::Fungible(a_amount.saturating_add(b_amount)), + }, + ( + Asset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + Asset { fun: Fungibility::NonFungible(b_instance), id: b_id }, + ) if a_id == b_id && a_instance == b_instance => + Asset { fun: Fungibility::NonFungible(a_instance), id: a_id }, + (to_push, to_remember) => { + res.push(to_push); + to_remember + }, + } + }); + res.push(last); + } + } + Self(res) + } +} + +impl> From for Assets { + fn from(x: T) -> Self { + Self(vec![x.into()]) + } +} + +impl Assets { + /// A new (empty) value. + pub fn new() -> Self { + Self(Vec::new()) + } + + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. + /// If you can't guarantee that `r` is sorted and deduplicated, then use + /// `From::>::from` which is infallible. + pub fn from_sorted_and_deduplicated(r: Vec) -> Result { + if r.is_empty() { + return Ok(Self(Vec::new())) + } + r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&Asset, ()> { + if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) { + Ok(b) + } else { + Err(()) + } + })?; + Ok(Self(r)) + } + + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + #[cfg(test)] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped") + } + /// Create a new instance of `Assets` from a `Vec` whose contents are sorted + /// and which contain no duplicates. + /// + /// In release mode, this skips any checks to ensure that `r` is correct, making it a + /// negligible-cost operation. Generally though you should avoid using it unless you have a + /// strict proof that `r` is valid. + /// + /// In test mode, this checks anyway and panics on fail. + #[cfg(not(test))] + pub fn from_sorted_and_deduplicated_skip_checks(r: Vec) -> Self { + Self(r) + } + + /// Add some asset onto the list, saturating. This is quite a laborious operation since it + /// maintains the ordering. + pub fn push(&mut self, a: Asset) { + for asset in self.0.iter_mut().filter(|x| x.id == a.id) { + match (&a.fun, &mut asset.fun) { + (Fungibility::Fungible(amount), Fungibility::Fungible(balance)) => { + *balance = balance.saturating_add(*amount); + return + }, + (Fungibility::NonFungible(inst1), Fungibility::NonFungible(inst2)) + if inst1 == inst2 => + return, + _ => (), + } + } + self.0.push(a); + self.0.sort(); + } + + /// Returns `true` if this definitely represents no asset. + pub fn is_none(&self) -> bool { + self.0.is_empty() + } + + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + self.0.iter().any(|i| i.contains(inner)) + } + + /// Consume `self` and return the inner vec. + #[deprecated = "Use `into_inner()` instead"] + pub fn drain(self) -> Vec { + self.0 + } + + /// Consume `self` and return the inner vec. + pub fn into_inner(self) -> Vec { + self.0 + } + + /// Return a reference to the inner vec. + pub fn inner(&self) -> &Vec { + &self.0 + } + + /// Return the number of distinct asset instances contained. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Prepend a `Location` to any concrete asset items, giving it a new root location. + pub fn prepend_with(&mut self, prefix: &Location) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix)) + } + + /// Return a reference to an item at a specific index or `None` if it doesn't exist. + pub fn get(&self, index: usize) -> Option<&Asset> { + self.0.get(index) + } +} + +impl Reanchorable for Assets { + type Error = (); + + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + self.0.iter_mut().try_for_each(|i| i.reanchor(target, context))?; + self.0.sort(); + Ok(()) + } + + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(()), + } + } +} + +/// A wildcard representing a set of assets. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum WildAsset { + /// All assets in Holding. + All, + /// All assets in Holding of a given fungibility and ID. + AllOf { id: AssetId, fun: WildFungibility }, + /// All assets in Holding, up to `u32` individual assets (different instances of non-fungibles + /// are separate assets). + AllCounted(#[codec(compact)] u32), + /// All assets in Holding of a given fungibility and ID up to `count` individual assets + /// (different instances of non-fungibles are separate assets). + AllOfCounted { + id: AssetId, + fun: WildFungibility, + #[codec(compact)] + count: u32, + }, +} + +impl TryFrom for WildAsset { + type Error = (); + fn try_from(old: OldWildAsset) -> Result { + use OldWildAsset::*; + Ok(match old { + AllOf { id, fun } => Self::AllOf { id: id.try_into()?, fun: fun.try_into()? }, + All => Self::All, + AllOfCounted { id, fun, count } => + Self::AllOfCounted { id: id.try_into()?, fun: fun.try_into()?, count }, + AllCounted(count) => Self::AllCounted(count), + }) + } +} + +impl WildAsset { + /// Returns true if `self` is a super-set of the given `inner` asset. + pub fn contains(&self, inner: &Asset) -> bool { + use WildAsset::*; + match self { + AllOfCounted { count: 0, .. } | AllCounted(0) => false, + AllOf { fun, id } | AllOfCounted { id, fun, .. } => + inner.fun.is_kind(*fun) && &inner.id == id, + All | AllCounted(_) => true, + } + } + + /// Returns true if the wild element of `self` matches `inner`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + #[deprecated = "Use `contains` instead"] + pub fn matches(&self, inner: &Asset) -> bool { + self.contains(inner) + } + + /// Mutate the asset to represent the same value from the perspective of a new `target` + /// location. The local chain's location is provided in `context`. + pub fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + use WildAsset::*; + match self { + AllOf { ref mut id, .. } | AllOfCounted { ref mut id, .. } => + id.reanchor(target, context), + All | AllCounted(_) => Ok(()), + } + } + + /// Maximum count of assets allowed to match, if any. + pub fn count(&self) -> Option { + use WildAsset::*; + match self { + AllOfCounted { count, .. } | AllCounted(count) => Some(*count), + All | AllOf { .. } => None, + } + } + + /// Explicit limit on number of assets allowed to match, if any. + pub fn limit(&self) -> Option { + self.count() + } + + /// Consume self and return the equivalent version but counted and with the `count` set to the + /// given parameter. + pub fn counted(self, count: u32) -> Self { + use WildAsset::*; + match self { + AllOfCounted { fun, id, .. } | AllOf { fun, id } => AllOfCounted { fun, id, count }, + All | AllCounted(_) => AllCounted(count), + } + } +} + +impl, B: Into> From<(A, B)> for WildAsset { + fn from((id, fun): (A, B)) -> WildAsset { + WildAsset::AllOf { fun: fun.into(), id: id.into() } + } +} + +/// `Asset` collection, defined either by a number of `Assets` or a single wildcard. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum AssetFilter { + /// Specify the filter as being everything contained by the given `Assets` inner. + Definite(Assets), + /// Specify the filter as the given `WildAsset` wildcard. + Wild(WildAsset), +} + +impl> From for AssetFilter { + fn from(x: T) -> Self { + Self::Wild(x.into()) + } +} + +impl From for AssetFilter { + fn from(x: Asset) -> Self { + Self::Definite(vec![x].into()) + } +} + +impl From> for AssetFilter { + fn from(x: Vec) -> Self { + Self::Definite(x.into()) + } +} + +impl From for AssetFilter { + fn from(x: Assets) -> Self { + Self::Definite(x) + } +} + +impl AssetFilter { + /// Returns true if `inner` would be matched by `self`. + /// + /// Note that for `Counted` variants of wildcards, then it will disregard the count except for + /// always returning `false` when equal to 0. + pub fn matches(&self, inner: &Asset) -> bool { + match self { + AssetFilter::Definite(ref assets) => assets.contains(inner), + AssetFilter::Wild(ref wild) => wild.contains(inner), + } + } + + /// Mutate the location of the asset identifier if concrete, giving it the same location + /// relative to a `target` context. The local context is provided as `context`. + pub fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + match self { + AssetFilter::Definite(ref mut assets) => assets.reanchor(target, context), + AssetFilter::Wild(ref mut wild) => wild.reanchor(target, context), + } + } + + /// Maximum count of assets it is possible to match, if known. + pub fn count(&self) -> Option { + use AssetFilter::*; + match self { + Definite(x) => Some(x.len() as u32), + Wild(x) => x.count(), + } + } + + /// Explicit limit placed on the number of items, if any. + pub fn limit(&self) -> Option { + use AssetFilter::*; + match self { + Definite(_) => None, + Wild(x) => x.limit(), + } + } +} + +impl TryFrom for AssetFilter { + type Error = (); + fn try_from(old: OldAssetFilter) -> Result { + Ok(match old { + OldAssetFilter::Definite(x) => Self::Definite(x.try_into()?), + OldAssetFilter::Wild(x) => Self::Wild(x.try_into()?), + }) + } +} + +#[cfg(test)] +mod tests { + use super::super::prelude::*; + + #[test] + fn conversion_works() { + let _: Assets = (Here, 1u128).into(); + } + + #[test] + fn from_sorted_and_deduplicated_works() { + use super::*; + use alloc::vec; + + let empty = vec![]; + let r = Assets::from_sorted_and_deduplicated(empty); + assert_eq!(r, Ok(Assets(vec![]))); + + let dup_fun = vec![(Here, 100).into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(dup_fun); + assert!(r.is_err()); + + let dup_nft = vec![(Here, *b"notgood!").into(), (Here, *b"notgood!").into()]; + let r = Assets::from_sorted_and_deduplicated(dup_nft); + assert!(r.is_err()); + + let good_fun = vec![(Here, 10).into(), (Parent, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(good_fun.clone()); + assert_eq!(r, Ok(Assets(good_fun))); + + let bad_fun = vec![(Parent, 10).into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(bad_fun); + assert!(r.is_err()); + + let good_nft = vec![(Here, ()).into(), (Here, *b"good").into()]; + let r = Assets::from_sorted_and_deduplicated(good_nft.clone()); + assert_eq!(r, Ok(Assets(good_nft))); + + let bad_nft = vec![(Here, *b"bad!").into(), (Here, ()).into()]; + let r = Assets::from_sorted_and_deduplicated(bad_nft); + assert!(r.is_err()); + + let mixed_good = vec![(Here, 10).into(), (Here, *b"good").into()]; + let r = Assets::from_sorted_and_deduplicated(mixed_good.clone()); + assert_eq!(r, Ok(Assets(mixed_good))); + + let mixed_bad = vec![(Here, *b"bad!").into(), (Here, 10).into()]; + let r = Assets::from_sorted_and_deduplicated(mixed_bad); + assert!(r.is_err()); + } +} diff --git a/polkadot/xcm/src/v4/junction.rs b/polkadot/xcm/src/v4/junction.rs new file mode 100644 index 00000000000..b5d10484aa0 --- /dev/null +++ b/polkadot/xcm/src/v4/junction.rs @@ -0,0 +1,317 @@ +// 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 . + +//! Support data structures for `Location`, primarily the `Junction` datatype. + +use super::Location; +pub use crate::v3::{BodyId, BodyPart}; +use crate::{ + v3::{Junction as OldJunction, NetworkId as OldNetworkId}, + VersionedLocation, +}; +use bounded_collections::{BoundedSlice, BoundedVec, ConstU32}; +use core::convert::TryFrom; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; + +/// A single item in a path to describe the relative location of a consensus system. +/// +/// Each item assumes a pre-existing location as its context and is defined in terms of it. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum Junction { + /// An indexed parachain belonging to and operated by the context. + /// + /// Generally used when the context is a Polkadot Relay-chain. + Parachain(#[codec(compact)] u32), + /// A 32-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// Generally used when the context is a Substrate-based chain. + AccountId32 { network: Option, id: [u8; 32] }, + /// An 8-byte index for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is a Frame-based chain and includes e.g. an indices pallet. + AccountIndex64 { + network: Option, + #[codec(compact)] + index: u64, + }, + /// A 20-byte identifier for an account of a specific network that is respected as a sovereign + /// endpoint within the context. + /// + /// May be used when the context is an Ethereum or Bitcoin chain or smart-contract. + AccountKey20 { network: Option, key: [u8; 20] }, + /// An instanced, indexed pallet that forms a constituent part of the context. + /// + /// Generally used when the context is a Frame-based chain. + // TODO XCMv4 inner should be `Compact`. + PalletInstance(u8), + /// A non-descript index within the context location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + GeneralIndex(#[codec(compact)] u128), + /// A nondescript array datum, 32 bytes, acting as a key within the context + /// location. + /// + /// Usage will vary widely owing to its generality. + /// + /// NOTE: Try to avoid using this and instead use a more specific item. + // Note this is implemented as an array with a length rather than using `BoundedVec` owing to + // the bound for `Copy`. + GeneralKey { length: u8, data: [u8; 32] }, + /// The unambiguous child. + /// + /// Not currently used except as a fallback when deriving context. + OnlyChild, + /// A pluralistic body existing within consensus. + /// + /// Typical to be used to represent a governance origin of a chain, but could in principle be + /// used to represent things such as multisigs also. + Plurality { id: BodyId, part: BodyPart }, + /// A global network capable of externalizing its own consensus. This is not generally + /// meaningful outside of the universal level. + GlobalConsensus(NetworkId), +} + +/// A global identifier of a data structure existing within consensus. +/// +/// Maintenance note: Networks with global consensus and which are practically bridgeable within the +/// Polkadot ecosystem are given preference over explicit naming in this enumeration. +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub enum NetworkId { + /// Network specified by the first 32 bytes of its genesis block. + ByGenesis([u8; 32]), + /// Network defined by the first 32-bytes of the hash and number of some block it contains. + ByFork { block_number: u64, block_hash: [u8; 32] }, + /// The Polkadot mainnet Relay-chain. + Polkadot, + /// The Kusama canary-net Relay-chain. + Kusama, + /// The Westend testnet Relay-chain. + Westend, + /// The Rococo testnet Relay-chain. + Rococo, + /// The Wococo testnet Relay-chain. + Wococo, + /// An Ethereum network specified by its chain ID. + Ethereum { + /// The EIP-155 chain ID. + #[codec(compact)] + chain_id: u64, + }, + /// The Bitcoin network, including hard-forks supported by Bitcoin Core development team. + BitcoinCore, + /// The Bitcoin network, including hard-forks supported by Bitcoin Cash developers. + BitcoinCash, + /// The Polkadot Bulletin chain. + PolkadotBulletin, +} + +impl From for Option { + fn from(old: OldNetworkId) -> Self { + Some(NetworkId::from(old)) + } +} + +impl From for NetworkId { + fn from(old: OldNetworkId) -> Self { + use OldNetworkId::*; + match old { + ByGenesis(hash) => Self::ByGenesis(hash), + ByFork { block_number, block_hash } => Self::ByFork { block_number, block_hash }, + Polkadot => Self::Polkadot, + Kusama => Self::Kusama, + Westend => Self::Westend, + Rococo => Self::Rococo, + Wococo => Self::Wococo, + Ethereum { chain_id } => Self::Ethereum { chain_id }, + BitcoinCore => Self::BitcoinCore, + BitcoinCash => Self::BitcoinCash, + PolkadotBulletin => Self::PolkadotBulletin, + } + } +} + +impl From for Junction { + fn from(n: NetworkId) -> Self { + Self::GlobalConsensus(n) + } +} + +impl From<[u8; 32]> for Junction { + fn from(id: [u8; 32]) -> Self { + Self::AccountId32 { network: None, id } + } +} + +impl From>> for Junction { + fn from(key: BoundedVec>) -> Self { + key.as_bounded_slice().into() + } +} + +impl<'a> From>> for Junction { + fn from(key: BoundedSlice<'a, u8, ConstU32<32>>) -> Self { + let mut data = [0u8; 32]; + data[..key.len()].copy_from_slice(&key[..]); + Self::GeneralKey { length: key.len() as u8, data } + } +} + +impl<'a> TryFrom<&'a Junction> for BoundedSlice<'a, u8, ConstU32<32>> { + type Error = (); + fn try_from(key: &'a Junction) -> Result { + match key { + Junction::GeneralKey { length, data } => + BoundedSlice::try_from(&data[..data.len().min(*length as usize)]).map_err(|_| ()), + _ => Err(()), + } + } +} + +impl From<[u8; 20]> for Junction { + fn from(key: [u8; 20]) -> Self { + Self::AccountKey20 { network: None, key } + } +} + +impl From for Junction { + fn from(index: u64) -> Self { + Self::AccountIndex64 { network: None, index } + } +} + +impl From for Junction { + fn from(id: u128) -> Self { + Self::GeneralIndex(id) + } +} + +impl TryFrom for Junction { + type Error = (); + fn try_from(value: OldJunction) -> Result { + use OldJunction::*; + Ok(match value { + Parachain(id) => Self::Parachain(id), + AccountId32 { network: maybe_network, id } => + Self::AccountId32 { network: maybe_network.map(|network| network.into()), id }, + AccountIndex64 { network: maybe_network, index } => + Self::AccountIndex64 { network: maybe_network.map(|network| network.into()), index }, + AccountKey20 { network: maybe_network, key } => + Self::AccountKey20 { network: maybe_network.map(|network| network.into()), key }, + PalletInstance(index) => Self::PalletInstance(index), + GeneralIndex(id) => Self::GeneralIndex(id), + GeneralKey { length, data } => Self::GeneralKey { length, data }, + OnlyChild => Self::OnlyChild, + Plurality { id, part } => Self::Plurality { id, part }, + GlobalConsensus(network) => Self::GlobalConsensus(network.into()), + }) + } +} + +impl Junction { + /// Convert `self` into a `Location` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub fn into_location(self) -> Location { + Location::new(0, [self]) + } + + /// Convert `self` into a `Location` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub fn into_exterior(self, n: u8) -> Location { + Location::new(n, [self]) + } + + /// Convert `self` into a `VersionedLocation` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub fn into_versioned(self) -> VersionedLocation { + self.into_location().into_versioned() + } + + /// Remove the `NetworkId` value. + pub fn remove_network_id(&mut self) { + use Junction::*; + match self { + AccountId32 { ref mut network, .. } | + AccountIndex64 { ref mut network, .. } | + AccountKey20 { ref mut network, .. } => *network = None, + _ => {}, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::vec; + + #[test] + fn junction_round_trip_works() { + let j = Junction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = OldJunction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = OldJunction::try_from(Junction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + + let j = Junction::from(BoundedVec::try_from(vec![1u8, 2, 3, 4]).unwrap()); + let k = Junction::try_from(OldJunction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + let s: BoundedSlice<_, _> = (&k).try_into().unwrap(); + assert_eq!(s, &[1u8, 2, 3, 4][..]); + + let j = OldJunction::GeneralKey { length: 32, data: [1u8; 32] }; + let k = OldJunction::try_from(Junction::try_from(j).unwrap()).unwrap(); + assert_eq!(j, k); + } +} diff --git a/polkadot/xcm/src/v4/junctions.rs b/polkadot/xcm/src/v4/junctions.rs new file mode 100644 index 00000000000..48712dd74c6 --- /dev/null +++ b/polkadot/xcm/src/v4/junctions.rs @@ -0,0 +1,723 @@ +// 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 . + +//! XCM `Junctions`/`InteriorLocation` datatype. + +use super::{Junction, Location, NetworkId}; +use alloc::sync::Arc; +use core::{convert::TryFrom, mem, ops::Range, result}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// Maximum number of `Junction`s that a `Junctions` can contain. +pub(crate) const MAX_JUNCTIONS: usize = 8; + +/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions` +/// implementation uses a Rust `enum` in order to make pattern matching easier. +/// +/// Parent junctions cannot be constructed with this type. Refer to `Location` for +/// instructions on constructing parent junctions. +#[derive( + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + Encode, + Decode, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub enum Junctions { + /// The interpreting consensus system. + Here, + /// A relative path comprising 1 junction. + X1(Arc<[Junction; 1]>), + /// A relative path comprising 2 junctions. + X2(Arc<[Junction; 2]>), + /// A relative path comprising 3 junctions. + X3(Arc<[Junction; 3]>), + /// A relative path comprising 4 junctions. + X4(Arc<[Junction; 4]>), + /// A relative path comprising 5 junctions. + X5(Arc<[Junction; 5]>), + /// A relative path comprising 6 junctions. + X6(Arc<[Junction; 6]>), + /// A relative path comprising 7 junctions. + X7(Arc<[Junction; 7]>), + /// A relative path comprising 8 junctions. + X8(Arc<[Junction; 8]>), +} + +macro_rules! impl_junctions { + ($count:expr, $variant:ident) => { + impl From<[Junction; $count]> for Junctions { + fn from(junctions: [Junction; $count]) -> Self { + Self::$variant(Arc::new(junctions)) + } + } + impl PartialEq<[Junction; $count]> for Junctions { + fn eq(&self, rhs: &[Junction; $count]) -> bool { + self.as_slice() == rhs + } + } + }; +} + +impl_junctions!(1, X1); +impl_junctions!(2, X2); +impl_junctions!(3, X3); +impl_junctions!(4, X4); +impl_junctions!(5, X5); +impl_junctions!(6, X6); +impl_junctions!(7, X7); +impl_junctions!(8, X8); + +pub struct JunctionsIterator { + junctions: Junctions, + range: Range, +} + +impl Iterator for JunctionsIterator { + type Item = Junction; + fn next(&mut self) -> Option { + self.junctions.at(self.range.next()?).cloned() + } +} + +impl DoubleEndedIterator for JunctionsIterator { + fn next_back(&mut self) -> Option { + self.junctions.at(self.range.next_back()?).cloned() + } +} + +pub struct JunctionsRefIterator<'a> { + junctions: &'a Junctions, + range: Range, +} + +impl<'a> Iterator for JunctionsRefIterator<'a> { + type Item = &'a Junction; + fn next(&mut self) -> Option<&'a Junction> { + self.junctions.at(self.range.next()?) + } +} + +impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> { + fn next_back(&mut self) -> Option<&'a Junction> { + self.junctions.at(self.range.next_back()?) + } +} +impl<'a> IntoIterator for &'a Junctions { + type Item = &'a Junction; + type IntoIter = JunctionsRefIterator<'a>; + fn into_iter(self) -> Self::IntoIter { + JunctionsRefIterator { junctions: self, range: 0..self.len() } + } +} + +impl IntoIterator for Junctions { + type Item = Junction; + type IntoIter = JunctionsIterator; + fn into_iter(self) -> Self::IntoIter { + JunctionsIterator { range: 0..self.len(), junctions: self } + } +} + +impl Junctions { + /// Convert `self` into a `Location` containing 0 parents. + /// + /// Similar to `Into::into`, except that this method can be used in a const evaluation context. + pub const fn into_location(self) -> Location { + Location { parents: 0, interior: self } + } + + /// Convert `self` into a `Location` containing `n` parents. + /// + /// Similar to `Self::into_location`, with the added ability to specify the number of parent + /// junctions. + pub const fn into_exterior(self, n: u8) -> Location { + Location { parents: n, interior: self } + } + + /// Casts `self` into a slice containing `Junction`s. + pub fn as_slice(&self) -> &[Junction] { + match self { + Junctions::Here => &[], + Junctions::X1(ref a) => &a[..], + Junctions::X2(ref a) => &a[..], + Junctions::X3(ref a) => &a[..], + Junctions::X4(ref a) => &a[..], + Junctions::X5(ref a) => &a[..], + Junctions::X6(ref a) => &a[..], + Junctions::X7(ref a) => &a[..], + Junctions::X8(ref a) => &a[..], + } + } + + /// Casts `self` into a mutable slice containing `Junction`s. + pub fn as_slice_mut(&mut self) -> &mut [Junction] { + match self { + Junctions::Here => &mut [], + Junctions::X1(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X2(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X3(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X4(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X5(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X6(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X7(ref mut a) => &mut Arc::make_mut(a)[..], + Junctions::X8(ref mut a) => &mut Arc::make_mut(a)[..], + } + } + + /// Remove the `NetworkId` value in any `Junction`s. + pub fn remove_network_id(&mut self) { + self.for_each_mut(Junction::remove_network_id); + } + + /// Treating `self` as the universal context, return the location of the local consensus system + /// from the point of view of the given `target`. + pub fn invert_target(&self, target: &Location) -> Result { + let mut itself = self.clone(); + let mut junctions = Self::Here; + for _ in 0..target.parent_count() { + junctions = junctions + .pushed_front_with(itself.take_last().unwrap_or(Junction::OnlyChild)) + .map_err(|_| ())?; + } + let parents = target.interior().len() as u8; + Ok(Location::new(parents, junctions)) + } + + /// Execute a function `f` on every junction. We use this since we cannot implement a mutable + /// `Iterator` without unsafe code. + pub fn for_each_mut(&mut self, x: impl FnMut(&mut Junction)) { + self.as_slice_mut().iter_mut().for_each(x) + } + + /// Extract the network ID treating this value as a universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn global_consensus(&self) -> Result { + if let Some(Junction::GlobalConsensus(network)) = self.first() { + Ok(*network) + } else { + Err(()) + } + } + + /// Extract the network ID and the interior consensus location, treating this value as a + /// universal location. + /// + /// This will return an `Err` if the first item is not a `GlobalConsensus`, which would indicate + /// that this value is not a universal location. + pub fn split_global(self) -> Result<(NetworkId, Junctions), ()> { + match self.split_first() { + (location, Some(Junction::GlobalConsensus(network))) => Ok((network, location)), + _ => return Err(()), + } + } + + /// Treat `self` as a universal location and the context of `relative`, returning the universal + /// location of relative. + /// + /// This will return an error if `relative` has as many (or more) parents than there are + /// junctions in `self`, implying that relative refers into a different global consensus. + pub fn within_global(mut self, relative: Location) -> Result { + if self.len() <= relative.parent_count() as usize { + return Err(()) + } + for _ in 0..relative.parent_count() { + self.take_last(); + } + for j in relative.interior() { + self.push(*j).map_err(|_| ())?; + } + Ok(self) + } + + /// Consumes `self` and returns how `viewer` would address it locally. + pub fn relative_to(mut self, viewer: &Junctions) -> Location { + let mut i = 0; + while match (self.first(), viewer.at(i)) { + (Some(x), Some(y)) => x == y, + _ => false, + } { + self = self.split_first().0; + // NOTE: Cannot overflow as loop can only iterate at most `MAX_JUNCTIONS` times. + i += 1; + } + // AUDIT NOTES: + // - above loop ensures that `i <= viewer.len()`. + // - `viewer.len()` is at most `MAX_JUNCTIONS`, so won't overflow a `u8`. + Location::new((viewer.len() - i) as u8, self) + } + + /// Returns first junction, or `None` if the location is empty. + pub fn first(&self) -> Option<&Junction> { + self.as_slice().first() + } + + /// Returns last junction, or `None` if the location is empty. + pub fn last(&self) -> Option<&Junction> { + self.as_slice().last() + } + + /// Splits off the first junction, returning the remaining suffix (first item in tuple) and the + /// first element (second item in tuple) or `None` if it was empty. + pub fn split_first(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(xs) => { + let [a] = *xs; + (Junctions::Here, Some(a)) + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + ([b].into(), Some(a)) + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + ([b, c].into(), Some(a)) + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + ([b, c, d].into(), Some(a)) + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + ([b, c, d, e].into(), Some(a)) + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + ([b, c, d, e, f].into(), Some(a)) + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + ([b, c, d, e, f, g].into(), Some(a)) + }, + Junctions::X8(xs) => { + let [a, b, c, d, e, f, g, h] = *xs; + ([b, c, d, e, f, g, h].into(), Some(a)) + }, + } + } + + /// Splits off the last junction, returning the remaining prefix (first item in tuple) and the + /// last element (second item in tuple) or `None` if it was empty. + pub fn split_last(self) -> (Junctions, Option) { + match self { + Junctions::Here => (Junctions::Here, None), + Junctions::X1(xs) => { + let [a] = *xs; + (Junctions::Here, Some(a)) + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + ([a].into(), Some(b)) + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + ([a, b].into(), Some(c)) + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + ([a, b, c].into(), Some(d)) + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + ([a, b, c, d].into(), Some(e)) + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + ([a, b, c, d, e].into(), Some(f)) + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + ([a, b, c, d, e, f].into(), Some(g)) + }, + Junctions::X8(xs) => { + let [a, b, c, d, e, f, g, h] = *xs; + ([a, b, c, d, e, f, g].into(), Some(h)) + }, + } + } + + /// Removes the first element from `self`, returning it (or `None` if it was empty). + pub fn take_first(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (tail, head) = d.split_first(); + *self = tail; + head + } + + /// Removes the last element from `self`, returning it (or `None` if it was empty). + pub fn take_last(&mut self) -> Option { + let mut d = Junctions::Here; + mem::swap(&mut *self, &mut d); + let (head, tail) = d.split_last(); + *self = head; + tail + } + + /// Mutates `self` to be appended with `new` or returns an `Err` with `new` if would overflow. + pub fn push(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Mutates `self` to be prepended with `new` or returns an `Err` with `new` if would overflow. + pub fn push_front(&mut self, new: impl Into) -> result::Result<(), Junction> { + let new = new.into(); + let mut dummy = Junctions::Here; + mem::swap(self, &mut dummy); + match dummy.pushed_front_with(new) { + Ok(s) => { + *self = s; + Ok(()) + }, + Err((s, j)) => { + *self = s; + Err(j) + }, + } + } + + /// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_with(self, new: impl Into) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => [new].into(), + Junctions::X1(xs) => { + let [a] = *xs; + [a, new].into() + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + [a, b, new].into() + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + [a, b, c, new].into() + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + [a, b, c, d, new].into() + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + [a, b, c, d, e, new].into() + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + [a, b, c, d, e, f, new].into() + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + [a, b, c, d, e, f, g, new].into() + }, + s => Err((s, new))?, + }) + } + + /// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the + /// original value of `self` and `new` in case of overflow. + pub fn pushed_front_with( + self, + new: impl Into, + ) -> result::Result { + let new = new.into(); + Ok(match self { + Junctions::Here => [new].into(), + Junctions::X1(xs) => { + let [a] = *xs; + [new, a].into() + }, + Junctions::X2(xs) => { + let [a, b] = *xs; + [new, a, b].into() + }, + Junctions::X3(xs) => { + let [a, b, c] = *xs; + [new, a, b, c].into() + }, + Junctions::X4(xs) => { + let [a, b, c, d] = *xs; + [new, a, b, c, d].into() + }, + Junctions::X5(xs) => { + let [a, b, c, d, e] = *xs; + [new, a, b, c, d, e].into() + }, + Junctions::X6(xs) => { + let [a, b, c, d, e, f] = *xs; + [new, a, b, c, d, e, f].into() + }, + Junctions::X7(xs) => { + let [a, b, c, d, e, f, g] = *xs; + [new, a, b, c, d, e, f, g].into() + }, + s => Err((s, new))?, + }) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions, Junction::*, Location}; + /// # fn main() { + /// let mut m = Junctions::from([Parachain(21)]); + /// assert_eq!(m.append_with([PalletInstance(3)]), Ok(())); + /// assert_eq!(m, [Parachain(21), PalletInstance(3)]); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Junctions> { + let suffix = suffix.into(); + if self.len().saturating_add(suffix.len()) > MAX_JUNCTIONS { + return Err(suffix) + } + for j in suffix.into_iter() { + self.push(j).expect("Already checked the sum of the len()s; qed") + } + Ok(()) + } + + /// Returns the number of junctions in `self`. + pub fn len(&self) -> usize { + self.as_slice().len() + } + + /// Returns the junction at index `i`, or `None` if the location doesn't contain that many + /// elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + self.as_slice().get(i) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't + /// contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + self.as_slice_mut().get_mut(i) + } + + /// Returns a reference iterator over the junctions. + pub fn iter(&self) -> JunctionsRefIterator { + JunctionsRefIterator { junctions: self, range: 0..self.len() } + } + + /// Ensures that self begins with `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions, Junction::*}; + /// # fn main() { + /// let mut m = Junctions::from([Parachain(2), PalletInstance(3), OnlyChild]); + /// assert_eq!(m.match_and_split(&[Parachain(2), PalletInstance(3)].into()), Some(&OnlyChild)); + /// assert_eq!(m.match_and_split(&[Parachain(2)].into()), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> { + if prefix.len() + 1 != self.len() { + return None + } + for i in 0..prefix.len() { + if prefix.at(i) != self.at(i) { + return None + } + } + return self.at(prefix.len()) + } + + pub fn starts_with(&self, prefix: &Junctions) -> bool { + prefix.len() <= self.len() && prefix.iter().zip(self.iter()).all(|(x, y)| x == y) + } +} + +impl TryFrom for Junctions { + type Error = Location; + fn try_from(x: Location) -> result::Result { + if x.parent_count() > 0 { + Err(x) + } else { + Ok(x.interior().clone()) + } + } +} + +impl> From for Junctions { + fn from(x: T) -> Self { + [x.into()].into() + } +} + +impl From<[Junction; 0]> for Junctions { + fn from(_: [Junction; 0]) -> Self { + Self::Here + } +} + +impl From<()> for Junctions { + fn from(_: ()) -> Self { + Self::Here + } +} + +xcm_procedural::impl_conversion_functions_for_junctions_v4!(); + +#[cfg(test)] +mod tests { + use super::{super::prelude::*, *}; + + #[test] + fn inverting_works() { + let context: InteriorLocation = (Parachain(1000), PalletInstance(42)).into(); + let target = (Parent, PalletInstance(69)).into(); + let expected = (Parent, PalletInstance(42)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + + let context: InteriorLocation = + (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into(); + let target = (Parent, Parent, PalletInstance(69), GeneralIndex(2)).into(); + let expected = (Parent, Parent, PalletInstance(42), GeneralIndex(1)).into(); + let inverted = context.invert_target(&target).unwrap(); + assert_eq!(inverted, expected); + } + + #[test] + fn relative_to_works() { + use NetworkId::*; + assert_eq!( + Junctions::from([Polkadot.into()]).relative_to(&Junctions::from([Kusama.into()])), + (Parent, Polkadot).into() + ); + let base = Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]); + + // Ancestors. + assert_eq!(Here.relative_to(&base), (Parent, Parent, Parent).into()); + assert_eq!(Junctions::from([Kusama.into()]).relative_to(&base), (Parent, Parent).into()); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1)]).relative_to(&base), + (Parent,).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1)]).relative_to(&base), + Here.into() + ); + + // Ancestors with one child. + assert_eq!( + Junctions::from([Polkadot.into()]).relative_to(&base), + (Parent, Parent, Parent, Polkadot).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(2)]).relative_to(&base), + (Parent, Parent, Parachain(2)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2)]).relative_to(&base), + (Parent, PalletInstance(2)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(1), [1u8; 32].into()]) + .relative_to(&base), + ([1u8; 32],).into() + ); + + // Ancestors with grandchildren. + assert_eq!( + Junctions::from([Polkadot.into(), Parachain(1)]).relative_to(&base), + (Parent, Parent, Parent, Polkadot, Parachain(1)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(2), PalletInstance(1)]).relative_to(&base), + (Parent, Parent, Parachain(2), PalletInstance(1)).into() + ); + assert_eq!( + Junctions::from([Kusama.into(), Parachain(1), PalletInstance(2), [1u8; 32].into()]) + .relative_to(&base), + (Parent, PalletInstance(2), [1u8; 32]).into() + ); + assert_eq!( + Junctions::from([ + Kusama.into(), + Parachain(1), + PalletInstance(1), + [1u8; 32].into(), + 1u128.into() + ]) + .relative_to(&base), + ([1u8; 32], 1u128).into() + ); + } + + #[test] + fn global_consensus_works() { + use NetworkId::*; + assert_eq!(Junctions::from([Polkadot.into()]).global_consensus(), Ok(Polkadot)); + assert_eq!(Junctions::from([Kusama.into(), 1u64.into()]).global_consensus(), Ok(Kusama)); + assert_eq!(Here.global_consensus(), Err(())); + assert_eq!(Junctions::from([1u64.into()]).global_consensus(), Err(())); + assert_eq!(Junctions::from([1u64.into(), Kusama.into()]).global_consensus(), Err(())); + } + + #[test] + fn test_conversion() { + use super::{Junction::*, NetworkId::*}; + let x: Junctions = GlobalConsensus(Polkadot).into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)])); + let x: Junctions = Polkadot.into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot)])); + let x: Junctions = (Polkadot, Kusama).into(); + assert_eq!(x, Junctions::from([GlobalConsensus(Polkadot), GlobalConsensus(Kusama)])); + } + + #[test] + fn encode_decode_junctions_works() { + let original = Junctions::from([ + Polkadot.into(), + Kusama.into(), + 1u64.into(), + GlobalConsensus(Polkadot), + Parachain(123), + PalletInstance(45), + ]); + let encoded = original.encode(); + assert_eq!(encoded, &[6, 9, 2, 9, 3, 2, 0, 4, 9, 2, 0, 237, 1, 4, 45]); + let decoded = Junctions::decode(&mut &encoded[..]).unwrap(); + assert_eq!(decoded, original); + } +} diff --git a/polkadot/xcm/src/v4/location.rs b/polkadot/xcm/src/v4/location.rs new file mode 100644 index 00000000000..db55c3d3034 --- /dev/null +++ b/polkadot/xcm/src/v4/location.rs @@ -0,0 +1,746 @@ +// 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 . + +//! XCM `Location` datatype. + +use super::{traits::Reanchorable, Junction, Junctions}; +use crate::{v3::MultiLocation as OldLocation, VersionedLocation}; +use core::{ + convert::{TryFrom, TryInto}, + result, +}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +/// A relative path between state-bearing consensus systems. +/// +/// A location in a consensus system is defined as an *isolatable state machine* held within global +/// consensus. The location in question need not have a sophisticated consensus algorithm of its +/// own; a single account within Ethereum, for example, could be considered a location. +/// +/// A very-much non-exhaustive list of types of location include: +/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain. +/// - A layer-0 super-chain, e.g. the Polkadot Relay chain. +/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum. +/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based +/// Substrate chain. +/// - An account. +/// +/// A `Location` is a *relative identifier*, meaning that it can only be used to define the +/// relative path between two locations, and cannot generally be used to refer to a location +/// universally. It is comprised of an integer number of parents specifying the number of times to +/// "escape" upwards into the containing consensus system and then a number of *junctions*, each +/// diving down and specifying some interior portion of state (which may be considered a +/// "sub-consensus" system). +/// +/// This specific `Location` implementation uses a `Junctions` datatype which is a Rust `enum` +/// in order to make pattern matching easier. There are occasions where it is important to ensure +/// that a value is strictly an interior location, in those cases, `Junctions` may be used. +/// +/// The `Location` value of `Null` simply refers to the interpreting consensus system. +#[derive( + Clone, + Decode, + Encode, + Eq, + PartialEq, + Ord, + PartialOrd, + Debug, + TypeInfo, + MaxEncodedLen, + serde::Serialize, + serde::Deserialize, +)] +pub struct Location { + /// The number of parent junctions at the beginning of this `Location`. + pub parents: u8, + /// The interior (i.e. non-parent) junctions that this `Location` contains. + pub interior: Junctions, +} + +impl Default for Location { + fn default() -> Self { + Self { parents: 0, interior: Junctions::Here } + } +} + +/// A relative location which is constrained to be an interior location of the context. +/// +/// See also `Location`. +pub type InteriorLocation = Junctions; + +impl Location { + /// Creates a new `Location` with the given number of parents and interior junctions. + pub fn new(parents: u8, interior: impl Into) -> Location { + Location { parents, interior: interior.into() } + } + + /// Consume `self` and return the equivalent `VersionedLocation` value. + pub const fn into_versioned(self) -> VersionedLocation { + VersionedLocation::V4(self) + } + + /// Creates a new `Location` with 0 parents and a `Here` interior. + /// + /// The resulting `Location` can be interpreted as the "current consensus system". + pub const fn here() -> Location { + Location { parents: 0, interior: Junctions::Here } + } + + /// Creates a new `Location` which evaluates to the parent context. + pub const fn parent() -> Location { + Location { parents: 1, interior: Junctions::Here } + } + + /// Creates a new `Location` with `parents` and an empty (`Here`) interior. + pub const fn ancestor(parents: u8) -> Location { + Location { parents, interior: Junctions::Here } + } + + /// Whether the `Location` has no parents and has a `Here` interior. + pub fn is_here(&self) -> bool { + self.parents == 0 && self.interior.len() == 0 + } + + /// Remove the `NetworkId` value in any interior `Junction`s. + pub fn remove_network_id(&mut self) { + self.interior.remove_network_id(); + } + + /// Return a reference to the interior field. + pub fn interior(&self) -> &Junctions { + &self.interior + } + + /// Return a mutable reference to the interior field. + pub fn interior_mut(&mut self) -> &mut Junctions { + &mut self.interior + } + + /// Returns the number of `Parent` junctions at the beginning of `self`. + pub const fn parent_count(&self) -> u8 { + self.parents + } + + /// Returns the parent count and the interior [`Junctions`] as a tuple. + /// + /// To be used when pattern matching, for example: + /// + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location}; + /// fn get_parachain_id(loc: &Location) -> Option { + /// match loc.unpack() { + /// (0, [Parachain(id)]) => Some(*id), + /// _ => None + /// } + /// } + /// ``` + pub fn unpack(&self) -> (u8, &[Junction]) { + (self.parents, self.interior.as_slice()) + } + + /// Returns boolean indicating whether `self` contains only the specified amount of + /// parents and no interior junctions. + pub const fn contains_parents_only(&self, count: u8) -> bool { + matches!(self.interior, Junctions::Here) && self.parents == count + } + + /// Returns the number of parents and junctions in `self`. + pub fn len(&self) -> usize { + self.parent_count() as usize + self.interior.len() + } + + /// Returns the first interior junction, or `None` if the location is empty or contains only + /// parents. + pub fn first_interior(&self) -> Option<&Junction> { + self.interior.first() + } + + /// Returns last junction, or `None` if the location is empty or contains only parents. + pub fn last(&self) -> Option<&Junction> { + self.interior.last() + } + + /// Splits off the first interior junction, returning the remaining suffix (first item in tuple) + /// and the first element (second item in tuple) or `None` if it was empty. + pub fn split_first_interior(self) -> (Location, Option) { + let Location { parents, interior: junctions } = self; + let (suffix, first) = junctions.split_first(); + let location = Location { parents, interior: suffix }; + (location, first) + } + + /// Splits off the last interior junction, returning the remaining prefix (first item in tuple) + /// and the last element (second item in tuple) or `None` if it was empty or if `self` only + /// contains parents. + pub fn split_last_interior(self) -> (Location, Option) { + let Location { parents, interior: junctions } = self; + let (prefix, last) = junctions.split_last(); + let location = Location { parents, interior: prefix }; + (location, last) + } + + /// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_interior(&mut self, new: impl Into) -> result::Result<(), Junction> { + self.interior.push(new) + } + + /// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` with `new` in + /// case of overflow. + pub fn push_front_interior( + &mut self, + new: impl Into, + ) -> result::Result<(), Junction> { + self.interior.push_front(new) + } + + /// Consumes `self` and returns a `Location` suffixed with `new`, or an `Err` with + /// theoriginal value of `self` in case of overflow. + pub fn pushed_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_with(new) { + Ok(i) => Ok(Location { interior: i, parents: self.parents }), + Err((i, j)) => Err((Location { interior: i, parents: self.parents }, j)), + } + } + + /// Consumes `self` and returns a `Location` prefixed with `new`, or an `Err` with the + /// original value of `self` in case of overflow. + pub fn pushed_front_with_interior( + self, + new: impl Into, + ) -> result::Result { + match self.interior.pushed_front_with(new) { + Ok(i) => Ok(Location { interior: i, parents: self.parents }), + Err((i, j)) => Err((Location { interior: i, parents: self.parents }, j)), + } + } + + /// Returns the junction at index `i`, or `None` if the location is a parent or if the location + /// does not contain that many elements. + pub fn at(&self, i: usize) -> Option<&Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at(i - num_parents) + } + + /// Returns a mutable reference to the junction at index `i`, or `None` if the location is a + /// parent or if it doesn't contain that many elements. + pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> { + let num_parents = self.parents as usize; + if i < num_parents { + return None + } + self.interior.at_mut(i - num_parents) + } + + /// Decrements the parent count by 1. + pub fn dec_parent(&mut self) { + self.parents = self.parents.saturating_sub(1); + } + + /// Removes the first interior junction from `self`, returning it + /// (or `None` if it was empty or if `self` contains only parents). + pub fn take_first_interior(&mut self) -> Option { + self.interior.take_first() + } + + /// Removes the last element from `interior`, returning it (or `None` if it was empty or if + /// `self` only contains parents). + pub fn take_last(&mut self) -> Option { + self.interior.take_last() + } + + /// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with + /// the junctions of `prefix` and that it has a single `Junction` item following. + /// If so, returns a reference to this `Junction` item. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location}; + /// # fn main() { + /// let mut m = Location::new(1, [PalletInstance(3), OnlyChild]); + /// assert_eq!( + /// m.match_and_split(&Location::new(1, [PalletInstance(3)])), + /// Some(&OnlyChild), + /// ); + /// assert_eq!(m.match_and_split(&Location::new(1, Here)), None); + /// # } + /// ``` + pub fn match_and_split(&self, prefix: &Location) -> Option<&Junction> { + if self.parents != prefix.parents { + return None + } + self.interior.match_and_split(&prefix.interior) + } + + pub fn starts_with(&self, prefix: &Location) -> bool { + self.parents == prefix.parents && self.interior.starts_with(&prefix.interior) + } + + /// Mutate `self` so that it is suffixed with `suffix`. + /// + /// Does not modify `self` and returns `Err` with `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parachain(21), 69u64).into(); + /// assert_eq!(m.append_with((Parent, PalletInstance(3))), Ok(())); + /// assert_eq!(m, Location::new(1, [Parachain(21), PalletInstance(3)])); + /// # } + /// ``` + pub fn append_with(&mut self, suffix: impl Into) -> Result<(), Self> { + let prefix = core::mem::replace(self, suffix.into()); + match self.prepend_with(prefix) { + Ok(()) => Ok(()), + Err(prefix) => Err(core::mem::replace(self, prefix)), + } + } + + /// Consume `self` and return its value suffixed with `suffix`. + /// + /// Returns `Err` with the original value of `self` and `suffix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parachain(21), 69u64).into(); + /// let r = m.appended_with((Parent, PalletInstance(3))).unwrap(); + /// assert_eq!(r, Location::new(1, [Parachain(21), PalletInstance(3)])); + /// # } + /// ``` + pub fn appended_with(mut self, suffix: impl Into) -> Result { + match self.append_with(suffix) { + Ok(()) => Ok(self), + Err(suffix) => Err((self, suffix)), + } + } + + /// Mutate `self` so that it is prefixed with `prefix`. + /// + /// Does not modify `self` and returns `Err` with `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let mut m: Location = (Parent, Parent, PalletInstance(3)).into(); + /// assert_eq!(m.prepend_with((Parent, Parachain(21), OnlyChild)), Ok(())); + /// assert_eq!(m, Location::new(1, [PalletInstance(3)])); + /// # } + /// ``` + pub fn prepend_with(&mut self, prefix: impl Into) -> Result<(), Self> { + // prefix self (suffix) + // P .. P I .. I p .. p i .. i + let mut prefix = prefix.into(); + let prepend_interior = prefix.interior.len().saturating_sub(self.parents as usize); + let final_interior = self.interior.len().saturating_add(prepend_interior); + if final_interior > super::junctions::MAX_JUNCTIONS { + return Err(prefix) + } + let suffix_parents = (self.parents as usize).saturating_sub(prefix.interior.len()); + let final_parents = (prefix.parents as usize).saturating_add(suffix_parents); + if final_parents > 255 { + return Err(prefix) + } + + // cancel out the final item on the prefix interior for one of the suffix's parents. + while self.parents > 0 && prefix.take_last().is_some() { + self.dec_parent(); + } + + // now we have either removed all suffix's parents or prefix interior. + // this means we can combine the prefix's and suffix's remaining parents/interior since + // we know that with at least one empty, the overall order will be respected: + // prefix self (suffix) + // P .. P (I) p .. p i .. i => P + p .. (no I) i + // -- or -- + // P .. P I .. I (p) i .. i => P (no p) .. I + i + + self.parents = self.parents.saturating_add(prefix.parents); + for j in prefix.interior.into_iter().rev() { + self.push_front_interior(j) + .expect("final_interior no greater than MAX_JUNCTIONS; qed"); + } + Ok(()) + } + + /// Consume `self` and return its value prefixed with `prefix`. + /// + /// Returns `Err` with the original value of `self` and `prefix` in case of overflow. + /// + /// # Example + /// ```rust + /// # use staging_xcm::v4::{Junctions::*, Junction::*, Location, Parent}; + /// # fn main() { + /// let m: Location = (Parent, Parent, PalletInstance(3)).into(); + /// let r = m.prepended_with((Parent, Parachain(21), OnlyChild)).unwrap(); + /// assert_eq!(r, Location::new(1, [PalletInstance(3)])); + /// # } + /// ``` + pub fn prepended_with(mut self, prefix: impl Into) -> Result { + match self.prepend_with(prefix) { + Ok(()) => Ok(self), + Err(prefix) => Err((self, prefix)), + } + } + + /// Remove any unneeded parents/junctions in `self` based on the given context it will be + /// interpreted in. + pub fn simplify(&mut self, context: &Junctions) { + if context.len() < self.parents as usize { + // Not enough context + return + } + while self.parents > 0 { + let maybe = context.at(context.len() - (self.parents as usize)); + match (self.interior.first(), maybe) { + (Some(i), Some(j)) if i == j => { + self.interior.take_first(); + self.parents -= 1; + }, + _ => break, + } + } + } + + /// Return the Location subsection identifying the chain that `self` points to. + pub fn chain_location(&self) -> Location { + let mut clone = self.clone(); + // start popping junctions until we reach chain identifier + while let Some(j) = clone.last() { + if matches!(j, Junction::Parachain(_) | Junction::GlobalConsensus(_)) { + // return chain subsection + return clone + } else { + (clone, _) = clone.split_last_interior(); + } + } + Location::new(clone.parents, Junctions::Here) + } +} + +impl Reanchorable for Location { + type Error = Self; + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + fn reanchor(&mut self, target: &Location, context: &InteriorLocation) -> Result<(), ()> { + // TODO: https://github.com/paritytech/polkadot/issues/4489 Optimize this. + + // 1. Use our `context` to figure out how the `target` would address us. + let inverted_target = context.invert_target(target)?; + + // 2. Prepend `inverted_target` to `self` to get self's location from the perspective of + // `target`. + self.prepend_with(inverted_target).map_err(|_| ())?; + + // 3. Given that we know some of `target` context, ensure that any parents in `self` are + // strictly needed. + self.simplify(target.interior()); + + Ok(()) + } + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + fn reanchored(mut self, target: &Location, context: &InteriorLocation) -> Result { + match self.reanchor(target, context) { + Ok(()) => Ok(self), + Err(()) => Err(self), + } + } +} + +impl TryFrom for Option { + type Error = (); + fn try_from(value: OldLocation) -> result::Result { + Ok(Some(Location::try_from(value)?)) + } +} + +impl TryFrom for Location { + type Error = (); + fn try_from(x: OldLocation) -> result::Result { + Ok(Location { parents: x.parents, interior: x.interior.try_into()? }) + } +} + +/// A unit struct which can be converted into a `Location` of `parents` value 1. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Parent; +impl From for Location { + fn from(_: Parent) -> Self { + Location { parents: 1, interior: Junctions::Here } + } +} + +/// A tuple struct which can be converted into a `Location` of `parents` value 1 with the inner +/// interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct ParentThen(pub Junctions); +impl From for Location { + fn from(ParentThen(interior): ParentThen) -> Self { + Location { parents: 1, interior } + } +} + +/// A unit struct which can be converted into a `Location` of the inner `parents` value. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Ancestor(pub u8); +impl From for Location { + fn from(Ancestor(parents): Ancestor) -> Self { + Location { parents, interior: Junctions::Here } + } +} + +/// A unit struct which can be converted into a `Location` of the inner `parents` value and the +/// inner interior. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct AncestorThen(pub u8, pub Interior); +impl> From> for Location { + fn from(AncestorThen(parents, interior): AncestorThen) -> Self { + Location { parents, interior: interior.into() } + } +} + +xcm_procedural::impl_conversion_functions_for_location_v4!(); + +#[cfg(test)] +mod tests { + use crate::v4::prelude::*; + use parity_scale_codec::{Decode, Encode}; + + #[test] + fn conversion_works() { + let x: Location = Parent.into(); + assert_eq!(x, Location { parents: 1, interior: Here }); + // let x: Location = (Parent,).into(); + // assert_eq!(x, Location { parents: 1, interior: Here }); + // let x: Location = (Parent, Parent).into(); + // assert_eq!(x, Location { parents: 2, interior: Here }); + let x: Location = (Parent, Parent, OnlyChild).into(); + assert_eq!(x, Location { parents: 2, interior: OnlyChild.into() }); + let x: Location = OnlyChild.into(); + assert_eq!(x, Location { parents: 0, interior: OnlyChild.into() }); + let x: Location = (OnlyChild,).into(); + assert_eq!(x, Location { parents: 0, interior: OnlyChild.into() }); + } + + #[test] + fn simplify_basic_works() { + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = [PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = (Parent, PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [OnlyChild, Parachain(1000), PalletInstance(42)].into(); + let expected = GeneralIndex(69).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn simplify_incompatible_location_fails() { + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000), PalletInstance(42), GeneralIndex(42)].into(); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + + let mut location: Location = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + let context = [Parachain(1000)].into(); + let expected = + (Parent, Parent, Parachain(1000), PalletInstance(42), GeneralIndex(69)).into(); + location.simplify(&context); + assert_eq!(location, expected); + } + + #[test] + fn reanchor_works() { + let mut id: Location = (Parent, Parachain(1000), GeneralIndex(42)).into(); + let context = Parachain(2000).into(); + let target = (Parent, Parachain(1000)).into(); + let expected = GeneralIndex(42).into(); + id.reanchor(&target, &context).unwrap(); + assert_eq!(id, expected); + } + + #[test] + fn encode_and_decode_works() { + let m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + let encoded = m.encode(); + assert_eq!(encoded, [1, 2, 0, 168, 2, 0, 92].to_vec()); + let decoded = Location::decode(&mut &encoded[..]); + assert_eq!(decoded, Ok(m)); + } + + #[test] + fn match_and_split_works() { + let m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + assert_eq!(m.match_and_split(&Location { parents: 1, interior: Here }), None); + assert_eq!( + m.match_and_split(&Location { parents: 1, interior: [Parachain(42)].into() }), + Some(&AccountIndex64 { network: None, index: 23 }) + ); + assert_eq!(m.match_and_split(&m), None); + } + + #[test] + fn append_with_works() { + let acc = AccountIndex64 { network: None, index: 23 }; + let mut m = Location { parents: 1, interior: [Parachain(42)].into() }; + assert_eq!(m.append_with([PalletInstance(3), acc]), Ok(())); + assert_eq!( + m, + Location { parents: 1, interior: [Parachain(42), PalletInstance(3), acc].into() } + ); + + // cannot append to create overly long location + let acc = AccountIndex64 { network: None, index: 23 }; + let m = Location { + parents: 254, + interior: [Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild].into(), + }; + let suffix: Location = (PalletInstance(3), acc, OnlyChild, OnlyChild).into(); + assert_eq!(m.clone().append_with(suffix.clone()), Err(suffix)); + } + + #[test] + fn prepend_with_works() { + let mut m = Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into(), + }; + assert_eq!(m.prepend_with(Location { parents: 1, interior: [OnlyChild].into() }), Ok(())); + assert_eq!( + m, + Location { + parents: 1, + interior: [Parachain(42), AccountIndex64 { network: None, index: 23 }].into() + } + ); + + // cannot prepend to create overly long location + let mut m = Location { parents: 254, interior: [Parachain(42)].into() }; + let prefix = Location { parents: 2, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Err(prefix)); + + let prefix = Location { parents: 1, interior: Here }; + assert_eq!(m.prepend_with(prefix.clone()), Ok(())); + assert_eq!(m, Location { parents: 255, interior: [Parachain(42)].into() }); + } + + #[test] + fn double_ended_ref_iteration_works() { + let m: Junctions = [Parachain(1000), Parachain(3), PalletInstance(5)].into(); + let mut iter = m.iter(); + + let first = iter.next().unwrap(); + assert_eq!(first, &Parachain(1000)); + let third = iter.next_back().unwrap(); + assert_eq!(third, &PalletInstance(5)); + let second = iter.next_back().unwrap(); + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + assert_eq!(second, &Parachain(3)); + + let res = Here + .pushed_with(*first) + .unwrap() + .pushed_with(*second) + .unwrap() + .pushed_with(*third) + .unwrap(); + assert_eq!(m, res); + + // make sure there's no funny business with the 0 indexing + let m = Here; + let mut iter = m.iter(); + + assert_eq!(iter.next(), None); + assert_eq!(iter.next_back(), None); + } + + #[test] + fn conversion_from_other_types_works() { + use crate::v3; + use core::convert::TryInto; + + fn takes_location>(_arg: Arg) {} + + takes_location(Parent); + takes_location(Here); + takes_location([Parachain(42)]); + takes_location((Ancestor(255), PalletInstance(8))); + takes_location((Ancestor(5), Parachain(1), PalletInstance(3))); + takes_location((Ancestor(2), Here)); + takes_location(AncestorThen( + 3, + [Parachain(43), AccountIndex64 { network: None, index: 155 }], + )); + takes_location((Parent, AccountId32 { network: None, id: [0; 32] })); + takes_location((Parent, Here)); + takes_location(ParentThen([Parachain(75)].into())); + takes_location([Parachain(100), PalletInstance(3)]); + + assert_eq!(v3::Location::from(v3::Junctions::Here).try_into(), Ok(Location::here())); + assert_eq!(v3::Location::from(v3::Parent).try_into(), Ok(Location::parent())); + assert_eq!( + v3::Location::from((v3::Parent, v3::Parent, v3::Junction::GeneralIndex(42u128),)) + .try_into(), + Ok(Location { parents: 2, interior: [GeneralIndex(42u128)].into() }), + ); + } +} diff --git a/polkadot/xcm/src/v4/mod.rs b/polkadot/xcm/src/v4/mod.rs new file mode 100644 index 00000000000..3b57ba1b137 --- /dev/null +++ b/polkadot/xcm/src/v4/mod.rs @@ -0,0 +1,1457 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate 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. + +// Substrate 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 . + +//! Version 4 of the Cross-Consensus Message format data structures. + +pub use super::v2::GetWeight; +use super::v3::{ + Instruction as OldInstruction, PalletInfo as OldPalletInfo, + QueryResponseInfo as OldQueryResponseInfo, Response as OldResponse, Xcm as OldXcm, +}; +use crate::DoubleEncoded; +use alloc::{vec, vec::Vec}; +use bounded_collections::{parameter_types, BoundedVec}; +use core::{ + convert::{TryFrom, TryInto}, + fmt::Debug, + result, +}; +use derivative::Derivative; +use parity_scale_codec::{self, Decode, Encode, MaxEncodedLen}; +use scale_info::TypeInfo; + +mod asset; +mod junction; +pub(crate) mod junctions; +mod location; +mod traits; + +pub use asset::{ + Asset, AssetFilter, AssetId, AssetInstance, Assets, Fungibility, WildAsset, WildFungibility, + MAX_ITEMS_IN_ASSETS, +}; +pub use junction::{BodyId, BodyPart, Junction, NetworkId}; +pub use junctions::Junctions; +pub use location::{Ancestor, AncestorThen, InteriorLocation, Location, Parent, ParentThen}; +pub use traits::{ + send_xcm, validate_send, Error, ExecuteXcm, Outcome, PreparedMessage, Reanchorable, Result, + SendError, SendResult, SendXcm, Weight, XcmHash, +}; +// These parts of XCM v3 are unchanged in XCM v4, and are re-imported here. +pub use super::v3::{MaybeErrorCode, OriginKind, WeightLimit}; + +/// This module's XCM version. +pub const VERSION: super::Version = 4; + +/// An identifier for a query. +pub type QueryId = u64; + +#[derive(Derivative, Default, Encode, Decode, TypeInfo)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub struct Xcm(pub Vec>); + +pub const MAX_INSTRUCTIONS_TO_DECODE: u8 = 100; + +impl Xcm { + /// Create an empty instance. + pub fn new() -> Self { + Self(vec![]) + } + + /// Return `true` if no instructions are held in `self`. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Return the number of instructions held in `self`. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Return a reference to the inner value. + pub fn inner(&self) -> &[Instruction] { + &self.0 + } + + /// Return a mutable reference to the inner value. + pub fn inner_mut(&mut self) -> &mut Vec> { + &mut self.0 + } + + /// Consume and return the inner value. + pub fn into_inner(self) -> Vec> { + self.0 + } + + /// Return an iterator over references to the items. + pub fn iter(&self) -> impl Iterator> { + self.0.iter() + } + + /// Return an iterator over mutable references to the items. + pub fn iter_mut(&mut self) -> impl Iterator> { + self.0.iter_mut() + } + + /// Consume and return an iterator over the items. + pub fn into_iter(self) -> impl Iterator> { + self.0.into_iter() + } + + /// Consume and either return `self` if it contains some instructions, or if it's empty, then + /// instead return the result of `f`. + pub fn or_else(self, f: impl FnOnce() -> Self) -> Self { + if self.0.is_empty() { + f() + } else { + self + } + } + + /// Return the first instruction, if any. + pub fn first(&self) -> Option<&Instruction> { + self.0.first() + } + + /// Return the last instruction, if any. + pub fn last(&self) -> Option<&Instruction> { + self.0.last() + } + + /// Return the only instruction, contained in `Self`, iff only one exists (`None` otherwise). + pub fn only(&self) -> Option<&Instruction> { + if self.0.len() == 1 { + self.0.first() + } else { + None + } + } + + /// Return the only instruction, contained in `Self`, iff only one exists (returns `self` + /// otherwise). + pub fn into_only(mut self) -> core::result::Result, Self> { + if self.0.len() == 1 { + self.0.pop().ok_or(self) + } else { + Err(self) + } + } +} + +impl From>> for Xcm { + fn from(c: Vec>) -> Self { + Self(c) + } +} + +impl From> for Vec> { + fn from(c: Xcm) -> Self { + c.0 + } +} + +/// A prelude for importing all types typically used when interacting with XCM messages. +pub mod prelude { + mod contents { + pub use super::super::{ + send_xcm, validate_send, Ancestor, AncestorThen, Asset, + AssetFilter::{self, *}, + AssetId, + AssetInstance::{self, *}, + Assets, BodyId, BodyPart, Error as XcmError, ExecuteXcm, + Fungibility::{self, *}, + Instruction::*, + InteriorLocation, + Junction::{self, *}, + Junctions::{self, Here}, + Location, MaybeErrorCode, + NetworkId::{self, *}, + OriginKind, Outcome, PalletInfo, Parent, ParentThen, PreparedMessage, QueryId, + QueryResponseInfo, Reanchorable, Response, Result as XcmResult, SendError, SendResult, + SendXcm, Weight, + WeightLimit::{self, *}, + WildAsset::{self, *}, + WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible}, + XcmContext, XcmHash, XcmWeightInfo, VERSION as XCM_VERSION, + }; + } + pub use super::{Instruction, Xcm}; + pub use contents::*; + pub mod opaque { + pub use super::{ + super::opaque::{Instruction, Xcm}, + contents::*, + }; + } +} + +parameter_types! { + pub MaxPalletNameLen: u32 = 48; + /// Maximum size of the encoded error code coming from a `Dispatch` result, used for + /// `MaybeErrorCode`. This is not (yet) enforced, so it's just an indication of expectation. + pub MaxDispatchErrorLen: u32 = 128; + pub MaxPalletsInfo: u32 = 64; +} + +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub struct PalletInfo { + #[codec(compact)] + index: u32, + name: BoundedVec, + module_name: BoundedVec, + #[codec(compact)] + major: u32, + #[codec(compact)] + minor: u32, + #[codec(compact)] + patch: u32, +} + +impl TryInto for PalletInfo { + type Error = (); + + fn try_into(self) -> result::Result { + OldPalletInfo::new( + self.index, + self.name.into_inner(), + self.module_name.into_inner(), + self.major, + self.minor, + self.patch, + ) + .map_err(|_| ()) + } +} + +impl PalletInfo { + pub fn new( + index: u32, + name: Vec, + module_name: Vec, + major: u32, + minor: u32, + patch: u32, + ) -> result::Result { + let name = BoundedVec::try_from(name).map_err(|_| Error::Overflow)?; + let module_name = BoundedVec::try_from(module_name).map_err(|_| Error::Overflow)?; + + Ok(Self { index, name, module_name, major, minor, patch }) + } +} + +/// Response data to a query. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo, MaxEncodedLen)] +pub enum Response { + /// No response. Serves as a neutral default. + Null, + /// Some assets. + Assets(Assets), + /// The outcome of an XCM instruction. + ExecutionResult(Option<(u32, Error)>), + /// An XCM version. + Version(super::Version), + /// The index, instance name, pallet name and version of some pallets. + PalletsInfo(BoundedVec), + /// The status of a dispatch attempt using `Transact`. + DispatchResult(MaybeErrorCode), +} + +impl Default for Response { + fn default() -> Self { + Self::Null + } +} + +impl TryFrom for Response { + type Error = (); + + fn try_from(old: OldResponse) -> result::Result { + use OldResponse::*; + Ok(match old { + Null => Self::Null, + Assets(assets) => Self::Assets(assets.try_into()?), + ExecutionResult(result) => + Self::ExecutionResult(result.map(|(num, old_error)| (num, old_error.into()))), + Version(version) => Self::Version(version), + PalletsInfo(pallet_info) => { + let inner = pallet_info + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + Self::PalletsInfo( + BoundedVec::::try_from(inner).map_err(|_| ())?, + ) + }, + DispatchResult(maybe_error) => Self::DispatchResult(maybe_error), + }) + } +} + +/// Information regarding the composition of a query response. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)] +pub struct QueryResponseInfo { + /// The destination to which the query response message should be send. + pub destination: Location, + /// The `query_id` field of the `QueryResponse` message. + #[codec(compact)] + pub query_id: QueryId, + /// The `max_weight` field of the `QueryResponse` message. + pub max_weight: Weight, +} + +impl TryFrom for QueryResponseInfo { + type Error = (); + + fn try_from(old: OldQueryResponseInfo) -> result::Result { + Ok(Self { + destination: old.destination.try_into()?, + query_id: old.query_id, + max_weight: old.max_weight, + }) + } +} + +/// Contextual data pertaining to a specific list of XCM instructions. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)] +pub struct XcmContext { + /// The current value of the Origin register of the `XCVM`. + pub origin: Option, + /// The identity of the XCM; this may be a hash of its versioned encoding but could also be + /// a high-level identity set by an appropriate barrier. + pub message_id: XcmHash, + /// The current value of the Topic register of the `XCVM`. + pub topic: Option<[u8; 32]>, +} + +impl XcmContext { + /// Constructor which sets the message ID to the supplied parameter and leaves the origin and + /// topic unset. + pub fn with_message_id(message_id: XcmHash) -> XcmContext { + XcmContext { origin: None, message_id, topic: None } + } +} + +/// Cross-Consensus Message: A message from one consensus system to another. +/// +/// Consensus systems that may send and receive messages include blockchains and smart contracts. +/// +/// All messages are delivered from a known *origin*, expressed as a `Location`. +/// +/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the +/// outer XCM format, known as `VersionedXcm`. +#[derive( + Derivative, + Encode, + Decode, + TypeInfo, + xcm_procedural::XcmWeightInfoTrait, + xcm_procedural::Builder, +)] +#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))] +#[codec(encode_bound())] +#[codec(decode_bound())] +#[scale_info(bounds(), skip_type_params(Call))] +pub enum Instruction { + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into the Holding + /// Register. + /// + /// - `assets`: The asset(s) to be withdrawn into holding. + /// + /// Kind: *Command*. + /// + /// Errors: + #[builder(loads_holding)] + WithdrawAsset(Assets), + + /// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` + /// system and equivalent derivatives should be placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into holding. + /// + /// Safety: `origin` must be trusted to have received and be storing `assets` such that they + /// may later be withdrawn should this system send a corresponding message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + #[builder(loads_holding)] + ReserveAssetDeposited(Assets), + + /// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should + /// be created and placed into the Holding Register. + /// + /// - `assets`: The asset(s) that are minted into the Holding Register. + /// + /// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding `assets` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + #[builder(loads_holding)] + ReceiveTeleportedAsset(Assets), + + /// Respond with information that the local system is expecting. + /// + /// - `query_id`: The identifier of the query that resulted in this message being sent. + /// - `response`: The message content. + /// - `max_weight`: The maximum weight that handling this response should take. + /// - `querier`: The location responsible for the initiation of the response, if there is one. + /// In general this will tend to be the same location as the receiver of this message. NOTE: + /// As usual, this is interpreted from the perspective of the receiving consensus system. + /// + /// Safety: Since this is information only, there are no immediate concerns. However, it should + /// be remembered that even if the Origin behaves reasonably, it can always be asked to make + /// a response to a third-party chain who may or may not be expecting the response. Therefore + /// the `querier` should be checked to match the expected value. + /// + /// Kind: *Information*. + /// + /// Errors: + QueryResponse { + #[codec(compact)] + query_id: QueryId, + response: Response, + max_weight: Weight, + querier: Option, + }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `beneficiary`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `beneficiary`: The new owner for the assets. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferAsset { assets: Assets, beneficiary: Location }, + + /// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets + /// under the ownership of `dest` within this consensus system (i.e. its sovereign account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given + /// `xcm`. + /// + /// - `assets`: The asset(s) to be withdrawn. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which + /// is sent onwards to `dest`. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + TransferReserveAsset { assets: Assets, dest: Location, xcm: Xcm<()> }, + + /// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed + /// by the kind of origin `origin_kind`. + /// + /// The Transact Status Register is set according to the result of dispatching the call. + /// + /// - `origin_kind`: The means of expressing the message origin as a dispatch origin. + /// - `require_weight_at_most`: The weight of `call`; this should be at least the chain's + /// calculated weight and will be used in the weight determination arithmetic. + /// - `call`: The encoded transaction to be applied. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + Transact { origin_kind: OriginKind, require_weight_at_most: Weight, call: DoubleEncoded }, + + /// A message to notify about a new incoming HRMP channel. This message is meant to be sent by + /// the relay-chain to a para. + /// + /// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel + /// opening. + /// - `max_message_size`: The maximum size of a message proposed by the sender. + /// - `max_capacity`: The maximum number of messages that can be queued in the channel. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + HrmpNewChannelOpenRequest { + #[codec(compact)] + sender: u32, + #[codec(compact)] + max_message_size: u32, + #[codec(compact)] + max_capacity: u32, + }, + + /// A message to notify about that a previously sent open channel request has been accepted by + /// the recipient. That means that the channel will be opened during the next relay-chain + /// session change. This message is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelAccepted { + // NOTE: We keep this as a structured item to a) keep it consistent with the other Hrmp + // items; and b) because the field's meaning is not obvious/mentioned from the item name. + #[codec(compact)] + recipient: u32, + }, + + /// A message to notify that the other party in an open channel decided to close it. In + /// particular, `initiator` is going to close the channel opened from `sender` to the + /// `recipient`. The close will be enacted at the next relay-chain session change. This message + /// is meant to be sent by the relay-chain to a para. + /// + /// Safety: The message should originate directly from the relay-chain. + /// + /// Kind: *System Notification* + /// + /// Errors: + HrmpChannelClosing { + #[codec(compact)] + initiator: u32, + #[codec(compact)] + sender: u32, + #[codec(compact)] + recipient: u32, + }, + + /// Clear the origin. + /// + /// This may be used by the XCM author to ensure that later instructions cannot command the + /// authority of the origin (e.g. if they are being relayed from an untrusted source, as often + /// the case with `ReserveAssetDeposited`). + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + ClearOrigin, + + /// Mutate the origin to some interior location. + /// + /// Kind: *Command* + /// + /// Errors: + DescendOrigin(InteriorLocation), + + /// Immediately report the contents of the Error Register to the given destination via XCM. + /// + /// A `QueryResponse` message of type `ExecutionOutcome` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// + /// Kind: *Command* + /// + /// Errors: + ReportError(QueryResponseInfo), + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `beneficiary` within this consensus system. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `beneficiary`: The new owner for the assets. + /// + /// Kind: *Command* + /// + /// Errors: + DepositAsset { assets: AssetFilter, beneficiary: Location }, + + /// Remove the asset(s) (`assets`) from the Holding Register and place equivalent assets under + /// the ownership of `dest` within this consensus system (i.e. deposit them into its sovereign + /// account). + /// + /// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: The location whose sovereign account will own the assets and thus the effective + /// beneficiary for the assets and the notification target for the reserve asset deposit + /// message. + /// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is + /// sent onwards to `dest`. + /// + /// Kind: *Command* + /// + /// Errors: + DepositReserveAsset { assets: AssetFilter, dest: Location, xcm: Xcm<()> }, + + /// Remove the asset(s) (`want`) from the Holding Register and replace them with alternative + /// assets. + /// + /// The minimum amount of assets to be received into the Holding Register for the order not to + /// fail may be stated. + /// + /// - `give`: The maximum amount of assets to remove from holding. + /// - `want`: The minimum amount of assets which `give` should be exchanged for. + /// - `maximal`: If `true`, then prefer to give as much as possible up to the limit of `give` + /// and receive accordingly more. If `false`, then prefer to give as little as possible in + /// order to receive as little as possible while receiving at least `want`. + /// + /// Kind: *Command* + /// + /// Errors: + ExchangeAsset { give: AssetFilter, want: Assets, maximal: bool }, + + /// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a + /// reserve location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The + /// sovereign account of this consensus system *on the reserve location* will have + /// appropriate assets withdrawn and `effects` will be executed on them. There will typically + /// be only one valid location on any given asset/chain combination. + /// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve + /// location*. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateReserveWithdraw { assets: AssetFilter, reserve: Location, xcm: Xcm<()> }, + + /// Remove the asset(s) (`assets`) from holding and send a `ReceiveTeleportedAsset` XCM message + /// to a `dest` location. + /// + /// - `assets`: The asset(s) to remove from holding. + /// - `dest`: A valid location that respects teleports coming from this location. + /// - `xcm`: The instructions to execute on the assets once arrived *on the destination + /// location*. + /// + /// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for + /// all `assets`. If it does not, then the assets may be lost. + /// + /// Kind: *Command* + /// + /// Errors: + InitiateTeleport { assets: AssetFilter, dest: Location, xcm: Xcm<()> }, + + /// Report to a given destination the contents of the Holding Register. + /// + /// A `QueryResponse` message of type `Assets` is sent to the described destination. + /// + /// - `response_info`: Information for making the response. + /// - `assets`: A filter for the assets that should be reported back. The assets reported back + /// will be, asset-wise, *the lesser of this value and the holding register*. No wildcards + /// will be used when reporting assets back. + /// + /// Kind: *Command* + /// + /// Errors: + ReportHolding { response_info: QueryResponseInfo, assets: AssetFilter }, + + /// Pay for the execution of some XCM `xcm` and `orders` with up to `weight` + /// picoseconds of execution time, paying for this with up to `fees` from the Holding Register. + /// + /// - `fees`: The asset(s) to remove from the Holding Register to pay for fees. + /// - `weight_limit`: The maximum amount of weight to purchase; this must be at least the + /// expected maximum weight of the total XCM to be executed for the + /// `AllowTopLevelPaidExecutionFrom` barrier to allow the XCM be executed. + /// + /// Kind: *Command* + /// + /// Errors: + BuyExecution { fees: Asset, weight_limit: WeightLimit }, + + /// Refund any surplus weight previously bought with `BuyExecution`. + /// + /// Kind: *Command* + /// + /// Errors: None. + RefundSurplus, + + /// Set the Error Handler Register. This is code that should be called in the case of an error + /// happening. + /// + /// An error occurring within execution of this code will _NOT_ result in the error register + /// being set, nor will an error handler be called due to it. The error handler and appendix + /// may each still be set. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous handler and the new + /// handler, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetErrorHandler(Xcm), + + /// Set the Appendix Register. This is code that should be called after code execution + /// (including the error handler if any) is finished. This will be called regardless of whether + /// an error occurred. + /// + /// Any error occurring due to execution of this code will result in the error register being + /// set, and the error handler (if set) firing. + /// + /// The apparent weight of this instruction is inclusive of the inner `Xcm`; the executing + /// weight however includes only the difference between the previous appendix and the new + /// appendix, which can reasonably be negative, which would result in a surplus. + /// + /// Kind: *Command* + /// + /// Errors: None. + SetAppendix(Xcm), + + /// Clear the Error Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearError, + + /// Create some assets which are being held on behalf of the origin. + /// + /// - `assets`: The assets which are to be claimed. This must match exactly with the assets + /// claimable by the origin of the ticket. + /// - `ticket`: The ticket of the asset; this is an abstract identifier to help locate the + /// asset. + /// + /// Kind: *Command* + /// + /// Errors: + #[builder(loads_holding)] + ClaimAsset { assets: Assets, ticket: Location }, + + /// Always throws an error of type `Trap`. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `Trap`: All circumstances, whose inner value is the same as this item's inner value. + Trap(#[codec(compact)] u64), + + /// Ask the destination system to respond with the most recent version of XCM that they + /// support in a `QueryResponse` instruction. Any changes to this should also elicit similar + /// responses when they happen. + /// + /// - `query_id`: An identifier that will be replicated into the returned XCM message. + /// - `max_response_weight`: The maximum amount of weight that the `QueryResponse` item which + /// is sent as a reply may take to execute. NOTE: If this is unexpectedly large then the + /// response may not execute at all. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + SubscribeVersion { + #[codec(compact)] + query_id: QueryId, + max_response_weight: Weight, + }, + + /// Cancel the effect of a previous `SubscribeVersion` instruction. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible* + UnsubscribeVersion, + + /// Reduce Holding by up to the given assets. + /// + /// Holding is reduced by as much as possible up to the assets in the parameter. It is not an + /// error if the Holding does not contain the assets (to make this an error, use `ExpectAsset` + /// prior). + /// + /// Kind: *Command* + /// + /// Errors: *Infallible* + BurnAsset(Assets), + + /// Throw an error if Holding does not contain at least the given assets. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Holding Register does not contain the assets in the parameter. + ExpectAsset(Assets), + + /// Ensure that the Origin Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If Origin Register is not equal to the parameter. + ExpectOrigin(Option), + + /// Ensure that the Error Register equals some given value and throw an error if not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter. + ExpectError(Option<(u32, Error)>), + + /// Ensure that the Transact Status Register equals some given value and throw an error if + /// not. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the + /// parameter. + ExpectTransactStatus(MaybeErrorCode), + + /// Query the existence of a particular pallet type. + /// + /// - `module_name`: The module name of the pallet to query. + /// - `response_info`: Information for making the response. + /// + /// Sends a `QueryResponse` to Origin whose data field `PalletsInfo` containing the information + /// of all pallets on the local chain whose name is equal to `name`. This is empty in the case + /// that the local chain is not based on Substrate Frame. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + QueryPallet { module_name: Vec, response_info: QueryResponseInfo }, + + /// Ensure that a particular pallet with a particular version exists. + /// + /// - `index: Compact`: The index which identifies the pallet. An error if no pallet exists at + /// this index. + /// - `name: Vec`: Name which must be equal to the name of the pallet. + /// - `module_name: Vec`: Module name which must be equal to the name of the module in + /// which the pallet exists. + /// - `crate_major: Compact`: Version number which must be equal to the major version of the + /// crate which implements the pallet. + /// - `min_crate_minor: Compact`: Version number which must be at most the minor version of the + /// crate which implements the pallet. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + /// - `ExpectationFalse`: In case any of the expectations are broken. + ExpectPallet { + #[codec(compact)] + index: u32, + name: Vec, + module_name: Vec, + #[codec(compact)] + crate_major: u32, + #[codec(compact)] + min_crate_minor: u32, + }, + + /// Send a `QueryResponse` message containing the value of the Transact Status Register to some + /// destination. + /// + /// - `query_response_info`: The information needed for constructing and sending the + /// `QueryResponse` message. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ReportTransactStatus(QueryResponseInfo), + + /// Set the Transact Status Register to its default, cleared, value. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: *Infallible*. + ClearTransactStatus, + + /// Set the Origin Register to be some child of the Universal Ancestor. + /// + /// Safety: Should only be usable if the Origin is trusted to represent the Universal Ancestor + /// child in general. In general, no Origin should be able to represent the Universal Ancestor + /// child which is the root of the local consensus system since it would by extension + /// allow it to act as any location within the local consensus. + /// + /// The `Junction` parameter should generally be a `GlobalConsensus` variant since it is only + /// these which are children of the Universal Ancestor. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + UniversalOrigin(Junction), + + /// Send a message on to Non-Local Consensus system. + /// + /// This will tend to utilize some extra-consensus mechanism, the obvious one being a bridge. + /// A fee may be charged; this may be determined based on the contents of `xcm`. It will be + /// taken from the Holding register. + /// + /// - `network`: The remote consensus system to which the message should be exported. + /// - `destination`: The location relative to the remote consensus system to which the message + /// should be sent on arrival. + /// - `xcm`: The message to be exported. + /// + /// As an example, to export a message for execution on Statemine (parachain #1000 in the + /// Kusama network), you would call with `network: NetworkId::Kusama` and + /// `destination: [Parachain(1000)].into()`. Alternatively, to export a message for execution + /// on Polkadot, you would call with `network: NetworkId:: Polkadot` and `destination: Here`. + /// + /// Kind: *Command* + /// + /// Errors: *Fallible*. + ExportMessage { network: NetworkId, destination: InteriorLocation, xcm: Xcm<()> }, + + /// Lock the locally held asset and prevent further transfer or withdrawal. + /// + /// This restriction may be removed by the `UnlockAsset` instruction being called with an + /// Origin of `unlocker` and a `target` equal to the current `Origin`. + /// + /// If the locking is successful, then a `NoteUnlockable` instruction is sent to `unlocker`. + /// + /// - `asset`: The asset(s) which should be locked. + /// - `unlocker`: The value which the Origin must be for a corresponding `UnlockAsset` + /// instruction to work. + /// + /// Kind: *Command*. + /// + /// Errors: + LockAsset { asset: Asset, unlocker: Location }, + + /// Remove the lock over `asset` on this chain and (if nothing else is preventing it) allow the + /// asset to be transferred. + /// + /// - `asset`: The asset to be unlocked. + /// - `target`: The owner of the asset on the local chain. + /// + /// Safety: No concerns. + /// + /// Kind: *Command*. + /// + /// Errors: + UnlockAsset { asset: Asset, target: Location }, + + /// Asset (`asset`) has been locked on the `origin` system and may not be transferred. It may + /// only be unlocked with the receipt of the `UnlockAsset` instruction from this chain. + /// + /// - `asset`: The asset(s) which are now unlockable from this origin. + /// - `owner`: The owner of the asset on the chain in which it was locked. This may be a + /// location specific to the origin network. + /// + /// Safety: `origin` must be trusted to have locked the corresponding `asset` + /// prior as a consequence of sending this message. + /// + /// Kind: *Trusted Indication*. + /// + /// Errors: + NoteUnlockable { asset: Asset, owner: Location }, + + /// Send an `UnlockAsset` instruction to the `locker` for the given `asset`. + /// + /// This may fail if the local system is making use of the fact that the asset is locked or, + /// of course, if there is no record that the asset actually is locked. + /// + /// - `asset`: The asset(s) to be unlocked. + /// - `locker`: The location from which a previous `NoteUnlockable` was sent and to which an + /// `UnlockAsset` should be sent. + /// + /// Kind: *Command*. + /// + /// Errors: + RequestUnlock { asset: Asset, locker: Location }, + + /// Sets the Fees Mode Register. + /// + /// - `jit_withdraw`: The fees mode item; if set to `true` then fees for any instructions are + /// withdrawn as needed using the same mechanism as `WithdrawAssets`. + /// + /// Kind: *Command*. + /// + /// Errors: + SetFeesMode { jit_withdraw: bool }, + + /// Set the Topic Register. + /// + /// The 32-byte array identifier in the parameter is not guaranteed to be + /// unique; if such a property is desired, it is up to the code author to + /// enforce uniqueness. + /// + /// Safety: No concerns. + /// + /// Kind: *Command* + /// + /// Errors: + SetTopic([u8; 32]), + + /// Clear the Topic Register. + /// + /// Kind: *Command* + /// + /// Errors: None. + ClearTopic, + + /// Alter the current Origin to another given origin. + /// + /// Kind: *Command* + /// + /// Errors: If the existing state would not allow such a change. + AliasOrigin(Location), + + /// A directive to indicate that the origin expects free execution of the message. + /// + /// At execution time, this instruction just does a check on the Origin register. + /// However, at the barrier stage messages starting with this instruction can be disregarded if + /// the origin is not acceptable for free execution or the `weight_limit` is `Limited` and + /// insufficient. + /// + /// Kind: *Indication* + /// + /// Errors: If the given origin is `Some` and not equal to the current Origin register. + UnpaidExecution { weight_limit: WeightLimit, check_origin: Option }, +} + +impl Xcm { + pub fn into(self) -> Xcm { + Xcm::from(self) + } + pub fn from(xcm: Xcm) -> Self { + Self(xcm.0.into_iter().map(Instruction::::from).collect()) + } +} + +impl Instruction { + pub fn into(self) -> Instruction { + Instruction::from(self) + } + pub fn from(xcm: Instruction) -> Self { + use Instruction::*; + match xcm { + WithdrawAsset(assets) => WithdrawAsset(assets), + ReserveAssetDeposited(assets) => ReserveAssetDeposited(assets), + ReceiveTeleportedAsset(assets) => ReceiveTeleportedAsset(assets), + QueryResponse { query_id, response, max_weight, querier } => + QueryResponse { query_id, response, max_weight, querier }, + TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary }, + TransferReserveAsset { assets, dest, xcm } => + TransferReserveAsset { assets, dest, xcm }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => ReportError(response_info), + DepositAsset { assets, beneficiary } => DepositAsset { assets, beneficiary }, + DepositReserveAsset { assets, dest, xcm } => DepositReserveAsset { assets, dest, xcm }, + ExchangeAsset { give, want, maximal } => ExchangeAsset { give, want, maximal }, + InitiateReserveWithdraw { assets, reserve, xcm } => + InitiateReserveWithdraw { assets, reserve, xcm }, + InitiateTeleport { assets, dest, xcm } => InitiateTeleport { assets, dest, xcm }, + ReportHolding { response_info, assets } => ReportHolding { response_info, assets }, + BuyExecution { fees, weight_limit } => BuyExecution { fees, weight_limit }, + ClearOrigin => ClearOrigin, + DescendOrigin(who) => DescendOrigin(who), + RefundSurplus => RefundSurplus, + SetErrorHandler(xcm) => SetErrorHandler(xcm.into()), + SetAppendix(xcm) => SetAppendix(xcm.into()), + ClearError => ClearError, + ClaimAsset { assets, ticket } => ClaimAsset { assets, ticket }, + Trap(code) => Trap(code), + SubscribeVersion { query_id, max_response_weight } => + SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => UnsubscribeVersion, + BurnAsset(assets) => BurnAsset(assets), + ExpectAsset(assets) => ExpectAsset(assets), + ExpectOrigin(origin) => ExpectOrigin(origin), + ExpectError(error) => ExpectError(error), + ExpectTransactStatus(transact_status) => ExpectTransactStatus(transact_status), + QueryPallet { module_name, response_info } => + QueryPallet { module_name, response_info }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => ReportTransactStatus(response_info), + ClearTransactStatus => ClearTransactStatus, + UniversalOrigin(j) => UniversalOrigin(j), + ExportMessage { network, destination, xcm } => + ExportMessage { network, destination, xcm }, + LockAsset { asset, unlocker } => LockAsset { asset, unlocker }, + UnlockAsset { asset, target } => UnlockAsset { asset, target }, + NoteUnlockable { asset, owner } => NoteUnlockable { asset, owner }, + RequestUnlock { asset, locker } => RequestUnlock { asset, locker }, + SetFeesMode { jit_withdraw } => SetFeesMode { jit_withdraw }, + SetTopic(topic) => SetTopic(topic), + ClearTopic => ClearTopic, + AliasOrigin(location) => AliasOrigin(location), + UnpaidExecution { weight_limit, check_origin } => + UnpaidExecution { weight_limit, check_origin }, + } + } +} + +// TODO: Automate Generation +impl> GetWeight for Instruction { + fn weight(&self) -> Weight { + use Instruction::*; + match self { + WithdrawAsset(assets) => W::withdraw_asset(assets), + ReserveAssetDeposited(assets) => W::reserve_asset_deposited(assets), + ReceiveTeleportedAsset(assets) => W::receive_teleported_asset(assets), + QueryResponse { query_id, response, max_weight, querier } => + W::query_response(query_id, response, max_weight, querier), + TransferAsset { assets, beneficiary } => W::transfer_asset(assets, beneficiary), + TransferReserveAsset { assets, dest, xcm } => + W::transfer_reserve_asset(&assets, dest, xcm), + Transact { origin_kind, require_weight_at_most, call } => + W::transact(origin_kind, require_weight_at_most, call), + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + W::hrmp_new_channel_open_request(sender, max_message_size, max_capacity), + HrmpChannelAccepted { recipient } => W::hrmp_channel_accepted(recipient), + HrmpChannelClosing { initiator, sender, recipient } => + W::hrmp_channel_closing(initiator, sender, recipient), + ClearOrigin => W::clear_origin(), + DescendOrigin(who) => W::descend_origin(who), + ReportError(response_info) => W::report_error(&response_info), + DepositAsset { assets, beneficiary } => W::deposit_asset(assets, beneficiary), + DepositReserveAsset { assets, dest, xcm } => + W::deposit_reserve_asset(assets, dest, xcm), + ExchangeAsset { give, want, maximal } => W::exchange_asset(give, want, maximal), + InitiateReserveWithdraw { assets, reserve, xcm } => + W::initiate_reserve_withdraw(assets, reserve, xcm), + InitiateTeleport { assets, dest, xcm } => W::initiate_teleport(assets, dest, xcm), + ReportHolding { response_info, assets } => W::report_holding(&response_info, &assets), + BuyExecution { fees, weight_limit } => W::buy_execution(fees, weight_limit), + RefundSurplus => W::refund_surplus(), + SetErrorHandler(xcm) => W::set_error_handler(xcm), + SetAppendix(xcm) => W::set_appendix(xcm), + ClearError => W::clear_error(), + ClaimAsset { assets, ticket } => W::claim_asset(assets, ticket), + Trap(code) => W::trap(code), + SubscribeVersion { query_id, max_response_weight } => + W::subscribe_version(query_id, max_response_weight), + UnsubscribeVersion => W::unsubscribe_version(), + BurnAsset(assets) => W::burn_asset(assets), + ExpectAsset(assets) => W::expect_asset(assets), + ExpectOrigin(origin) => W::expect_origin(origin), + ExpectError(error) => W::expect_error(error), + ExpectTransactStatus(transact_status) => W::expect_transact_status(transact_status), + QueryPallet { module_name, response_info } => + W::query_pallet(module_name, response_info), + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + W::expect_pallet(index, name, module_name, crate_major, min_crate_minor), + ReportTransactStatus(response_info) => W::report_transact_status(response_info), + ClearTransactStatus => W::clear_transact_status(), + UniversalOrigin(j) => W::universal_origin(j), + ExportMessage { network, destination, xcm } => + W::export_message(network, destination, xcm), + LockAsset { asset, unlocker } => W::lock_asset(asset, unlocker), + UnlockAsset { asset, target } => W::unlock_asset(asset, target), + NoteUnlockable { asset, owner } => W::note_unlockable(asset, owner), + RequestUnlock { asset, locker } => W::request_unlock(asset, locker), + SetFeesMode { jit_withdraw } => W::set_fees_mode(jit_withdraw), + SetTopic(topic) => W::set_topic(topic), + ClearTopic => W::clear_topic(), + AliasOrigin(location) => W::alias_origin(location), + UnpaidExecution { weight_limit, check_origin } => + W::unpaid_execution(weight_limit, check_origin), + } + } +} + +pub mod opaque { + /// The basic concrete type of `Xcm`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Xcm = super::Xcm<()>; + + /// The basic concrete type of `Instruction`, which doesn't make any assumptions about the + /// format of a call other than it is pre-encoded. + pub type Instruction = super::Instruction<()>; +} + +// Convert from a v3 XCM to a v4 XCM +impl TryFrom> for Xcm { + type Error = (); + fn try_from(old_xcm: OldXcm) -> result::Result { + Ok(Xcm(old_xcm.0.into_iter().map(TryInto::try_into).collect::>()?)) + } +} + +// Convert from a v3 instruction to a v4 instruction +impl TryFrom> for Instruction { + type Error = (); + fn try_from(old_instruction: OldInstruction) -> result::Result { + use OldInstruction::*; + Ok(match old_instruction { + WithdrawAsset(assets) => Self::WithdrawAsset(assets.try_into()?), + ReserveAssetDeposited(assets) => Self::ReserveAssetDeposited(assets.try_into()?), + ReceiveTeleportedAsset(assets) => Self::ReceiveTeleportedAsset(assets.try_into()?), + QueryResponse { query_id, response, max_weight, querier: Some(querier) } => + Self::QueryResponse { + query_id, + querier: querier.try_into()?, + response: response.try_into()?, + max_weight, + }, + QueryResponse { query_id, response, max_weight, querier: None } => + Self::QueryResponse { + query_id, + querier: None, + response: response.try_into()?, + max_weight, + }, + TransferAsset { assets, beneficiary } => Self::TransferAsset { + assets: assets.try_into()?, + beneficiary: beneficiary.try_into()?, + }, + TransferReserveAsset { assets, dest, xcm } => Self::TransferReserveAsset { + assets: assets.try_into()?, + dest: dest.try_into()?, + xcm: xcm.try_into()?, + }, + HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } => + Self::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity }, + HrmpChannelAccepted { recipient } => Self::HrmpChannelAccepted { recipient }, + HrmpChannelClosing { initiator, sender, recipient } => + Self::HrmpChannelClosing { initiator, sender, recipient }, + Transact { origin_kind, require_weight_at_most, call } => + Self::Transact { origin_kind, require_weight_at_most, call: call.into() }, + ReportError(response_info) => Self::ReportError(QueryResponseInfo { + query_id: response_info.query_id, + destination: response_info.destination.try_into().map_err(|_| ())?, + max_weight: response_info.max_weight, + }), + DepositAsset { assets, beneficiary } => { + let beneficiary = beneficiary.try_into()?; + let assets = assets.try_into()?; + Self::DepositAsset { assets, beneficiary } + }, + DepositReserveAsset { assets, dest, xcm } => { + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + let assets = assets.try_into()?; + Self::DepositReserveAsset { assets, dest, xcm } + }, + ExchangeAsset { give, want, maximal } => { + let give = give.try_into()?; + let want = want.try_into()?; + Self::ExchangeAsset { give, want, maximal } + }, + InitiateReserveWithdraw { assets, reserve, xcm } => { + let assets = assets.try_into()?; + let reserve = reserve.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateReserveWithdraw { assets, reserve, xcm } + }, + InitiateTeleport { assets, dest, xcm } => { + let assets = assets.try_into()?; + let dest = dest.try_into()?; + let xcm = xcm.try_into()?; + Self::InitiateTeleport { assets, dest, xcm } + }, + ReportHolding { response_info, assets } => { + let response_info = QueryResponseInfo { + destination: response_info.destination.try_into().map_err(|_| ())?, + query_id: response_info.query_id, + max_weight: response_info.max_weight, + }; + Self::ReportHolding { response_info, assets: assets.try_into()? } + }, + BuyExecution { fees, weight_limit } => { + let fees = fees.try_into()?; + let weight_limit = weight_limit.into(); + Self::BuyExecution { fees, weight_limit } + }, + ClearOrigin => Self::ClearOrigin, + DescendOrigin(who) => Self::DescendOrigin(who.try_into()?), + RefundSurplus => Self::RefundSurplus, + SetErrorHandler(xcm) => Self::SetErrorHandler(xcm.try_into()?), + SetAppendix(xcm) => Self::SetAppendix(xcm.try_into()?), + ClearError => Self::ClearError, + ClaimAsset { assets, ticket } => { + let assets = assets.try_into()?; + let ticket = ticket.try_into()?; + Self::ClaimAsset { assets, ticket } + }, + Trap(code) => Self::Trap(code), + SubscribeVersion { query_id, max_response_weight } => + Self::SubscribeVersion { query_id, max_response_weight }, + UnsubscribeVersion => Self::UnsubscribeVersion, + BurnAsset(assets) => Self::BurnAsset(assets.try_into()?), + ExpectAsset(assets) => Self::ExpectAsset(assets.try_into()?), + ExpectOrigin(maybe_location) => Self::ExpectOrigin( + maybe_location.map(|location| location.try_into()).transpose().map_err(|_| ())?, + ), + ExpectError(maybe_error) => Self::ExpectError( + maybe_error.map(|error| error.try_into()).transpose().map_err(|_| ())?, + ), + ExpectTransactStatus(maybe_error_code) => Self::ExpectTransactStatus(maybe_error_code), + QueryPallet { module_name, response_info } => Self::QueryPallet { + module_name, + response_info: response_info.try_into().map_err(|_| ())?, + }, + ExpectPallet { index, name, module_name, crate_major, min_crate_minor } => + Self::ExpectPallet { index, name, module_name, crate_major, min_crate_minor }, + ReportTransactStatus(response_info) => + Self::ReportTransactStatus(response_info.try_into().map_err(|_| ())?), + ClearTransactStatus => Self::ClearTransactStatus, + UniversalOrigin(junction) => + Self::UniversalOrigin(junction.try_into().map_err(|_| ())?), + ExportMessage { network, destination, xcm } => Self::ExportMessage { + network: network.into(), + destination: destination.try_into().map_err(|_| ())?, + xcm: xcm.try_into().map_err(|_| ())?, + }, + LockAsset { asset, unlocker } => Self::LockAsset { + asset: asset.try_into().map_err(|_| ())?, + unlocker: unlocker.try_into().map_err(|_| ())?, + }, + UnlockAsset { asset, target } => Self::UnlockAsset { + asset: asset.try_into().map_err(|_| ())?, + target: target.try_into().map_err(|_| ())?, + }, + NoteUnlockable { asset, owner } => Self::NoteUnlockable { + asset: asset.try_into().map_err(|_| ())?, + owner: owner.try_into().map_err(|_| ())?, + }, + RequestUnlock { asset, locker } => Self::RequestUnlock { + asset: asset.try_into().map_err(|_| ())?, + locker: locker.try_into().map_err(|_| ())?, + }, + SetFeesMode { jit_withdraw } => Self::SetFeesMode { jit_withdraw }, + SetTopic(topic) => Self::SetTopic(topic), + ClearTopic => Self::ClearTopic, + AliasOrigin(location) => Self::AliasOrigin(location.try_into().map_err(|_| ())?), + UnpaidExecution { weight_limit, check_origin } => Self::UnpaidExecution { + weight_limit, + check_origin: check_origin + .map(|location| location.try_into()) + .transpose() + .map_err(|_| ())?, + }, + }) + } +} + +#[cfg(test)] +mod tests { + use super::{prelude::*, *}; + use crate::v3::{ + Junctions::Here as OldHere, MultiAssetFilter as OldMultiAssetFilter, + WildMultiAsset as OldWildMultiAsset, + }; + + #[test] + fn basic_roundtrip_works() { + let xcm = Xcm::<()>(vec![TransferAsset { + assets: (Here, 1u128).into(), + beneficiary: Here.into(), + }]); + let old_xcm = OldXcm::<()>(vec![OldInstruction::TransferAsset { + assets: (OldHere, 1u128).into(), + beneficiary: OldHere.into(), + }]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn teleport_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReceiveTeleportedAsset((Here, 1u128).into()), + ClearOrigin, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm: OldXcm<()> = OldXcm::<()>(vec![ + OldInstruction::ReceiveTeleportedAsset((OldHere, 1u128).into()), + OldInstruction::ClearOrigin, + OldInstruction::DepositAsset { + assets: crate::v3::MultiAssetFilter::Wild(crate::v3::WildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn reserve_deposit_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + ReserveAssetDeposited((Here, 1u128).into()), + ClearOrigin, + BuyExecution { + fees: (Here, 1u128).into(), + weight_limit: Some(Weight::from_parts(1, 1)).into(), + }, + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::ReserveAssetDeposited((OldHere, 1u128).into()), + OldInstruction::ClearOrigin, + OldInstruction::BuyExecution { + fees: (OldHere, 1u128).into(), + weight_limit: WeightLimit::Limited(Weight::from_parts(1, 1)), + }, + OldInstruction::DepositAsset { + assets: crate::v3::MultiAssetFilter::Wild(crate::v3::WildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Here.into() }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::DepositAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::AllCounted(1)), + beneficiary: OldHere.into(), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } + + #[test] + fn deposit_reserve_asset_roundtrip_works() { + let xcm = Xcm::<()>(vec![ + WithdrawAsset((Here, 1u128).into()), + DepositReserveAsset { + assets: Wild(AllCounted(1)), + dest: Here.into(), + xcm: Xcm::<()>(vec![]), + }, + ]); + let old_xcm = OldXcm::<()>(vec![ + OldInstruction::WithdrawAsset((OldHere, 1u128).into()), + OldInstruction::DepositReserveAsset { + assets: OldMultiAssetFilter::Wild(OldWildMultiAsset::AllCounted(1)), + dest: OldHere.into(), + xcm: OldXcm::<()>(vec![]), + }, + ]); + assert_eq!(old_xcm, OldXcm::<()>::try_from(xcm.clone()).unwrap()); + let new_xcm: Xcm<()> = old_xcm.try_into().unwrap(); + assert_eq!(new_xcm, xcm); + } +} diff --git a/polkadot/xcm/src/v4/traits.rs b/polkadot/xcm/src/v4/traits.rs new file mode 100644 index 00000000000..f6136c76d80 --- /dev/null +++ b/polkadot/xcm/src/v4/traits.rs @@ -0,0 +1,312 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Substrate 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. + +// Substrate 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 . + +//! Cross-Consensus Message format data structures. + +pub use crate::v3::{Error, Result, SendError, XcmHash}; +use core::result; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +pub use sp_weights::Weight; + +use super::*; + +/// Outcome of an XCM execution. +#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] +pub enum Outcome { + /// Execution completed successfully; given weight was used. + Complete { used: Weight }, + /// Execution started, but did not complete successfully due to the given error; given weight + /// was used. + Incomplete { used: Weight, error: Error }, + /// Execution did not start due to the given error. + Error { error: Error }, +} + +impl Outcome { + pub fn ensure_complete(self) -> Result { + match self { + Outcome::Complete { .. } => Ok(()), + Outcome::Incomplete { error, .. } => Err(error), + Outcome::Error { error, .. } => Err(error), + } + } + pub fn ensure_execution(self) -> result::Result { + match self { + Outcome::Complete { used, .. } => Ok(used), + Outcome::Incomplete { used, .. } => Ok(used), + Outcome::Error { error, .. } => Err(error), + } + } + /// How much weight was used by the XCM execution attempt. + pub fn weight_used(&self) -> Weight { + match self { + Outcome::Complete { used, .. } => *used, + Outcome::Incomplete { used, .. } => *used, + Outcome::Error { .. } => Weight::zero(), + } + } +} + +impl From for Outcome { + fn from(error: Error) -> Self { + Self::Error { error } + } +} + +pub trait PreparedMessage { + fn weight_of(&self) -> Weight; +} + +/// Type of XCM message executor. +pub trait ExecuteXcm { + type Prepared: PreparedMessage; + fn prepare(message: Xcm) -> result::Result>; + fn execute( + origin: impl Into, + pre: Self::Prepared, + id: &mut XcmHash, + weight_credit: Weight, + ) -> Outcome; + fn prepare_and_execute( + origin: impl Into, + message: Xcm, + id: &mut XcmHash, + weight_limit: Weight, + weight_credit: Weight, + ) -> Outcome { + let pre = match Self::prepare(message) { + Ok(x) => x, + Err(_) => return Outcome::Error { error: Error::WeightNotComputable }, + }; + let xcm_weight = pre.weight_of(); + if xcm_weight.any_gt(weight_limit) { + return Outcome::Error { error: Error::WeightLimitReached(xcm_weight) } + } + Self::execute(origin, pre, id, weight_credit) + } + + /// Deduct some `fees` to the sovereign account of the given `location` and place them as per + /// the convention for fees. + fn charge_fees(location: impl Into, fees: Assets) -> Result; +} + +pub enum Weightless {} +impl PreparedMessage for Weightless { + fn weight_of(&self) -> Weight { + unreachable!() + } +} + +impl ExecuteXcm for () { + type Prepared = Weightless; + fn prepare(message: Xcm) -> result::Result> { + Err(message) + } + fn execute(_: impl Into, _: Self::Prepared, _: &mut XcmHash, _: Weight) -> Outcome { + unreachable!() + } + fn charge_fees(_location: impl Into, _fees: Assets) -> Result { + Err(Error::Unimplemented) + } +} + +pub trait Reanchorable: Sized { + /// Type to return in case of an error. + type Error: Debug; + + /// Mutate `self` so that it represents the same location from the point of view of `target`. + /// The context of `self` is provided as `context`. + /// + /// Does not modify `self` in case of overflow. + fn reanchor( + &mut self, + target: &Location, + context: &InteriorLocation, + ) -> core::result::Result<(), ()>; + + /// Consume `self` and return a new value representing the same location from the point of view + /// of `target`. The context of `self` is provided as `context`. + /// + /// Returns the original `self` in case of overflow. + fn reanchored( + self, + target: &Location, + context: &InteriorLocation, + ) -> core::result::Result; +} + +/// Result value when attempting to send an XCM message. +pub type SendResult = result::Result<(T, Assets), SendError>; + +/// Utility for sending an XCM message to a given location. +/// +/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each +/// router might return `NotApplicable` to pass the execution to the next sender item. Note that +/// each `NotApplicable` might alter the destination and the XCM message for to the next router. +/// +/// # Example +/// ```rust +/// # use parity_scale_codec::Encode; +/// # use staging_xcm::v4::{prelude::*, Weight}; +/// # use staging_xcm::VersionedXcm; +/// # use std::convert::Infallible; +/// +/// /// A sender that only passes the message through and does nothing. +/// struct Sender1; +/// impl SendXcm for Sender1 { +/// type Ticket = Infallible; +/// fn validate(_: &mut Option, _: &mut Option>) -> SendResult { +/// Err(SendError::NotApplicable) +/// } +/// fn deliver(_: Infallible) -> Result { +/// unreachable!() +/// } +/// } +/// +/// /// A sender that accepts a message that has two junctions, otherwise stops the routing. +/// struct Sender2; +/// impl SendXcm for Sender2 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)?.unpack() { +/// (0, [j1, j2]) => Ok(((), Assets::new())), +/// _ => Err(SendError::Unroutable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// /// A sender that accepts a message from a parent, passing through otherwise. +/// struct Sender3; +/// impl SendXcm for Sender3 { +/// type Ticket = (); +/// fn validate(destination: &mut Option, message: &mut Option>) -> SendResult<()> { +/// match destination.as_ref().ok_or(SendError::MissingArgument)?.unpack() { +/// (1, []) => Ok(((), Assets::new())), +/// _ => Err(SendError::NotApplicable), +/// } +/// } +/// fn deliver(_: ()) -> Result { +/// Ok([0; 32]) +/// } +/// } +/// +/// // A call to send via XCM. We don't really care about this. +/// # fn main() { +/// let call: Vec = ().encode(); +/// let message = Xcm(vec![Instruction::Transact { +/// origin_kind: OriginKind::Superuser, +/// require_weight_at_most: Weight::zero(), +/// call: call.into(), +/// }]); +/// let message_hash = message.using_encoded(sp_io::hashing::blake2_256); +/// +/// // Sender2 will block this. +/// assert!(send_xcm::<(Sender1, Sender2, Sender3)>(Parent.into(), message.clone()).is_err()); +/// +/// // Sender3 will catch this. +/// assert!(send_xcm::<(Sender1, Sender3)>(Parent.into(), message.clone()).is_ok()); +/// # } +/// ``` +pub trait SendXcm { + /// Intermediate value which connects the two phases of the send operation. + type Ticket; + + /// Check whether the given `_message` is deliverable to the given `_destination` and if so + /// determine the cost which will be paid by this chain to do so, returning a `Validated` token + /// which can be used to enact delivery. + /// + /// The `destination` and `message` must be `Some` (or else an error will be returned) and they + /// may only be consumed if the `Err` is not `NotApplicable`. + /// + /// If it is not a destination which can be reached with this type but possibly could by others, + /// then this *MUST* return `NotApplicable`. Any other error will cause the tuple + /// implementation to exit early without trying other type fields. + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult; + + /// Actually carry out the delivery operation for a previously validated message sending. + fn deliver(ticket: Self::Ticket) -> result::Result; +} + +#[impl_trait_for_tuples::impl_for_tuples(30)] +impl SendXcm for Tuple { + for_tuples! { type Ticket = (#( Option ),* ); } + + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + let mut maybe_cost: Option = None; + let one_ticket: Self::Ticket = (for_tuples! { #( + if maybe_cost.is_some() { + None + } else { + match Tuple::validate(destination, message) { + Err(SendError::NotApplicable) => None, + Err(e) => { return Err(e) }, + Ok((v, c)) => { + maybe_cost = Some(c); + Some(v) + }, + } + } + ),* }); + if let Some(cost) = maybe_cost { + Ok((one_ticket, cost)) + } else { + Err(SendError::NotApplicable) + } + } + + fn deliver(one_ticket: Self::Ticket) -> result::Result { + for_tuples!( #( + if let Some(validated) = one_ticket.Tuple { + return Tuple::deliver(validated); + } + )* ); + Err(SendError::Unroutable) + } +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +pub fn validate_send(dest: Location, msg: Xcm<()>) -> SendResult { + T::validate(&mut Some(dest), &mut Some(msg)) +} + +/// Convenience function for using a `SendXcm` implementation. Just interprets the `dest` and wraps +/// both in `Some` before passing them as as mutable references into `T::send_xcm`. +/// +/// Returns either `Ok` with the price of the delivery, or `Err` with the reason why the message +/// could not be sent. +/// +/// Generally you'll want to validate and get the price first to ensure that the sender can pay it +/// before actually doing the delivery. +pub fn send_xcm( + dest: Location, + msg: Xcm<()>, +) -> result::Result<(XcmHash, Assets), SendError> { + let (ticket, price) = T::validate(&mut Some(dest), &mut Some(msg))?; + let hash = T::deliver(ticket)?; + Ok((hash, price)) +} diff --git a/polkadot/xcm/xcm-builder/src/asset_conversion.rs b/polkadot/xcm/xcm-builder/src/asset_conversion.rs index 5b76ed764a8..e38af149be5 100644 --- a/polkadot/xcm/xcm-builder/src/asset_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/asset_conversion.rs @@ -23,39 +23,42 @@ use xcm::latest::prelude::*; use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles}; /// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be -/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `MultiLocation` value. -/// The `MultiLocation` value will typically be a `PalletInstance` junction. -pub struct AsPrefixedGeneralIndex( - PhantomData<(Prefix, AssetId, ConvertAssetId)>, +/// `TryFrom/TryInto`) into a `GeneralIndex` junction, prefixed by some `Location` value. +/// The `Location` value will typically be a `PalletInstance` junction. +pub struct AsPrefixedGeneralIndex( + PhantomData<(Prefix, AssetId, ConvertAssetId, L)>, ); impl< - Prefix: Get, + Prefix: Get, AssetId: Clone, ConvertAssetId: MaybeEquivalence, - > MaybeEquivalence - for AsPrefixedGeneralIndex + L: TryInto + TryFrom + Clone, + > MaybeEquivalence for AsPrefixedGeneralIndex { - fn convert(id: &MultiLocation) -> Option { + fn convert(id: &L) -> Option { let prefix = Prefix::get(); - if prefix.parent_count() != id.parent_count() || - prefix + let latest_prefix: Location = prefix.try_into().ok()?; + let latest_id: Location = (*id).clone().try_into().ok()?; + if latest_prefix.parent_count() != latest_id.parent_count() || + latest_prefix .interior() .iter() .enumerate() - .any(|(index, junction)| id.interior().at(index) != Some(junction)) + .any(|(index, junction)| latest_id.interior().at(index) != Some(junction)) { return None } - match id.interior().at(prefix.interior().len()) { - Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(id), + match latest_id.interior().at(latest_prefix.interior().len()) { + Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(&id), _ => None, } } - fn convert_back(what: &AssetId) -> Option { - let mut location = Prefix::get(); + fn convert_back(what: &AssetId) -> Option { + let location = Prefix::get(); + let mut latest_location: Location = location.try_into().ok()?; let id = ConvertAssetId::convert_back(what)?; - location.push_interior(Junction::GeneralIndex(id)).ok()?; - Some(location) + latest_location.push_interior(Junction::GeneralIndex(id)).ok()?; + latest_location.try_into().ok() } } @@ -65,14 +68,14 @@ pub struct ConvertedConcreteId( impl< AssetId: Clone, Balance: Clone, - ConvertAssetId: MaybeEquivalence, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, > MatchesFungibles for ConvertedConcreteId { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), MatchError> { let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Concrete(ref id)) => (amount, id), + (Fungible(ref amount), AssetId(ref id)) => (amount, id), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; @@ -84,14 +87,14 @@ impl< impl< ClassId: Clone, InstanceId: Clone, - ConvertClassId: MaybeEquivalence, + ConvertClassId: MaybeEquivalence, ConvertInstanceId: MaybeEquivalence, > MatchesNonFungibles for ConvertedConcreteId { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> { let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Concrete(ref class)) => (instance, class), + (NonFungible(ref instance), AssetId(ref class)) => (instance, class), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; @@ -101,68 +104,35 @@ impl< } } -pub struct ConvertedAbstractId( - PhantomData<(AssetId, Balance, ConvertAssetId, ConvertOther)>, -); -impl< - AssetId: Clone, - Balance: Clone, - ConvertAssetId: MaybeEquivalence<[u8; 32], AssetId>, - ConvertBalance: MaybeEquivalence, - > MatchesFungibles - for ConvertedAbstractId -{ - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { - let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Abstract(ref id)) => (amount, id), - _ => return Err(MatchError::AssetNotHandled), - }; - let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; - let amount = - ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?; - Ok((what, amount)) +#[deprecated = "Use `ConvertedConcreteId` instead"] +pub type ConvertedConcreteAssetId = ConvertedConcreteId; + +pub struct V4V3LocationConverter; +impl MaybeEquivalence for V4V3LocationConverter { + fn convert(old: &xcm::v4::Location) -> Option { + (*old).clone().try_into().ok() } -} -impl< - ClassId: Clone, - InstanceId: Clone, - ConvertClassId: MaybeEquivalence<[u8; 32], ClassId>, - ConvertInstanceId: MaybeEquivalence, - > MatchesNonFungibles - for ConvertedAbstractId -{ - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { - let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Abstract(ref class)) => (instance, class), - _ => return Err(MatchError::AssetNotHandled), - }; - let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?; - let instance = - ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?; - Ok((what, instance)) + + fn convert_back(new: &xcm::v3::Location) -> Option { + (*new).try_into().ok() } } -#[deprecated = "Use `ConvertedConcreteId` instead"] -pub type ConvertedConcreteAssetId = ConvertedConcreteId; -#[deprecated = "Use `ConvertedAbstractId` instead"] -pub type ConvertedAbstractAssetId = ConvertedAbstractId; - pub struct MatchedConvertedConcreteId( PhantomData<(AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertOther)>, ); impl< AssetId: Clone, Balance: Clone, - MatchAssetId: Contains, - ConvertAssetId: MaybeEquivalence, + MatchAssetId: Contains, + ConvertAssetId: MaybeEquivalence, ConvertBalance: MaybeEquivalence, > MatchesFungibles for MatchedConvertedConcreteId { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), MatchError> { let (amount, id) = match (&a.fun, &a.id) { - (Fungible(ref amount), Concrete(ref id)) if MatchAssetId::contains(id) => (amount, id), + (Fungible(ref amount), AssetId(ref id)) if MatchAssetId::contains(id) => (amount, id), _ => return Err(MatchError::AssetNotHandled), }; let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?; @@ -174,15 +144,15 @@ impl< impl< ClassId: Clone, InstanceId: Clone, - MatchClassId: Contains, - ConvertClassId: MaybeEquivalence, + MatchClassId: Contains, + ConvertClassId: MaybeEquivalence, ConvertInstanceId: MaybeEquivalence, > MatchesNonFungibles for MatchedConvertedConcreteId { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(ClassId, InstanceId), MatchError> { let (instance, class) = match (&a.fun, &a.id) { - (NonFungible(ref instance), Concrete(ref class)) if MatchClassId::contains(class) => + (NonFungible(ref instance), AssetId(ref class)) if MatchClassId::contains(class) => (instance, class), _ => return Err(MatchError::AssetNotHandled), }; @@ -200,10 +170,10 @@ mod tests { use xcm_executor::traits::JustTry; struct OnlyParentZero; - impl Contains for OnlyParentZero { - fn contains(a: &MultiLocation) -> bool { + impl Contains for OnlyParentZero { + fn contains(a: &Location) -> bool { match a { - MultiLocation { parents: 0, .. } => true, + Location { parents: 0, .. } => true, _ => false, } } @@ -214,7 +184,7 @@ mod tests { type AssetIdForTrustBackedAssets = u32; type Balance = u128; frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + pub TrustBackedAssetsPalletLocation: Location = PalletInstance(50).into(); } // ConvertedConcreteId cfg @@ -231,13 +201,13 @@ mod tests { >; assert_eq!( TrustBackedAssetsPalletLocation::get(), - MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + Location { parents: 0, interior: [PalletInstance(50)].into() } ); // err - does not match assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(1, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Err(MatchError::AssetNotHandled) @@ -245,10 +215,10 @@ mod tests { // err - matches, but convert fails assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new( + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new( 0, - X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + [PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }] )), fun: Fungible(12345), }), @@ -257,8 +227,8 @@ mod tests { // err - matches, but NonFungible assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Err(MatchError::AssetNotHandled) @@ -266,8 +236,8 @@ mod tests { // ok assert_eq!( - Converter::matches_fungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_fungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Ok((1, 12345)) @@ -279,7 +249,7 @@ mod tests { type ClassId = u32; type ClassInstanceId = u64; frame_support::parameter_types! { - pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into(); + pub TrustBackedAssetsPalletLocation: Location = PalletInstance(50).into(); } // ConvertedConcreteId cfg @@ -303,13 +273,13 @@ mod tests { >; assert_eq!( TrustBackedAssetsPalletLocation::get(), - MultiLocation { parents: 0, interior: X1(PalletInstance(50)) } + Location { parents: 0, interior: [PalletInstance(50)].into() } ); // err - does not match assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(1, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Err(MatchError::AssetNotHandled) @@ -317,10 +287,10 @@ mod tests { // err - matches, but convert fails assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new( + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new( 0, - X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }) + [PalletInstance(50), GeneralKey { length: 1, data: [1; 32] }] )), fun: NonFungible(Index(54321)), }), @@ -329,8 +299,8 @@ mod tests { // err - matches, but Fungible vs NonFungible assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: Fungible(12345), }), Err(MatchError::AssetNotHandled) @@ -338,8 +308,8 @@ mod tests { // ok assert_eq!( - Converter::matches_nonfungibles(&MultiAsset { - id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))), + Converter::matches_nonfungibles(&Asset { + id: AssetId(Location::new(0, [PalletInstance(50), GeneralIndex(1)])), fun: NonFungible(Index(54321)), }), Ok((1, 54321)) diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index c2b62751c68..80411ab5a22 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -34,7 +34,7 @@ use xcm_executor::traits::{CheckSuspension, OnResponse, Properties, ShouldExecut pub struct TakeWeightCredit; impl ShouldExecute for TakeWeightCredit { fn should_execute( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -60,9 +60,9 @@ const MAX_ASSETS_FOR_BUY_EXECUTION: usize = 2; /// 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. pub struct AllowTopLevelPaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { +impl> ShouldExecute for AllowTopLevelPaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, _properties: &mut Properties, @@ -158,14 +158,11 @@ impl> ShouldExecute for AllowTopLevelPaidExecutionFro pub struct WithComputedOrigin( PhantomData<(InnerBarrier, LocalUniversal, MaxPrefixes)>, ); -impl< - InnerBarrier: ShouldExecute, - LocalUniversal: Get, - MaxPrefixes: Get, - > ShouldExecute for WithComputedOrigin +impl, MaxPrefixes: Get> + ShouldExecute for WithComputedOrigin { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -175,7 +172,7 @@ impl< "WithComputedOrigin origin: {:?}, instructions: {:?}, max_weight: {:?}, properties: {:?}", origin, instructions, max_weight, properties, ); - let mut actual_origin = *origin; + let mut actual_origin = origin.clone(); let skipped = Cell::new(0usize); // NOTE: We do not check the validity of `UniversalOrigin` here, meaning that a malicious // origin could place a `UniversalOrigin` in order to spoof some location which gets free @@ -190,10 +187,11 @@ impl< // Note the origin is *relative to local consensus*! So we need to escape // local consensus with the `parents` before diving in into the // `universal_location`. - actual_origin = X1(*new_global).relative_to(&LocalUniversal::get()); + actual_origin = + Junctions::from([*new_global]).relative_to(&LocalUniversal::get()); }, DescendOrigin(j) => { - let Ok(_) = actual_origin.append_with(*j) else { + let Ok(_) = actual_origin.append_with(j.clone()) else { return Err(ProcessMessageError::Unsupported) }; }, @@ -221,7 +219,7 @@ impl< pub struct TrailingSetTopicAsId(PhantomData); impl ShouldExecute for TrailingSetTopicAsId { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -250,7 +248,7 @@ where SuspensionChecker: CheckSuspension, { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -268,9 +266,9 @@ where /// Use only for executions from completely trusted origins, from which no permissionless messages /// can be sent. pub struct AllowUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowUnpaidExecutionFrom { +impl> ShouldExecute for AllowUnpaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -290,9 +288,9 @@ impl> ShouldExecute for AllowUnpaidExecutionFrom { /// /// Use only for executions from trusted origin groups. pub struct AllowExplicitUnpaidExecutionFrom(PhantomData); -impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { +impl> ShouldExecute for AllowExplicitUnpaidExecutionFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, _properties: &mut Properties, @@ -314,11 +312,11 @@ impl> ShouldExecute for AllowExplicitUnpaidExecutionF /// Allows a message only if it is from a system-level child parachain. pub struct IsChildSystemParachain(PhantomData); -impl> Contains for IsChildSystemParachain { - fn contains(l: &MultiLocation) -> bool { +impl> Contains for IsChildSystemParachain { + fn contains(l: &Location) -> bool { matches!( - l.interior(), - Junctions::X1(Junction::Parachain(id)) + l.interior().as_slice(), + [Junction::Parachain(id)] if ParaId::from(*id).is_system() && l.parent_count() == 0, ) } @@ -328,7 +326,7 @@ impl> Contains for IsChildSystemPara pub struct AllowKnownQueryResponses(PhantomData); impl ShouldExecute for AllowKnownQueryResponses { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -354,9 +352,9 @@ impl ShouldExecute for AllowKnownQueryResponses(PhantomData); -impl> ShouldExecute for AllowSubscriptionsFrom { +impl> ShouldExecute for AllowSubscriptionsFrom { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -391,7 +389,7 @@ where Allow: ShouldExecute, { fn should_execute( - origin: &MultiLocation, + origin: &Location, message: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -405,7 +403,7 @@ where pub struct DenyReserveTransferToRelayChain; impl ShouldExecute for DenyReserveTransferToRelayChain { fn should_execute( - origin: &MultiLocation, + origin: &Location, message: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -414,22 +412,18 @@ impl ShouldExecute for DenyReserveTransferToRelayChain { |_| true, |inst| match inst { InitiateReserveWithdraw { - reserve: MultiLocation { parents: 1, interior: Here }, + reserve: Location { parents: 1, interior: Here }, .. } | - DepositReserveAsset { - dest: MultiLocation { parents: 1, interior: Here }, .. - } | - TransferReserveAsset { - dest: MultiLocation { parents: 1, interior: Here }, .. - } => { + DepositReserveAsset { dest: Location { parents: 1, interior: Here }, .. } | + TransferReserveAsset { dest: Location { parents: 1, interior: Here }, .. } => { Err(ProcessMessageError::Unsupported) // 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 }) => + if matches!(origin, Location { parents: 1, interior: Here }) => { log::warn!( target: "xcm::barrier", diff --git a/polkadot/xcm/xcm-builder/src/controller.rs b/polkadot/xcm/xcm-builder/src/controller.rs index 931d812eaaf..8ead18b5bd7 100644 --- a/polkadot/xcm/xcm-builder/src/controller.rs +++ b/polkadot/xcm/xcm-builder/src/controller.rs @@ -45,7 +45,7 @@ pub trait ExecuteControllerWeightInfo { /// Execute an XCM locally, for a given origin. /// /// An implementation of that trait will handle the low-level details of the execution, such as: -/// - Validating and Converting the origin to a MultiLocation. +/// - Validating and Converting the origin to a Location. /// - Handling versioning. /// - Calling the internal executor, which implements [`ExecuteXcm`]. pub trait ExecuteController { @@ -92,7 +92,7 @@ pub trait SendController { /// - `msg`: the XCM to be sent. fn send( origin: Origin, - dest: Box, + dest: Box, message: Box>, ) -> Result; } @@ -127,7 +127,7 @@ pub trait QueryController: QueryHandler { fn query( origin: Origin, timeout: Timeout, - match_querier: VersionedMultiLocation, + match_querier: VersionedLocation, ) -> Result; } @@ -138,7 +138,7 @@ impl ExecuteController for () { _message: Box>, _max_weight: Weight, ) -> Result { - Ok(Outcome::Error(XcmError::Unimplemented)) + Ok(Outcome::Error { error: XcmError::Unimplemented }) } } @@ -152,7 +152,7 @@ impl SendController for () { type WeightInfo = (); fn send( _origin: Origin, - _dest: Box, + _dest: Box, _message: Box>, ) -> Result { Ok(Default::default()) @@ -180,7 +180,7 @@ impl QueryController for () { fn query( _origin: Origin, _timeout: Timeout, - _match_querier: VersionedMultiLocation, + _match_querier: VersionedLocation, ) -> Result { Ok(Default::default()) } diff --git a/polkadot/xcm/xcm-builder/src/currency_adapter.rs b/polkadot/xcm/xcm-builder/src/currency_adapter.rs index 68ca0111174..fe26b7319bb 100644 --- a/polkadot/xcm/xcm-builder/src/currency_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/currency_adapter.rs @@ -22,17 +22,17 @@ use super::MintLocation; use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons}; use sp_runtime::traits::CheckedSub; use sp_std::{marker::PhantomData, result}; -use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result, XcmContext}; +use xcm::latest::{Asset, Error as XcmError, Location, Result, XcmContext}; use xcm_executor::{ traits::{ConvertLocation, MatchesFungible, TransactAsset}, - Assets, + AssetsInHolding, }; /// Asset transaction errors. enum Error { /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) AssetNotHandled, - /// `MultiLocation` to `AccountId` conversion failed. + /// `Location` to `AccountId` conversion failed. AccountIdConversionFailed, } @@ -62,7 +62,7 @@ impl From for XcmError { /// /// /// Our relay chain's location. /// parameter_types! { -/// pub RelayChain: MultiLocation = Parent.into(); +/// pub RelayChain: Location = Parent.into(); /// pub CheckingAccount: AccountId = PalletId(*b"checking").into_account_truncating(); /// } /// @@ -142,7 +142,7 @@ impl< > TransactAsset for CurrencyAdapter { - fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> Result { log::trace!(target: "xcm::currency_adapter", "can_check_in origin: {:?}, what: {:?}", _origin, what); // Check we handle this asset. let amount: Currency::Balance = @@ -156,7 +156,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!(target: "xcm::currency_adapter", "check_in origin: {:?}, what: {:?}", _origin, what); if let Some(amount) = Matcher::matches_fungible(what) { match CheckedAccount::get() { @@ -169,7 +169,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result { + fn can_check_out(_dest: &Location, what: &Asset, _context: &XcmContext) -> Result { log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; match CheckedAccount::get() { @@ -181,7 +181,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what); if let Some(amount) = Matcher::matches_fungible(what) { match CheckedAccount::get() { @@ -194,11 +194,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> Result { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> Result { log::trace!(target: "xcm::currency_adapter", "deposit_asset what: {:?}, who: {:?}", what, who); // Check we handle this asset. let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotHandled)?; @@ -209,10 +205,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!(target: "xcm::currency_adapter", "withdraw_asset what: {:?}, who: {:?}", what, who); // Check we handle this asset. let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?; @@ -224,11 +220,11 @@ impl< } fn internal_transfer_asset( - asset: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + asset: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to); let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotHandled)?; let from = diff --git a/polkadot/xcm/xcm-builder/src/fee_handling.rs b/polkadot/xcm/xcm-builder/src/fee_handling.rs index c158d5d862d..e114b3601c8 100644 --- a/polkadot/xcm/xcm-builder/src/fee_handling.rs +++ b/polkadot/xcm/xcm-builder/src/fee_handling.rs @@ -25,27 +25,22 @@ pub trait HandleFee { /// fees. /// /// Returns any part of the fee that wasn't consumed. - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) - -> MultiAssets; + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets; } // Default `HandleFee` implementation that just burns the fee. impl HandleFee for () { - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) -> MultiAssets { - MultiAssets::new() + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) -> Assets { + Assets::new() } } #[impl_trait_for_tuples::impl_for_tuples(1, 30)] impl HandleFee for Tuple { - fn handle_fee( - fee: MultiAssets, - context: Option<&XcmContext>, - reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) -> Assets { let mut unconsumed_fee = fee; for_tuples!( #( - unconsumed_fee = Tuple::handle_fee(unconsumed_fee, context, reason); + unconsumed_fee = Tuple::handle_fee(unconsumed_fee, context, reason.clone()); if unconsumed_fee.is_none() { return unconsumed_fee; } @@ -60,15 +55,15 @@ impl HandleFee for Tuple { pub struct XcmFeeManagerFromComponents( PhantomData<(WaivedLocations, HandleFee)>, ); -impl, FeeHandler: HandleFee> FeeManager +impl, FeeHandler: HandleFee> FeeManager for XcmFeeManagerFromComponents { - fn is_waived(origin: Option<&MultiLocation>, _: FeeReason) -> bool { + fn is_waived(origin: Option<&Location>, _: FeeReason) -> bool { let Some(loc) = origin else { return false }; WaivedLocations::contains(loc) } - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, reason: FeeReason) { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, reason: FeeReason) { FeeHandler::handle_fee(fee, context, reason); } } @@ -76,7 +71,7 @@ impl, FeeHandler: HandleFee> FeeManager /// Try to deposit the given fee in the specified account. /// Burns the fee in case of a failure. pub fn deposit_or_burn_fee>( - fee: MultiAssets, + fee: Assets, context: Option<&XcmContext>, receiver: AccountId, ) { @@ -109,13 +104,9 @@ impl< ReceiverAccount: Get, > HandleFee for XcmFeeToAccount { - fn handle_fee( - fee: MultiAssets, - context: Option<&XcmContext>, - _reason: FeeReason, - ) -> MultiAssets { + fn handle_fee(fee: Assets, context: Option<&XcmContext>, _reason: FeeReason) -> Assets { deposit_or_burn_fee::(fee, context, ReceiverAccount::get()); - MultiAssets::new() + Assets::new() } } diff --git a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs index df81f536f7b..d80c5d70dee 100644 --- a/polkadot/xcm/xcm-builder/src/filter_asset_location.rs +++ b/polkadot/xcm/xcm-builder/src/filter_asset_location.rs @@ -14,28 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Various implementations of `ContainsPair` or -//! `Contains<(MultiLocation, Vec)>`. +//! Various implementations of `ContainsPair` or +//! `Contains<(Location, Vec)>`. use frame_support::traits::{Contains, ContainsPair, Get}; use sp_std::{marker::PhantomData, vec::Vec}; -use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation, WildMultiAsset}; +use xcm::latest::{Asset, AssetFilter, AssetId, Location, WildAsset}; /// Accepts an asset iff it is a native asset. pub struct NativeAsset; -impl ContainsPair for NativeAsset { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for NativeAsset { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "NativeAsset asset: {:?}, origin: {:?}", asset, origin); - matches!(asset.id, Concrete(ref id) if id == origin) + matches!(asset.id, AssetId(ref id) if id == origin) } } /// Accepts an asset if it is contained in the given `T`'s `Get` implementation. pub struct Case(PhantomData); -impl> ContainsPair - for Case -{ - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> ContainsPair for Case { + fn contains(asset: &Asset, origin: &Location) -> bool { log::trace!(target: "xcm::contains", "Case asset: {:?}, origin: {:?}", asset, origin); let (a, o) = T::get(); a.matches(asset) && &o == origin @@ -44,18 +42,18 @@ impl> ContainsPair( - sp_std::marker::PhantomData<(Location, AssetFilters)>, +/// the `AssetFilter` instances provided by the `Get` implementation of `AssetFilters`. +pub struct LocationWithAssetFilters( + sp_std::marker::PhantomData<(LocationFilter, AssetFilters)>, ); -impl, AssetFilters: Get>> - Contains<(MultiLocation, Vec)> for LocationWithAssetFilters +impl, AssetFilters: Get>> + Contains<(Location, Vec)> for LocationWithAssetFilters { - fn contains((location, assets): &(MultiLocation, Vec)) -> bool { + fn contains((location, assets): &(Location, Vec)) -> bool { log::trace!(target: "xcm::contains", "LocationWithAssetFilters location: {:?}, assets: {:?}", location, assets); // `location` must match the `Location` filter. - if !Location::contains(location) { + if !LocationFilter::contains(location) { return false } @@ -72,12 +70,12 @@ impl, AssetFilters: Get> } } -/// Implementation of `Get>` which accepts every asset. +/// Implementation of `Get>` which accepts every asset. /// (For example, it can be used with `LocationWithAssetFilters`). pub struct AllAssets; -impl Get> for AllAssets { - fn get() -> Vec { - sp_std::vec![MultiAssetFilter::Wild(WildMultiAsset::All)] +impl Get> for AllAssets { + fn get() -> Vec { + sp_std::vec![AssetFilter::Wild(WildAsset::All)] } } @@ -90,24 +88,24 @@ mod tests { #[test] fn location_with_asset_filters_works() { frame_support::parameter_types! { - pub ParaA: MultiLocation = MultiLocation::new(1, X1(Parachain(1001))); - pub ParaB: MultiLocation = MultiLocation::new(1, X1(Parachain(1002))); - pub ParaC: MultiLocation = MultiLocation::new(1, X1(Parachain(1003))); + pub ParaA: Location = Location::new(1, [Parachain(1001)]); + pub ParaB: Location = Location::new(1, [Parachain(1002)]); + pub ParaC: Location = Location::new(1, [Parachain(1003)]); - pub AssetXLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(1111))); - pub AssetYLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(2222))); - pub AssetZLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(3333))); + pub AssetXLocation: Location = Location::new(1, [GeneralIndex(1111)]); + pub AssetYLocation: Location = Location::new(1, [GeneralIndex(2222)]); + pub AssetZLocation: Location = Location::new(1, [GeneralIndex(3333)]); - pub OnlyAssetXOrAssetY: sp_std::vec::Vec = sp_std::vec![ - Wild(AllOf { fun: WildFungible, id: Concrete(AssetXLocation::get()) }), - Wild(AllOf { fun: WildFungible, id: Concrete(AssetYLocation::get()) }), + pub OnlyAssetXOrAssetY: sp_std::vec::Vec = sp_std::vec![ + Wild(AllOf { fun: WildFungible, id: AssetId(AssetXLocation::get()) }), + Wild(AllOf { fun: WildFungible, id: AssetId(AssetYLocation::get()) }), ]; - pub OnlyAssetZ: sp_std::vec::Vec = sp_std::vec![ - Wild(AllOf { fun: WildFungible, id: Concrete(AssetZLocation::get()) }) + pub OnlyAssetZ: sp_std::vec::Vec = sp_std::vec![ + Wild(AllOf { fun: WildFungible, id: AssetId(AssetZLocation::get()) }) ]; } - let test_data: Vec<(MultiLocation, Vec, bool)> = vec![ + let test_data: Vec<(Location, Vec, bool)> = vec![ (ParaA::get(), vec![(AssetXLocation::get(), 1).into()], true), (ParaA::get(), vec![(AssetYLocation::get(), 1).into()], true), (ParaA::get(), vec![(AssetZLocation::get(), 1).into()], false), @@ -202,7 +200,7 @@ mod tests { for (location, assets, expected_result) in test_data { assert_eq!( - Filter::contains(&(location, assets.clone())), + Filter::contains(&(location.clone(), assets.clone())), expected_result, "expected_result: {expected_result} not matched for (location, assets): ({:?}, {:?})!", location, assets, ) diff --git a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs index 90608faa447..7bea8cdf957 100644 --- a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs @@ -25,7 +25,10 @@ use frame_support::traits::{ }; use sp_std::{marker::PhantomData, prelude::*, result}; use xcm::latest::prelude::*; -use xcm_executor::traits::{ConvertLocation, Error as MatchError, MatchesFungible, TransactAsset}; +use xcm_executor::{ + traits::{ConvertLocation, Error as MatchError, MatchesFungible, TransactAsset}, + AssetsInHolding, +}; /// [`TransactAsset`] implementation that allows the use of a [`fungible`] implementation for /// handling an asset in the XCM executor. @@ -41,11 +44,11 @@ impl< > TransactAsset for FungibleTransferAdapter { fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungible_adapter", "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", @@ -111,11 +114,7 @@ impl< > TransactAsset for FungibleMutateAdapter { - fn can_check_in( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -132,7 +131,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungible_adapter", "check_in origin: {:?}, what: {:?}", @@ -149,7 +148,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> XcmResult { + fn can_check_out(_dest: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "check_out dest: {:?}, what: {:?}", @@ -166,7 +165,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungible_adapter", "check_out dest: {:?}, what: {:?}", @@ -184,11 +183,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult { log::trace!( target: "xcm::fungible_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -203,10 +198,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungible_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -236,7 +231,7 @@ impl< > TransactAsset for FungibleAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -246,7 +241,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { FungibleMutateAdapter::< Fungible, Matcher, @@ -256,7 +251,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -266,7 +261,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { FungibleMutateAdapter::< Fungible, Matcher, @@ -276,11 +271,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { FungibleMutateAdapter::< Fungible, Matcher, @@ -291,10 +282,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { FungibleMutateAdapter::< Fungible, Matcher, @@ -305,11 +296,11 @@ impl< } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { FungibleTransferAdapter::::internal_transfer_asset( what, from, to, context ) diff --git a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs index 63ce608824e..4574d5ed4c6 100644 --- a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs @@ -38,11 +38,11 @@ impl< > TransactAsset for FungiblesTransferAdapter { fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, _context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungibles_adapter", "internal_transfer_asset what: {:?}, from: {:?}, to: {:?}", @@ -198,11 +198,7 @@ impl< CheckingAccount, > { - fn can_check_in( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -219,7 +215,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungibles_adapter", "check_in origin: {:?}, what: {:?}", @@ -236,11 +232,7 @@ impl< } } - fn can_check_out( - _origin: &MultiLocation, - what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_origin: &Location, what: &Asset, _context: &XcmContext) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "can_check_in origin: {:?}, what: {:?}", @@ -257,7 +249,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, _context: &XcmContext) { log::trace!( target: "xcm::fungibles_adapter", "check_out dest: {:?}, what: {:?}", @@ -274,11 +266,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult { log::trace!( target: "xcm::fungibles_adapter", "deposit_asset what: {:?}, who: {:?}", @@ -294,10 +282,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: "xcm::fungibles_adapter", "withdraw_asset what: {:?}, who: {:?}", @@ -331,7 +319,7 @@ impl< > TransactAsset for FungiblesAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -342,7 +330,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { FungiblesMutateAdapter::< Assets, Matcher, @@ -353,7 +341,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -364,7 +352,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { FungiblesMutateAdapter::< Assets, Matcher, @@ -375,11 +363,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { FungiblesMutateAdapter::< Assets, Matcher, @@ -391,10 +375,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { FungiblesMutateAdapter::< Assets, Matcher, @@ -406,11 +390,11 @@ impl< } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { FungiblesTransferAdapter::::internal_transfer_asset( what, from, to, context ) diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs index e7431ae0254..c00cd62e872 100644 --- a/polkadot/xcm/xcm-builder/src/lib.rs +++ b/polkadot/xcm/xcm-builder/src/lib.rs @@ -47,11 +47,11 @@ pub use origin_conversion::{ }; mod asset_conversion; +#[allow(deprecated)] +pub use asset_conversion::ConvertedConcreteAssetId; pub use asset_conversion::{ - AsPrefixedGeneralIndex, ConvertedAbstractId, ConvertedConcreteId, MatchedConvertedConcreteId, + AsPrefixedGeneralIndex, ConvertedConcreteId, MatchedConvertedConcreteId, V4V3LocationConverter, }; -#[allow(deprecated)] -pub use asset_conversion::{ConvertedAbstractAssetId, ConvertedConcreteAssetId}; mod barriers; pub use barriers::{ @@ -96,7 +96,7 @@ mod matches_location; pub use matches_location::{StartsWith, StartsWithExplicitGlobalConsensus}; mod matches_token; -pub use matches_token::{IsAbstract, IsConcrete}; +pub use matches_token::IsConcrete; mod matcher; pub use matcher::{CreateMatcher, MatchXcm, Matcher}; diff --git a/polkadot/xcm/xcm-builder/src/location_conversion.rs b/polkadot/xcm/xcm-builder/src/location_conversion.rs index 25d16f7eb8c..c9553030817 100644 --- a/polkadot/xcm/xcm-builder/src/location_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/location_conversion.rs @@ -27,12 +27,12 @@ use xcm_executor::traits::ConvertLocation; pub trait DescribeLocation { /// Create a description of the given `location` if possible. No two locations should have the /// same descriptor. - fn describe_location(location: &MultiLocation) -> Option>; + fn describe_location(location: &Location) -> Option>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl DescribeLocation for Tuple { - fn describe_location(l: &MultiLocation) -> Option> { + fn describe_location(l: &Location) -> Option> { for_tuples!( #( match Tuple::describe_location(l) { Some(result) => return Some(result), @@ -45,9 +45,9 @@ impl DescribeLocation for Tuple { pub struct DescribeTerminus; impl DescribeLocation for DescribeTerminus { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, Here) => Some(Vec::new()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, []) => Some(Vec::new()), _ => return None, } } @@ -55,10 +55,9 @@ impl DescribeLocation for DescribeTerminus { pub struct DescribePalletTerminal; impl DescribeLocation for DescribePalletTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(PalletInstance(i))) => - Some((b"Pallet", Compact::::from(*i as u32)).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [PalletInstance(i)]) => Some((b"Pallet", Compact::::from(*i as u32)).encode()), _ => return None, } } @@ -66,9 +65,9 @@ impl DescribeLocation for DescribePalletTerminal { pub struct DescribeAccountId32Terminal; impl DescribeLocation for DescribeAccountId32Terminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(AccountId32 { id, .. })) => Some((b"AccountId32", id).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [AccountId32 { id, .. }]) => Some((b"AccountId32", id).encode()), _ => return None, } } @@ -76,9 +75,9 @@ impl DescribeLocation for DescribeAccountId32Terminal { pub struct DescribeAccountKey20Terminal; impl DescribeLocation for DescribeAccountKey20Terminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(AccountKey20 { key, .. })) => Some((b"AccountKey20", key).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [AccountKey20 { key, .. }]) => Some((b"AccountKey20", key).encode()), _ => return None, } } @@ -89,9 +88,9 @@ impl DescribeLocation for DescribeAccountKey20Terminal { pub struct DescribeTreasuryVoiceTerminal; impl DescribeLocation for DescribeTreasuryVoiceTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice })) => + fn describe_location(location: &Location) -> Option> { + match location.unpack() { + (0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => Some((b"Treasury", b"Voice").encode()), _ => None, } @@ -102,9 +101,9 @@ pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccou pub struct DescribeBodyTerminal; impl DescribeLocation for DescribeBodyTerminal { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, &l.interior) { - (0, X1(Plurality { id, part })) => Some((b"Body", id, part).encode()), + fn describe_location(l: &Location) -> Option> { + match l.unpack() { + (0, [Plurality { id, part }]) => Some((b"Body", id, part).encode()), _ => return None, } } @@ -121,20 +120,21 @@ pub type DescribeAllTerminal = ( pub struct DescribeFamily(PhantomData); impl DescribeLocation for DescribeFamily { - fn describe_location(l: &MultiLocation) -> Option> { - match (l.parents, l.interior.first()) { + fn describe_location(l: &Location) -> Option> { + match (l.parent_count(), l.first_interior()) { (0, Some(Parachain(index))) => { - let tail = l.interior.split_first().0; + let tail = l.clone().split_first_interior().0; let interior = Suffix::describe_location(&tail.into())?; Some((b"ChildChain", Compact::::from(*index), interior).encode()) }, (1, Some(Parachain(index))) => { - let tail = l.interior.split_first().0; - let interior = Suffix::describe_location(&tail.into())?; + let tail_junctions = l.interior().clone().split_first().0; + let tail = Location::new(0, tail_junctions); + let interior = Suffix::describe_location(&tail)?; Some((b"SiblingChain", Compact::::from(*index), interior).encode()) }, (1, _) => { - let tail = l.interior.into(); + let tail = l.interior().clone().into(); let interior = Suffix::describe_location(&tail)?; Some((b"ParentChain", interior).encode()) }, @@ -147,7 +147,7 @@ pub struct HashedDescription(PhantomData<(AccountId, Descri impl + Clone, Describe: DescribeLocation> ConvertLocation for HashedDescription { - fn convert_location(value: &MultiLocation) -> Option { + fn convert_location(value: &Location) -> Option { Some(blake2_256(&Describe::describe_location(value)?).into()) } } @@ -156,34 +156,26 @@ impl + Clone, Describe: DescribeLocation> ConvertLocat /// are recommended to use the more extensible `HashedDescription` type. pub struct LegacyDescribeForeignChainAccount; impl DescribeLocation for LegacyDescribeForeignChainAccount { - fn describe_location(location: &MultiLocation) -> Option> { - Some(match location { + fn describe_location(location: &Location) -> Option> { + Some(match location.unpack() { // Used on the relay chain for sending paras that use 32 byte accounts - MultiLocation { - parents: 0, - interior: X2(Parachain(para_id), AccountId32 { id, .. }), - } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), + (0, [Parachain(para_id), AccountId32 { id, .. }]) => + LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0), // Used on the relay chain for sending paras that use 20 byte accounts - MultiLocation { - parents: 0, - interior: X2(Parachain(para_id), AccountKey20 { key, .. }), - } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), + (0, [Parachain(para_id), AccountKey20 { key, .. }]) => + LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0), // Used on para-chain for sending paras that use 32 byte accounts - MultiLocation { - parents: 1, - interior: X2(Parachain(para_id), AccountId32 { id, .. }), - } => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), + (1, [Parachain(para_id), AccountId32 { id, .. }]) => + LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1), // Used on para-chain for sending paras that use 20 byte accounts - MultiLocation { - parents: 1, - interior: X2(Parachain(para_id), AccountKey20 { key, .. }), - } => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), + (1, [Parachain(para_id), AccountKey20 { key, .. }]) => + LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1), // Used on para-chain for sending from the relay chain - MultiLocation { parents: 1, interior: X1(AccountId32 { id, .. }) } => + (1, [AccountId32 { id, .. }]) => LegacyDescribeForeignChainAccount::from_relay_32(id, 1), // No other conversions provided @@ -278,16 +270,16 @@ pub struct Account32Hash(PhantomData<(Network, AccountId)>); impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for Account32Hash { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { Some(("multiloc", location).using_encoded(blake2_256).into()) } } -/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the +/// A [`Location`] consisting of a single `Parent` [`Junction`] will be converted to the /// parent `AccountId`. pub struct ParentIsPreset(PhantomData); impl ConvertLocation for ParentIsPreset { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { if location.contains_parents_only(1) { Some( b"Parent" @@ -304,10 +296,9 @@ pub struct ChildParachainConvertsVia(PhantomData<(ParaId, Acc impl + Into + AccountIdConversion, AccountId: Clone> ConvertLocation for ChildParachainConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { parents: 0, interior: X1(Parachain(id)) } => - Some(ParaId::from(*id).into_account_truncating()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (0, [Parachain(id)]) => Some(ParaId::from(*id).into_account_truncating()), _ => None, } } @@ -317,10 +308,9 @@ pub struct SiblingParachainConvertsVia(PhantomData<(ParaId, A impl + Into + AccountIdConversion, AccountId: Clone> ConvertLocation for SiblingParachainConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => - Some(ParaId::from(*id).into_account_truncating()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (1, [Parachain(id)]) => Some(ParaId::from(*id).into_account_truncating()), _ => None, } } @@ -331,15 +321,13 @@ pub struct AccountId32Aliases(PhantomData<(Network, AccountI impl>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for AccountId32Aliases { - fn convert_location(location: &MultiLocation) -> Option { - let id = match *location { - MultiLocation { parents: 0, interior: X1(AccountId32 { id, network: None }) } => id, - MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) } - if network == Network::get() => - id, + fn convert_location(location: &Location) -> Option { + let id = match location.unpack() { + (0, [AccountId32 { id, network: None }]) => id, + (0, [AccountId32 { id, network }]) if *network == Network::get() => id, _ => return None, }; - Some(id.into()) + Some((*id).into()) } } @@ -351,25 +339,23 @@ pub struct LocalTreasuryVoiceConvertsVia( impl, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone> ConvertLocation for LocalTreasuryVoiceConvertsVia { - fn convert_location(location: &MultiLocation) -> Option { - match *location { - MultiLocation { - parents: 0, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - } => Some((TreasuryAccount::get().into() as [u8; 32]).into()), + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => + Some((TreasuryAccount::get().into() as [u8; 32]).into()), _ => None, } } } /// Conversion implementation which converts from a `[u8; 32]`-based `AccountId` into a -/// `MultiLocation` consisting solely of a `AccountId32` junction with a fixed value for its +/// `Location` consisting solely of a `AccountId32` junction with a fixed value for its /// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`. pub struct AliasesIntoAccountId32(PhantomData<(Network, AccountId)>); impl<'a, Network: Get>, AccountId: Clone + Into<[u8; 32]> + Clone> - TryConvert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32 + TryConvert<&'a AccountId, Location> for AliasesIntoAccountId32 { - fn try_convert(who: &AccountId) -> Result { + fn try_convert(who: &AccountId) -> Result { Ok(AccountId32 { network: Network::get(), id: who.clone().into() }.into()) } } @@ -378,15 +364,13 @@ pub struct AccountKey20Aliases(PhantomData<(Network, Account impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> ConvertLocation for AccountKey20Aliases { - fn convert_location(location: &MultiLocation) -> Option { - let key = match *location { - MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: None }) } => key, - MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) } - if network == Network::get() => - key, + fn convert_location(location: &Location) -> Option { + let key = match location.unpack() { + (0, [AccountKey20 { key, network: None }]) => key, + (0, [AccountKey20 { key, network }]) if *network == Network::get() => key, _ => return None, }; - Some(key.into()) + Some((*key).into()) } } @@ -402,10 +386,10 @@ impl>, AccountId: From<[u8; 20]> + Into<[u8; 20]> pub struct GlobalConsensusConvertsFor( PhantomData<(UniversalLocation, AccountId)>, ); -impl, AccountId: From<[u8; 32]> + Clone> +impl, AccountId: From<[u8; 32]> + Clone> ConvertLocation for GlobalConsensusConvertsFor { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::location_conversion", @@ -413,7 +397,7 @@ impl, AccountId: From<[u8; 32]> + universal_source, location, ); let (remote_network, remote_location) = - ensure_is_remote(universal_source, *location).ok()?; + ensure_is_remote(universal_source, location.clone()).ok()?; match remote_location { Here => Some(AccountId::from(Self::from_params(&remote_network))), @@ -445,21 +429,21 @@ impl GlobalConsensusConvertsFor( PhantomData<(UniversalLocation, AccountId)>, ); -impl, AccountId: From<[u8; 32]> + Clone> +impl, AccountId: From<[u8; 32]> + Clone> ConvertLocation for GlobalConsensusParachainConvertsFor { - fn convert_location(location: &MultiLocation) -> Option { + fn convert_location(location: &Location) -> Option { let universal_source = UniversalLocation::get(); log::trace!( target: "xcm::location_conversion", "GlobalConsensusParachainConvertsFor universal_source: {:?}, location: {:?}", universal_source, location, ); - let devolved = ensure_is_remote(universal_source, *location).ok()?; + let devolved = ensure_is_remote(universal_source, location.clone()).ok()?; let (remote_network, remote_location) = devolved; - match remote_location { - X1(Parachain(remote_network_para_id)) => + match remote_location.as_slice() { + [Parachain(remote_network_para_id)] => Some(AccountId::from(Self::from_params(&remote_network, &remote_network_para_id))), _ => None, } @@ -509,12 +493,12 @@ mod tests { #[test] fn inverter_works_in_tree() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X3(Parachain(1), account20(), account20()); + pub UniversalLocation: InteriorLocation = [Parachain(1), account20(), account20()].into(); } - let input = MultiLocation::new(3, X2(Parachain(2), account32())); + let input = Location::new(3, [Parachain(2), account32()]); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); - assert_eq!(inverted, MultiLocation::new(2, X3(Parachain(1), account20(), account20()))); + assert_eq!(inverted, Location::new(2, [Parachain(1), account20(), account20()])); } // Network Topology @@ -524,12 +508,12 @@ mod tests { #[test] fn inverter_uses_context_as_inverted_location() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(account20(), account20()); + pub UniversalLocation: InteriorLocation = [account20(), account20()].into(); } - let input = MultiLocation::grandparent(); + let input = Location::new(2, Here); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); - assert_eq!(inverted, X2(account20(), account20()).into()); + assert_eq!(inverted, [account20(), account20()].into()); } // Network Topology @@ -539,10 +523,10 @@ mod tests { #[test] fn inverter_uses_only_child_on_missing_context() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = PalletInstance(5).into(); + pub UniversalLocation: InteriorLocation = PalletInstance(5).into(); } - let input = MultiLocation::grandparent(); + let input = Location::new(2, Here); let inverted = UniversalLocation::get().invert_target(&input).unwrap(); assert_eq!(inverted, (OnlyChild, PalletInstance(5)).into()); } @@ -550,10 +534,10 @@ mod tests { #[test] fn inverter_errors_when_location_is_too_large() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; } - let input = MultiLocation { parents: 99, interior: X1(Parachain(88)) }; + let input = Location { parents: 99, interior: [Parachain(88)].into() }; let inverted = UniversalLocation::get().invert_target(&input); assert_eq!(inverted, Err(())); } @@ -561,8 +545,8 @@ mod tests { #[test] fn global_consensus_converts_for_works() { parameter_types! { - pub UniversalLocationInNetwork1: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)); - pub UniversalLocationInNetwork2: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)); + pub UniversalLocationInNetwork1: InteriorLocation = [GlobalConsensus(ByGenesis([1; 32])), Parachain(1234)].into(); + pub UniversalLocationInNetwork2: InteriorLocation = [GlobalConsensus(ByGenesis([2; 32])), Parachain(1234)].into(); } let network_1 = UniversalLocationInNetwork1::get().global_consensus().expect("NetworkId"); let network_2 = UniversalLocationInNetwork2::get().global_consensus().expect("NetworkId"); @@ -571,17 +555,17 @@ mod tests { let network_5 = ByGenesis([5; 32]); let test_data = vec![ - (MultiLocation::parent(), false), - (MultiLocation::new(0, Here), false), - (MultiLocation::new(0, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(1, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(2, X1(GlobalConsensus(network_1))), false), - (MultiLocation::new(0, X1(GlobalConsensus(network_2))), false), - (MultiLocation::new(1, X1(GlobalConsensus(network_2))), false), - (MultiLocation::new(2, X1(GlobalConsensus(network_2))), true), - (MultiLocation::new(0, X2(GlobalConsensus(network_2), Parachain(1000))), false), - (MultiLocation::new(1, X2(GlobalConsensus(network_2), Parachain(1000))), false), - (MultiLocation::new(2, X2(GlobalConsensus(network_2), Parachain(1000))), false), + (Location::parent(), false), + (Location::new(0, Here), false), + (Location::new(0, [GlobalConsensus(network_1)]), false), + (Location::new(1, [GlobalConsensus(network_1)]), false), + (Location::new(2, [GlobalConsensus(network_1)]), false), + (Location::new(0, [GlobalConsensus(network_2)]), false), + (Location::new(1, [GlobalConsensus(network_2)]), false), + (Location::new(2, [GlobalConsensus(network_2)]), true), + (Location::new(0, [GlobalConsensus(network_2), Parachain(1000)]), false), + (Location::new(1, [GlobalConsensus(network_2), Parachain(1000)]), false), + (Location::new(2, [GlobalConsensus(network_2), Parachain(1000)]), false), ]; for (location, expected_result) in test_data { @@ -596,14 +580,14 @@ mod tests { "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ); - match &location { - MultiLocation { interior: X1(GlobalConsensus(network)), .. } => + match location.unpack() { + (_, [GlobalConsensus(network)]) => assert_eq!( account, GlobalConsensusConvertsFor::::from_params(network), "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ), - _ => panic!("expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location) + _ => panic!("expected_result: {}, conversion passed: {:?}, but Location does not match expected pattern, location: {:?}", expected_result, account, location) } }, None => { @@ -619,32 +603,32 @@ mod tests { // all success let res_1_gc_network_3 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + &Location::new(2, [GlobalConsensus(network_3)]), ) .expect("conversion is ok"); let res_2_gc_network_3 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_3))), + &Location::new(2, [GlobalConsensus(network_3)]), ) .expect("conversion is ok"); let res_1_gc_network_4 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + &Location::new(2, [GlobalConsensus(network_4)]), ) .expect("conversion is ok"); let res_2_gc_network_4 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_4))), + &Location::new(2, [GlobalConsensus(network_4)]), ) .expect("conversion is ok"); let res_1_gc_network_5 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + &Location::new(2, [GlobalConsensus(network_5)]), ) .expect("conversion is ok"); let res_2_gc_network_5 = GlobalConsensusConvertsFor::::convert_location( - &MultiLocation::new(2, X1(GlobalConsensus(network_5))), + &Location::new(2, [GlobalConsensus(network_5)]), ) .expect("conversion is ok"); @@ -660,42 +644,30 @@ mod tests { #[test] fn global_consensus_parachain_converts_for_works() { parameter_types! { - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(ByGenesis([9; 32])), Parachain(1234)].into(); } let test_data = vec![ - (MultiLocation::parent(), false), - (MultiLocation::new(0, X1(Parachain(1000))), false), - (MultiLocation::new(1, X1(Parachain(1000))), false), + (Location::parent(), false), + (Location::new(0, [Parachain(1000)]), false), + (Location::new(1, [Parachain(1000)]), false), ( - MultiLocation::new( + Location::new( 2, - X3( + [ GlobalConsensus(ByGenesis([0; 32])), Parachain(1000), AccountId32 { network: None, id: [1; 32].into() }, - ), + ], ), false, ), - (MultiLocation::new(2, X1(GlobalConsensus(ByGenesis([0; 32])))), false), - ( - MultiLocation::new(0, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - ( - MultiLocation::new(1, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - (MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), true), - ( - MultiLocation::new(3, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), - ( - MultiLocation::new(9, X2(GlobalConsensus(ByGenesis([0; 32])), Parachain(1000))), - false, - ), + (Location::new(2, [GlobalConsensus(ByGenesis([0; 32]))]), false), + (Location::new(0, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(1, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(2, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), true), + (Location::new(3, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), + (Location::new(9, [GlobalConsensus(ByGenesis([0; 32])), Parachain(1000)]), false), ]; for (location, expected_result) in test_data { @@ -710,8 +682,8 @@ mod tests { "expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location ); - match &location { - MultiLocation { interior: X2(GlobalConsensus(network), Parachain(para_id)), .. } => + match location.unpack() { + (_, [GlobalConsensus(network), Parachain(para_id)]) => assert_eq!( account, GlobalConsensusParachainConvertsFor::::from_params(network, para_id), @@ -720,7 +692,7 @@ mod tests { _ => assert_eq!( true, expected_result, - "expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location + "expected_result: {}, conversion passed: {:?}, but Location does not match expected pattern, location: {:?}", expected_result, account, location ) } }, @@ -737,22 +709,22 @@ mod tests { // all success let res_gc_a_p1000 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1000))), + &Location::new(2, [GlobalConsensus(ByGenesis([3; 32])), Parachain(1000)]), ) .expect("conversion is ok"); let res_gc_a_p1001 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1001))), + &Location::new(2, [GlobalConsensus(ByGenesis([3; 32])), Parachain(1001)]), ) .expect("conversion is ok"); let res_gc_b_p1000 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1000))), + &Location::new(2, [GlobalConsensus(ByGenesis([4; 32])), Parachain(1000)]), ) .expect("conversion is ok"); let res_gc_b_p1001 = GlobalConsensusParachainConvertsFor::::convert_location( - &MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1001))), + &Location::new(2, [GlobalConsensus(ByGenesis([4; 32])), Parachain(1001)]), ) .expect("conversion is ok"); assert_ne!(res_gc_a_p1000, res_gc_a_p1001); @@ -765,9 +737,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_para_32() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(1), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -779,19 +751,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2( + interior: [ Parachain(1), AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(2), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -808,9 +781,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_para_20() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -822,19 +795,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2( + interior: [ Parachain(1), AccountKey20 { network: Some(NetworkId::Polkadot), key: [0u8; 20] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -851,9 +825,9 @@ mod tests { #[test] fn remote_account_convert_on_para_sending_relay() { - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: None, id: [0u8; 32] }), + interior: [AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -865,16 +839,16 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }), + interior: [AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }].into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 1, - interior: X1(AccountId32 { network: None, id: [1u8; 32] }), + interior: [AccountId32 { network: None, id: [1u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -891,9 +865,9 @@ mod tests { #[test] fn remote_account_convert_on_relay_sending_para_20() { - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -905,9 +879,9 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }), + interior: [Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -924,9 +898,9 @@ mod tests { #[test] fn remote_account_convert_on_relay_sending_para_32() { - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(1), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -938,19 +912,20 @@ mod tests { rem_1 ); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2( + interior: [ Parachain(1), AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }, - ), + ] + .into(), }; assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1); - let mul = MultiLocation { + let mul = Location { parents: 0, - interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }), + interior: [Parachain(2), AccountId32 { network: None, id: [0u8; 32] }].into(), }; let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(); @@ -966,20 +941,18 @@ mod tests { } #[test] - fn remote_account_fails_with_bad_multilocation() { - let mul = MultiLocation { + fn remote_account_fails_with_bad_location() { + let mul = Location { parents: 1, - interior: X1(AccountKey20 { network: None, key: [0u8; 20] }), + interior: [AccountKey20 { network: None, key: [0u8; 20] }].into(), }; assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none()); } #[test] fn remote_account_convert_on_para_sending_from_remote_para_treasury() { - let relay_treasury_to_para_location = MultiLocation { - parents: 1, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - }; + let relay_treasury_to_para_location = + Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]); let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location( &relay_treasury_to_para_location, ) @@ -993,13 +966,10 @@ mod tests { actual_description ); - let para_to_para_treasury_location = MultiLocation { - parents: 1, - interior: X2( - Parachain(1001), - Plurality { id: BodyId::Treasury, part: BodyPart::Voice }, - ), - }; + let para_to_para_treasury_location = Location::new( + 1, + [Parachain(1001), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }], + ); let actual_description = ForeignChainAliasTreasuryAccount::<[u8; 32]>::convert_location( ¶_to_para_treasury_location, ) @@ -1016,10 +986,8 @@ mod tests { #[test] fn local_account_convert_on_para_from_relay_treasury() { - let location = MultiLocation { - parents: 0, - interior: X1(Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - }; + let location = + Location::new(0, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]); parameter_types! { pub TreasuryAccountId: AccountId = AccountId::new([42u8; 32]); diff --git a/polkadot/xcm/xcm-builder/src/matcher.rs b/polkadot/xcm/xcm-builder/src/matcher.rs index 9da135dae31..eae43b290fb 100644 --- a/polkadot/xcm/xcm-builder/src/matcher.rs +++ b/polkadot/xcm/xcm-builder/src/matcher.rs @@ -18,7 +18,7 @@ use core::ops::ControlFlow; use frame_support::traits::ProcessMessageError; -use xcm::latest::{Instruction, MultiLocation}; +use xcm::latest::{Instruction, Location}; /// Creates an instruction matcher from an XCM. Since XCM versions differ, we need to make a trait /// here to unify the interfaces among them. @@ -67,7 +67,7 @@ impl<'a, Call> CreateMatcher for &'a mut [Instruction] { pub trait MatchXcm { /// The concrete instruction type. Necessary to specify as it changes between XCM versions. type Inst; - /// The `MultiLocation` type. Necessary to specify as it changes between XCM versions. + /// The `Location` type. Necessary to specify as it changes between XCM versions. type Loc; /// The error type to throw when errors happen during matching. type Error; @@ -125,7 +125,7 @@ pub struct Matcher<'a, Call> { impl<'a, Call> MatchXcm for Matcher<'a, Call> { type Error = ProcessMessageError; type Inst = Instruction; - type Loc = MultiLocation; + type Loc = Location; fn assert_remaining_insts(self, n: usize) -> Result where diff --git a/polkadot/xcm/xcm-builder/src/matches_location.rs b/polkadot/xcm/xcm-builder/src/matches_location.rs index cfc71eafd02..a96df9e92de 100644 --- a/polkadot/xcm/xcm-builder/src/matches_location.rs +++ b/polkadot/xcm/xcm-builder/src/matches_location.rs @@ -14,37 +14,47 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Various implementations and utilities for matching and filtering `MultiLocation` and -//! `InteriorMultiLocation` types. +//! Various implementations and utilities for matching and filtering `Location` and +//! `InteriorLocation` types. use frame_support::traits::{Contains, Get}; -use xcm::latest::{InteriorMultiLocation, MultiLocation, NetworkId}; +use xcm::latest::{InteriorLocation, Location, NetworkId}; -/// An implementation of `Contains` that checks for `MultiLocation` or -/// `InteriorMultiLocation` if starts with the provided type `T`. -pub struct StartsWith(sp_std::marker::PhantomData); -impl> Contains for StartsWith { - fn contains(t: &MultiLocation) -> bool { - t.starts_with(&T::get()) +/// An implementation of `Contains` that checks for `Location` or +/// `InteriorLocation` if starts with the provided type `T`. +pub struct StartsWith(sp_std::marker::PhantomData<(T, L)>); +impl, L: TryInto + Clone> Contains for StartsWith { + fn contains(location: &L) -> bool { + let latest_location: Location = if let Ok(location) = (*location).clone().try_into() { + location + } else { + return false; + }; + let latest_t = if let Ok(location) = T::get().try_into() { + location + } else { + return false; + }; + latest_location.starts_with(&latest_t) } } -impl> Contains for StartsWith { - fn contains(t: &InteriorMultiLocation) -> bool { +impl> Contains for StartsWith { + fn contains(t: &InteriorLocation) -> bool { t.starts_with(&T::get()) } } -/// An implementation of `Contains` that checks for `MultiLocation` or -/// `InteriorMultiLocation` if starts with expected `GlobalConsensus(NetworkId)` provided as type +/// An implementation of `Contains` that checks for `Location` or +/// `InteriorLocation` if starts with expected `GlobalConsensus(NetworkId)` provided as type /// `T`. pub struct StartsWithExplicitGlobalConsensus(sp_std::marker::PhantomData); -impl> Contains for StartsWithExplicitGlobalConsensus { - fn contains(location: &MultiLocation) -> bool { - matches!(location.interior.global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) +impl> Contains for StartsWithExplicitGlobalConsensus { + fn contains(location: &Location) -> bool { + matches!(location.interior().global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) } } -impl> Contains for StartsWithExplicitGlobalConsensus { - fn contains(location: &InteriorMultiLocation) -> bool { +impl> Contains for StartsWithExplicitGlobalConsensus { + fn contains(location: &InteriorLocation) -> bool { matches!(location.global_consensus(), Ok(requested_network) if requested_network.eq(&T::get())) } } diff --git a/polkadot/xcm/xcm-builder/src/matches_token.rs b/polkadot/xcm/xcm-builder/src/matches_token.rs index b6a320d8931..e49fd18f88d 100644 --- a/polkadot/xcm/xcm-builder/src/matches_token.rs +++ b/polkadot/xcm/xcm-builder/src/matches_token.rs @@ -19,25 +19,24 @@ use frame_support::traits::Get; use sp_std::marker::PhantomData; use xcm::latest::{ - AssetId::{Abstract, Concrete}, - AssetInstance, + Asset, AssetId, AssetInstance, Fungibility::{Fungible, NonFungible}, - MultiAsset, MultiLocation, + Location, }; use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; -/// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that +/// Converts a `Asset` into balance `B` if its id is equal to that /// given by `T`'s `Get`. /// /// # Example /// /// ``` -/// use xcm::latest::{MultiLocation, Parent}; +/// use xcm::latest::{Location, Parent}; /// use staging_xcm_builder::IsConcrete; /// use xcm_executor::traits::MatchesFungible; /// /// frame_support::parameter_types! { -/// pub TargetLocation: MultiLocation = Parent.into(); +/// pub TargetLocation: Location = Parent.into(); /// } /// /// # fn main() { @@ -47,62 +46,18 @@ use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; /// # } /// ``` pub struct IsConcrete(PhantomData); -impl, B: TryFrom> MatchesFungible for IsConcrete { - fn matches_fungible(a: &MultiAsset) -> Option { +impl, B: TryFrom> MatchesFungible for IsConcrete { + fn matches_fungible(a: &Asset) -> Option { match (&a.id, &a.fun) { - (Concrete(ref id), Fungible(ref amount)) if id == &T::get() => - (*amount).try_into().ok(), + (AssetId(ref id), Fungible(ref amount)) if id == &T::get() => (*amount).try_into().ok(), _ => None, } } } -impl, I: TryFrom> MatchesNonFungible for IsConcrete { - fn matches_nonfungible(a: &MultiAsset) -> Option { +impl, I: TryFrom> MatchesNonFungible for IsConcrete { + fn matches_nonfungible(a: &Asset) -> Option { match (&a.id, &a.fun) { - (Concrete(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), - _ => None, - } - } -} - -/// Same as [`IsConcrete`] but for a fungible with abstract location. -/// -/// # Example -/// -/// ``` -/// use xcm::latest::prelude::*; -/// use staging_xcm_builder::IsAbstract; -/// use xcm_executor::traits::{MatchesFungible, MatchesNonFungible}; -/// -/// frame_support::parameter_types! { -/// pub TargetLocation: [u8; 32] = [7u8; 32]; -/// } -/// -/// # fn main() { -/// let asset = ([7u8; 32], 999u128).into(); -/// // match `asset` if it is an abstract asset in `TargetLocation`. -/// assert_eq!( as MatchesFungible>::matches_fungible(&asset), Some(999)); -/// let nft = ([7u8; 32], [42u8; 4]).into(); -/// assert_eq!( -/// as MatchesNonFungible<[u8; 4]>>::matches_nonfungible(&nft), -/// Some([42u8; 4]) -/// ); -/// # } -/// ``` -pub struct IsAbstract(PhantomData); -impl, B: TryFrom> MatchesFungible for IsAbstract { - fn matches_fungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Abstract(ref id), Fungible(ref amount)) if id == &T::get() => - (*amount).try_into().ok(), - _ => None, - } - } -} -impl, B: TryFrom> MatchesNonFungible for IsAbstract { - fn matches_nonfungible(a: &MultiAsset) -> Option { - match (&a.id, &a.fun) { - (Abstract(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), + (AssetId(id), NonFungible(instance)) if id == &T::get() => (*instance).try_into().ok(), _ => None, } } diff --git a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs index 357dc534a5f..b4801d3a23a 100644 --- a/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs +++ b/polkadot/xcm/xcm-builder/src/nonfungibles_adapter.rs @@ -40,11 +40,11 @@ impl< > TransactAsset for NonFungiblesTransferAdapter { fn transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { log::trace!( target: LOG_TARGET, "transfer_asset what: {:?}, from: {:?}, to: {:?}, context: {:?}", @@ -131,7 +131,7 @@ impl< CheckingAccount, > { - fn can_check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(_origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { log::trace!( target: LOG_TARGET, "can_check_in origin: {:?}, what: {:?}, context: {:?}", @@ -150,7 +150,7 @@ impl< } } - fn check_in(_origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(_origin: &Location, what: &Asset, context: &XcmContext) { log::trace!( target: LOG_TARGET, "check_in origin: {:?}, what: {:?}, context: {:?}", @@ -169,7 +169,7 @@ impl< } } - fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(_dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { log::trace!( target: LOG_TARGET, "can_check_out dest: {:?}, what: {:?}, context: {:?}", @@ -188,7 +188,7 @@ impl< } } - fn check_out(_dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(_dest: &Location, what: &Asset, context: &XcmContext) { log::trace!( target: LOG_TARGET, "check_out dest: {:?}, what: {:?}, context: {:?}", @@ -207,11 +207,7 @@ impl< } } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { log::trace!( target: LOG_TARGET, "deposit_asset what: {:?}, who: {:?}, context: {:?}", @@ -228,10 +224,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { log::trace!( target: LOG_TARGET, "withdraw_asset what: {:?}, who: {:?}, maybe_context: {:?}", @@ -267,7 +263,7 @@ impl< > TransactAsset for NonFungiblesAdapter { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -278,7 +274,7 @@ impl< >::can_check_in(origin, what, context) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -289,7 +285,7 @@ impl< >::check_in(origin, what, context) } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -300,7 +296,7 @@ impl< >::can_check_out(dest, what, context) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -311,11 +307,7 @@ impl< >::check_out(dest, what, context) } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -327,10 +319,10 @@ impl< } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> result::Result { + ) -> result::Result { NonFungiblesMutateAdapter::< Assets, Matcher, @@ -342,11 +334,11 @@ impl< } fn transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> result::Result { + ) -> result::Result { NonFungiblesTransferAdapter::::transfer_asset( what, from, to, context, ) diff --git a/polkadot/xcm/xcm-builder/src/origin_aliases.rs b/polkadot/xcm/xcm-builder/src/origin_aliases.rs index 82c5f71b7a1..bbf810463a7 100644 --- a/polkadot/xcm/xcm-builder/src/origin_aliases.rs +++ b/polkadot/xcm/xcm-builder/src/origin_aliases.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! Implementation for `ContainsPair`. +//! Implementation for `ContainsPair`. use frame_support::traits::{Contains, ContainsPair}; use sp_std::marker::PhantomData; @@ -25,13 +25,15 @@ use xcm::latest::prelude::*; /// /// Requires that the prefixed origin `AccountId32` matches the target `AccountId32`. pub struct AliasForeignAccountId32(PhantomData); -impl> ContainsPair +impl> ContainsPair for AliasForeignAccountId32 { - fn contains(origin: &MultiLocation, target: &MultiLocation) -> bool { - if let (prefix, Some(account_id @ AccountId32 { .. })) = origin.split_last_interior() { + fn contains(origin: &Location, target: &Location) -> bool { + if let (prefix, Some(account_id @ AccountId32 { .. })) = + origin.clone().split_last_interior() + { return Prefix::contains(&prefix) && - *target == MultiLocation { parents: 0, interior: X1(account_id) } + *target == Location { parents: 0, interior: [account_id].into() } } false } diff --git a/polkadot/xcm/xcm-builder/src/origin_conversion.rs b/polkadot/xcm/xcm-builder/src/origin_conversion.rs index cced7dedf62..f64b5660f66 100644 --- a/polkadot/xcm/xcm-builder/src/origin_conversion.rs +++ b/polkadot/xcm/xcm-builder/src/origin_conversion.rs @@ -21,7 +21,7 @@ use frame_system::RawOrigin as SystemRawOrigin; use polkadot_parachain_primitives::primitives::IsSystem; use sp_runtime::traits::TryConvert; use sp_std::marker::PhantomData; -use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind}; +use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, Location, NetworkId, OriginKind}; use xcm_executor::traits::{ConvertLocation, ConvertOrigin}; /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the @@ -35,9 +35,9 @@ where RuntimeOrigin::AccountId: Clone, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", @@ -56,9 +56,9 @@ where pub struct ParentAsSuperuser(PhantomData); impl ConvertOrigin for ParentAsSuperuser { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ParentAsSuperuser origin: {:?}, kind: {:?}", origin, kind); if kind == OriginKind::Superuser && origin.contains_parents_only(1) { @@ -76,17 +76,16 @@ impl, RuntimeOrigin: OriginTrait> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ChildSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind); - match (kind, origin) { - ( - OriginKind::Superuser, - MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, - ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Superuser, (0, [Junction::Parachain(id)])) + if ParaId::from(*id).is_system() => + Ok(RuntimeOrigin::root()), + _ => Err(origin), } } } @@ -98,21 +97,20 @@ impl, RuntimeOrigin: OriginTrait> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SiblingSystemParachainAsSuperuser origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Superuser, - MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, - ) if ParaId::from(id).is_system() => Ok(RuntimeOrigin::root()), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Superuser, (1, [Junction::Parachain(id)])) + if ParaId::from(*id).is_system() => + Ok(RuntimeOrigin::root()), + _ => Err(origin), } } } @@ -124,17 +122,15 @@ impl, RuntimeOrigin: From> ConvertOr for ChildParachainAsNative { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "ChildParachainAsNative origin: {:?}, kind: {:?}", origin, kind); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) }, - ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::Parachain(id)])) => + Ok(RuntimeOrigin::from(ParachainOrigin::from(*id))), + _ => Err(origin), } } } @@ -146,21 +142,19 @@ impl, RuntimeOrigin: From> ConvertOr for SiblingParachainAsNative { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SiblingParachainAsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) }, - ) => Ok(RuntimeOrigin::from(ParachainOrigin::from(id))), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (1, [Junction::Parachain(id)])) => + Ok(RuntimeOrigin::from(ParachainOrigin::from(*id))), + _ => Err(origin), } } } @@ -173,9 +167,9 @@ impl, RuntimeOrigin> ConvertOrigin { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!(target: "xcm::origin_conversion", "RelayChainAsNative origin: {:?}, kind: {:?}", origin, kind); if kind == OriginKind::Native && origin.contains_parents_only(1) { @@ -193,22 +187,20 @@ where RuntimeOrigin::AccountId: From<[u8; 32]>, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SignedAccountId32AsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, network }) }, - ) if matches!(network, None) || network == Network::get() => - Ok(RuntimeOrigin::signed(id.into())), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::AccountId32 { id, network }])) + if matches!(network, None) || *network == Network::get() => + Ok(RuntimeOrigin::signed((*id).into())), + _ => Err(origin), } } } @@ -222,34 +214,32 @@ where RuntimeOrigin::AccountId: From<[u8; 20]>, { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { let origin = origin.into(); log::trace!( target: "xcm::origin_conversion", "SignedAccountKey20AsNative origin: {:?}, kind: {:?}", origin, kind, ); - match (kind, origin) { - ( - OriginKind::Native, - MultiLocation { parents: 0, interior: X1(Junction::AccountKey20 { key, network }) }, - ) if (matches!(network, None) || network == Network::get()) => - Ok(RuntimeOrigin::signed(key.into())), - (_, origin) => Err(origin), + match (kind, origin.unpack()) { + (OriginKind::Native, (0, [Junction::AccountKey20 { key, network }])) + if (matches!(network, None) || *network == Network::get()) => + Ok(RuntimeOrigin::signed((*key).into())), + _ => Err(origin), } } } /// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists. pub struct EnsureXcmOrigin(PhantomData<(RuntimeOrigin, Conversion)>); -impl> +impl> EnsureOrigin for EnsureXcmOrigin where RuntimeOrigin::PalletsOrigin: PartialEq, { - type Success = MultiLocation; + type Success = Location; fn try_origin(o: RuntimeOrigin) -> Result { let o = match Conversion::try_convert(o) { Ok(location) => return Ok(location), @@ -282,13 +272,12 @@ impl< RuntimeOrigin: OriginTrait + Clone, AccountId: Into<[u8; 32]>, Network: Get>, - > TryConvert - for SignedToAccountId32 + > TryConvert for SignedToAccountId32 where RuntimeOrigin::PalletsOrigin: From> + TryInto, Error = RuntimeOrigin::PalletsOrigin>, { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { o.try_with_caller(|caller| match caller.try_into() { Ok(SystemRawOrigin::Signed(who)) => Ok(Junction::AccountId32 { network: Network::get(), id: who.into() }.into()), @@ -299,7 +288,7 @@ where } /// `Convert` implementation to convert from some an origin which implements `Backing` into a -/// corresponding `Plurality` `MultiLocation`. +/// corresponding `Plurality` `Location`. /// /// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an /// XCM from a `Plurality` origin. @@ -307,12 +296,12 @@ pub struct BackingToPlurality( PhantomData<(RuntimeOrigin, COrigin, Body)>, ); impl> - TryConvert for BackingToPlurality + TryConvert for BackingToPlurality where RuntimeOrigin::PalletsOrigin: From + TryInto, { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { o.try_with_caller(|caller| match caller.try_into() { Ok(co) => match co.get_backing() { Some(backing) => Ok(Junction::Plurality { @@ -333,10 +322,10 @@ pub struct OriginToPluralityVoice( PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>, ); impl, Body: Get> - TryConvert + TryConvert for OriginToPluralityVoice { - fn try_convert(o: RuntimeOrigin) -> Result { + fn try_convert(o: RuntimeOrigin) -> Result { match EnsureBodyOrigin::try_origin(o) { Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()), Err(o) => Err(o), diff --git a/polkadot/xcm/xcm-builder/src/pay.rs b/polkadot/xcm/xcm-builder/src/pay.rs index 4c9b9a6088d..6b466483cfa 100644 --- a/polkadot/xcm/xcm-builder/src/pay.rs +++ b/polkadot/xcm/xcm-builder/src/pay.rs @@ -30,7 +30,7 @@ use xcm_executor::traits::{QueryHandler, QueryResponseStatus}; /// ownership of some `Interior` location of the local chain to a particular `Beneficiary`. The /// `AssetKind` value is not itself bounded (to avoid the issue of needing to wrap some preexisting /// datatype), however a converter type `AssetKindToLocatableAsset` must be provided in order to -/// translate it into a `LocatableAsset`, which comprises both an XCM `MultiLocation` describing +/// translate it into a `LocatableAsset`, which comprises both an XCM `Location` describing /// the XCM endpoint on which the asset to be paid resides and an XCM `AssetId` to identify the /// specific asset at that endpoint. /// @@ -65,14 +65,14 @@ pub struct PayOverXcm< )>, ); impl< - Interior: Get, + Interior: Get, Router: SendXcm, Querier: QueryHandler, Timeout: Get, Beneficiary: Clone, AssetKind, AssetKindToLocatableAsset: TryConvert, - BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, MultiLocation>, + BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, Location>, > Pay for PayOverXcm< Interior, @@ -105,7 +105,7 @@ impl< let beneficiary = BeneficiaryRefToLocation::try_convert(&who) .map_err(|_| xcm::latest::Error::InvalidLocation)?; - let query_id = Querier::new_query(asset_location, Timeout::get(), Interior::get()); + let query_id = Querier::new_query(asset_location.clone(), Timeout::get(), Interior::get()); let message = Xcm(vec![ DescendOrigin(Interior::get()), @@ -120,8 +120,7 @@ impl< ])), TransferAsset { beneficiary, - assets: vec![MultiAsset { id: asset_id, fun: Fungibility::Fungible(amount) }] - .into(), + assets: vec![Asset { id: asset_id, fun: Fungibility::Fungible(amount) }].into(), }, ]); @@ -195,16 +194,16 @@ pub struct LocatableAssetId { /// The asset's ID. pub asset_id: AssetId, /// The (relative) location in which the asset ID is meaningful. - pub location: MultiLocation, + pub location: Location, } /// Adapter `struct` which implements a conversion from any `AssetKind` into a [`LocatableAssetId`] /// value using a fixed `Location` for the `location` field. -pub struct FixedLocation(sp_std::marker::PhantomData); -impl, AssetKind: Into> TryConvert - for FixedLocation +pub struct FixedLocation(sp_std::marker::PhantomData); +impl, AssetKind: Into> + TryConvert for FixedLocation { fn try_convert(value: AssetKind) -> Result { - Ok(LocatableAssetId { asset_id: value.into(), location: Location::get() }) + Ok(LocatableAssetId { asset_id: value.into(), location: FixedLocationValue::get() }) } } diff --git a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs index 7334bcd2010..bcf91d8e68c 100644 --- a/polkadot/xcm/xcm-builder/src/process_xcm_message.rs +++ b/polkadot/xcm/xcm-builder/src/process_xcm_message.rs @@ -30,7 +30,7 @@ pub struct ProcessXcmMessage( PhantomData<(MessageOrigin, XcmExecutor, Call)>, ); impl< - MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, + MessageOrigin: Into + FullCodec + MaxEncodedLen + Clone + Eq + PartialEq + TypeInfo + Debug, XcmExecutor: ExecuteXcm, Call, > ProcessMessage for ProcessXcmMessage @@ -82,28 +82,26 @@ impl< let (consumed, result) = match XcmExecutor::execute(origin.into(), pre, id, Weight::zero()) { - Outcome::Complete(w) => { + Outcome::Complete { used } => { log::trace!( target: LOG_TARGET, - "XCM message execution complete, used weight: {w}", + "XCM message execution complete, used weight: {used}", ); - (w, Ok(true)) + (used, Ok(true)) }, - Outcome::Incomplete(w, e) => { + Outcome::Incomplete { used, error } => { log::trace!( target: LOG_TARGET, - "XCM message execution incomplete, used weight: {w}, error: {e:?}", + "XCM message execution incomplete, used weight: {used}, error: {error:?}", ); - - (w, Ok(false)) + (used, Ok(false)) }, // In the error-case we assume the worst case and consume all possible weight. - Outcome::Error(e) => { + Outcome::Error { error } => { log::trace!( target: LOG_TARGET, - "XCM message execution error: {e:?}", + "XCM message execution error: {error:?}", ); - (required, Err(ProcessMessageError::Unsupported)) }, }; diff --git a/polkadot/xcm/xcm-builder/src/routing.rs b/polkadot/xcm/xcm-builder/src/routing.rs index f4c18adddb3..9c0302baee0 100644 --- a/polkadot/xcm/xcm-builder/src/routing.rs +++ b/polkadot/xcm/xcm-builder/src/routing.rs @@ -38,7 +38,7 @@ impl SendXcm for WithUniqueTopic { type Ticket = (Inner::Ticket, [u8; 32]); fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let mut message = message.take().ok_or(SendError::MissingArgument)?; @@ -82,7 +82,7 @@ impl SendXcm for WithTopicSource, + destination: &mut Option, message: &mut Option>, ) -> SendResult { let mut message = message.take().ok_or(SendError::MissingArgument)?; diff --git a/polkadot/xcm/xcm-builder/src/test_utils.rs b/polkadot/xcm/xcm-builder/src/test_utils.rs index d0f867ba62d..3131dece375 100644 --- a/polkadot/xcm/xcm-builder/src/test_utils.rs +++ b/polkadot/xcm/xcm-builder/src/test_utils.rs @@ -27,11 +27,11 @@ pub use xcm_executor::{ traits::{ AssetExchange, AssetLock, ConvertOrigin, Enact, LockError, OnResponse, TransactAsset, }, - Assets, Config, + AssetsInHolding, Config, }; parameter_types! { - pub static SubscriptionRequests: Vec<(MultiLocation, Option<(QueryId, Weight)>)> = vec![]; + pub static SubscriptionRequests: Vec<(Location, Option<(QueryId, Weight)>)> = vec![]; pub static MaxAssetsIntoHolding: u32 = 4; } @@ -39,39 +39,39 @@ pub struct TestSubscriptionService; impl VersionChangeNotifier for TestSubscriptionService { fn start( - location: &MultiLocation, + location: &Location, query_id: QueryId, max_weight: Weight, _context: &XcmContext, ) -> XcmResult { let mut r = SubscriptionRequests::get(); - r.push((*location, Some((query_id, max_weight)))); + r.push((location.clone(), Some((query_id, max_weight)))); SubscriptionRequests::set(r); Ok(()) } - fn stop(location: &MultiLocation, _context: &XcmContext) -> XcmResult { + fn stop(location: &Location, _context: &XcmContext) -> XcmResult { let mut r = SubscriptionRequests::get(); r.retain(|(l, _q)| l != location); - r.push((*location, None)); + r.push((location.clone(), None)); SubscriptionRequests::set(r); Ok(()) } - fn is_subscribed(location: &MultiLocation) -> bool { + fn is_subscribed(location: &Location) -> bool { let r = SubscriptionRequests::get(); r.iter().any(|(l, q)| l == location && q.is_some()) } } parameter_types! { - pub static TrappedAssets: Vec<(MultiLocation, MultiAssets)> = vec![]; + pub static TrappedAssets: Vec<(Location, Assets)> = vec![]; } pub struct TestAssetTrap; impl DropAssets for TestAssetTrap { - fn drop_assets(origin: &MultiLocation, assets: Assets, _context: &XcmContext) -> Weight { - let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); - t.push((*origin, assets.into())); + fn drop_assets(origin: &Location, assets: AssetsInHolding, _context: &XcmContext) -> Weight { + let mut t: Vec<(Location, Assets)> = TrappedAssets::get(); + t.push((origin.clone(), assets.into())); TrappedAssets::set(t); Weight::from_parts(5, 5) } @@ -79,13 +79,13 @@ impl DropAssets for TestAssetTrap { impl ClaimAssets for TestAssetTrap { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, _context: &XcmContext, ) -> bool { - let mut t: Vec<(MultiLocation, MultiAssets)> = TrappedAssets::get(); - if let (0, X1(GeneralIndex(i))) = (ticket.parents, &ticket.interior) { + let mut t: Vec<(Location, Assets)> = TrappedAssets::get(); + if let (0, [GeneralIndex(i)]) = ticket.unpack() { if let Some((l, a)) = t.get(*i as usize) { if l == origin && a == what { t.swap_remove(*i as usize); @@ -102,11 +102,11 @@ pub struct TestAssetExchanger; impl AssetExchange for TestAssetExchanger { fn exchange_asset( - _origin: Option<&MultiLocation>, - _give: Assets, - want: &MultiAssets, + _origin: Option<&Location>, + _give: AssetsInHolding, + want: &Assets, _maximal: bool, - ) -> Result { + ) -> Result { Ok(want.clone().into()) } } @@ -135,17 +135,17 @@ impl PalletsInfoAccess for TestPalletsInfo { } pub struct TestUniversalAliases; -impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { - fn contains(aliases: &(MultiLocation, Junction)) -> bool { +impl Contains<(Location, Junction)> for TestUniversalAliases { + fn contains(aliases: &(Location, Junction)) -> bool { &aliases.0 == &Here.into_location() && &aliases.1 == &GlobalConsensus(ByGenesis([0; 32])) } } parameter_types! { - pub static LockedAssets: Vec<(MultiLocation, MultiAsset)> = vec![]; + pub static LockedAssets: Vec<(Location, Asset)> = vec![]; } -pub struct TestLockTicket(MultiLocation, MultiAsset); +pub struct TestLockTicket(Location, Asset); impl Enact for TestLockTicket { fn enact(self) -> Result<(), LockError> { let mut locked_assets = LockedAssets::get(); @@ -154,7 +154,7 @@ impl Enact for TestLockTicket { Ok(()) } } -pub struct TestUnlockTicket(MultiLocation, MultiAsset); +pub struct TestUnlockTicket(Location, Asset); impl Enact for TestUnlockTicket { fn enact(self) -> Result<(), LockError> { let mut locked_assets = LockedAssets::get(); @@ -183,33 +183,33 @@ impl AssetLock for TestAssetLocker { type ReduceTicket = TestReduceTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - _owner: MultiLocation, + unlocker: Location, + asset: Asset, + _owner: Location, ) -> Result { Ok(TestLockTicket(unlocker, asset)) } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - _owner: MultiLocation, + unlocker: Location, + asset: Asset, + _owner: Location, ) -> Result { Ok(TestUnlockTicket(unlocker, asset)) } fn note_unlockable( - _locker: MultiLocation, - _asset: MultiAsset, - _owner: MultiLocation, + _locker: Location, + _asset: Asset, + _owner: Location, ) -> Result<(), LockError> { Ok(()) } fn prepare_reduce_unlockable( - _locker: MultiLocation, - _asset: MultiAsset, - _owner: MultiLocation, + _locker: Location, + _asset: Asset, + _owner: Location, ) -> Result { Ok(TestReduceTicket) } diff --git a/polkadot/xcm/xcm-builder/src/tests/aliases.rs b/polkadot/xcm/xcm-builder/src/tests/aliases.rs index f686926a252..89c17b09396 100644 --- a/polkadot/xcm/xcm-builder/src/tests/aliases.rs +++ b/polkadot/xcm/xcm-builder/src/tests/aliases.rs @@ -66,20 +66,25 @@ fn alias_origin_should_work() { ]); let message = Xcm(vec![AliasOrigin((AccountId32 { network: None, id: [0; 32] }).into())]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parachain(1), AccountId32 { network: None, id: [0; 32] }), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NoPermission } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NoPermission)); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1), AccountId32 { network: None, id: [0; 32] }), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/assets.rs b/polkadot/xcm/xcm-builder/src/tests/assets.rs index e1d61a9d1c6..b510eab8df5 100644 --- a/polkadot/xcm/xcm-builder/src/tests/assets.rs +++ b/polkadot/xcm/xcm-builder/src/tests/assets.rs @@ -32,10 +32,15 @@ fn exchange_asset_should_work() { maximal: true, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list(Parent), vec![(Here, 100u128).into(), (Parent, 950u128).into()]); assert_eq!(exchange_assets(), vec![(Parent, 50u128).into()].into()); } @@ -56,10 +61,15 @@ fn exchange_asset_without_maximal_should_work() { maximal: false, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list(Parent), vec![(Here, 50u128).into(), (Parent, 950u128).into()]); assert_eq!(exchange_assets(), vec![(Here, 50u128).into(), (Parent, 50u128).into()].into()); } @@ -80,10 +90,18 @@ fn exchange_asset_should_fail_when_no_deal_possible() { maximal: false, }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm(Parent, message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(40, 40), XcmError::NoDeal)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(40, 40), error: XcmError::NoDeal } + ); assert_eq!(asset_list(Parent), vec![(Parent, 1000u128).into()]); assert_eq!(exchange_assets(), vec![(Here, 100u128).into()].into()); } @@ -100,32 +118,39 @@ fn paying_reserve_deposit_should_work() { BuyExecution { fees, weight_limit: Limited(Weight::from_parts(30, 30)) }, DepositAsset { assets: AllCounted(1).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(50, 50); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Here), vec![(Parent, 40u128).into()]); } #[test] fn transfer_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // They want to transfer 100 of them to their sibling parachain #2 let message = Xcm(vec![TransferAsset { assets: (Here, 100u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 100u128).into()] @@ -136,27 +161,31 @@ fn transfer_should_work() { #[test] fn reserve_transfer_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // The remote account owned by gav. - let three: MultiLocation = X1(AccountIndex64 { index: 3, network: None }).into(); + let three: Location = [AccountIndex64 { index: 3, network: None }].into(); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![TransferReserveAsset { assets: (Here, 100u128).into(), dest: Parachain(2).into(), - xcm: Xcm::<()>(vec![DepositAsset { assets: AllCounted(1).into(), beneficiary: three }]), + xcm: Xcm::<()>(vec![DepositAsset { + assets: AllCounted(1).into(), + beneficiary: three.clone(), + }]), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![ ReserveAssetDeposited((Parent, 100u128).into()), @@ -171,7 +200,7 @@ fn reserve_transfer_should_work() { #[test] fn burn_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); // They want to burn 100 of them @@ -180,14 +209,15 @@ fn burn_should_work() { BurnAsset((Here, 100u128).into()), DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(sent_xcm(), vec![]); @@ -197,14 +227,15 @@ fn burn_should_work() { BurnAsset((Here, 1000u128).into()), DepositAsset { assets: Wild(AllCounted(1)), beneficiary: Parachain(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(Parachain(1)), vec![]); assert_eq!(sent_xcm(), vec![]); } @@ -212,7 +243,7 @@ fn burn_should_work() { #[test] fn basic_asset_trap_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into(), [Parachain(2)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. add_asset(Parachain(1), (Here, 1000)); @@ -224,14 +255,15 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(25, 25))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(25, 25) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); @@ -243,15 +275,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -264,15 +300,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -285,15 +325,19 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let old_trapped_assets = TrappedAssets::get(); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![]); assert_eq!(old_trapped_assets, TrappedAssets::get()); @@ -305,14 +349,15 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list(Parachain(1)), vec![(Here, 900u128).into()]); assert_eq!( asset_list(AccountIndex64 { index: 3, network: None }), @@ -327,141 +372,168 @@ fn basic_asset_trap_should_work() { beneficiary: AccountIndex64 { index: 3, network: None }.into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(20, 20), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::UnknownClaim } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::UnknownClaim)); } #[test] fn max_assets_limit_should_work() { // we'll let them have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Child parachain #1 owns 1000 tokens held by us in reserve. - add_asset(Parachain(1), ([1u8; 32], 1000u128)); - add_asset(Parachain(1), ([2u8; 32], 1000u128)); - add_asset(Parachain(1), ([3u8; 32], 1000u128)); - add_asset(Parachain(1), ([4u8; 32], 1000u128)); - add_asset(Parachain(1), ([5u8; 32], 1000u128)); - add_asset(Parachain(1), ([6u8; 32], 1000u128)); - add_asset(Parachain(1), ([7u8; 32], 1000u128)); - add_asset(Parachain(1), ([8u8; 32], 1000u128)); - add_asset(Parachain(1), ([9u8; 32], 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(0)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(1)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(2)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(3)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(4)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(5)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(6)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(7)]), 1000u128)); + add_asset(Parachain(1), (Junctions::from([GeneralIndex(8)]), 1000u128)); // Attempt to withdraw 8 (=2x4)different assets. This will succeed. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(100, 100), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(85, 85))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(85, 85) }); // Attempt to withdraw 9 different assets will fail. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), - WithdrawAsset(([9u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(8)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(100, 100), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(95, 95), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); // Attempt to withdraw 4 different assets and then the same 4 and then a different 4 will // succeed. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(125, 125))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(125, 125) }); // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. let message = Xcm(vec![ - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), - WithdrawAsset(([5u8; 32], 100u128).into()), - WithdrawAsset(([6u8; 32], 100u128).into()), - WithdrawAsset(([7u8; 32], 100u128).into()), - WithdrawAsset(([8u8; 32], 100u128).into()), - WithdrawAsset(([1u8; 32], 100u128).into()), - WithdrawAsset(([2u8; 32], 100u128).into()), - WithdrawAsset(([3u8; 32], 100u128).into()), - WithdrawAsset(([4u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(4)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(5)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(6)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(7)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(1)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(2)]), 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(3)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(95, 95), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow)); // Attempt to withdraw 4 different assets and then a different 4 and then the same 4 will fail. let message = Xcm(vec![ - WithdrawAsset(MultiAssets::from(vec![ - ([1u8; 32], 100u128).into(), - ([2u8; 32], 100u128).into(), - ([3u8; 32], 100u128).into(), - ([4u8; 32], 100u128).into(), - ([5u8; 32], 100u128).into(), - ([6u8; 32], 100u128).into(), - ([7u8; 32], 100u128).into(), - ([8u8; 32], 100u128).into(), + WithdrawAsset(Assets::from(vec![ + (Junctions::from([GeneralIndex(0)]), 100u128).into(), + (Junctions::from([GeneralIndex(1)]), 100u128).into(), + (Junctions::from([GeneralIndex(2)]), 100u128).into(), + (Junctions::from([GeneralIndex(3)]), 100u128).into(), + (Junctions::from([GeneralIndex(4)]), 100u128).into(), + (Junctions::from([GeneralIndex(5)]), 100u128).into(), + (Junctions::from([GeneralIndex(6)]), 100u128).into(), + (Junctions::from([GeneralIndex(7)]), 100u128).into(), ])), - WithdrawAsset(([1u8; 32], 100u128).into()), + WithdrawAsset((Junctions::from([GeneralIndex(0)]), 100u128).into()), ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(200, 200), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(25, 25), + error: XcmError::HoldingWouldOverflow + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(25, 25), XcmError::HoldingWouldOverflow)); } diff --git a/polkadot/xcm/xcm-builder/src/tests/basic.rs b/polkadot/xcm/xcm-builder/src/tests/basic.rs index 02fcd8962db..1482e3d700f 100644 --- a/polkadot/xcm/xcm-builder/src/tests/basic.rs +++ b/polkadot/xcm/xcm-builder/src/tests/basic.rs @@ -27,14 +27,8 @@ fn basic_setup_works() { assert_eq!(to_account(Parachain(50)), Ok(1050)); assert_eq!(to_account((Parent, Parachain(1))), Ok(2001)); assert_eq!(to_account((Parent, Parachain(50))), Ok(2050)); - assert_eq!( - to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: None }))), - Ok(1), - ); - assert_eq!( - to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: None }))), - Ok(42), - ); + assert_eq!(to_account(Location::new(0, [AccountIndex64 { index: 1, network: None }])), Ok(1),); + assert_eq!(to_account(Location::new(0, [AccountIndex64 { index: 42, network: None }])), Ok(42),); assert_eq!(to_account(Here), Ok(3000)); } @@ -65,7 +59,7 @@ fn code_registers_should_work() { SetErrorHandler(Xcm(vec![ TransferAsset { assets: (Here, 2u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // It was handled fine. ClearError, @@ -73,33 +67,45 @@ fn code_registers_should_work() { // Set the appendix - this will always fire. SetAppendix(Xcm(vec![TransferAsset { assets: (Here, 4u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }])), // First xfer always works ok TransferAsset { assets: (Here, 1u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Second xfer results in error on the second message - our error handler will fire. TransferAsset { assets: (Here, 8u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, ]); // Weight limit of 70 is needed. let limit = ::Weigher::weight(&mut message).unwrap(); assert_eq!(limit, Weight::from_parts(70, 70)); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(50, 50))); // We don't pay the 20 weight for the error handler. + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(50, 50) }); // We don't pay the 20 weight for the error handler. assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 13u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 8u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); // We pay the full weight here. + let r = XcmExecutor::::prepare_and_execute( + Here, + message, + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); // We pay the full weight here. assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 20u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); assert_eq!(sent_xcm(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs index b1361cc8577..ea584bf9d48 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs @@ -21,9 +21,9 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); } type TheBridge = TestBridge>; diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs index 5371abccf66..38ffe2532d5 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs @@ -21,9 +21,9 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); } type TheBridge = TestBridge>; diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs index 0c749b66da6..11f0044fbca 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/mod.rs @@ -37,7 +37,7 @@ mod remote_relay_relay; parameter_types! { pub Local: NetworkId = ByGenesis([0; 32]); pub Remote: NetworkId = ByGenesis([1; 32]); - pub Price: MultiAssets = MultiAssets::from((Here, 100u128)); + pub Price: Assets = Assets::from((Here, 100u128)); pub static UsingTopic: bool = false; } @@ -92,7 +92,7 @@ impl SendXcm for TestTopic { } } fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { Ok(if UsingTopic::get() { @@ -120,26 +120,26 @@ impl HaulBlob for TestBridge { } std::thread_local! { - static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); + static REMOTE_INCOMING_XCM: RefCell)>> = RefCell::new(Vec::new()); } struct TestRemoteIncomingRouter; impl SendXcm for TestRemoteIncomingRouter { - type Ticket = (MultiLocation, Xcm<()>); + type Ticket = (Location, Xcm<()>); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>)> { + ) -> SendResult<(Location, Xcm<()>)> { let pair = (dest.take().unwrap(), msg.take().unwrap()); - Ok((pair, MultiAssets::new())) + Ok((pair, Assets::new())) } - fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result { + fn deliver(pair: (Location, Xcm<()>)) -> Result { let hash = fake_id(); REMOTE_INCOMING_XCM.with(|q| q.borrow_mut().push(pair)); Ok(hash) } } -fn take_received_remote_messages() -> Vec<(MultiLocation, Xcm<()>)> { +fn take_received_remote_messages() -> Vec<(Location, Xcm<()>)> { REMOTE_INCOMING_XCM.with(|r| r.replace(vec![])) } @@ -152,18 +152,18 @@ struct UnpaidExecutingRouter( fn price( n: NetworkId, c: u32, - s: &InteriorMultiLocation, - d: &InteriorMultiLocation, + s: &InteriorLocation, + d: &InteriorLocation, m: &Xcm<()>, -) -> Result { - Ok(validate_export::(n, c, *s, *d, m.clone())?.1) +) -> Result { + Ok(validate_export::(n, c, s.clone(), d.clone(), m.clone())?.1) } fn deliver( n: NetworkId, c: u32, - s: InteriorMultiLocation, - d: InteriorMultiLocation, + s: InteriorLocation, + d: InteriorLocation, m: Xcm<()>, ) -> Result { export_xcm::(n, c, s, d, m).map(|(hash, _)| hash) @@ -189,7 +189,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S type Ticket = Xcm<()>; fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult> { let expect_dest = Remote::get().relative_to(&Local::get()); @@ -197,7 +197,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S return Err(NotApplicable) } let message = message.take().ok_or(MissingArgument)?; - Ok((message, MultiAssets::new())) + Ok((message, Assets::new())) } fn deliver(message: Xcm<()>) -> Result { @@ -206,7 +206,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S // though it is `Remote`. ExecutorUniversalLocation::set(Remote::get()); let origin = Local::get().relative_to(&Remote::get()); - AllowUnpaidFrom::set(vec![origin]); + AllowUnpaidFrom::set(vec![origin.clone()]); set_exporter_override(price::, deliver::); // The we execute it: let mut id = fake_id(); @@ -222,9 +222,9 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: false }; RoutingLog::mutate(|l| l.push(entry)); match outcome { - Outcome::Complete(..) => Ok(id), - Outcome::Incomplete(..) => Err(Transport("Error executing")), - Outcome::Error(..) => Err(Transport("Unable to execute")), + Outcome::Complete { .. } => Ok(id), + Outcome::Incomplete { .. } => Err(Transport("Error executing")), + Outcome::Error { .. } => Err(Transport("Unable to execute")), } } } @@ -239,7 +239,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S type Ticket = Xcm<()>; fn validate( - destination: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult> { let expect_dest = Remote::get().relative_to(&Local::get()); @@ -247,7 +247,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S return Err(NotApplicable) } let message = message.take().ok_or(MissingArgument)?; - Ok((message, MultiAssets::new())) + Ok((message, Assets::new())) } fn deliver(message: Xcm<()>) -> Result { @@ -256,7 +256,7 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S // though it is `Remote`. ExecutorUniversalLocation::set(Remote::get()); let origin = Local::get().relative_to(&Remote::get()); - AllowPaidFrom::set(vec![origin]); + AllowPaidFrom::set(vec![origin.clone()]); set_exporter_override(price::, deliver::); // Then we execute it: let mut id = fake_id(); @@ -272,9 +272,9 @@ impl, Remote: Get, RemoteExporter: ExportXcm> S let entry = LogEntry { local, remote, id, message, outcome: outcome.clone(), paid: true }; RoutingLog::mutate(|l| l.push(entry)); match outcome { - Outcome::Complete(..) => Ok(id), - Outcome::Incomplete(..) => Err(Transport("Error executing")), - Outcome::Error(..) => Err(Transport("Unable to execute")), + Outcome::Complete { .. } => Ok(id), + Outcome::Incomplete { .. } => Err(Transport("Error executing")), + Outcome::Error { .. } => Err(Transport("Unable to execute")), } } } diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs index 079eb0175d7..85d6524fb68 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs @@ -27,15 +27,15 @@ parameter_types! { // 100 to use the bridge (export) and 80 for the remote execution weight (4 instructions x (10 + // 10) weight each). pub SendOverBridgePrice: u128 = 180u128 + if UsingTopic::get() { 20 } else { 0 }; - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(100)); - pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(100)].into(); + pub RelayUniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), None, - MultiLocation::parent(), + Location::parent(), Some((Parent, SendOverBridgePrice::get()).into()) ) ]; @@ -64,7 +64,7 @@ type LocalRouter = TestTopic<(LocalInnerRouter, LocalBridgeRouter)>; #[test] fn sending_to_bridged_chain_works() { maybe_with_topic(|| { - let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + let dest: Location = (Parent, Parent, Remote::get()).into(); // Initialize the local relay so that our parachain has funds to pay for export. clear_assets(Parachain(100)); @@ -99,7 +99,7 @@ fn sending_to_bridged_chain_works() { message: xcm_with_topic( maybe_forward_id_for(&[0; 32]), vec![ - WithdrawAsset(MultiAsset::from((Here, price)).into()), + WithdrawAsset(Asset::from((Here, price)).into()), BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, ExportMessage { network: ByGenesis([1; 32]), @@ -109,7 +109,7 @@ fn sending_to_bridged_chain_works() { DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, ], ), - outcome: Outcome::Complete(test_weight(4)), + outcome: Outcome::Complete { used: test_weight(4) }, paid: true, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -117,7 +117,7 @@ fn sending_to_bridged_chain_works() { } #[test] fn sending_to_bridged_chain_without_funds_fails() { - let dest: MultiLocation = (Parent, Parent, Remote::get()).into(); + let dest: Location = (Parent, Parent, Remote::get()).into(); // Routing won't work if we don't have enough funds. assert_eq!( send_xcm::(dest, Xcm(vec![Trap(1)])), @@ -138,7 +138,7 @@ fn sending_to_bridged_chain_without_funds_fails() { #[test] fn sending_to_parachain_of_bridged_chain_works() { maybe_with_topic(|| { - let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + let dest: Location = (Parent, Parent, Remote::get(), Parachain(100)).into(); // Initialize the local relay so that our parachain has funds to pay for export. clear_assets(Parachain(100)); @@ -173,7 +173,7 @@ fn sending_to_parachain_of_bridged_chain_works() { message: xcm_with_topic( maybe_forward_id_for(&[0; 32]), vec![ - WithdrawAsset(MultiAsset::from((Here, price)).into()), + WithdrawAsset(Asset::from((Here, price)).into()), BuyExecution { fees: (Here, price).into(), weight_limit: Unlimited }, ExportMessage { network: ByGenesis([1; 32]), @@ -183,7 +183,7 @@ fn sending_to_parachain_of_bridged_chain_works() { DepositAsset { assets: Wild(All), beneficiary: Parachain(100).into() }, ], ), - outcome: Outcome::Complete(test_weight(4)), + outcome: Outcome::Complete { used: test_weight(4) }, paid: true, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -191,7 +191,7 @@ fn sending_to_parachain_of_bridged_chain_works() { } #[test] fn sending_to_parachain_of_bridged_chain_without_funds_fails() { - let dest: MultiLocation = (Parent, Parent, Remote::get(), Parachain(100)).into(); + let dest: Location = (Parent, Parent, Remote::get(), Parachain(100)).into(); // Routing won't work if we don't have enough funds. assert_eq!( send_xcm::(dest, Xcm(vec![Trap(1)])), diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs index fb6c5da3eb0..b92c59281c6 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs @@ -21,10 +21,10 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); - pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1000)].into(); + pub ParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), @@ -62,7 +62,7 @@ fn sending_to_bridged_chain_works() { send_xcm::((Parent, Parent, Remote::get(), Parachain(1)).into(), msg) .unwrap() .1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); assert_eq!( @@ -94,7 +94,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -116,7 +116,7 @@ fn sending_to_sibling_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( (Parent, Parachain(1000)).into(), @@ -145,7 +145,7 @@ fn sending_to_sibling_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -167,7 +167,7 @@ fn sending_to_relay_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get()).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parent.into(), @@ -196,7 +196,7 @@ fn sending_to_relay_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs index 0b6dc01e2bf..1d433628825 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs @@ -21,10 +21,10 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub ParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1)); - pub RemoteParaBridgeUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1)); - pub RemoteNetwork: MultiLocation = AncestorThen(2, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub ParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1)].into(); + pub RemoteParaBridgeUniversalLocation: Junctions = [GlobalConsensus(Remote::get()), Parachain(1)].into(); + pub RemoteNetwork: Location = AncestorThen(2, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), @@ -62,7 +62,7 @@ fn sending_to_bridged_chain_works() { send_xcm::((Parent, Remote::get(), Parachain(1)).into(), msg) .unwrap() .1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); let expected = vec![( @@ -85,7 +85,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -107,7 +107,7 @@ fn sending_to_sibling_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( (Parent, Parachain(1000)).into(), @@ -129,7 +129,7 @@ fn sending_to_sibling_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -151,7 +151,7 @@ fn sending_to_relay_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Remote::get()).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parent.into(), @@ -173,7 +173,7 @@ fn sending_to_relay_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs index e33c7b15b0a..d40a941c791 100644 --- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs @@ -21,15 +21,15 @@ use super::*; parameter_types! { - pub UniversalLocation: Junctions = X2(GlobalConsensus(Local::get()), Parachain(1000)); - pub RelayUniversalLocation: Junctions = X1(GlobalConsensus(Local::get())); - pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get())); - pub RemoteNetwork: MultiLocation = AncestorThen(1, GlobalConsensus(Remote::get())).into(); + pub UniversalLocation: Junctions = [GlobalConsensus(Local::get()), Parachain(1000)].into(); + pub RelayUniversalLocation: Junctions = [GlobalConsensus(Local::get())].into(); + pub RemoteUniversalLocation: Junctions = [GlobalConsensus(Remote::get())].into(); + pub RemoteNetwork: Location = AncestorThen(1, GlobalConsensus(Remote::get())).into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( Remote::get(), None, - MultiLocation::parent(), + Location::parent(), None ) ]; @@ -59,7 +59,7 @@ fn sending_to_bridged_chain_works() { let msg = Xcm(vec![Trap(1)]); assert_eq!( send_xcm::((Parent, Parent, Remote::get()).into(), msg).unwrap().1, - MultiAssets::new() + Assets::new() ); assert_eq!(TheBridge::service(), 1); assert_eq!( @@ -91,7 +91,7 @@ fn sending_to_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); @@ -113,7 +113,7 @@ fn sending_to_parachain_of_bridged_chain_works() { maybe_with_topic(|| { let msg = Xcm(vec![Trap(1)]); let dest = (Parent, Parent, Remote::get(), Parachain(1000)).into(); - assert_eq!(send_xcm::(dest, msg).unwrap().1, MultiAssets::new()); + assert_eq!(send_xcm::(dest, msg).unwrap().1, Assets::new()); assert_eq!(TheBridge::service(), 1); let expected = vec![( Parachain(1000).into(), @@ -142,7 +142,7 @@ fn sending_to_parachain_of_bridged_chain_works() { }, ], ), - outcome: Outcome::Complete(test_weight(2)), + outcome: Outcome::Complete { used: test_weight(2) }, paid: false, }; assert_eq!(RoutingLog::take(), vec![entry]); diff --git a/polkadot/xcm/xcm-builder/src/tests/expecting.rs b/polkadot/xcm/xcm-builder/src/tests/expecting.rs index 6d5e0ff47b5..1b36ef4517c 100644 --- a/polkadot/xcm/xcm-builder/src/tests/expecting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/expecting.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn expect_pallet_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![ExpectPallet { @@ -28,14 +28,15 @@ fn expect_pallet_should_work() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let message = Xcm(vec![ExpectPallet { index: 1, @@ -44,19 +45,20 @@ fn expect_pallet_should_work() { crate_major: 1, min_crate_minor: 41, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } #[test] fn expect_pallet_should_fail_correctly() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); let message = Xcm(vec![ExpectPallet { index: 1, name: b"Balances".as_ref().into(), @@ -64,14 +66,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 60, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -80,14 +89,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -96,14 +109,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 0, @@ -112,14 +129,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NameMismatch } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NameMismatch)); let message = Xcm(vec![ExpectPallet { index: 2, @@ -128,14 +149,18 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::PalletNotFound } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::PalletNotFound)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -144,14 +169,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 2, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -160,14 +192,21 @@ fn expect_pallet_should_fail_correctly() { crate_major: 0, min_crate_minor: 42, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); let message = Xcm(vec![ExpectPallet { index: 1, @@ -176,12 +215,19 @@ fn expect_pallet_should_fail_correctly() { crate_major: 1, min_crate_minor: 43, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { + used: Weight::from_parts(10, 10), + error: XcmError::VersionIncompatible + } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::VersionIncompatible)); } diff --git a/polkadot/xcm/xcm-builder/src/tests/locking.rs b/polkadot/xcm/xcm-builder/src/tests/locking.rs index f4ef618ac0e..75160e31155 100644 --- a/polkadot/xcm/xcm-builder/src/tests/locking.rs +++ b/polkadot/xcm/xcm-builder/src/tests/locking.rs @@ -34,10 +34,15 @@ fn lock_roundtrip_should_work() { ), LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); let expected_msg = Xcm::<()>(vec![NoteUnlockable { @@ -58,14 +63,15 @@ fn lock_roundtrip_should_work() { // Now we'll unlock it. let message = Xcm(vec![UnlockAsset { asset: (Parent, 100u128).into(), target: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } #[test] @@ -82,10 +88,15 @@ fn auto_fee_paying_should_work() { SetFeesMode { jit_withdraw: true }, LockAsset { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); } @@ -100,10 +111,18 @@ fn lock_should_fail_correctly() { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::LockError } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); @@ -118,10 +137,18 @@ fn lock_should_fail_correctly() { asset: (Parent, 100u128).into(), unlocker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotHoldingFees } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); } @@ -140,14 +167,15 @@ fn remote_unlock_roundtrip_should_work() { // This caused Parachain #1 to send us the NoteUnlockable instruction. let message = Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( take_lock_trace(), vec![Note { @@ -165,10 +193,15 @@ fn remote_unlock_roundtrip_should_work() { ), RequestUnlock { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into() }, ]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]); let expected_msg = Xcm::<()>(vec![UnlockAsset { @@ -201,24 +234,33 @@ fn remote_unlock_should_fail_correctly() { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::LockError)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::LockError } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); // We have been told by Parachain #1 that Account #3 has locked funds which we can unlock. let message = Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( (Parent, Parachain(1)), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let _discard = take_lock_trace(); // We want to unlock 100 of the native parent tokens which were locked for us on parachain. @@ -228,10 +270,18 @@ fn remote_unlock_should_fail_correctly() { asset: (Parent, 100u128).into(), locker: (Parent, Parachain(1)).into(), }]); - let hash = fake_message_hash(&message); - let r = - XcmExecutor::::execute_xcm((3u64,), message, hash, Weight::from_parts(50, 50)); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotHoldingFees)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + (3u64,), + message, + &mut hash, + Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotHoldingFees } + ); assert_eq!(sent_xcm(), vec![]); assert_eq!(take_lock_trace(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/mock.rs b/polkadot/xcm/xcm-builder/src/tests/mock.rs index c1b3f0cf224..f561c7d3bd4 100644 --- a/polkadot/xcm/xcm-builder/src/tests/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/mock.rs @@ -28,7 +28,7 @@ pub use crate::{ use frame_support::traits::{ContainsPair, Everything}; pub use frame_support::{ dispatch::{DispatchInfo, DispatchResultWithPostInfo, GetDispatchInfo, PostDispatchInfo}, - ensure, match_types, parameter_types, + ensure, parameter_types, sp_runtime::{traits::Dispatchable, DispatchError, DispatchErrorWithPostInfo}, traits::{Contains, Get, IsInVec}, }; @@ -45,7 +45,7 @@ pub use xcm_executor::{ AssetExchange, AssetLock, CheckSuspension, ConvertOrigin, Enact, ExportXcm, FeeManager, FeeReason, LockError, OnResponse, TransactAsset, }, - Assets, Config, + AssetsInHolding, Config, }; #[derive(Debug)] @@ -110,52 +110,52 @@ impl GetDispatchInfo for TestCall { } thread_local! { - pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell, XcmHash)>> = RefCell::new(Vec::new()); pub static EXPORTED_XCM: RefCell< - Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> + Vec<(NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash)> > = RefCell::new(Vec::new()); pub static EXPORTER_OVERRIDE: RefCell, - ) -> Result, + ) -> Result, fn( NetworkId, u32, - InteriorMultiLocation, - InteriorMultiLocation, + InteriorLocation, + InteriorLocation, Xcm<()>, ) -> Result, )>> = RefCell::new(None); - pub static SEND_PRICE: RefCell = RefCell::new(MultiAssets::new()); + pub static SEND_PRICE: RefCell = RefCell::new(Assets::new()); pub static SUSPENDED: Cell = Cell::new(false); } -pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { +pub fn sent_xcm() -> Vec<(Location, opaque::Xcm, XcmHash)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } -pub fn set_send_price(p: impl Into) { +pub fn set_send_price(p: impl Into) { SEND_PRICE.with(|l| l.replace(p.into().into())); } pub fn exported_xcm( -) -> Vec<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, opaque::Xcm, XcmHash)> { +) -> Vec<(NetworkId, u32, InteriorLocation, InteriorLocation, opaque::Xcm, XcmHash)> { EXPORTED_XCM.with(|q| (*q.borrow()).clone()) } pub fn set_exporter_override( price: fn( NetworkId, u32, - &InteriorMultiLocation, - &InteriorMultiLocation, + &InteriorLocation, + &InteriorLocation, &Xcm<()>, - ) -> Result, + ) -> Result, deliver: fn( NetworkId, u32, - InteriorMultiLocation, - InteriorMultiLocation, + InteriorLocation, + InteriorLocation, Xcm<()>, ) -> Result, ) { @@ -167,17 +167,17 @@ pub fn clear_exporter_override() { } pub struct TestMessageSender; impl SendXcm for TestMessageSender { - type Ticket = (MultiLocation, Xcm<()>, XcmHash); + type Ticket = (Location, Xcm<()>, XcmHash); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + ) -> SendResult<(Location, Xcm<()>, XcmHash)> { let msg = msg.take().unwrap(); let hash = fake_message_hash(&msg); let triplet = (dest.take().unwrap(), msg, hash); Ok((triplet, SEND_PRICE.with(|l| l.borrow().clone()))) } - fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + fn deliver(triplet: (Location, Xcm<()>, XcmHash)) -> Result { let hash = triplet.2; SENT_XCM.with(|q| q.borrow_mut().push(triplet)); Ok(hash) @@ -185,21 +185,20 @@ impl SendXcm for TestMessageSender { } pub struct TestMessageExporter; impl ExportXcm for TestMessageExporter { - type Ticket = (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash); + type Ticket = (NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash); fn validate( network: NetworkId, channel: u32, - uni_src: &mut Option, - dest: &mut Option, + uni_src: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash)> - { + ) -> SendResult<(NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash)> { let (s, d, m) = (uni_src.take().unwrap(), dest.take().unwrap(), msg.take().unwrap()); - let r: Result = EXPORTER_OVERRIDE.with(|e| { + let r: Result = EXPORTER_OVERRIDE.with(|e| { if let Some((ref f, _)) = &*e.borrow() { f(network, channel, &s, &d, &m) } else { - Ok(MultiAssets::new()) + Ok(Assets::new()) } }); let h = fake_message_hash(&m); @@ -214,7 +213,7 @@ impl ExportXcm for TestMessageExporter { } } fn deliver( - tuple: (NetworkId, u32, InteriorMultiLocation, InteriorMultiLocation, Xcm<()>, XcmHash), + tuple: (NetworkId, u32, InteriorLocation, InteriorLocation, Xcm<()>, XcmHash), ) -> Result { EXPORTER_OVERRIDE.with(|e| { if let Some((_, ref f)) = &*e.borrow() { @@ -230,37 +229,42 @@ impl ExportXcm for TestMessageExporter { } thread_local! { - pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ASSETS: RefCell> = RefCell::new(BTreeMap::new()); } -pub fn assets(who: impl Into) -> Assets { +pub fn assets(who: impl Into) -> AssetsInHolding { ASSETS.with(|a| a.borrow().get(&who.into()).cloned()).unwrap_or_default() } -pub fn asset_list(who: impl Into) -> Vec { - MultiAssets::from(assets(who)).into_inner() +pub fn asset_list(who: impl Into) -> Vec { + Assets::from(assets(who)).into_inner() } -pub fn add_asset(who: impl Into, what: impl Into) { - ASSETS.with(|a| a.borrow_mut().entry(who.into()).or_insert(Assets::new()).subsume(what.into())); +pub fn add_asset(who: impl Into, what: impl Into) { + ASSETS.with(|a| { + a.borrow_mut() + .entry(who.into()) + .or_insert(AssetsInHolding::new()) + .subsume(what.into()) + }); } -pub fn clear_assets(who: impl Into) { +pub fn clear_assets(who: impl Into) { ASSETS.with(|a| a.borrow_mut().remove(&who.into())); } pub struct TestAssetTransactor; impl TransactAsset for TestAssetTransactor { fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _context: Option<&XcmContext>, ) -> Result<(), XcmError> { - add_asset(*who, what.clone()); + add_asset(who.clone(), what.clone()); Ok(()) } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { ASSETS.with(|a| { a.borrow_mut() .get_mut(who) @@ -271,19 +275,20 @@ impl TransactAsset for TestAssetTransactor { } } -pub fn to_account(l: impl Into) -> Result { - Ok(match l.into() { +pub fn to_account(l: impl Into) -> Result { + let l = l.into(); + Ok(match l.unpack() { // Siblings at 2000+id - MultiLocation { parents: 1, interior: X1(Parachain(id)) } => 2000 + id as u64, + (1, [Parachain(id)]) => 2000 + *id as u64, // Accounts are their number - MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) } => index, + (0, [AccountIndex64 { index, .. }]) => *index, // Children at 1000+id - MultiLocation { parents: 0, interior: X1(Parachain(id)) } => 1000 + id as u64, + (0, [Parachain(id)]) => 1000 + *id as u64, // Self at 3000 - MultiLocation { parents: 0, interior: Here } => 3000, + (0, []) => 3000, // Parent at 3001 - MultiLocation { parents: 1, interior: Here } => 3001, - l => { + (1, []) => 3001, + _ => { // Is it a foreign-consensus? let uni = ExecutorUniversalLocation::get(); if l.parents as usize != uni.len() { @@ -301,36 +306,35 @@ pub fn to_account(l: impl Into) -> Result { pub struct TestOriginConverter; impl ConvertOrigin for TestOriginConverter { fn convert_origin( - origin: impl Into, + origin: impl Into, kind: OriginKind, - ) -> Result { + ) -> Result { use OriginKind::*; - match (kind, origin.into()) { + let origin = origin.into(); + match (kind, origin.unpack()) { (Superuser, _) => Ok(TestOrigin::Root), - (SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)), - (Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) => - Ok(TestOrigin::Parachain(id)), - (Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay), - (Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) => - Ok(TestOrigin::Signed(index)), - (_, origin) => Err(origin), + (SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)), + (Native, (0, [Parachain(id)])) => Ok(TestOrigin::Parachain(*id)), + (Native, (1, [])) => Ok(TestOrigin::Relay), + (Native, (0, [AccountIndex64 { index, .. }])) => Ok(TestOrigin::Signed(*index)), + _ => Err(origin), } } } thread_local! { - pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); - pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); - pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); + pub static IS_RESERVE: RefCell>> = RefCell::new(BTreeMap::new()); + pub static IS_TELEPORTER: RefCell>> = RefCell::new(BTreeMap::new()); + pub static UNIVERSAL_ALIASES: RefCell> = RefCell::new(BTreeSet::new()); } -pub fn add_reserve(from: MultiLocation, asset: MultiAssetFilter) { +pub fn add_reserve(from: Location, asset: AssetFilter) { IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } #[allow(dead_code)] -pub fn add_teleporter(from: MultiLocation, asset: MultiAssetFilter) { +pub fn add_teleporter(from: Location, asset: AssetFilter) { IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset)); } -pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { +pub fn add_universal_alias(bridge: impl Into, consensus: impl Into) { UNIVERSAL_ALIASES.with(|r| r.borrow_mut().insert((bridge.into(), consensus.into()))); } pub fn clear_universal_aliases() { @@ -338,29 +342,29 @@ pub fn clear_universal_aliases() { } pub struct TestIsReserve; -impl ContainsPair for TestIsReserve { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for TestIsReserve { + fn contains(asset: &Asset, origin: &Location) -> bool { IS_RESERVE .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) } } pub struct TestIsTeleporter; -impl ContainsPair for TestIsTeleporter { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl ContainsPair for TestIsTeleporter { + fn contains(asset: &Asset, origin: &Location) -> bool { IS_TELEPORTER .with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.matches(asset)))) } } pub struct TestUniversalAliases; -impl Contains<(MultiLocation, Junction)> for TestUniversalAliases { - fn contains(t: &(MultiLocation, Junction)) -> bool { +impl Contains<(Location, Junction)> for TestUniversalAliases { + fn contains(t: &(Location, Junction)) -> bool { UNIVERSAL_ALIASES.with(|r| r.borrow().contains(t)) } } pub enum ResponseSlot { - Expecting(MultiLocation), + Expecting(Location), Received(Response), } thread_local! { @@ -368,20 +372,16 @@ thread_local! { } pub struct TestResponseHandler; impl OnResponse for TestResponseHandler { - fn expecting_response( - origin: &MultiLocation, - query_id: u64, - _querier: Option<&MultiLocation>, - ) -> bool { + fn expecting_response(origin: &Location, query_id: u64, _querier: Option<&Location>) -> bool { QUERIES.with(|q| match q.borrow().get(&query_id) { Some(ResponseSlot::Expecting(ref l)) => l == origin, _ => false, }) } fn on_response( - _origin: &MultiLocation, + _origin: &Location, query_id: u64, - _querier: Option<&MultiLocation>, + _querier: Option<&Location>, response: xcm::latest::Response, _max_weight: Weight, _context: &XcmContext, @@ -396,7 +396,7 @@ impl OnResponse for TestResponseHandler { Weight::from_parts(10, 10) } } -pub fn expect_response(query_id: u64, from: MultiLocation) { +pub fn expect_response(query_id: u64, from: Location) { QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from))); } pub fn response(query_id: u64) -> Option { @@ -420,9 +420,9 @@ impl QueryHandler type UniversalLocation = T::UniversalLocation; fn new_query( - responder: impl Into, + responder: impl Into, _timeout: Self::BlockNumber, - _match_querier: impl Into, + _match_querier: impl Into, ) -> Self::QueryId { let query_id = 1; expect_response(query_id, responder.into()); @@ -431,7 +431,7 @@ impl QueryHandler fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> Result { let responder = responder.into(); @@ -466,16 +466,16 @@ impl QueryHandler } parameter_types! { - pub static ExecutorUniversalLocation: InteriorMultiLocation + pub static ExecutorUniversalLocation: InteriorLocation = (ByGenesis([0; 32]), Parachain(42)).into(); pub UnitWeightCost: Weight = Weight::from_parts(10, 10); } parameter_types! { // Nothing is allowed to be paid/unpaid by default. - pub static AllowExplicitUnpaidFrom: Vec = vec![]; - pub static AllowUnpaidFrom: Vec = vec![]; - pub static AllowPaidFrom: Vec = vec![]; - pub static AllowSubsFrom: Vec = vec![]; + pub static AllowExplicitUnpaidFrom: Vec = vec![]; + pub static AllowUnpaidFrom: Vec = vec![]; + pub static AllowPaidFrom: Vec = vec![]; + pub static AllowSubsFrom: Vec = vec![]; // 1_000_000_000_000 => 1 unit of asset for 1 unit of ref time weight. // 1024 * 1024 => 1 unit of asset for 1 unit of proof size weight. pub static WeightPrice: (AssetId, u128, u128) = @@ -486,7 +486,7 @@ parameter_types! { pub struct TestSuspender; impl CheckSuspension for TestSuspender { fn is_suspended( - _origin: &MultiLocation, + _origin: &Location, _instructions: &mut [Instruction], _max_weight: Weight, _properties: &mut Properties, @@ -520,34 +520,34 @@ pub fn set_fee_waiver(waived: Vec) { pub struct TestFeeManager; impl FeeManager for TestFeeManager { - fn is_waived(_: Option<&MultiLocation>, r: FeeReason) -> bool { + fn is_waived(_: Option<&Location>, r: FeeReason) -> bool { IS_WAIVED.with(|l| l.borrow().contains(&r)) } - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) {} + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) {} } #[derive(Clone, Eq, PartialEq, Debug)] pub enum LockTraceItem { - Lock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Unlock { unlocker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Note { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, - Reduce { locker: MultiLocation, asset: MultiAsset, owner: MultiLocation }, + Lock { unlocker: Location, asset: Asset, owner: Location }, + Unlock { unlocker: Location, asset: Asset, owner: Location }, + Note { locker: Location, asset: Asset, owner: Location }, + Reduce { locker: Location, asset: Asset, owner: Location }, } thread_local! { pub static NEXT_INDEX: RefCell = RefCell::new(0); pub static LOCK_TRACE: RefCell> = RefCell::new(Vec::new()); - pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); - pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); + pub static ALLOWED_REQUEST_UNLOCKS: RefCell> = RefCell::new(BTreeMap::new()); } pub fn take_lock_trace() -> Vec { LOCK_TRACE.with(|l| l.replace(Vec::new())) } pub fn allow_unlock( - unlocker: impl Into, - asset: impl Into, - owner: impl Into, + unlocker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() @@ -557,9 +557,9 @@ pub fn allow_unlock( }); } pub fn disallow_unlock( - unlocker: impl Into, - asset: impl Into, - owner: impl Into, + unlocker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() @@ -568,17 +568,17 @@ pub fn disallow_unlock( .saturating_take(asset.into().into()) }); } -pub fn unlock_allowed(unlocker: &MultiLocation, asset: &MultiAsset, owner: &MultiLocation) -> bool { +pub fn unlock_allowed(unlocker: &Location, asset: &Asset, owner: &Location) -> bool { ALLOWED_UNLOCKS.with(|l| { l.borrow_mut() - .get(&(*owner, *unlocker)) + .get(&(owner.clone(), unlocker.clone())) .map_or(false, |x| x.contains_asset(asset)) }) } pub fn allow_request_unlock( - locker: impl Into, - asset: impl Into, - owner: impl Into, + locker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() @@ -588,9 +588,9 @@ pub fn allow_request_unlock( }); } pub fn disallow_request_unlock( - locker: impl Into, - asset: impl Into, - owner: impl Into, + locker: impl Into, + asset: impl Into, + owner: impl Into, ) { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() @@ -599,14 +599,10 @@ pub fn disallow_request_unlock( .saturating_take(asset.into().into()) }); } -pub fn request_unlock_allowed( - locker: &MultiLocation, - asset: &MultiAsset, - owner: &MultiLocation, -) -> bool { +pub fn request_unlock_allowed(locker: &Location, asset: &Asset, owner: &Location) -> bool { ALLOWED_REQUEST_UNLOCKS.with(|l| { l.borrow_mut() - .get(&(*owner, *locker)) + .get(&(owner.clone(), locker.clone())) .map_or(false, |x| x.contains_asset(asset)) }) } @@ -616,11 +612,11 @@ impl Enact for TestTicket { fn enact(self) -> Result<(), LockError> { match &self.0 { LockTraceItem::Lock { unlocker, asset, owner } => - allow_unlock(*unlocker, asset.clone(), *owner), + allow_unlock(unlocker.clone(), asset.clone(), owner.clone()), LockTraceItem::Unlock { unlocker, asset, owner } => - disallow_unlock(*unlocker, asset.clone(), *owner), + disallow_unlock(unlocker.clone(), asset.clone(), owner.clone()), LockTraceItem::Reduce { locker, asset, owner } => - disallow_request_unlock(*locker, asset.clone(), *owner), + disallow_request_unlock(locker.clone(), asset.clone(), owner.clone()), _ => {}, } LOCK_TRACE.with(move |l| l.borrow_mut().push(self.0)); @@ -635,38 +631,34 @@ impl AssetLock for TestAssetLock { type ReduceTicket = TestTicket; fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result { - ensure!(assets(owner).contains_asset(&asset), LockError::AssetNotOwned); + ensure!(assets(owner.clone()).contains_asset(&asset), LockError::AssetNotOwned); Ok(TestTicket(LockTraceItem::Lock { unlocker, asset, owner })) } fn prepare_unlock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result { ensure!(unlock_allowed(&unlocker, &asset, &owner), LockError::NotLocked); Ok(TestTicket(LockTraceItem::Unlock { unlocker, asset, owner })) } - fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, - ) -> Result<(), LockError> { - allow_request_unlock(locker, asset.clone(), owner); + fn note_unlockable(locker: Location, asset: Asset, owner: Location) -> Result<(), LockError> { + allow_request_unlock(locker.clone(), asset.clone(), owner.clone()); let item = LockTraceItem::Note { locker, asset, owner }; LOCK_TRACE.with(move |l| l.borrow_mut().push(item)); Ok(()) } fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result { ensure!(request_unlock_allowed(&locker, &asset, &owner), LockError::NotLocked); Ok(TestTicket(LockTraceItem::Reduce { locker, asset, owner })) @@ -674,26 +666,26 @@ impl AssetLock for TestAssetLock { } thread_local! { - pub static EXCHANGE_ASSETS: RefCell = RefCell::new(Assets::new()); + pub static EXCHANGE_ASSETS: RefCell = RefCell::new(AssetsInHolding::new()); } -pub fn set_exchange_assets(assets: impl Into) { +pub fn set_exchange_assets(assets: impl Into) { EXCHANGE_ASSETS.with(|a| a.replace(assets.into().into())); } -pub fn exchange_assets() -> MultiAssets { +pub fn exchange_assets() -> Assets { EXCHANGE_ASSETS.with(|a| a.borrow().clone().into()) } pub struct TestAssetExchange; impl AssetExchange for TestAssetExchange { fn exchange_asset( - _origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + _origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result { + ) -> Result { let mut have = EXCHANGE_ASSETS.with(|l| l.borrow().clone()); ensure!(have.contains_assets(want), give); let get = if maximal { - std::mem::replace(&mut have, Assets::new()) + std::mem::replace(&mut have, AssetsInHolding::new()) } else { have.saturating_take(want.clone().into()) }; @@ -703,16 +695,25 @@ impl AssetExchange for TestAssetExchange { } } -match_types! { - pub type SiblingPrefix: impl Contains = { - MultiLocation { parents: 1, interior: X1(Parachain(_)) } - }; - pub type ChildPrefix: impl Contains = { - MultiLocation { parents: 0, interior: X1(Parachain(_)) } - }; - pub type ParentPrefix: impl Contains = { - MultiLocation { parents: 1, interior: Here } - }; +pub struct SiblingPrefix; +impl Contains for SiblingPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (1, [Parachain(_)])) + } +} + +pub struct ChildPrefix; +impl Contains for ChildPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (0, [Parachain(_)])) + } +} + +pub struct ParentPrefix; +impl Contains for ParentPrefix { + fn contains(loc: &Location) -> bool { + matches!(loc.unpack(), (1, [])) + } } pub struct TestConfig; @@ -743,7 +744,7 @@ impl Config for TestConfig { type Aliasers = AliasForeignAccountId32; } -pub fn fungible_multi_asset(location: MultiLocation, amount: u128) -> MultiAsset { +pub fn fungible_multi_asset(location: Location, amount: u128) -> Asset { (AssetId::from(location), Fungibility::Fungible(amount)).into() } diff --git a/polkadot/xcm/xcm-builder/src/tests/origins.rs b/polkadot/xcm/xcm-builder/src/tests/origins.rs index d3d6278eff8..c717d1e2af8 100644 --- a/polkadot/xcm/xcm-builder/src/tests/origins.rs +++ b/polkadot/xcm/xcm-builder/src/tests/origins.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn universal_origin_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into(), X1(Parachain(2)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into(), [Parachain(2)].into()]); clear_universal_aliases(); // Parachain 1 may represent Kusama to us add_universal_alias(Parachain(1), Kusama); @@ -29,48 +29,57 @@ fn universal_origin_should_work() { UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::InvalidLocation } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::InvalidLocation)); let message = Xcm(vec![ UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::NotWithdrawable } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); add_asset((Ancestor(2), GlobalConsensus(Kusama)), (Parent, 100)); let message = Xcm(vec![ UniversalOrigin(GlobalConsensus(Kusama)), TransferAsset { assets: (Parent, 100u128).into(), beneficiary: Here.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(asset_list((Ancestor(2), GlobalConsensus(Kusama))), vec![]); } #[test] fn export_message_should_work() { // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Local parachain #1 issues a transfer asset on Polkadot Relay-chain, transfering 100 Planck to // Polkadot parachain #2. let expected_message = Xcm(vec![TransferAsset { @@ -83,14 +92,15 @@ fn export_message_should_work() { destination: Here, xcm: expected_message.clone(), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let uni_src = (ByGenesis([0; 32]), Parachain(42), Parachain(1)).into(); assert_eq!( exported_xcm(), @@ -101,40 +111,46 @@ fn export_message_should_work() { #[test] fn unpaid_execution_should_work() { // Bridge chain (assumed to be Relay) lets Parachain #1 have message execution for free. - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // Bridge chain (assumed to be Relay) lets Parachain #2 have message execution for free if it // asks. - AllowExplicitUnpaidFrom::set(vec![X1(Parachain(2)).into()]); + AllowExplicitUnpaidFrom::set(vec![[Parachain(2)].into()]); // Asking for unpaid execution of up to 9 weight on the assumption it is origin of #2. let message = Xcm(vec![UnpaidExecution { weight_limit: Limited(Weight::from_parts(9, 9)), check_origin: Some(Parachain(2).into()), }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::BadOrigin } ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::BadOrigin)); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let message = Xcm(vec![UnpaidExecution { weight_limit: Limited(Weight::from_parts(10, 10)), check_origin: Some(Parachain(2).into()), }]); - let r = XcmExecutor::::execute_xcm( + let r = XcmExecutor::::prepare_and_execute( Parachain(2), message.clone(), - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 78b9284c689..01ff8c29f3d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -115,14 +115,14 @@ impl pallet_assets::Config for Test { } parameter_types! { - pub const RelayLocation: MultiLocation = Here.into_location(); + pub const RelayLocation: Location = Here.into_location(); pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = (ByGenesis([0; 32]), Parachain(42)).into(); + pub UniversalLocation: InteriorLocation = (ByGenesis([0; 32]), Parachain(42)).into(); pub UnitWeightCost: u64 = 1_000; pub static AdvertisedXcmVersion: u32 = 3; pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1); - pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into()); + pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (AssetId(RelayLocation::get()), 1, 1); + pub TrustedAssets: (AssetFilter, Location) = (All.into(), Here.into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub CheckingAccount: AccountId = XcmPallet::check_account(); @@ -130,28 +130,25 @@ parameter_types! { type AssetIdForAssets = u128; -pub struct FromMultiLocationToAsset( - core::marker::PhantomData<(MultiLocation, AssetId)>, -); -impl MaybeEquivalence - for FromMultiLocationToAsset +pub struct FromLocationToAsset(core::marker::PhantomData<(Location, AssetId)>); +impl MaybeEquivalence + for FromLocationToAsset { - fn convert(value: &MultiLocation) -> Option { - match value { - MultiLocation { parents: 0, interior: Here } => Some(0 as AssetIdForAssets), - MultiLocation { parents: 1, interior: Here } => Some(1 as AssetIdForAssets), - MultiLocation { parents: 0, interior: X2(PalletInstance(1), GeneralIndex(index)) } - if ![0, 1].contains(index) => + fn convert(value: &Location) -> Option { + match value.unpack() { + (0, []) => Some(0 as AssetIdForAssets), + (1, []) => Some(1 as AssetIdForAssets), + (0, [PalletInstance(1), GeneralIndex(index)]) if ![0, 1].contains(index) => Some(*index as AssetIdForAssets), _ => None, } } - fn convert_back(value: &AssetIdForAssets) -> Option { + fn convert_back(value: &AssetIdForAssets) -> Option { match value { - 0u128 => Some(MultiLocation { parents: 1, interior: Here }), + 0u128 => Some(Location { parents: 1, interior: Here }), para_id @ 1..=1000 => - Some(MultiLocation { parents: 1, interior: X1(Parachain(*para_id as u32)) }), + Some(Location { parents: 1, interior: [Parachain(*para_id as u32)].into() }), _ => None, } } @@ -163,7 +160,7 @@ pub type LocalAssetsTransactor = FungiblesAdapter< ConvertedConcreteId< AssetIdForAssets, Balance, - FromMultiLocationToAsset, + FromLocationToAsset, JustTry, >, SovereignAccountOf, @@ -187,10 +184,10 @@ impl WeightTrader for DummyWeightTrader { fn buy_weight( &mut self, _weight: Weight, - _payment: xcm_executor::Assets, + _payment: xcm_executor::AssetsInHolding, _context: &XcmContext, - ) -> Result { - Ok(xcm_executor::Assets::default()) + ) -> Result { + Ok(xcm_executor::AssetsInHolding::default()) } } @@ -228,13 +225,10 @@ parameter_types! { pub struct TreasuryToAccount; impl ConvertLocation for TreasuryToAccount { - fn convert_location(location: &MultiLocation) -> Option { - match location { - MultiLocation { - parents: 1, - interior: - X2(Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }), - } => Some(TreasuryAccountId::get()), // Hardcoded test treasury account id + fn convert_location(location: &Location) -> Option { + match location.unpack() { + (1, [Parachain(42), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]) => + Some(TreasuryAccountId::get()), // Hardcoded test treasury account id _ => None, } } @@ -277,7 +271,7 @@ pub const INITIAL_BALANCE: Balance = 100 * UNITS; pub const MINIMUM_BALANCE: Balance = 1 * UNITS; pub fn sibling_chain_account_id(para_id: u32, account: [u8; 32]) -> AccountId { - let location: MultiLocation = + let location: Location = (Parent, Parachain(para_id), Junction::AccountId32 { id: account, network: None }).into(); SovereignAccountOf::convert_location(&location).unwrap() } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs index 178b9384273..062faee2abd 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/pay.rs @@ -22,9 +22,9 @@ use frame_support::{assert_ok, traits::tokens::Pay}; /// Type representing both a location and an asset that is held at that location. /// The id of the held asset is relative to the location where it is being held. -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq)] +#[derive(Encode, Decode, Clone, PartialEq, Eq)] pub struct AssetKind { - destination: MultiLocation, + destination: Location, asset_id: AssetId, } @@ -37,8 +37,8 @@ impl sp_runtime::traits::TryConvert for LocatableAs parameter_types! { pub SenderAccount: AccountId = AccountId::new([3u8; 32]); - pub InteriorAccount: InteriorMultiLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); - pub InteriorBody: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub InteriorAccount: InteriorLocation = AccountId32 { id: SenderAccount::get().into(), network: None }.into(); + pub InteriorBody: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); pub Timeout: BlockNumber = 5; // 5 blocks } @@ -91,13 +91,19 @@ fn pay_over_xcm_works() { vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] ); - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); let message = Xcm::<::RuntimeCall>::from(message.clone()); // Execute message in parachain 2 with parachain 42's origin let origin = (Parent, Parachain(42)); - XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); assert_eq!(mock::Assets::balance(0, &recipient), amount); }); } @@ -152,13 +158,19 @@ fn pay_over_xcm_governance_body() { vec![((Parent, Parachain(2)).into(), expected_message, expected_hash)] ); - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); let message = Xcm::<::RuntimeCall>::from(message.clone()); // Execute message in parachain 2 with parachain 42's origin let origin = (Parent, Parachain(42)); - XcmExecutor::::execute_xcm(origin, message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); assert_eq!(mock::Assets::balance(relay_asset_index, &recipient), amount); }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs index e490fe326b3..6a2945c6a9b 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/salary.rs @@ -25,9 +25,9 @@ use frame_support::{ use sp_runtime::{traits::ConvertToValue, DispatchResult}; parameter_types! { - pub Interior: InteriorMultiLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); + pub Interior: InteriorLocation = Plurality { id: BodyId::Treasury, part: BodyPart::Voice }.into(); pub Timeout: BlockNumber = 5; - pub AssetHub: MultiLocation = (Parent, Parachain(1)).into(); + pub AssetHub: Location = (Parent, Parachain(1)).into(); pub AssetIdGeneralIndex: u128 = 100; pub AssetHubAssetId: AssetId = (PalletInstance(1), GeneralIndex(AssetIdGeneralIndex::get())).into(); pub LocatableAsset: LocatableAssetId = LocatableAssetId { asset_id: AssetHubAssetId::get(), location: AssetHub::get() }; @@ -140,7 +140,7 @@ fn salary_pay_over_xcm_works() { assert_ok!(Salary::payout(RuntimeOrigin::signed(recipient.clone()))); // Get message from mock transport layer - let (_, message, hash) = sent_xcm()[0].clone(); + let (_, message, mut hash) = sent_xcm()[0].clone(); // Change type from `Xcm<()>` to `Xcm` to be able to execute later let message = Xcm::<::RuntimeCall>::from(message.clone()); @@ -164,7 +164,13 @@ fn salary_pay_over_xcm_works() { assert_eq!(message, expected_message); // Execute message as the asset hub - XcmExecutor::::execute_xcm((Parent, Parachain(42)), message, hash, Weight::MAX); + XcmExecutor::::prepare_and_execute( + (Parent, Parachain(42)), + message, + &mut hash, + Weight::MAX, + Weight::zero(), + ); // Recipient receives the payment assert_eq!( diff --git a/polkadot/xcm/xcm-builder/src/tests/querying.rs b/polkadot/xcm/xcm-builder/src/tests/querying.rs index 8fbb55eb254..3b47073d53d 100644 --- a/polkadot/xcm/xcm-builder/src/tests/querying.rs +++ b/polkadot/xcm/xcm-builder/src/tests/querying.rs @@ -18,7 +18,7 @@ use super::*; #[test] fn pallet_query_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![QueryPallet { @@ -29,14 +29,15 @@ fn pallet_query_should_work() { max_weight: Weight::from_parts(50, 50), }, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![QueryResponse { query_id: 1, @@ -50,7 +51,7 @@ fn pallet_query_should_work() { #[test] fn pallet_query_with_results_should_work() { - AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]); + AllowUnpaidFrom::set(vec![[Parachain(1)].into()]); // They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2 // and let them know to hand it to account #3. let message = Xcm(vec![QueryPallet { @@ -61,14 +62,15 @@ fn pallet_query_with_results_should_work() { max_weight: Weight::from_parts(50, 50), }, }]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( Parachain(1), message, - hash, + &mut hash, Weight::from_parts(50, 50), + Weight::zero(), ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); let expected_msg = Xcm::<()>(vec![QueryResponse { query_id: 1, @@ -106,15 +108,27 @@ fn prepaid_result_of_query_should_get_free_execution() { max_weight: Weight::from_parts(10, 10), querier: Some(Here.into()), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); // First time the response gets through since we're expecting it... - let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!(response(query_id).unwrap(), the_response); // Second time it doesn't, since we're not. - let r = XcmExecutor::::execute_xcm(Parent, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); } diff --git a/polkadot/xcm/xcm-builder/src/tests/transacting.rs b/polkadot/xcm/xcm-builder/src/tests/transacting.rs index 743ad7039f7..a85c8b9986c 100644 --- a/polkadot/xcm/xcm-builder/src/tests/transacting.rs +++ b/polkadot/xcm/xcm-builder/src/tests/transacting.rs @@ -25,10 +25,16 @@ fn transacting_should_work() { require_weight_at_most: Weight::from_parts(50, 50), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(60, 60) }); } #[test] @@ -40,10 +46,19 @@ fn transacting_should_respect_max_weight_requirement() { require_weight_at_most: Weight::from_parts(40, 40), call: TestCall::Any(Weight::from_parts(50, 50), None).encode().into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(50, 50), XcmError::MaxWeightInvalid)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(50, 50), error: XcmError::MaxWeightInvalid } + ); } #[test] @@ -57,20 +72,26 @@ fn transacting_should_refund_weight() { .encode() .into(), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(60, 60); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(40, 40) }); } #[test] fn paid_transacting_should_refund_payment_for_unused_weight() { - let one: MultiLocation = AccountIndex64 { index: 1, network: None }.into(); - AllowPaidFrom::set(vec![one]); + let one: Location = AccountIndex64 { index: 1, network: None }.into(); + AllowPaidFrom::set(vec![one.clone()]); add_asset(AccountIndex64 { index: 1, network: None }, (Parent, 200u128)); WeightPrice::set((Parent.into(), 1_000_000_000_000, 1024 * 1024)); - let origin = one; + let origin = one.clone(); let fees = (Parent, 200u128).into(); let message = Xcm::(vec![ WithdrawAsset((Parent, 200u128).into()), // enough for 200 units of weight. @@ -86,10 +107,16 @@ fn paid_transacting_should_refund_payment_for_unused_weight() { RefundSurplus, DepositAsset { assets: AllCounted(1).into(), beneficiary: one }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(100, 100); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(60, 60))); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(60, 60) }); assert_eq!( asset_list(AccountIndex64 { index: 1, network: None }), vec![(Parent, 80u128).into()] @@ -112,10 +139,16 @@ fn report_successful_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(MaybeErrorCode::Success), query_id: 42, @@ -142,10 +175,16 @@ fn report_failed_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(vec![2].into()), query_id: 42, @@ -168,10 +207,16 @@ fn expect_successful_transact_status_should_work() { }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let message = Xcm::(vec![ Transact { @@ -181,10 +226,19 @@ fn expect_successful_transact_status_should_work() { }, ExpectTransactStatus(MaybeErrorCode::Success), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(70, 70), error: XcmError::ExpectationFalse } + ); } #[test] @@ -199,10 +253,16 @@ fn expect_failed_transact_status_should_work() { }, ExpectTransactStatus(vec![2].into()), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(70, 70))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(70, 70) }); let message = Xcm::(vec![ Transact { @@ -212,10 +272,19 @@ fn expect_failed_transact_status_should_work() { }, ExpectTransactStatus(vec![2].into()), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(70, 70); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(70, 70), XcmError::ExpectationFalse)); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(70, 70), error: XcmError::ExpectationFalse } + ); } #[test] @@ -235,10 +304,16 @@ fn clear_transact_status_should_work() { max_weight: Weight::from_parts(5000, 5000), }), ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(80, 80); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(80, 80))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(80, 80) }); let expected_msg = Xcm(vec![QueryResponse { response: Response::DispatchResult(MaybeErrorCode::Success), query_id: 42, diff --git a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs index 44ab7d34c51..e29e3a54661 100644 --- a/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs +++ b/polkadot/xcm/xcm-builder/src/tests/version_subscriptions.rs @@ -25,23 +25,41 @@ fn simple_version_subscriptions_should_work() { SetAppendix(Xcm(vec![])), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let origin = Parachain(1000); let message = Xcm::(vec![SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000), }]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); - let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!( SubscriptionRequests::get(), @@ -53,33 +71,36 @@ fn simple_version_subscriptions_should_work() { fn version_subscription_instruction_should_work() { let origin = Parachain(1000); let message = Xcm::(vec![ - DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + DescendOrigin([AccountIndex64 { index: 1, network: None }].into()), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm_in_credit( + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::BadOrigin } + ); let message = Xcm::(vec![ SetAppendix(Xcm(vec![])), SubscribeVersion { query_id: 42, max_response_weight: Weight::from_parts(5000, 5000) }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!( SubscriptionRequests::get(), @@ -93,20 +114,38 @@ fn simple_version_unsubscriptions_should_work() { let origin = Parachain(1000); let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm(origin, message, hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); let origin = Parachain(1000); let message = Xcm::(vec![UnsubscribeVersion]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(10, 10); - let r = XcmExecutor::::execute_xcm(origin, message.clone(), hash, weight_limit); - assert_eq!(r, Outcome::Error(XcmError::Barrier)); + let r = XcmExecutor::::prepare_and_execute( + origin, + message.clone(), + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Error { error: XcmError::Barrier }); - let r = XcmExecutor::::execute_xcm(Parent, message, hash, weight_limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(10, 10))); + let r = XcmExecutor::::prepare_and_execute( + Parent, + message, + &mut hash, + weight_limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(10, 10) }); assert_eq!(SubscriptionRequests::get(), vec![(Parent.into(), None)]); assert_eq!(sent_xcm(), vec![]); @@ -118,31 +157,34 @@ fn version_unsubscription_instruction_should_work() { // Not allowed to do it when origin has been changed. let message = Xcm::(vec![ - DescendOrigin(X1(AccountIndex64 { index: 1, network: None })), + DescendOrigin([AccountIndex64 { index: 1, network: None }].into()), UnsubscribeVersion, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight_limit = Weight::from_parts(20, 20); - let r = XcmExecutor::::execute_xcm_in_credit( + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::BadOrigin)); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::BadOrigin } + ); // Fine to do it when origin is untouched. let message = Xcm::(vec![SetAppendix(Xcm(vec![])), UnsubscribeVersion]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( origin, message, - hash, + &mut hash, weight_limit, weight_limit, ); - assert_eq!(r, Outcome::Complete(Weight::from_parts(20, 20))); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(20, 20) }); assert_eq!(SubscriptionRequests::get(), vec![(Parachain(1000).into(), None)]); assert_eq!(sent_xcm(), vec![]); diff --git a/polkadot/xcm/xcm-builder/src/tests/weight.rs b/polkadot/xcm/xcm-builder/src/tests/weight.rs index a2fb265413f..637e30cce99 100644 --- a/polkadot/xcm/xcm-builder/src/tests/weight.rs +++ b/polkadot/xcm/xcm-builder/src/tests/weight.rs @@ -74,45 +74,78 @@ fn errors_should_return_unused_weight() { // First xfer results in an error on the last message only TransferAsset { assets: (Here, 1u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Second xfer results in error third message and after TransferAsset { assets: (Here, 2u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, // Third xfer results in error second message and after TransferAsset { assets: (Here, 4u128).into(), - beneficiary: X1(AccountIndex64 { index: 3, network: None }).into(), + beneficiary: [AccountIndex64 { index: 3, network: None }].into(), }, ]); // Weight limit of 70 is needed. let limit = ::Weigher::weight(&mut message).unwrap(); assert_eq!(limit, Weight::from_parts(30, 30)); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Complete(Weight::from_parts(30, 30))); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: Weight::from_parts(30, 30) }); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 7u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 4u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(30, 30), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(30, 30), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 10u128).into()]); assert_eq!(asset_list(Here), vec![(Here, 1u128).into()]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message.clone(), hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(20, 20), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message.clone(), + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(20, 20), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); assert_eq!(asset_list(Here), vec![]); assert_eq!(sent_xcm(), vec![]); - let r = XcmExecutor::::execute_xcm(Here, message, hash, limit); - assert_eq!(r, Outcome::Incomplete(Weight::from_parts(10, 10), XcmError::NotWithdrawable)); + let r = XcmExecutor::::prepare_and_execute( + Here, + message, + &mut hash, + limit, + Weight::zero(), + ); + assert_eq!( + r, + Outcome::Incomplete { used: Weight::from_parts(10, 10), error: XcmError::NotWithdrawable } + ); assert_eq!(asset_list(AccountIndex64 { index: 3, network: None }), vec![(Here, 11u128).into()]); assert_eq!(asset_list(Here), vec![]); assert_eq!(sent_xcm(), vec![]); @@ -148,8 +181,8 @@ fn weight_bounds_should_respect_instructions_limit() { #[test] fn weight_trader_tuple_should_work() { - let para_1: MultiLocation = Parachain(1).into(); - let para_2: MultiLocation = Parachain(2).into(); + let para_1: Location = Parachain(1).into(); + let para_2: Location = Parachain(2).into(); parameter_types! { pub static HereWeightPrice: (AssetId, u128, u128) = @@ -186,7 +219,11 @@ fn weight_trader_tuple_should_work() { let mut traders = Traders::new(); // trader one failed; trader two buys weight assert_eq!( - traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into(), &ctx), + traders.buy_weight( + Weight::from_parts(5, 5), + fungible_multi_asset(para_1.clone(), 10).into(), + &ctx + ), Ok(vec![].into()), ); // trader two refunds diff --git a/polkadot/xcm/xcm-builder/src/universal_exports.rs b/polkadot/xcm/xcm-builder/src/universal_exports.rs index 4aa6a0ef7a5..1d084e022c9 100644 --- a/polkadot/xcm/xcm-builder/src/universal_exports.rs +++ b/polkadot/xcm/xcm-builder/src/universal_exports.rs @@ -28,18 +28,18 @@ use SendError::*; /// chain, itself situated at `universal_local` within the consensus universe. If /// `dest` is not a location in remote consensus, then an error is returned. pub fn ensure_is_remote( - universal_local: impl Into, - dest: impl Into, -) -> Result<(NetworkId, InteriorMultiLocation), MultiLocation> { + universal_local: impl Into, + dest: impl Into, +) -> Result<(NetworkId, InteriorLocation), Location> { let dest = dest.into(); let universal_local = universal_local.into(); let local_net = match universal_local.global_consensus() { Ok(x) => x, Err(_) => return Err(dest), }; - let universal_destination: InteriorMultiLocation = universal_local + let universal_destination: InteriorLocation = universal_local .into_location() - .appended_with(dest) + .appended_with(dest.clone()) .map_err(|x| x.1)? .try_into()?; let (remote_dest, remote_net) = match universal_destination.split_first() { @@ -59,18 +59,18 @@ pub fn ensure_is_remote( pub struct UnpaidLocalExporter( PhantomData<(Exporter, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for UnpaidLocalExporter { type Ticket = Exporter::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, xcm: &mut Option>, ) -> SendResult { let d = dest.take().ok_or(MissingArgument)?; let universal_source = UniversalLocation::get(); - let devolved = match ensure_is_remote(universal_source, d) { + let devolved = match ensure_is_remote(universal_source.clone(), d) { Ok(x) => x, Err(d) => { *dest = Some(d); @@ -96,18 +96,18 @@ pub trait ExporterFor { /// the bridge chain as well as payment for the use of the `ExportMessage` instruction. fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)>; + ) -> Option<(Location, Option)>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ExporterFor for Tuple { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, message: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { for_tuples!( #( if let Some(r) = Tuple::exporter_for(network, remote_location, message) { return Some(r); @@ -125,21 +125,21 @@ pub struct NetworkExportTableItem { /// If `Some`, the requested remote location must be equal to one of the items in the vector. /// These are locations in the remote network. /// If `None`, then the check is skipped. - pub remote_location_filter: Option>, + pub remote_location_filter: Option>, /// Locally-routable bridge with bridging capabilities to the `remote_network` and /// `remote_location`. See [`ExporterFor`] for more details. - pub bridge: MultiLocation, + pub bridge: Location, /// The local payment. /// See [`ExporterFor`] for more details. - pub payment: Option, + pub payment: Option, } impl NetworkExportTableItem { pub fn new( remote_network: NetworkId, - remote_location_filter: Option>, - bridge: MultiLocation, - payment: Option, + remote_location_filter: Option>, + bridge: Location, + payment: Option, ) -> Self { Self { remote_network, remote_location_filter, bridge, payment } } @@ -152,9 +152,9 @@ pub struct NetworkExportTable(sp_std::marker::PhantomData); impl>> ExporterFor for NetworkExportTable { fn exporter_for( network: &NetworkId, - remote_location: &InteriorMultiLocation, + remote_location: &InteriorLocation, _: &Xcm<()>, - ) -> Option<(MultiLocation, Option)> { + ) -> Option<(Location, Option)> { T::get() .into_iter() .find(|item| { @@ -194,16 +194,16 @@ pub fn forward_id_for(original_id: &XcmHash) -> XcmHash { pub struct UnpaidRemoteExporter( PhantomData<(Bridges, Router, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for UnpaidRemoteExporter { type Ticket = Router::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult { - let d = dest.ok_or(MissingArgument)?; + let d = dest.clone().ok_or(MissingArgument)?; let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; let (remote_network, remote_location) = devolved; let xcm = msg.take().ok_or(MissingArgument)?; @@ -261,17 +261,18 @@ impl( PhantomData<(Bridges, Router, UniversalLocation)>, ); -impl> SendXcm +impl> SendXcm for SovereignPaidRemoteExporter { type Ticket = Router::Ticket; fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, ) -> SendResult { - let d = *dest.as_ref().ok_or(MissingArgument)?; - let devolved = ensure_is_remote(UniversalLocation::get(), d).map_err(|_| NotApplicable)?; + let d = dest.as_ref().ok_or(MissingArgument)?; + let devolved = + ensure_is_remote(UniversalLocation::get(), d.clone()).map_err(|_| NotApplicable)?; let (remote_network, remote_location) = devolved; let xcm = msg.take().ok_or(MissingArgument)?; @@ -299,7 +300,7 @@ impl, } @@ -386,8 +387,8 @@ pub struct BridgeBlobDispatcher( ); impl< Router: SendXcm, - OurPlace: Get, - OurPlaceBridgeInstance: Get>, + OurPlace: Get, + OurPlaceBridgeInstance: Get>, > DispatchBlob for BridgeBlobDispatcher { fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { @@ -396,7 +397,7 @@ impl< our_universal.global_consensus().map_err(|()| DispatchBlobError::Unbridgable)?; let BridgeMessage { universal_dest, message } = Decode::decode(&mut &blob[..]).map_err(|_| DispatchBlobError::InvalidEncoding)?; - let universal_dest: InteriorMultiLocation = universal_dest + let universal_dest: InteriorLocation = universal_dest .try_into() .map_err(|_| DispatchBlobError::UnsupportedLocationVersion)?; // `universal_dest` is the desired destination within the universe: first we need to check @@ -437,9 +438,9 @@ pub struct HaulBlobExporter( /// ``` impl< Bridge: HaulBlob, - BridgedNetwork: Get, + BridgedNetwork: Get, DestinationVersion: GetVersion, - Price: Get, + Price: Get, > ExportXcm for HaulBlobExporter { type Ticket = (Vec, XcmHash); @@ -447,12 +448,12 @@ impl< fn validate( network: NetworkId, _channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, - ) -> Result<((Vec, XcmHash), MultiAssets), SendError> { + ) -> Result<((Vec, XcmHash), Assets), SendError> { let (bridged_network, bridged_network_location_parents) = { - let MultiLocation { parents, interior: mut junctions } = BridgedNetwork::get(); + let Location { parents, interior: mut junctions } = BridgedNetwork::get(); match junctions.take_first() { Some(GlobalConsensus(network)) => (network, parents), _ => return Err(SendError::NotApplicable), @@ -467,8 +468,8 @@ impl< let (universal_dest, version) = match dest.pushed_front_with(GlobalConsensus(bridged_network)) { Ok(d) => { - let version = DestinationVersion::get_version_for(&MultiLocation::from( - AncestorThen(bridged_network_location_parents, d), + let version = DestinationVersion::get_version_for(&Location::from( + AncestorThen(bridged_network_location_parents, d.clone()), )) .ok_or(SendError::DestinationUnsupported)?; (d, version) @@ -501,7 +502,7 @@ impl< let message = VersionedXcm::from(message) .into_version(version) .map_err(|()| SendError::DestinationUnsupported)?; - let universal_dest = VersionedInteriorMultiLocation::from(universal_dest) + let universal_dest = VersionedInteriorLocation::from(universal_dest) .into_version(version) .map_err(|()| SendError::DestinationUnsupported)?; @@ -548,10 +549,10 @@ mod tests { type Ticket = (); fn validate( - _destination: &mut Option, + _destination: &mut Option, _message: &mut Option>, ) -> SendResult { - Ok(((), MultiAssets::new())) + Ok(((), Assets::new())) } fn deliver(_ticket: Self::Ticket) -> Result { @@ -562,10 +563,10 @@ mod tests { /// Generic test case asserting that dest and msg is not consumed by `validate` implementation /// of `SendXcm` in case of expected result. fn ensure_validate_does_not_consume_dest_or_msg( - dest: MultiLocation, + dest: Location, assert_result: impl Fn(SendResult), ) { - let mut dest_wrapper = Some(dest); + let mut dest_wrapper = Some(dest.clone()); let msg = Xcm::<()>::new(); let mut msg_wrapper = Some(msg.clone()); @@ -580,19 +581,19 @@ mod tests { fn remote_exporters_does_not_consume_dest_or_msg_on_not_applicable() { frame_support::parameter_types! { pub Local: NetworkId = ByGenesis([0; 32]); - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(Local::get()), Parachain(1234)); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(Local::get()), Parachain(1234)].into(); pub DifferentRemote: NetworkId = ByGenesis([22; 32]); // no routers pub BridgeTable: Vec = vec![]; } // check with local destination (should be remote) - let local_dest = (Parent, Parachain(5678)).into(); - assert!(ensure_is_remote(UniversalLocation::get(), local_dest).is_err()); + let local_dest: Location = (Parent, Parachain(5678)).into(); + assert!(ensure_is_remote(UniversalLocation::get(), local_dest.clone()).is_err()); ensure_validate_does_not_consume_dest_or_msg::< UnpaidRemoteExporter, OkSender, UniversalLocation>, - >(local_dest, |result| assert_eq!(Err(NotApplicable), result)); + >(local_dest.clone(), |result| assert_eq!(Err(NotApplicable), result)); ensure_validate_does_not_consume_dest_or_msg::< SovereignPaidRemoteExporter< @@ -603,12 +604,12 @@ mod tests { >(local_dest, |result| assert_eq!(Err(NotApplicable), result)); // check with not applicable destination - let remote_dest = (Parent, Parent, DifferentRemote::get()).into(); - assert!(ensure_is_remote(UniversalLocation::get(), remote_dest).is_ok()); + let remote_dest: Location = (Parent, Parent, DifferentRemote::get()).into(); + assert!(ensure_is_remote(UniversalLocation::get(), remote_dest.clone()).is_ok()); ensure_validate_does_not_consume_dest_or_msg::< UnpaidRemoteExporter, OkSender, UniversalLocation>, - >(remote_dest, |result| assert_eq!(Err(NotApplicable), result)); + >(remote_dest.clone(), |result| assert_eq!(Err(NotApplicable), result)); ensure_validate_does_not_consume_dest_or_msg::< SovereignPaidRemoteExporter< @@ -623,15 +624,15 @@ mod tests { fn network_export_table_works() { frame_support::parameter_types! { pub NetworkA: NetworkId = ByGenesis([0; 32]); - pub Parachain1000InNetworkA: InteriorMultiLocation = X1(Parachain(1000)); - pub Parachain2000InNetworkA: InteriorMultiLocation = X1(Parachain(2000)); + pub Parachain1000InNetworkA: InteriorLocation = [Parachain(1000)].into(); + pub Parachain2000InNetworkA: InteriorLocation = [Parachain(2000)].into(); pub NetworkB: NetworkId = ByGenesis([1; 32]); - pub BridgeToALocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1234))); - pub BridgeToBLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(4321))); + pub BridgeToALocation: Location = Location::new(1, [Parachain(1234)]); + pub BridgeToBLocation: Location = Location::new(1, [Parachain(4321)]); - pub PaymentForNetworkAAndParachain2000: MultiAsset = (MultiLocation::parent(), 150).into(); + pub PaymentForNetworkAAndParachain2000: Asset = (Location::parent(), 150).into(); pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ // NetworkA allows `Parachain(1000)` as remote location WITHOUT payment. @@ -658,19 +659,19 @@ mod tests { ]; } - let test_data = vec![ - (NetworkA::get(), X1(Parachain(1000)), Some((BridgeToALocation::get(), None))), - (NetworkA::get(), X2(Parachain(1000), GeneralIndex(1)), None), + let test_data: Vec<(NetworkId, InteriorLocation, Option<(Location, Option)>)> = vec![ + (NetworkA::get(), [Parachain(1000)].into(), Some((BridgeToALocation::get(), None))), + (NetworkA::get(), [Parachain(1000), GeneralIndex(1)].into(), None), ( NetworkA::get(), - X1(Parachain(2000)), + [Parachain(2000)].into(), Some((BridgeToALocation::get(), Some(PaymentForNetworkAAndParachain2000::get()))), ), - (NetworkA::get(), X2(Parachain(2000), GeneralIndex(1)), None), - (NetworkA::get(), X1(Parachain(3000)), None), - (NetworkB::get(), X1(Parachain(1000)), Some((BridgeToBLocation::get(), None))), - (NetworkB::get(), X1(Parachain(2000)), Some((BridgeToBLocation::get(), None))), - (NetworkB::get(), X1(Parachain(3000)), Some((BridgeToBLocation::get(), None))), + (NetworkA::get(), [Parachain(2000), GeneralIndex(1)].into(), None), + (NetworkA::get(), [Parachain(3000)].into(), None), + (NetworkB::get(), [Parachain(1000)].into(), Some((BridgeToBLocation::get(), None))), + (NetworkB::get(), [Parachain(2000)].into(), Some((BridgeToBLocation::get(), None))), + (NetworkB::get(), [Parachain(3000)].into(), Some((BridgeToBLocation::get(), None))), ]; for (network, remote_location, expected_result) in test_data { diff --git a/polkadot/xcm/xcm-builder/src/weight.rs b/polkadot/xcm/xcm-builder/src/weight.rs index c16c52939a3..2ae6a043843 100644 --- a/polkadot/xcm/xcm-builder/src/weight.rs +++ b/polkadot/xcm/xcm-builder/src/weight.rs @@ -25,10 +25,10 @@ use frame_support::{ use parity_scale_codec::Decode; use sp_runtime::traits::{SaturatedConversion, Saturating, Zero}; use sp_std::{marker::PhantomData, result::Result}; -use xcm::latest::{prelude::*, Weight}; +use xcm::latest::{prelude::*, GetWeight, Weight}; use xcm_executor::{ traits::{WeightBounds, WeightTrader}, - Assets, + AssetsInHolding, }; pub struct FixedWeightBounds(PhantomData<(T, C, M)>); @@ -114,16 +114,16 @@ where } /// Function trait for handling some revenue. Similar to a negative imbalance (credit) handler, but -/// for a `MultiAsset`. Sensible implementations will deposit the asset in some known treasury or +/// for a `Asset`. Sensible implementations will deposit the asset in some known treasury or /// block-author account. pub trait TakeRevenue { - /// Do something with the given `revenue`, which is a single non-wildcard `MultiAsset`. - fn take_revenue(revenue: MultiAsset); + /// Do something with the given `revenue`, which is a single non-wildcard `Asset`. + fn take_revenue(revenue: Asset); } /// Null implementation just burns the revenue. impl TakeRevenue for () { - fn take_revenue(_revenue: MultiAsset) {} + fn take_revenue(_revenue: Asset) {} } /// Simple fee calculator that requires payment in a single fungible at a fixed rate. @@ -143,9 +143,9 @@ impl, R: TakeRevenue> WeightTrader for FixedRateOf fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!( target: "xcm::weight", "FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}, context: {:?}", @@ -165,7 +165,7 @@ impl, R: TakeRevenue> WeightTrader for FixedRateOf Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}, context: {:?}", weight, context); let (id, units_per_second, units_per_mb) = T::get(); let weight = weight.min(self.0); @@ -194,22 +194,22 @@ impl, R: TakeRevenue> Drop for FixedRateOfFungible /// places any weight bought into the right account. pub struct UsingComponents< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetIdValue: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, >( Weight, Currency::Balance, - PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, + PhantomData<(WeightToFee, AssetIdValue, AccountId, Currency, OnUnbalanced)>, ); impl< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetIdValue: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, - > WeightTrader for UsingComponents + > WeightTrader for UsingComponents { fn new() -> Self { Self(Weight::zero(), Zero::zero(), PhantomData) @@ -218,20 +218,20 @@ impl< fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context); let amount = WeightToFee::weight_to_fee(&weight); let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?; - let required = (Concrete(AssetId::get()), u128_amount).into(); + let required = (AssetId(AssetIdValue::get()), u128_amount).into(); let unused = payment.checked_sub(required).map_err(|_| XcmError::TooExpensive)?; self.0 = self.0.saturating_add(weight); self.1 = self.1.saturating_add(amount); Ok(unused) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}, context: {:?}", weight, context); let weight = weight.min(self.0); let amount = WeightToFee::weight_to_fee(&weight); @@ -239,7 +239,7 @@ impl< self.1 = self.1.saturating_sub(amount); let amount: u128 = amount.saturated_into(); if amount > 0 { - Some((AssetId::get(), amount).into()) + Some((AssetIdValue::get(), amount).into()) } else { None } @@ -247,7 +247,7 @@ impl< } impl< WeightToFee: WeightToFeeT, - AssetId: Get, + AssetId: Get, AccountId, Currency: CurrencyT, OnUnbalanced: OnUnbalancedT, diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 6b4d893f73c..e08099280ba 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -46,24 +46,24 @@ pub type AccountId = AccountId32; pub type Balance = u128; thread_local! { - pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); + pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); } -pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm, XcmHash)> { +pub fn sent_xcm() -> Vec<(Location, opaque::Xcm, XcmHash)> { SENT_XCM.with(|q| (*q.borrow()).clone()) } pub struct TestSendXcm; impl SendXcm for TestSendXcm { - type Ticket = (MultiLocation, Xcm<()>, XcmHash); + type Ticket = (Location, Xcm<()>, XcmHash); fn validate( - dest: &mut Option, + dest: &mut Option, msg: &mut Option>, - ) -> SendResult<(MultiLocation, Xcm<()>, XcmHash)> { + ) -> SendResult<(Location, Xcm<()>, XcmHash)> { let msg = msg.take().unwrap(); let hash = fake_message_hash(&msg); let triplet = (dest.take().unwrap(), msg, hash); - Ok((triplet, MultiAssets::new())) + Ok((triplet, Assets::new())) } - fn deliver(triplet: (MultiLocation, Xcm<()>, XcmHash)) -> Result { + fn deliver(triplet: (Location, Xcm<()>, XcmHash)) -> Result { let hash = triplet.2; SENT_XCM.with(|q| q.borrow_mut().push(triplet)); Ok(hash) @@ -136,9 +136,9 @@ impl configuration::Config for Runtime { // aims to closely emulate the Kusama XcmConfig parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::here(); + pub const KsmLocation: Location = Location::here(); pub const KusamaNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub CheckAccount: (AccountId, MintLocation) = (XcmPallet::check_account(), MintLocation::Local); } @@ -176,8 +176,8 @@ pub type Barrier = ( ); parameter_types! { - pub KusamaForAssetHub: (MultiAssetFilter, MultiLocation) = - (Wild(AllOf { id: Concrete(Here.into()), fun: WildFungible }), Parachain(1000).into()); + pub KusamaForAssetHub: (AssetFilter, Location) = + (Wild(AllOf { id: AssetId(Here.into()), fun: WildFungible }), Parachain(1000).into()); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 4; } diff --git a/polkadot/xcm/xcm-builder/tests/scenarios.rs b/polkadot/xcm/xcm-builder/tests/scenarios.rs index 36780b9f007..db37f85acdb 100644 --- a/polkadot/xcm/xcm-builder/tests/scenarios.rs +++ b/polkadot/xcm/xcm-builder/tests/scenarios.rs @@ -55,9 +55,15 @@ fn withdraw_and_deposit_works() { beneficiary: Parachain(other_para_id).into(), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); assert_eq!(Balances::free_balance(other_para_acc), amount); @@ -79,19 +85,19 @@ fn transfer_asset_works() { assets: (Here, amount).into(), beneficiary: AccountId32 { network: None, id: bob.clone().into() }.into(), }]); - let hash = fake_message_hash(&message); - // Use `execute_xcm_in_credit` here to pass through the barrier - let r = XcmExecutor::::execute_xcm_in_credit( + let mut hash = fake_message_hash(&message); + // Use `prepare_and_execute` here to pass through the barrier + let r = XcmExecutor::::prepare_and_execute( AccountId32 { network: None, id: ALICE.into() }, message, - hash, + &mut hash, weight, weight, ); System::assert_last_event( pallet_balances::Event::Transfer { from: ALICE, to: bob.clone(), amount }.into(), ); - assert_eq!(r, Outcome::Complete(weight)); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - amount); assert_eq!(Balances::free_balance(bob), INITIAL_BALANCE + amount); }); @@ -129,14 +135,20 @@ fn report_holding_works() { // is not triggered becasue the deposit fails ReportHolding { response_info: response_info.clone(), assets: All.into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); assert_eq!( r, - Outcome::Incomplete( - weight - BaseXcmWeight::get(), - XcmError::FailedToTransactAsset("AccountIdConversionFailed") - ) + Outcome::Incomplete { + used: weight - BaseXcmWeight::get(), + error: XcmError::FailedToTransactAsset("AccountIdConversionFailed") + } ); // there should be no query response sent for the failed deposit assert_eq!(mock::sent_xcm(), vec![]); @@ -153,9 +165,15 @@ fn report_holding_works() { // used to get a notification in case of success ReportHolding { response_info: response_info.clone(), assets: AllCounted(1).into() }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let other_para_acc: AccountId = ParaId::from(other_para_id).into_account_truncating(); assert_eq!(Balances::free_balance(other_para_acc), amount); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); @@ -209,9 +227,15 @@ fn teleport_to_asset_hub_works() { xcm: Xcm(teleport_effects.clone()), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] .into_iter() .chain(teleport_effects.clone().into_iter()) @@ -232,9 +256,15 @@ fn teleport_to_asset_hub_works() { xcm: Xcm(teleport_effects.clone()), }, ]); - let hash = fake_message_hash(&message); - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let mut hash = fake_message_hash(&message); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); // 2 * amount because of the other teleport above assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - 2 * amount); let expected_msg = Xcm(vec![ReceiveTeleportedAsset((Parent, amount).into()), ClearOrigin] @@ -282,10 +312,16 @@ fn reserve_based_transfer_works() { xcm: Xcm(transfer_effects.clone()), }, ]); - let hash = fake_message_hash(&message); + let mut hash = fake_message_hash(&message); let weight = BaseXcmWeight::get() * 3; - let r = XcmExecutor::::execute_xcm(Parachain(PARA_ID), message, hash, weight); - assert_eq!(r, Outcome::Complete(weight)); + let r = XcmExecutor::::prepare_and_execute( + Parachain(PARA_ID), + message, + &mut hash, + weight, + Weight::zero(), + ); + assert_eq!(r, Outcome::Complete { used: weight }); assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE - amount); let expected_msg = Xcm(vec![ReserveAssetDeposited((Parent, amount).into()), ClearOrigin] .into_iter() diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs index c02cb218885..79d6cb1c411 100644 --- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs +++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs @@ -65,7 +65,7 @@ fn basic_buy_fees_message_executes() { assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( r.event, polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { - outcome: Outcome::Complete(_) + outcome: Outcome::Complete { .. } }), ))); }); @@ -147,7 +147,7 @@ fn transact_recursion_limit_works() { .filter(|r| matches!( r.event, polkadot_test_runtime::RuntimeEvent::Xcm(pallet_xcm::Event::Attempted { - outcome: Outcome::Complete(_) + outcome: Outcome::Complete { .. } }), )) .count(), @@ -242,7 +242,7 @@ fn query_response_fires() { assert_eq!( polkadot_test_runtime::Xcm::query(query_id), Some(QueryStatus::Ready { - response: VersionedResponse::V3(Response::ExecutionResult(None)), + response: VersionedResponse::V4(Response::ExecutionResult(None)), at: 2u32.into() }), ) @@ -314,12 +314,12 @@ fn query_response_elicits_handler() { client.state_at(block_hash).expect("state should exist").inspect_state(|| { assert!(polkadot_test_runtime::System::events().iter().any(|r| matches!( - r.event, + &r.event, TestNotifier(ResponseReceived( - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { .. }) }, + location, q, Response::ExecutionResult(None), - )) if q == query_id, + )) if *q == query_id && matches!(location.unpack(), (0, [Junction::AccountId32 { .. }])), ))); }); } diff --git a/polkadot/xcm/xcm-executor/src/assets.rs b/polkadot/xcm/xcm-executor/src/assets.rs index 33f2ff218c7..4407752f702 100644 --- a/polkadot/xcm/xcm-executor/src/assets.rs +++ b/polkadot/xcm/xcm-executor/src/assets.rs @@ -21,16 +21,16 @@ use sp_std::{ prelude::*, }; use xcm::latest::{ - AssetId, AssetInstance, + Asset, AssetFilter, AssetId, AssetInstance, Assets, Fungibility::{Fungible, NonFungible}, - InteriorMultiLocation, MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation, + InteriorLocation, Location, Reanchorable, + WildAsset::{All, AllCounted, AllOf, AllOfCounted}, WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}, - WildMultiAsset::{All, AllCounted, AllOf, AllOfCounted}, }; -/// List of non-wildcard fungible and non-fungible assets. +/// Map of non-wildcard fungible and non-fungible assets held in the holding register. #[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)] -pub struct Assets { +pub struct AssetsInHolding { /// The fungible assets. pub fungible: BTreeMap, @@ -40,16 +40,16 @@ pub struct Assets { pub non_fungible: BTreeSet<(AssetId, AssetInstance)>, } -impl From for Assets { - fn from(asset: MultiAsset) -> Assets { +impl From for AssetsInHolding { + fn from(asset: Asset) -> AssetsInHolding { let mut result = Self::default(); result.subsume(asset); result } } -impl From> for Assets { - fn from(assets: Vec) -> Assets { +impl From> for AssetsInHolding { + fn from(assets: Vec) -> AssetsInHolding { let mut result = Self::default(); for asset in assets.into_iter() { result.subsume(asset) @@ -58,21 +58,21 @@ impl From> for Assets { } } -impl From for Assets { - fn from(assets: MultiAssets) -> Assets { +impl From for AssetsInHolding { + fn from(assets: Assets) -> AssetsInHolding { assets.into_inner().into() } } -impl From for Vec { - fn from(a: Assets) -> Self { +impl From for Vec { + fn from(a: AssetsInHolding) -> Self { a.into_assets_iter().collect() } } -impl From for MultiAssets { - fn from(a: Assets) -> Self { - a.into_assets_iter().collect::>().into() +impl From for Assets { + fn from(a: AssetsInHolding) -> Self { + a.into_assets_iter().collect::>().into() } } @@ -80,10 +80,10 @@ impl From for MultiAssets { #[derive(Debug)] pub enum TakeError { /// There was an attempt to take an asset without saturating (enough of) which did not exist. - AssetUnderflow(MultiAsset), + AssetUnderflow(Asset), } -impl Assets { +impl AssetsInHolding { /// New value, containing no assets. pub fn new() -> Self { Self::default() @@ -100,41 +100,41 @@ impl Assets { } /// A borrowing iterator over the fungible assets. - pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { + pub fn fungible_assets_iter(&self) -> impl Iterator + '_ { self.fungible .iter() - .map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: *id }) + .map(|(id, &amount)| Asset { fun: Fungible(amount), id: id.clone() }) } /// A borrowing iterator over the non-fungible assets. - pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { + pub fn non_fungible_assets_iter(&self) -> impl Iterator + '_ { self.non_fungible .iter() - .map(|(id, instance)| MultiAsset { fun: NonFungible(*instance), id: *id }) + .map(|(id, instance)| Asset { fun: NonFungible(*instance), id: id.clone() }) } /// A consuming iterator over all assets. - pub fn into_assets_iter(self) -> impl Iterator { + pub fn into_assets_iter(self) -> impl Iterator { self.fungible .into_iter() - .map(|(id, amount)| MultiAsset { fun: Fungible(amount), id }) + .map(|(id, amount)| Asset { fun: Fungible(amount), id }) .chain( self.non_fungible .into_iter() - .map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }), + .map(|(id, instance)| Asset { fun: NonFungible(instance), id }), ) } /// A borrowing iterator over all assets. - pub fn assets_iter(&self) -> impl Iterator + '_ { + pub fn assets_iter(&self) -> impl Iterator + '_ { self.fungible_assets_iter().chain(self.non_fungible_assets_iter()) } /// Mutate `self` to contain all given `assets`, saturating if necessary. /// - /// NOTE: [`Assets`] are always sorted, allowing us to optimize this function from `O(n^2)` to - /// `O(n)`. - pub fn subsume_assets(&mut self, mut assets: Assets) { + /// NOTE: [`AssetsInHolding`] are always sorted, allowing us to optimize this function from + /// `O(n^2)` to `O(n)`. + pub fn subsume_assets(&mut self, mut assets: AssetsInHolding) { let mut f_iter = assets.fungible.iter_mut(); let mut g_iter = self.fungible.iter_mut(); if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) { @@ -166,7 +166,7 @@ impl Assets { /// Mutate `self` to contain the given `asset`, saturating if necessary. /// /// Wildcard values of `asset` do nothing. - pub fn subsume(&mut self, asset: MultiAsset) { + pub fn subsume(&mut self, asset: Asset) { match asset.fun { Fungible(amount) => { self.fungible @@ -180,18 +180,18 @@ impl Assets { } } - /// Swaps two mutable Assets, without deinitializing either one. - pub fn swapped(&mut self, mut with: Assets) -> Self { + /// Swaps two mutable AssetsInHolding, without deinitializing either one. + pub fn swapped(&mut self, mut with: AssetsInHolding) -> Self { mem::swap(&mut *self, &mut with); with } - /// Alter any concretely identified assets by prepending the given `MultiLocation`. + /// Alter any concretely identified assets by prepending the given `Location`. /// /// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's /// responsibility to ensure that any internal asset IDs are able to be prepended without /// overflow. - pub fn prepend_location(&mut self, prepend: &MultiLocation) { + pub fn prepend_location(&mut self, prepend: &Location) { let mut fungible = Default::default(); mem::swap(&mut self.fungible, &mut fungible); self.fungible = fungible @@ -218,8 +218,8 @@ impl Assets { /// Any assets which were unable to be reanchored are introduced into `failed_bin`. pub fn reanchor( &mut self, - target: &MultiLocation, - context: InteriorMultiLocation, + target: &Location, + context: &InteriorLocation, mut maybe_failed_bin: Option<&mut Self>, ) { let mut fungible = Default::default(); @@ -249,22 +249,22 @@ impl Assets { } /// Returns `true` if `asset` is contained within `self`. - pub fn contains_asset(&self, asset: &MultiAsset) -> bool { + pub fn contains_asset(&self, asset: &Asset) -> bool { match asset { - MultiAsset { fun: Fungible(amount), id } => + Asset { fun: Fungible(amount), id } => self.fungible.get(id).map_or(false, |a| a >= amount), - MultiAsset { fun: NonFungible(instance), id } => - self.non_fungible.contains(&(*id, *instance)), + Asset { fun: NonFungible(instance), id } => + self.non_fungible.contains(&(id.clone(), *instance)), } } /// Returns `true` if all `assets` are contained within `self`. - pub fn contains_assets(&self, assets: &MultiAssets) -> bool { + pub fn contains_assets(&self, assets: &Assets) -> bool { assets.inner().iter().all(|a| self.contains_asset(a)) } /// Returns `true` if all `assets` are contained within `self`. - pub fn contains(&self, assets: &Assets) -> bool { + pub fn contains(&self, assets: &AssetsInHolding) -> bool { assets .fungible .iter() @@ -274,16 +274,16 @@ impl Assets { /// Returns an error unless all `assets` are contained in `self`. In the case of an error, the /// first asset in `assets` which is not wholly in `self` is returned. - pub fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> { + pub fn ensure_contains(&self, assets: &Assets) -> Result<(), TakeError> { for asset in assets.inner().iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { if self.fungible.get(id).map_or(true, |a| a < amount) { - return Err(TakeError::AssetUnderflow((*id, *amount).into())) + return Err(TakeError::AssetUnderflow((id.clone(), *amount).into())) } }, - MultiAsset { fun: NonFungible(instance), id } => { - let id_instance = (*id, *instance); + Asset { fun: NonFungible(instance), id } => { + let id_instance = (id.clone(), *instance); if !self.non_fungible.contains(&id_instance) { return Err(TakeError::AssetUnderflow(id_instance.into())) } @@ -308,16 +308,16 @@ impl Assets { /// of) a definite asset to be removed. fn general_take( &mut self, - mask: MultiAssetFilter, + mask: AssetFilter, saturate: bool, - ) -> Result { - let mut taken = Assets::new(); + ) -> Result { + let mut taken = AssetsInHolding::new(); let maybe_limit = mask.limit().map(|x| x as usize); match mask { // TODO: Counted variants where we define `limit`. - MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + AssetFilter::Wild(All) | AssetFilter::Wild(AllCounted(_)) => { if maybe_limit.map_or(true, |l| self.len() <= l) { - return Ok(self.swapped(Assets::new())) + return Ok(self.swapped(AssetsInHolding::new())) } else { let fungible = mem::replace(&mut self.fungible, Default::default()); fungible.into_iter().for_each(|(c, amount)| { @@ -337,15 +337,15 @@ impl Assets { }); } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildFungible, id }) => if maybe_limit.map_or(true, |l| l >= 1) { if let Some((id, amount)) = self.fungible.remove_entry(&id) { taken.fungible.insert(id, amount); } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { + AssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => { let non_fungible = mem::replace(&mut self.non_fungible, Default::default()); non_fungible.into_iter().for_each(|(c, instance)| { if c == id && maybe_limit.map_or(true, |l| taken.len() < l) { @@ -355,13 +355,13 @@ impl Assets { } }); }, - MultiAssetFilter::Definite(assets) => { + AssetFilter::Definite(assets) => { if !saturate { self.ensure_contains(&assets)?; } for asset in assets.into_inner().into_iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { let (remove, amount) = match self.fungible.get_mut(&id) { Some(self_amount) => { let amount = amount.min(*self_amount); @@ -374,10 +374,10 @@ impl Assets { self.fungible.remove(&id); } if amount > 0 { - taken.subsume(MultiAsset::from((id, amount)).into()); + taken.subsume(Asset::from((id, amount)).into()); } }, - MultiAsset { fun: NonFungible(instance), id } => { + Asset { fun: NonFungible(instance), id } => { let id_instance = (id, instance); if self.non_fungible.remove(&id_instance) { taken.subsume(id_instance.into()) @@ -395,7 +395,7 @@ impl Assets { /// /// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its /// value minus `mask` if `self` contains `asset`, and return `Err` otherwise. - pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets { + pub fn saturating_take(&mut self, asset: AssetFilter) -> AssetsInHolding { self.general_take(asset, true) .expect("general_take never results in error when saturating") } @@ -405,13 +405,13 @@ impl Assets { /// /// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its /// value minus `asset` if `self` contains `asset`, and return `Err` otherwise. - pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result { + pub fn try_take(&mut self, mask: AssetFilter) -> Result { self.general_take(mask, false) } /// Consumes `self` and returns its original value excluding `asset` iff it contains at least /// `asset`. - pub fn checked_sub(mut self, asset: MultiAsset) -> Result { + pub fn checked_sub(mut self, asset: Asset) -> Result { match asset.fun { Fungible(amount) => { let remove = if let Some(balance) = self.fungible.get_mut(&asset.id) { @@ -446,66 +446,66 @@ impl Assets { /// Example: /// /// ``` - /// use staging_xcm_executor::Assets; + /// use staging_xcm_executor::AssetsInHolding; /// use xcm::latest::prelude::*; - /// let assets_i_have: Assets = vec![ (Here, 100).into(), ([0; 32], 100).into() ].into(); - /// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), ([0; 32], 50).into() ].into(); + /// let assets_i_have: AssetsInHolding = vec![ (Here, 100).into(), (Junctions::from([GeneralIndex(0)]), 100).into() ].into(); + /// let assets_they_want: AssetFilter = vec![ (Here, 200).into(), (Junctions::from([GeneralIndex(0)]), 50).into() ].into(); /// - /// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want); + /// let assets_we_can_trade: AssetsInHolding = assets_i_have.min(&assets_they_want); /// assert_eq!(assets_we_can_trade.into_assets_iter().collect::>(), vec![ - /// (Here, 100).into(), ([0; 32], 50).into(), + /// (Here, 100).into(), (Junctions::from([GeneralIndex(0)]), 50).into(), /// ]); /// ``` - pub fn min(&self, mask: &MultiAssetFilter) -> Assets { - let mut masked = Assets::new(); + pub fn min(&self, mask: &AssetFilter) -> AssetsInHolding { + let mut masked = AssetsInHolding::new(); let maybe_limit = mask.limit().map(|x| x as usize); if maybe_limit.map_or(false, |l| l == 0) { return masked } match mask { - MultiAssetFilter::Wild(All) | MultiAssetFilter::Wild(AllCounted(_)) => { + AssetFilter::Wild(All) | AssetFilter::Wild(AllCounted(_)) => { if maybe_limit.map_or(true, |l| self.len() <= l) { return self.clone() } else { - for (&c, &amount) in self.fungible.iter() { - masked.fungible.insert(c, amount); + for (c, &amount) in self.fungible.iter() { + masked.fungible.insert(c.clone(), amount); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } for (c, instance) in self.non_fungible.iter() { - masked.non_fungible.insert((*c, *instance)); + masked.non_fungible.insert((c.clone(), *instance)); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } } }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildFungible, id }) => if let Some(&amount) = self.fungible.get(&id) { - masked.fungible.insert(*id, amount); + masked.fungible.insert(id.clone(), amount); }, - MultiAssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | - MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => + AssetFilter::Wild(AllOfCounted { fun: WildNonFungible, id, .. }) | + AssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => for (c, instance) in self.non_fungible.iter() { if c == id { - masked.non_fungible.insert((*c, *instance)); + masked.non_fungible.insert((c.clone(), *instance)); if maybe_limit.map_or(false, |l| masked.len() >= l) { return masked } } }, - MultiAssetFilter::Definite(assets) => + AssetFilter::Definite(assets) => for asset in assets.inner().iter() { match asset { - MultiAsset { fun: Fungible(amount), id } => { + Asset { fun: Fungible(amount), id } => { if let Some(m) = self.fungible.get(id) { - masked.subsume((*id, Fungible(*amount.min(m))).into()); + masked.subsume((id.clone(), Fungible(*amount.min(m))).into()); } }, - MultiAsset { fun: NonFungible(instance), id } => { - let id_instance = (*id, *instance); + Asset { fun: NonFungible(instance), id } => { + let id_instance = (id.clone(), *instance); if self.non_fungible.contains(&id_instance) { masked.subsume(id_instance.into()); } @@ -522,30 +522,18 @@ mod tests { use super::*; use xcm::latest::prelude::*; #[allow(non_snake_case)] - /// Abstract fungible constructor - fn AF(id: u8, amount: u128) -> MultiAsset { - ([id; 32], amount).into() - } - #[allow(non_snake_case)] - /// Abstract non-fungible constructor - fn ANF(class: u8, instance_id: u8) -> MultiAsset { - ([class; 32], [instance_id; 4]).into() - } - #[allow(non_snake_case)] /// Concrete fungible constructor - fn CF(amount: u128) -> MultiAsset { + fn CF(amount: u128) -> Asset { (Here, amount).into() } #[allow(non_snake_case)] /// Concrete non-fungible constructor - fn CNF(instance_id: u8) -> MultiAsset { + fn CNF(instance_id: u8) -> Asset { (Here, [instance_id; 4]).into() } - fn test_assets() -> Assets { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + fn test_assets() -> AssetsInHolding { + let mut assets = AssetsInHolding::new(); assets.subsume(CF(300)); assets.subsume(CNF(40)); assets @@ -554,9 +542,7 @@ mod tests { #[test] fn subsume_assets_works() { let t1 = test_assets(); - let mut t2 = Assets::new(); - t2.subsume(AF(1, 50)); - t2.subsume(ANF(2, 10)); + let mut t2 = AssetsInHolding::new(); t2.subsume(CF(300)); t2.subsume(CNF(50)); let mut r1 = t1.clone(); @@ -571,63 +557,48 @@ mod tests { #[test] fn checked_sub_works() { let t = test_assets(); - let t = t.checked_sub(AF(1, 50)).unwrap(); - let t = t.checked_sub(AF(1, 51)).unwrap_err(); - let t = t.checked_sub(AF(1, 50)).unwrap(); - let t = t.checked_sub(AF(1, 1)).unwrap_err(); let t = t.checked_sub(CF(150)).unwrap(); let t = t.checked_sub(CF(151)).unwrap_err(); let t = t.checked_sub(CF(150)).unwrap(); let t = t.checked_sub(CF(1)).unwrap_err(); - let t = t.checked_sub(ANF(2, 21)).unwrap_err(); - let t = t.checked_sub(ANF(2, 20)).unwrap(); - let t = t.checked_sub(ANF(2, 20)).unwrap_err(); let t = t.checked_sub(CNF(41)).unwrap_err(); let t = t.checked_sub(CNF(40)).unwrap(); let t = t.checked_sub(CNF(40)).unwrap_err(); - assert_eq!(t, Assets::new()); + assert_eq!(t, AssetsInHolding::new()); } #[test] fn into_assets_iter_works() { let assets = test_assets(); let mut iter = assets.into_assets_iter(); - // Order defined by implementation: CF, AF, CNF, ANF + // Order defined by implementation: CF, CNF assert_eq!(Some(CF(300)), iter.next()); - assert_eq!(Some(AF(1, 100)), iter.next()); assert_eq!(Some(CNF(40)), iter.next()); - assert_eq!(Some(ANF(2, 20)), iter.next()); assert_eq!(None, iter.next()); } #[test] fn assets_into_works() { - let mut assets_vec: Vec = Vec::new(); - assets_vec.push(AF(1, 100)); - assets_vec.push(ANF(2, 20)); + let mut assets_vec: Vec = Vec::new(); assets_vec.push(CF(300)); assets_vec.push(CNF(40)); // Push same group of tokens again - assets_vec.push(AF(1, 100)); - assets_vec.push(ANF(2, 20)); assets_vec.push(CF(300)); assets_vec.push(CNF(40)); - let assets: Assets = assets_vec.into(); + let assets: AssetsInHolding = assets_vec.into(); let mut iter = assets.into_assets_iter(); // Fungibles add assert_eq!(Some(CF(600)), iter.next()); - assert_eq!(Some(AF(1, 200)), iter.next()); // Non-fungibles collapse assert_eq!(Some(CNF(40)), iter.next()); - assert_eq!(Some(ANF(2, 20)), iter.next()); assert_eq!(None, iter.next()); } #[test] fn min_all_and_none_works() { let assets = test_assets(); - let none = MultiAssets::new().into(); + let none = Assets::new().into(); let all = All.into(); let none_min = assets.min(&none); @@ -638,43 +609,15 @@ mod tests { #[test] fn min_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let fungible = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); - let non_fungible = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); - let all = WildMultiAsset::AllCounted(6).into(); + let all = WildAsset::AllCounted(6).into(); - let fungible = assets.min(&fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.min(&non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20), ANF(2, 30)]); let all = assets.min(&all); let all = all.assets_iter().collect::>(); - assert_eq!(all, vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),]); - } - - #[test] - fn min_all_abstract_works() { - let assets = test_assets(); - let fungible = Wild(([1u8; 32], WildFungible).into()); - let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); - - let fungible = assets.min(&fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.min(&non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20)]); + assert_eq!(all, vec![CF(3000), CNF(40), CNF(80)]); } #[test] @@ -695,20 +638,16 @@ mod tests { fn min_basic_works() { let assets1 = test_assets(); - let mut assets2 = Assets::new(); - // This is less than 100, so it will decrease to 50 - assets2.subsume(AF(1, 50)); - // This asset does not exist, so not included - assets2.subsume(ANF(2, 40)); + let mut assets2 = AssetsInHolding::new(); // This is more then 300, so it should stay at 300 assets2.subsume(CF(600)); // This asset should be included assets2.subsume(CNF(40)); - let assets2: MultiAssets = assets2.into(); + let assets2: Assets = assets2.into(); let assets_min = assets1.min(&assets2.into()); let assets_min = assets_min.into_assets_iter().collect::>(); - assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(40)]); + assert_eq!(assets_min, vec![CF(300), CNF(40)]); } #[test] @@ -724,23 +663,6 @@ mod tests { assert!(all_iter.eq(test_assets().assets_iter())); } - #[test] - fn saturating_take_all_abstract_works() { - let mut assets = test_assets(); - let fungible = Wild(([1u8; 32], WildFungible).into()); - let non_fungible = Wild(([2u8; 32], WildNonFungible).into()); - - let fungible = assets.saturating_take(fungible); - let fungible = fungible.assets_iter().collect::>(); - assert_eq!(fungible, vec![AF(1, 100)]); - let non_fungible = assets.saturating_take(non_fungible); - let non_fungible = non_fungible.assets_iter().collect::>(); - assert_eq!(non_fungible, vec![ANF(2, 20)]); - // Assets drained of abstract - let final_assets = assets.assets_iter().collect::>(); - assert_eq!(final_assets, vec![CF(300), CNF(40)]); - } - #[test] fn saturating_take_all_concrete_works() { let mut assets = test_assets(); @@ -753,102 +675,49 @@ mod tests { let non_fungible = assets.saturating_take(non_fungible); let non_fungible = non_fungible.assets_iter().collect::>(); assert_eq!(non_fungible, vec![CNF(40)]); - // Assets drained of concrete - let assets = assets.assets_iter().collect::>(); - assert_eq!(assets, vec![AF(1, 100), ANF(2, 20)]); } #[test] fn saturating_take_basic_works() { let mut assets1 = test_assets(); - let mut assets2 = Assets::new(); - // We should take 50 - assets2.subsume(AF(1, 50)); - // This asset should not be taken - assets2.subsume(ANF(2, 40)); + let mut assets2 = AssetsInHolding::new(); // This is more then 300, so it takes everything assets2.subsume(CF(600)); // This asset should be taken assets2.subsume(CNF(40)); - let assets2: MultiAssets = assets2.into(); + let assets2: Assets = assets2.into(); let taken = assets1.saturating_take(assets2.into()); let taken = taken.into_assets_iter().collect::>(); - assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(40)]); - - let assets = assets1.into_assets_iter().collect::>(); - assert_eq!(assets, vec![AF(1, 50), ANF(2, 20)]); + assert_eq!(taken, vec![CF(300), CNF(40)]); } #[test] fn try_take_all_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let all = assets.try_take(WildMultiAsset::AllCounted(6).into()).unwrap(); - assert_eq!( - MultiAssets::from(all).inner(), - &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 20),] - ); - assert_eq!(MultiAssets::from(assets).inner(), &vec![ANF(2, 30), ANF(2, 40), ANF(3, 10),]); + let all = assets.try_take(WildAsset::AllCounted(6).into()).unwrap(); + assert_eq!(Assets::from(all).inner(), &vec![CF(3000), CNF(40), CNF(80)]); } #[test] fn try_take_fungibles_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let mask = WildMultiAsset::from(([1u8; 32], WildFungible)).counted(2).into(); - let taken = assets.try_take(mask).unwrap(); - assert_eq!(MultiAssets::from(taken).inner(), &vec![AF(1, 100)]); - assert_eq!( - MultiAssets::from(assets).inner(), - &vec![ - CF(3000), - AF(10, 50), - CNF(40), - CNF(80), - ANF(2, 20), - ANF(2, 30), - ANF(2, 40), - ANF(3, 10), - ] - ); + assert_eq!(Assets::from(assets).inner(), &vec![CF(3000), CNF(40), CNF(80),]); } #[test] fn try_take_non_fungibles_counted_works() { - let mut assets = Assets::new(); - assets.subsume(AF(1, 100)); - assets.subsume(ANF(2, 20)); + let mut assets = AssetsInHolding::new(); assets.subsume(CNF(40)); - assets.subsume(AF(10, 50)); - assets.subsume(ANF(2, 40)); - assets.subsume(ANF(2, 30)); assets.subsume(CF(3000)); assets.subsume(CNF(80)); - assets.subsume(ANF(3, 10)); - let mask = WildMultiAsset::from(([2u8; 32], WildNonFungible)).counted(2).into(); - let taken = assets.try_take(mask).unwrap(); - assert_eq!(MultiAssets::from(taken).inner(), &vec![ANF(2, 20), ANF(2, 30),]); - assert_eq!( - MultiAssets::from(assets).inner(), - &vec![CF(3000), AF(1, 100), AF(10, 50), CNF(40), CNF(80), ANF(2, 40), ANF(3, 10),] - ); + assert_eq!(Assets::from(assets).inner(), &vec![CF(3000), CNF(40), CNF(80)]); } } diff --git a/polkadot/xcm/xcm-executor/src/config.rs b/polkadot/xcm/xcm-executor/src/config.rs index 2ff12cd7a53..3f1ea6d1fb8 100644 --- a/polkadot/xcm/xcm-executor/src/config.rs +++ b/polkadot/xcm/xcm-executor/src/config.rs @@ -41,17 +41,17 @@ pub trait Config { type OriginConverter: ConvertOrigin<::RuntimeOrigin>; /// Combinations of (Asset, Location) pairs which we trust as reserves. - type IsReserve: ContainsPair; + type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. - type IsTeleporter: ContainsPair; + type IsTeleporter: ContainsPair; /// A list of (Origin, Target) pairs allowing a given Origin to be substituted with its /// corresponding Target pair. - type Aliasers: ContainsPair; + type Aliasers: ContainsPair; /// This chain's Universal Location. - type UniversalLocation: Get; + type UniversalLocation: Get; /// Whether we should execute the given XCM at all. type Barrier: ShouldExecute; @@ -98,7 +98,7 @@ pub trait Config { /// The origin locations and specific universal junctions to which they are allowed to elevate /// themselves. - type UniversalAliases: Contains<(MultiLocation, Junction)>; + type UniversalAliases: Contains<(Location, Junction)>; /// The call dispatcher used by XCM. /// diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs index 665b051c130..1f5f2eba5e2 100644 --- a/polkadot/xcm/xcm-executor/src/lib.rs +++ b/polkadot/xcm/xcm-executor/src/lib.rs @@ -36,7 +36,7 @@ use traits::{ }; mod assets; -pub use assets::Assets; +pub use assets::AssetsInHolding; mod config; pub use config::Config; @@ -56,10 +56,10 @@ environmental::environmental!(recursion_count: u8); /// The XCM executor. pub struct XcmExecutor { - holding: Assets, + holding: AssetsInHolding, holding_limit: usize, context: XcmContext, - original_origin: MultiLocation, + original_origin: Location, trader: Config::Trader, /// The most recent error result and instruction index into the fragment in which it occurred, /// if any. @@ -81,10 +81,10 @@ pub struct XcmExecutor { #[cfg(feature = "runtime-benchmarks")] impl XcmExecutor { - pub fn holding(&self) -> &Assets { + pub fn holding(&self) -> &AssetsInHolding { &self.holding } - pub fn set_holding(&mut self, v: Assets) { + pub fn set_holding(&mut self, v: AssetsInHolding) { self.holding = v } pub fn holding_limit(&self) -> &usize { @@ -93,16 +93,16 @@ impl XcmExecutor { pub fn set_holding_limit(&mut self, v: usize) { self.holding_limit = v } - pub fn origin(&self) -> &Option { + pub fn origin(&self) -> &Option { &self.context.origin } - pub fn set_origin(&mut self, v: Option) { + pub fn set_origin(&mut self, v: Option) { self.context.origin = v } - pub fn original_origin(&self) -> &MultiLocation { + pub fn original_origin(&self) -> &Location { &self.original_origin } - pub fn set_original_origin(&mut self, v: MultiLocation) { + pub fn set_original_origin(&mut self, v: Location) { self.original_origin = v } pub fn trader(&self) -> &Config::Trader { @@ -191,14 +191,14 @@ impl ExecuteXcm for XcmExecutor, + origin: impl Into, WeighedMessage(xcm_weight, mut message): WeighedMessage, id: &mut XcmHash, weight_credit: Weight, ) -> Outcome { let origin = origin.into(); log::trace!( - target: "xcm::execute_xcm_in_credit", + target: "xcm::execute", "origin: {origin:?}, message: {message:?}, weight_credit: {weight_credit:?}", ); let mut properties = Properties { weight_credit, message_id: None }; @@ -209,11 +209,11 @@ impl ExecuteXcm for XcmExecutor ExecuteXcm for XcmExecutor ExecuteXcm for XcmExecutor, fees: MultiAssets) -> XcmResult { + fn charge_fees(origin: impl Into, fees: Assets) -> XcmResult { let origin = origin.into(); if !Config::FeeManager::is_waived(Some(&origin), FeeReason::ChargeFees) { for asset in fees.inner() { @@ -275,12 +275,12 @@ impl From for frame_benchmarking::BenchmarkError { } impl XcmExecutor { - pub fn new(origin: impl Into, message_id: XcmHash) -> Self { + pub fn new(origin: impl Into, message_id: XcmHash) -> Self { let origin = origin.into(); Self { - holding: Assets::new(), + holding: AssetsInHolding::new(), holding_limit: Config::MaxAssetsIntoHolding::get() as usize, - context: XcmContext { origin: Some(origin), message_id, topic: None }, + context: XcmContext { origin: Some(origin.clone()), message_id, topic: None }, original_origin: origin, trader: Config::Trader::new(), error: None, @@ -309,7 +309,7 @@ impl XcmExecutor { if !self.holding.is_empty() { log::trace!( - target: "xcm::execute_xcm_in_credit", + target: "xcm::post_process", "Trapping assets in holding register: {:?}, context: {:?} (original_origin: {:?})", self.holding, self.context, self.original_origin, ); @@ -320,28 +320,28 @@ impl XcmExecutor { }; match self.error { - None => Outcome::Complete(weight_used), + None => Outcome::Complete { used: weight_used }, // TODO: #2841 #REALWEIGHT We should deduct the cost of any instructions following // the error which didn't end up being executed. Some((_i, e)) => { - log::trace!(target: "xcm::execute_xcm_in_credit", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); - Outcome::Incomplete(weight_used, e) + log::trace!(target: "xcm::post_process", "Execution errored at {:?}: {:?} (original_origin: {:?})", _i, e, self.original_origin); + Outcome::Incomplete { used: weight_used, error: e } }, } } - fn origin_ref(&self) -> Option<&MultiLocation> { + fn origin_ref(&self) -> Option<&Location> { self.context.origin.as_ref() } - fn cloned_origin(&self) -> Option { - self.context.origin + fn cloned_origin(&self) -> Option { + self.context.origin.clone() } /// Send an XCM, charging fees from Holding as needed. fn send( &mut self, - dest: MultiLocation, + dest: Location, msg: Xcm<()>, reason: FeeReason, ) -> Result { @@ -373,14 +373,14 @@ impl XcmExecutor { r } - fn subsume_asset(&mut self, asset: MultiAsset) -> Result<(), XcmError> { + fn subsume_asset(&mut self, asset: Asset) -> Result<(), XcmError> { // worst-case, holding.len becomes 2 * holding_limit. ensure!(self.holding.len() < self.holding_limit * 2, XcmError::HoldingWouldOverflow); self.holding.subsume(asset); Ok(()) } - fn subsume_assets(&mut self, assets: Assets) -> Result<(), XcmError> { + fn subsume_assets(&mut self, assets: AssetsInHolding) -> Result<(), XcmError> { // worst-case, holding.len becomes 2 * holding_limit. // this guarantees that if holding.len() == holding_limit and you have holding_limit more // items (which has a best case outcome of holding.len() == holding_limit), then you'll @@ -403,8 +403,8 @@ impl XcmExecutor { Ok(()) } - fn take_fee(&mut self, fee: MultiAssets, reason: FeeReason) -> XcmResult { - if Config::FeeManager::is_waived(self.origin_ref(), reason) { + fn take_fee(&mut self, fee: Assets, reason: FeeReason) -> XcmResult { + if Config::FeeManager::is_waived(self.origin_ref(), reason.clone()) { return Ok(()) } log::trace!( @@ -430,13 +430,13 @@ impl XcmExecutor { /// Calculates what `local_querier` would be from the perspective of `destination`. fn to_querier( - local_querier: Option, - destination: &MultiLocation, - ) -> Result, XcmError> { + local_querier: Option, + destination: &Location, + ) -> Result, XcmError> { Ok(match local_querier { None => None, Some(q) => Some( - q.reanchored(&destination, Config::UniversalLocation::get()) + q.reanchored(&destination, &Config::UniversalLocation::get()) .map_err(|_| XcmError::ReanchorFailed)?, ), }) @@ -447,7 +447,7 @@ impl XcmExecutor { /// The `local_querier` argument is the querier (if any) specified from the *local* perspective. fn respond( &mut self, - local_querier: Option, + local_querier: Option, response: Response, info: QueryResponseInfo, fee_reason: FeeReason, @@ -459,36 +459,27 @@ impl XcmExecutor { self.send(destination, message, fee_reason) } - fn try_reanchor( - asset: MultiAsset, - destination: &MultiLocation, - ) -> Result<(MultiAsset, InteriorMultiLocation), XcmError> { + fn try_reanchor( + reanchorable: T, + destination: &Location, + ) -> Result<(T, InteriorLocation), XcmError> { let reanchor_context = Config::UniversalLocation::get(); - let asset = asset - .reanchored(&destination, reanchor_context) - .map_err(|()| XcmError::ReanchorFailed)?; - Ok((asset, reanchor_context)) - } - - fn try_reanchor_multilocation( - location: MultiLocation, - destination: &MultiLocation, - ) -> Result<(MultiLocation, InteriorMultiLocation), XcmError> { - let reanchor_context = Config::UniversalLocation::get(); - let location = location - .reanchored(&destination, reanchor_context) - .map_err(|_| XcmError::ReanchorFailed)?; - Ok((location, reanchor_context)) + let reanchored = + reanchorable.reanchored(&destination, &reanchor_context).map_err(|error| { + log::error!(target: "xcm::reanchor", "Failed reanchoring with error {error:?}"); + XcmError::ReanchorFailed + })?; + Ok((reanchored, reanchor_context)) } /// NOTE: Any assets which were unable to be reanchored are introduced into `failed_bin`. fn reanchored( - mut assets: Assets, - dest: &MultiLocation, - maybe_failed_bin: Option<&mut Assets>, - ) -> MultiAssets { + mut assets: AssetsInHolding, + dest: &Location, + maybe_failed_bin: Option<&mut AssetsInHolding>, + ) -> Assets { let reanchor_context = Config::UniversalLocation::get(); - assets.reanchor(dest, reanchor_context, maybe_failed_bin); + assets.reanchor(dest, &reanchor_context, maybe_failed_bin); assets.into_assets_iter().collect::>().into() } @@ -563,8 +554,8 @@ impl XcmExecutor { ); match instr { WithdrawAsset(assets) => { + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // Take `assets` from the origin account (on-chain) and place in holding. - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; for asset in assets.into_inner().into_iter() { Config::AssetTransactor::withdraw_asset(&asset, &origin, Some(&self.context))?; self.subsume_asset(asset)?; @@ -573,8 +564,8 @@ impl XcmExecutor { }, ReserveAssetDeposited(assets) => { // check whether we trust origin to be our reserve location for this asset. - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; for asset in assets.into_inner().into_iter() { + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // Must ensure that we recognise the asset as being managed by the origin. ensure!( Config::IsReserve::contains(&asset, &origin), @@ -604,14 +595,14 @@ impl XcmExecutor { Config::AssetTransactor::transfer_asset(asset, origin, &dest, &self.context)?; } let reanchor_context = Config::UniversalLocation::get(); - assets.reanchor(&dest, reanchor_context).map_err(|()| XcmError::LocationFull)?; + assets.reanchor(&dest, &reanchor_context).map_err(|()| XcmError::LocationFull)?; let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin]; message.extend(xcm.0.into_iter()); self.send(dest, Xcm(message), FeeReason::TransferReserveAsset)?; Ok(()) }, ReceiveTeleportedAsset(assets) => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; // check whether we trust origin to teleport this asset to us via config trait. for asset in assets.inner() { // We only trust the origin to send us assets that they identify as their @@ -627,6 +618,7 @@ impl XcmExecutor { Config::AssetTransactor::can_check_in(&origin, asset, &self.context)?; } for asset in assets.into_inner().into_iter() { + let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?; Config::AssetTransactor::check_in(&origin, &asset, &self.context); self.subsume_asset(asset)?; } @@ -634,7 +626,7 @@ impl XcmExecutor { }, Transact { origin_kind, require_weight_at_most, mut call } => { // We assume that the Relay-chain is allowed to use transact on this parachain. - let origin = *self.origin_ref().ok_or_else(|| { + let origin = self.cloned_origin().ok_or_else(|| { log::trace!( target: "xcm::process_instruction::transact", "No origin provided", @@ -667,15 +659,17 @@ impl XcmExecutor { return Err(XcmError::NoPermission) } - let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_kind) - .map_err(|_| { - log::trace!( - target: "xcm::process_instruction::transact", - "Failed to convert origin {origin:?} and origin kind {origin_kind:?} to a local origin." - ); + let dispatch_origin = + Config::OriginConverter::convert_origin(origin.clone(), origin_kind).map_err( + |_| { + log::trace!( + target: "xcm::process_instruction::transact", + "Failed to convert origin {origin:?} and origin kind {origin_kind:?} to a local origin." + ); - XcmError::BadOrigin - })?; + XcmError::BadOrigin + }, + )?; log::trace!( target: "xcm::process_instruction::transact", @@ -964,12 +958,12 @@ impl XcmExecutor { UniversalOrigin(new_global) => { let universal_location = Config::UniversalLocation::get(); ensure!(universal_location.first() != Some(&new_global), XcmError::InvalidLocation); - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let origin_xform = (origin, new_global); let ok = Config::UniversalAliases::contains(&origin_xform); ensure!(ok, XcmError::InvalidLocation); let (_, new_global) = origin_xform; - let new_origin = X1(new_global).relative_to(&universal_location); + let new_origin = Junctions::from([new_global]).relative_to(&universal_location); self.context.origin = Some(new_origin); Ok(()) }, @@ -983,7 +977,7 @@ impl XcmExecutor { // // This only works because the remote chain empowers the bridge // to speak for the local network. - let origin = self.context.origin.ok_or(XcmError::BadOrigin)?; + let origin = self.context.origin.as_ref().ok_or(XcmError::BadOrigin)?.clone(); let universal_source = Config::UniversalLocation::get() .within_global(origin) .map_err(|()| XcmError::Unanchored)?; @@ -996,7 +990,7 @@ impl XcmExecutor { network, channel, universal_source, - destination, + destination.clone(), xcm, )?; self.take_fee(fee, FeeReason::Export { network, destination })?; @@ -1004,11 +998,12 @@ impl XcmExecutor { Ok(()) }, LockAsset { asset, unlocker } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let (remote_asset, context) = Self::try_reanchor(asset.clone(), &unlocker)?; - let lock_ticket = Config::AssetLocker::prepare_lock(unlocker, asset, origin)?; + let lock_ticket = + Config::AssetLocker::prepare_lock(unlocker.clone(), asset, origin.clone())?; let owner = - origin.reanchored(&unlocker, context).map_err(|_| XcmError::ReanchorFailed)?; + origin.reanchored(&unlocker, &context).map_err(|_| XcmError::ReanchorFailed)?; let msg = Xcm::<()>(vec![NoteUnlockable { asset: remote_asset, owner }]); let (ticket, price) = validate_send::(unlocker, msg)?; self.take_fee(price, FeeReason::LockAsset)?; @@ -1017,21 +1012,24 @@ impl XcmExecutor { Ok(()) }, UnlockAsset { asset, target } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; Config::AssetLocker::prepare_unlock(origin, asset, target)?.enact()?; Ok(()) }, NoteUnlockable { asset, owner } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; Config::AssetLocker::note_unlockable(origin, asset, owner)?; Ok(()) }, RequestUnlock { asset, locker } => { - let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?; + let origin = self.cloned_origin().ok_or(XcmError::BadOrigin)?; let remote_asset = Self::try_reanchor(asset.clone(), &locker)?.0; - let remote_target = Self::try_reanchor_multilocation(origin, &locker)?.0; - let reduce_ticket = - Config::AssetLocker::prepare_reduce_unlockable(locker, asset, origin)?; + let remote_target = Self::try_reanchor(origin.clone(), &locker)?.0; + let reduce_ticket = Config::AssetLocker::prepare_reduce_unlockable( + locker.clone(), + asset, + origin.clone(), + )?; let msg = Xcm::<()>(vec![UnlockAsset { asset: remote_asset, target: remote_target }]); let (ticket, price) = validate_send::(locker, msg)?; diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs index 0cb188d348d..432a7498ed4 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_exchange.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use xcm::prelude::*; /// A service for exchanging assets. @@ -32,21 +32,21 @@ pub trait AssetExchange { /// least want must be in the set. Some assets originally in `give` may also be in this set. In /// the case of returning an `Err`, then `give` is returned. fn exchange_asset( - origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result; + ) -> Result; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl AssetExchange for Tuple { fn exchange_asset( - origin: Option<&MultiLocation>, - give: Assets, - want: &MultiAssets, + origin: Option<&Location>, + give: AssetsInHolding, + want: &Assets, maximal: bool, - ) -> Result { + ) -> Result { for_tuples!( #( let give = match Tuple::exchange_asset(origin, give, want, maximal) { Ok(r) => return Ok(r), diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs index b5a2b22f5fc..b6270c52945 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_lock.rs @@ -79,9 +79,9 @@ pub trait AssetLock { /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or /// `Self::UnlockTicket`. fn prepare_lock( - unlocker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + unlocker: Location, + asset: Asset, + owner: Location, ) -> Result; /// Prepare to unlock an asset. On success, a `Self::UnlockTicket` it returned, which can be @@ -90,9 +90,9 @@ pub trait AssetLock { /// WARNING: Don't call this with an undropped instance of `Self::LockTicket` or /// `Self::UnlockTicket`. fn prepare_unlock( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result; /// Handler for when a location reports to us that an asset has been locked for us to unlock @@ -102,11 +102,7 @@ pub trait AssetLock { /// sending chain can ensure the lock does not remain. /// /// We should only act upon this message if we believe that the `origin` is honest. - fn note_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, - ) -> Result<(), LockError>; + fn note_unlockable(locker: Location, asset: Asset, owner: Location) -> Result<(), LockError>; /// Handler for when an owner wishes to unlock an asset on a remote chain. /// @@ -115,9 +111,9 @@ pub trait AssetLock { /// /// WARNING: Don't call this with an undropped instance of `Self::ReduceTicket`. fn prepare_reduce_unlockable( - locker: MultiLocation, - asset: MultiAsset, - owner: MultiLocation, + locker: Location, + asset: Asset, + owner: Location, ) -> Result; } @@ -125,27 +121,19 @@ impl AssetLock for () { type LockTicket = Infallible; type UnlockTicket = Infallible; type ReduceTicket = Infallible; - fn prepare_lock( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, - ) -> Result { + fn prepare_lock(_: Location, _: Asset, _: Location) -> Result { Err(LockError::NotApplicable) } - fn prepare_unlock( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, - ) -> Result { + fn prepare_unlock(_: Location, _: Asset, _: Location) -> Result { Err(LockError::NotApplicable) } - fn note_unlockable(_: MultiLocation, _: MultiAsset, _: MultiLocation) -> Result<(), LockError> { + fn note_unlockable(_: Location, _: Asset, _: Location) -> Result<(), LockError> { Err(LockError::NotApplicable) } fn prepare_reduce_unlockable( - _: MultiLocation, - _: MultiAsset, - _: MultiLocation, + _: Location, + _: Asset, + _: Location, ) -> Result { Err(LockError::NotApplicable) } diff --git a/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs b/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs index 5fdc9b15e01..1fca84f36e2 100644 --- a/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs +++ b/polkadot/xcm/xcm-executor/src/traits/asset_transfer.rs @@ -30,7 +30,7 @@ pub enum Error { } /// Specify which type of asset transfer is required for a particular `(asset, dest)` combination. -#[derive(Copy, Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] pub enum TransferType { /// should teleport `asset` to `dest` Teleport, @@ -38,8 +38,8 @@ pub enum TransferType { LocalReserve, /// should reserve-transfer `asset` to `dest`, using `dest` as reserve DestinationReserve, - /// should reserve-transfer `asset` to `dest`, using remote chain `MultiLocation` as reserve - RemoteReserve(MultiLocation), + /// should reserve-transfer `asset` to `dest`, using remote chain `Location` as reserve + RemoteReserve(Location), } /// A trait for identifying asset transfer type based on `IsTeleporter` and `IsReserve` @@ -47,17 +47,17 @@ pub enum TransferType { pub trait XcmAssetTransfers { /// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning /// reserve-based-transfers are to be used for assets matching this filter. - type IsReserve: ContainsPair; + type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are /// to be used for assets matching this filter. - type IsTeleporter: ContainsPair; + type IsTeleporter: ContainsPair; /// How to withdraw and deposit an asset. type AssetTransactor: TransactAsset; /// Determine transfer type to be used for transferring `asset` from local chain to `dest`. - fn determine_for(asset: &MultiAsset, dest: &MultiLocation) -> Result { + fn determine_for(asset: &Asset, dest: &Location) -> Result { if Self::IsTeleporter::contains(asset, dest) { // we trust destination for teleporting asset return Ok(TransferType::Teleport) @@ -67,11 +67,8 @@ pub trait XcmAssetTransfers { } // try to determine reserve location based on asset id/location - let asset_location = match asset.id { - Concrete(location) => Ok(location.chain_location()), - _ => Err(Error::NotConcrete), - }?; - if asset_location == MultiLocation::here() || + let asset_location = asset.id.0.chain_location(); + if asset_location == Location::here() || Self::IsTeleporter::contains(asset, &asset_location) { // if the asset is local, then it's a local reserve diff --git a/polkadot/xcm/xcm-executor/src/traits/conversion.rs b/polkadot/xcm/xcm-executor/src/traits/conversion.rs index 1fcdf214057..9e2f4c83997 100644 --- a/polkadot/xcm/xcm-executor/src/traits/conversion.rs +++ b/polkadot/xcm/xcm-executor/src/traits/conversion.rs @@ -22,12 +22,12 @@ use xcm::latest::prelude::*; /// Means of converting a location into an account identifier. pub trait ConvertLocation { /// Convert the `location` into `Some` account ID, or `None` if not possible. - fn convert_location(location: &MultiLocation) -> Option; + fn convert_location(location: &Location) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ConvertLocation for Tuple { - fn convert_location(l: &MultiLocation) -> Option { + fn convert_location(l: &Location) -> Option { for_tuples!( #( match Tuple::convert_location(l) { Some(result) => return Some(result), @@ -45,15 +45,15 @@ impl ConvertLocation for Tuple { /// different `origin` of type `Origin` which is passed to the next convert item. /// /// ```rust -/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind}; +/// # use xcm::latest::{Location, Junctions, Junction, OriginKind}; /// # use staging_xcm_executor::traits::ConvertOrigin; /// // A convertor that will bump the para id and pass it to the next one. /// struct BumpParaId; /// impl ConvertOrigin for BumpParaId { -/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { -/// match origin.into() { -/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } => { -/// Err(Junctions::X1(Junction::Parachain(id + 1)).into()) +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// match origin.into().unpack() { +/// (0, [Junction::Parachain(id)]) => { +/// Err([Junction::Parachain(id + 1)].into()) /// } /// _ => unreachable!() /// } @@ -62,17 +62,18 @@ impl ConvertLocation for Tuple { /// /// struct AcceptPara7; /// impl ConvertOrigin for AcceptPara7 { -/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { -/// match origin.into() { -/// MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } if id == 7 => { +/// fn convert_origin(origin: impl Into, _: OriginKind) -> Result { +/// let origin = origin.into(); +/// match origin.unpack() { +/// (0, [Junction::Parachain(id)]) if *id == 7 => { /// Ok(7) /// } -/// o => Err(o) +/// _ => Err(origin) /// } /// } /// } /// # fn main() { -/// let origin: MultiLocation = Junctions::X1(Junction::Parachain(6)).into(); +/// let origin: Location = [Junction::Parachain(6)].into(); /// assert!( /// <(BumpParaId, AcceptPara7) as ConvertOrigin>::convert_origin(origin, OriginKind::Native) /// .is_ok() @@ -81,18 +82,12 @@ impl ConvertLocation for Tuple { /// ``` pub trait ConvertOrigin { /// Attempt to convert `origin` to the generic `Origin` whilst consuming it. - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result; + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl ConvertOrigin for Tuple { - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result { + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result { for_tuples!( #( let origin = match Tuple::convert_origin(origin, kind) { Err(o) => o, diff --git a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs index 9753f3a4213..339d485d979 100644 --- a/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs +++ b/polkadot/xcm/xcm-executor/src/traits/drop_assets.rs @@ -14,28 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use core::marker::PhantomData; use frame_support::traits::Contains; -use xcm::latest::{MultiAssets, MultiLocation, Weight, XcmContext}; +use xcm::latest::{Assets, Location, Weight, XcmContext}; -/// Define a handler for when some non-empty `Assets` value should be dropped. +/// Define a handler for when some non-empty `AssetsInHolding` value should be dropped. pub trait DropAssets { /// Handler for receiving dropped assets. Returns the weight consumed by this operation. - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight; + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight; } impl DropAssets for () { - fn drop_assets(_origin: &MultiLocation, _assets: Assets, _context: &XcmContext) -> Weight { + fn drop_assets(_origin: &Location, _assets: AssetsInHolding, _context: &XcmContext) -> Weight { Weight::zero() } } /// Morph a given `DropAssets` implementation into one which can filter based on assets. This can -/// be used to ensure that `Assets` values which hold no value are ignored. +/// be used to ensure that `AssetsInHolding` values which hold no value are ignored. pub struct FilterAssets(PhantomData<(D, A)>); -impl> DropAssets for FilterAssets { - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { +impl> DropAssets for FilterAssets { + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight { if A::contains(&assets) { D::drop_assets(origin, assets, context) } else { @@ -49,8 +49,8 @@ impl> DropAssets for FilterAssets { /// asset trap facility don't get to use it. pub struct FilterOrigin(PhantomData<(D, O)>); -impl> DropAssets for FilterOrigin { - fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight { +impl> DropAssets for FilterOrigin { + fn drop_assets(origin: &Location, assets: AssetsInHolding, context: &XcmContext) -> Weight { if O::contains(origin) { D::drop_assets(origin, assets, context) } else { @@ -64,9 +64,9 @@ pub trait ClaimAssets { /// Claim any assets available to `origin` and return them in a single `Assets` value, together /// with the weight used by this operation. fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, context: &XcmContext, ) -> bool; } @@ -74,9 +74,9 @@ pub trait ClaimAssets { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ClaimAssets for Tuple { fn claim_assets( - origin: &MultiLocation, - ticket: &MultiLocation, - what: &MultiAssets, + origin: &Location, + ticket: &Location, + what: &Assets, context: &XcmContext, ) -> bool { for_tuples!( #( diff --git a/polkadot/xcm/xcm-executor/src/traits/export.rs b/polkadot/xcm/xcm-executor/src/traits/export.rs index 7aeccd44566..78aa68ce264 100644 --- a/polkadot/xcm/xcm-executor/src/traits/export.rs +++ b/polkadot/xcm/xcm-executor/src/traits/export.rs @@ -51,8 +51,8 @@ pub trait ExportXcm { fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult; @@ -71,11 +71,11 @@ impl ExportXcm for Tuple { fn validate( network: NetworkId, channel: u32, - universal_source: &mut Option, - destination: &mut Option, + universal_source: &mut Option, + destination: &mut Option, message: &mut Option>, ) -> SendResult { - let mut maybe_cost: Option = None; + let mut maybe_cost: Option = None; let one_ticket: Self::Ticket = (for_tuples! { #( if maybe_cost.is_some() { None @@ -112,8 +112,8 @@ impl ExportXcm for Tuple { pub fn validate_export( network: NetworkId, channel: u32, - universal_source: InteriorMultiLocation, - dest: InteriorMultiLocation, + universal_source: InteriorLocation, + dest: InteriorLocation, msg: Xcm<()>, ) -> SendResult { T::validate(network, channel, &mut Some(universal_source), &mut Some(dest), &mut Some(msg)) @@ -130,10 +130,10 @@ pub fn validate_export( pub fn export_xcm( network: NetworkId, channel: u32, - universal_source: InteriorMultiLocation, - dest: InteriorMultiLocation, + universal_source: InteriorLocation, + dest: InteriorLocation, msg: Xcm<()>, -) -> Result<(XcmHash, MultiAssets), SendError> { +) -> Result<(XcmHash, Assets), SendError> { let (ticket, price) = T::validate( network, channel, diff --git a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs index d7146457f3b..b6e303daaad 100644 --- a/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs +++ b/polkadot/xcm/xcm-executor/src/traits/fee_manager.rs @@ -19,15 +19,15 @@ use xcm::prelude::*; /// Handle stuff to do with taking fees in certain XCM instructions. pub trait FeeManager { /// Determine if a fee should be waived. - fn is_waived(origin: Option<&MultiLocation>, r: FeeReason) -> bool; + fn is_waived(origin: Option<&Location>, r: FeeReason) -> bool; /// Do something with the fee which has been paid. Doing nothing here silently burns the /// fees. - fn handle_fee(fee: MultiAssets, context: Option<&XcmContext>, r: FeeReason); + fn handle_fee(fee: Assets, context: Option<&XcmContext>, r: FeeReason); } /// Context under which a fee is paid. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum FeeReason { /// When a reporting instruction is called. Report, @@ -42,7 +42,7 @@ pub enum FeeReason { /// When the `QueryPallet` instruction is called. QueryPallet, /// When the `ExportMessage` instruction is called (and includes the network ID). - Export { network: NetworkId, destination: InteriorMultiLocation }, + Export { network: NetworkId, destination: InteriorLocation }, /// The `charge_fees` API. ChargeFees, /// When the `LockAsset` instruction is called. @@ -52,9 +52,9 @@ pub enum FeeReason { } impl FeeManager for () { - fn is_waived(_: Option<&MultiLocation>, _: FeeReason) -> bool { + fn is_waived(_: Option<&Location>, _: FeeReason) -> bool { false } - fn handle_fee(_: MultiAssets, _: Option<&XcmContext>, _: FeeReason) {} + fn handle_fee(_: Assets, _: Option<&XcmContext>, _: FeeReason) {} } diff --git a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs index b162a8b0729..5d0c32890be 100644 --- a/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs +++ b/polkadot/xcm/xcm-executor/src/traits/filter_asset_location.rs @@ -15,21 +15,21 @@ // along with Polkadot. If not, see . use frame_support::traits::ContainsPair; -use xcm::latest::{MultiAsset, MultiLocation}; +use xcm::latest::{Asset, Location}; /// Filters assets/location pairs. /// /// Can be amalgamated into tuples. If any item returns `true`, it short-circuits, else `false` is /// returned. -#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] +#[deprecated = "Use `frame_support::traits::ContainsPair` instead"] pub trait FilterAssetLocation { /// A filter to distinguish between asset/location pairs. - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool; + fn contains(asset: &Asset, origin: &Location) -> bool; } #[allow(deprecated)] -impl> FilterAssetLocation for T { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { +impl> FilterAssetLocation for T { + fn contains(asset: &Asset, origin: &Location) -> bool { T::contains(asset, origin) } } diff --git a/polkadot/xcm/xcm-executor/src/traits/on_response.rs b/polkadot/xcm/xcm-executor/src/traits/on_response.rs index ea41f242a97..952bd2d0040 100644 --- a/polkadot/xcm/xcm-executor/src/traits/on_response.rs +++ b/polkadot/xcm/xcm-executor/src/traits/on_response.rs @@ -24,42 +24,34 @@ use parity_scale_codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use sp_arithmetic::traits::Zero; use sp_std::fmt::Debug; use xcm::latest::{ - Error as XcmError, InteriorMultiLocation, MultiLocation, QueryId, Response, - Result as XcmResult, Weight, XcmContext, + Error as XcmError, InteriorLocation, Location, QueryId, Response, Result as XcmResult, Weight, + XcmContext, }; /// Define what needs to be done upon receiving a query response. pub trait OnResponse { /// Returns `true` if we are expecting a response from `origin` for query `query_id` that was /// queried by `querier`. - fn expecting_response( - origin: &MultiLocation, - query_id: u64, - querier: Option<&MultiLocation>, - ) -> bool; + fn expecting_response(origin: &Location, query_id: u64, querier: Option<&Location>) -> bool; /// Handler for receiving a `response` from `origin` relating to `query_id` initiated by /// `querier`. fn on_response( - origin: &MultiLocation, + origin: &Location, query_id: u64, - querier: Option<&MultiLocation>, + querier: Option<&Location>, response: Response, max_weight: Weight, context: &XcmContext, ) -> Weight; } impl OnResponse for () { - fn expecting_response( - _origin: &MultiLocation, - _query_id: u64, - _querier: Option<&MultiLocation>, - ) -> bool { + fn expecting_response(_origin: &Location, _query_id: u64, _querier: Option<&Location>) -> bool { false } fn on_response( - _origin: &MultiLocation, + _origin: &Location, _query_id: u64, - _querier: Option<&MultiLocation>, + _querier: Option<&Location>, _response: Response, _max_weight: Weight, _context: &XcmContext, @@ -79,7 +71,7 @@ pub trait VersionChangeNotifier { /// If the `location` has an ongoing notification and when this function is called, then an /// error should be returned. fn start( - location: &MultiLocation, + location: &Location, query_id: QueryId, max_weight: Weight, context: &XcmContext, @@ -87,20 +79,20 @@ pub trait VersionChangeNotifier { /// Stop notifying `location` should the XCM change. Returns an error if there is no existing /// notification set up. - fn stop(location: &MultiLocation, context: &XcmContext) -> XcmResult; + fn stop(location: &Location, context: &XcmContext) -> XcmResult; /// Return true if a location is subscribed to XCM version changes. - fn is_subscribed(location: &MultiLocation) -> bool; + fn is_subscribed(location: &Location) -> bool; } impl VersionChangeNotifier for () { - fn start(_: &MultiLocation, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { + fn start(_: &Location, _: QueryId, _: Weight, _: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } - fn stop(_: &MultiLocation, _: &XcmContext) -> XcmResult { + fn stop(_: &Location, _: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } - fn is_subscribed(_: &MultiLocation) -> bool { + fn is_subscribed(_: &Location) -> bool { false } } @@ -134,13 +126,13 @@ pub trait QueryHandler { + Copy; type BlockNumber: Zero + Encode; type Error; - type UniversalLocation: Get; + type UniversalLocation: Get; /// Attempt to create a new query ID and register it as a query that is yet to respond. fn new_query( - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, - match_querier: impl Into, + match_querier: impl Into, ) -> QueryId; /// Consume `message` and return another which is equivalent to it except that it reports @@ -157,7 +149,7 @@ pub trait QueryHandler { /// The response can be queried with `take_response`. fn report_outcome( message: &mut Xcm<()>, - responder: impl Into, + responder: impl Into, timeout: Self::BlockNumber, ) -> result::Result; @@ -170,7 +162,7 @@ pub trait QueryHandler { } parameter_types! { - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; } impl QueryHandler for () { @@ -183,16 +175,16 @@ impl QueryHandler for () { QueryResponseStatus::NotFound } fn new_query( - _responder: impl Into, + _responder: impl Into, _timeout: Self::BlockNumber, - _match_querier: impl Into, + _match_querier: impl Into, ) -> Self::QueryId { 0u64 } fn report_outcome( _message: &mut Xcm<()>, - _responder: impl Into, + _responder: impl Into, _timeout: Self::BlockNumber, ) -> Result { Err(()) diff --git a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs index d85458b5470..449e82b5a6e 100644 --- a/polkadot/xcm/xcm-executor/src/traits/should_execute.rs +++ b/polkadot/xcm/xcm-executor/src/traits/should_execute.rs @@ -16,7 +16,7 @@ use frame_support::traits::ProcessMessageError; use sp_std::result::Result; -use xcm::latest::{Instruction, MultiLocation, Weight, XcmHash}; +use xcm::latest::{Instruction, Location, Weight, XcmHash}; /// Properyies of an XCM message and its imminent execution. #[derive(Clone, Eq, PartialEq, Debug)] @@ -43,7 +43,7 @@ pub trait ShouldExecute { /// - `properties`: Various pre-established properties of the message which may be mutated by /// this API. fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -53,7 +53,7 @@ pub trait ShouldExecute { #[impl_trait_for_tuples::impl_for_tuples(30)] impl ShouldExecute for Tuple { fn should_execute( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -87,7 +87,7 @@ impl ShouldExecute for Tuple { /// if any of the tuple elements returns true. pub trait CheckSuspension { fn is_suspended( - origin: &MultiLocation, + origin: &Location, instructions: &mut [Instruction], max_weight: Weight, properties: &mut Properties, @@ -97,7 +97,7 @@ pub trait CheckSuspension { #[impl_trait_for_tuples::impl_for_tuples(30)] impl CheckSuspension for Tuple { fn is_suspended( - origin: &MultiLocation, + origin: &Location, instruction: &mut [Instruction], max_weight: Weight, properties: &mut Properties, diff --git a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs index ad65a863021..e9a7e3ad845 100644 --- a/polkadot/xcm/xcm-executor/src/traits/token_matching.rs +++ b/polkadot/xcm/xcm-executor/src/traits/token_matching.rs @@ -18,12 +18,12 @@ use sp_std::result; use xcm::latest::prelude::*; pub trait MatchesFungible { - fn matches_fungible(a: &MultiAsset) -> Option; + fn matches_fungible(a: &Asset) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesFungible for Tuple { - fn matches_fungible(a: &MultiAsset) -> Option { + fn matches_fungible(a: &Asset) -> Option { for_tuples!( #( match Tuple::matches_fungible(a) { o @ Some(_) => return o, _ => () } )* ); @@ -33,12 +33,12 @@ impl MatchesFungible for Tuple { } pub trait MatchesNonFungible { - fn matches_nonfungible(a: &MultiAsset) -> Option; + fn matches_nonfungible(a: &Asset) -> Option; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesNonFungible for Tuple { - fn matches_nonfungible(a: &MultiAsset) -> Option { + fn matches_nonfungible(a: &Asset) -> Option { for_tuples!( #( match Tuple::matches_nonfungible(a) { o @ Some(_) => return o, _ => () } )* ); @@ -52,11 +52,11 @@ impl MatchesNonFungible for Tuple { pub enum Error { /// The given asset is not handled. (According to [`XcmError::AssetNotFound`]) AssetNotHandled, - /// `MultiLocation` to `AccountId` conversion failed. + /// `Location` to `AccountId` conversion failed. AccountIdConversionFailed, /// `u128` amount to currency `Balance` conversion failed. AmountToBalanceConversionFailed, - /// `MultiLocation` to `AssetId`/`ClassId` conversion failed. + /// `Location` to `AssetId`/`ClassId` conversion failed. AssetIdConversionFailed, /// `AssetInstance` to non-fungibles instance ID conversion failed. InstanceConversionFailed, @@ -77,12 +77,12 @@ impl From for XcmError { } pub trait MatchesFungibles { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error>; + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), Error>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesFungibles for Tuple { - fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> { + fn matches_fungibles(a: &Asset) -> result::Result<(AssetId, Balance), Error> { for_tuples!( #( match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () } )* ); @@ -92,12 +92,12 @@ impl MatchesFungibles for Tuple { } pub trait MatchesNonFungibles { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error>; + fn matches_nonfungibles(a: &Asset) -> result::Result<(AssetId, Instance), Error>; } #[impl_trait_for_tuples::impl_for_tuples(30)] impl MatchesNonFungibles for Tuple { - fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(AssetId, Instance), Error> { + fn matches_nonfungibles(a: &Asset) -> result::Result<(AssetId, Instance), Error> { for_tuples!( #( match Tuple::matches_nonfungibles(a) { o @ Ok(_) => return o, _ => () } )* ); diff --git a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs index c51befff88a..e8a52d82568 100644 --- a/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs +++ b/polkadot/xcm/xcm-executor/src/traits/transact_asset.rs @@ -14,14 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use sp_std::result::Result; -use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult, XcmContext}; +use xcm::latest::{Asset, Error as XcmError, Location, Result as XcmResult, XcmContext}; /// Facility for asset transacting. /// /// This should work with as many asset/location combinations as possible. Locations to support may -/// include non-account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different +/// include non-account locations such as a `[Junction::Parachain]`. Different /// chains may handle them in different ways. /// /// Can be amalgamated as a tuple of items that implement this trait. In such executions, if any of @@ -31,11 +31,7 @@ pub trait TransactAsset { /// Ensure that `check_in` will do as expected. /// /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } @@ -56,16 +52,12 @@ pub trait TransactAsset { /// When composed as a tuple, all type-items are called. It is up to the implementer that there /// exists no value for `_what` which can cause side-effects for more than one of the /// type-items. - fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + fn check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) {} /// Ensure that `check_out` will do as expected. /// /// When composed as a tuple, all type-items are called and at least one must result in `Ok`. - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Unimplemented) } @@ -82,16 +74,12 @@ pub trait TransactAsset { /// When composed as a tuple, all type-items are called. It is up to the implementer that there /// exists no value for `_what` which can cause side-effects for more than one of the /// type-items. - fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {} + fn check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) {} /// Deposit the `what` asset into the account of `who`. /// /// Implementations should return `XcmError::FailedToTransactAsset` if deposit failed. - fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, - _context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { Err(XcmError::Unimplemented) } @@ -104,10 +92,10 @@ pub trait TransactAsset { /// /// Implementations should return `XcmError::FailedToTransactAsset` if withdraw failed. fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::Unimplemented) } @@ -121,11 +109,11 @@ pub trait TransactAsset { /// turn has a default implementation that calls `internal_transfer_asset`. As such, **please /// do not call this method directly unless you know what you're doing**. fn internal_transfer_asset( - _asset: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _asset: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::Unimplemented) } @@ -134,11 +122,11 @@ pub trait TransactAsset { /// Attempts to use `internal_transfer_asset` and if not available then falls back to using a /// two-part withdraw/deposit. fn transfer_asset( - asset: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + asset: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> Result { + ) -> Result { match Self::internal_transfer_asset(asset, from, to, context) { Err(XcmError::AssetNotFound | XcmError::Unimplemented) => { let assets = Self::withdraw_asset(asset, from, Some(context))?; @@ -153,7 +141,7 @@ pub trait TransactAsset { #[impl_trait_for_tuples::impl_for_tuples(30)] impl TransactAsset for Tuple { - fn can_check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_in(origin: &Location, what: &Asset, context: &XcmContext) -> XcmResult { for_tuples!( #( match Tuple::can_check_in(origin, what, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -170,13 +158,13 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn check_in(origin: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_in(origin: &Location, what: &Asset, context: &XcmContext) { for_tuples!( #( Tuple::check_in(origin, what, context); )* ); } - fn can_check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) -> XcmResult { + fn can_check_out(dest: &Location, what: &Asset, context: &XcmContext) -> XcmResult { for_tuples!( #( match Tuple::can_check_out(dest, what, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -193,17 +181,13 @@ impl TransactAsset for Tuple { Err(XcmError::AssetNotFound) } - fn check_out(dest: &MultiLocation, what: &MultiAsset, context: &XcmContext) { + fn check_out(dest: &Location, what: &Asset, context: &XcmContext) { for_tuples!( #( Tuple::check_out(dest, what, context); )* ); } - fn deposit_asset( - what: &MultiAsset, - who: &MultiLocation, - context: Option<&XcmContext>, - ) -> XcmResult { + fn deposit_asset(what: &Asset, who: &Location, context: Option<&XcmContext>) -> XcmResult { for_tuples!( #( match Tuple::deposit_asset(what, who, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -221,10 +205,10 @@ impl TransactAsset for Tuple { } fn withdraw_asset( - what: &MultiAsset, - who: &MultiLocation, + what: &Asset, + who: &Location, maybe_context: Option<&XcmContext>, - ) -> Result { + ) -> Result { for_tuples!( #( match Tuple::withdraw_asset(what, who, maybe_context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -242,11 +226,11 @@ impl TransactAsset for Tuple { } fn internal_transfer_asset( - what: &MultiAsset, - from: &MultiLocation, - to: &MultiLocation, + what: &Asset, + from: &Location, + to: &Location, context: &XcmContext, - ) -> Result { + ) -> Result { for_tuples!( #( match Tuple::internal_transfer_asset(what, from, to, context) { Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (), @@ -275,133 +259,109 @@ mod tests { pub struct NotFoundTransactor; impl TransactAsset for NotFoundTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::AssetNotFound) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::AssetNotFound) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::AssetNotFound) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::AssetNotFound) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::AssetNotFound) } } pub struct OverflowTransactor; impl TransactAsset for OverflowTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Overflow) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Err(XcmError::Overflow) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Err(XcmError::Overflow) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { + ) -> Result { Err(XcmError::Overflow) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { + ) -> Result { Err(XcmError::Overflow) } } pub struct SuccessfulTransactor; impl TransactAsset for SuccessfulTransactor { - fn can_check_in( - _origin: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_in(_origin: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } - fn can_check_out( - _dest: &MultiLocation, - _what: &MultiAsset, - _context: &XcmContext, - ) -> XcmResult { + fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult { Ok(()) } fn deposit_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, ) -> XcmResult { Ok(()) } fn withdraw_asset( - _what: &MultiAsset, - _who: &MultiLocation, + _what: &Asset, + _who: &Location, _context: Option<&XcmContext>, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } fn internal_transfer_asset( - _what: &MultiAsset, - _from: &MultiLocation, - _to: &MultiLocation, + _what: &Asset, + _from: &Location, + _to: &Location, _context: &XcmContext, - ) -> Result { - Ok(Assets::default()) + ) -> Result { + Ok(AssetsInHolding::default()) } } diff --git a/polkadot/xcm/xcm-executor/src/traits/weight.rs b/polkadot/xcm/xcm-executor/src/traits/weight.rs index bc40c10074f..efb9a2dfb6e 100644 --- a/polkadot/xcm/xcm-executor/src/traits/weight.rs +++ b/polkadot/xcm/xcm-executor/src/traits/weight.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use crate::Assets; +use crate::AssetsInHolding; use sp_std::result::Result; use xcm::latest::{prelude::*, Weight}; @@ -33,7 +33,7 @@ pub trait WeightBounds { /// message. pub trait UniversalWeigher { /// Get the upper limit of weight required for `dest` to execute `message`. - fn weigh(dest: impl Into, message: Xcm<()>) -> Result; + fn weigh(dest: impl Into, message: Xcm<()>) -> Result; } /// Charge for weight in order to execute XCM. @@ -52,15 +52,15 @@ pub trait WeightTrader: Sized { fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result; + ) -> Result; /// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight /// was purchased using `buy_weight`. /// /// Default implementation refunds nothing. - fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { + fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option { None } } @@ -74,9 +74,9 @@ impl WeightTrader for Tuple { fn buy_weight( &mut self, weight: Weight, - payment: Assets, + payment: AssetsInHolding, context: &XcmContext, - ) -> Result { + ) -> Result { let mut too_expensive_error_found = false; let mut last_error = None; for_tuples!( #( @@ -102,7 +102,7 @@ impl WeightTrader for Tuple { }) } - fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { + fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option { for_tuples!( #( if let Some(asset) = Tuple.refund_weight(weight, context) { return Some(asset); diff --git a/polkadot/xcm/xcm-simulator/example/src/lib.rs b/polkadot/xcm/xcm-simulator/example/src/lib.rs index 85b8ad1c5cb..d134957fbc1 100644 --- a/polkadot/xcm/xcm-simulator/example/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/example/src/lib.rs @@ -148,7 +148,7 @@ mod tests { use xcm_simulator::TestExt; // Helper function for forming buy execution message - fn buy_execution(fees: impl Into) -> Instruction { + fn buy_execution(fees: impl Into) -> Instruction { BuyExecution { fees: fees.into(), weight_limit: Unlimited } } @@ -642,7 +642,7 @@ mod tests { parachain::MsgQueue::received_dmp(), vec![Xcm(vec![QueryResponse { query_id: query_id_set, - response: Response::Assets(MultiAssets::new()), + response: Response::Assets(Assets::new()), max_weight: Weight::from_parts(1_000_000_000, 1024 * 1024), querier: Some(Here.into()), }])], diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs index 69db81deff4..0b6c573f464 100644 --- a/polkadot/xcm/xcm-simulator/example/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs @@ -115,8 +115,8 @@ impl pallet_balances::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] pub struct UniquesHelper; #[cfg(feature = "runtime-benchmarks")] -impl pallet_uniques::BenchmarkHelper for UniquesHelper { - fn collection(i: u16) -> MultiLocation { +impl pallet_uniques::BenchmarkHelper for UniquesHelper { + fn collection(i: u16) -> Location { GeneralIndex(i as u128).into() } fn item(i: u16) -> AssetInstance { @@ -126,7 +126,7 @@ impl pallet_uniques::BenchmarkHelper for UniquesHe impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = MultiLocation; + type CollectionId = Location; type ItemId = AssetInstance; type Currency = Balances; type CreateOrigin = ForeignCreators; @@ -148,12 +148,12 @@ impl pallet_uniques::Config for Runtime { // `EnsureOriginWithArg` impl for `CreateOrigin` which allows only XCM origins // which are locations containing the class location. pub struct ForeignCreators; -impl EnsureOriginWithArg for ForeignCreators { +impl EnsureOriginWithArg for ForeignCreators { type Success = AccountId; fn try_origin( o: RuntimeOrigin, - a: &MultiLocation, + a: &Location, ) -> sp_std::result::Result { let origin_location = pallet_xcm::EnsureXcm::::try_origin(o.clone())?; if !a.starts_with(&origin_location) { @@ -163,8 +163,8 @@ impl EnsureOriginWithArg for ForeignCreators { } #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(a: &MultiLocation) -> Result { - Ok(pallet_xcm::Origin::Xcm(*a).into()) + fn try_successful_origin(a: &Location) -> Result { + Ok(pallet_xcm::Origin::Xcm(a.clone()).into()) } } @@ -174,9 +174,9 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const KsmLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type LocationToAccountId = ( @@ -194,17 +194,17 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub ForeignPrefix: MultiLocation = (Parent,).into(); + pub ForeignPrefix: Location = (Parent,).into(); } pub type LocalAssetTransactor = ( FungibleAdapter, LocationToAccountId, AccountId, ()>, NonFungiblesAdapter< ForeignUniques, - ConvertedConcreteId, + ConvertedConcreteId, SovereignAccountOf, AccountId, NoChecking, @@ -216,9 +216,9 @@ pub type XcmRouter = super::ParachainXcmRouter; pub type Barrier = AllowUnpaidExecutionFrom; parameter_types! { - pub NftCollectionOne: MultiAssetFilter - = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); - pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) = (NftCollectionOne::get(), (Parent,).into()); } pub type TrustedTeleporters = xcm_builder::Case; @@ -321,16 +321,23 @@ pub mod mock_msg_queue { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { let location = (Parent, Parachain(sender.into())); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -371,7 +378,7 @@ pub mod mock_msg_queue { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); match maybe_versioned { Err(_) => { @@ -380,7 +387,13 @@ pub mod mock_msg_queue { Ok(versioned) => match Xcm::try_from(versioned) { Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), Ok(x) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, @@ -400,17 +413,15 @@ impl mock_msg_queue::Config for Runtime { pub type LocalOriginToLocation = SignedToAccountId32; pub struct TrustedLockerCase(PhantomData); -impl> ContainsPair - for TrustedLockerCase -{ - fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { let (o, a) = T::get(); a.matches(asset) && &o == origin } } parameter_types! { - pub RelayTokenForRelay: (MultiLocation, MultiAssetFilter) = (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); + pub RelayTokenForRelay: (Location, AssetFilter) = (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); } pub type TrustedLockers = TrustedLockerCase; diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 24fc56eb717..1bcbe6da2cd 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -127,10 +127,10 @@ impl configuration::Config for Runtime { } parameter_types! { - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); pub RelayNetwork: NetworkId = ByGenesis([0; 32]); pub const AnyNetwork: Option = None; - pub UniversalLocation: InteriorMultiLocation = Here; + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; } @@ -162,7 +162,7 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); pub TokensPerSecondPerByte: (AssetId, u128, u128) = - (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs index 0893c7c086f..7026d5467c8 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/fuzz.rs @@ -158,7 +158,7 @@ fn run_input(xcm_messages: [XcmMessage; 5]) { if xcm_message.source % 4 == 0 { // We get the destination for the message let parachain_id = (xcm_message.destination % 3) + 1; - let destination: MultiLocation = Parachain(parachain_id).into(); + let destination: Location = Parachain(parachain_id).into(); #[cfg(not(fuzzing))] { println!(" source: Relay Chain"); @@ -176,7 +176,7 @@ fn run_input(xcm_messages: [XcmMessage; 5]) { _ => ParaC::execute_with, }; // We get the destination for the message - let destination: MultiLocation = match xcm_message.destination % 4 { + let destination: Location = match xcm_message.destination % 4 { n @ 1..=3 => (Parent, Parachain(n)).into(), _ => Parent.into(), }; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index 2262d18e860..41fc5af9708 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -109,9 +109,9 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); + pub const KsmLocation: Location = Location::parent(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type LocationToAccountId = ( @@ -128,7 +128,7 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const UnitWeightCost: Weight = Weight::from_parts(1, 1); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1, 1); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } @@ -237,16 +237,23 @@ pub mod mock_msg_queue { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let mut message_hash = xcm.using_encoded(sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { - let location = MultiLocation::new(1, X1(Parachain(sender.into()))); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + let location = Location::new(1, [Parachain(sender.into())]); + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -287,7 +294,7 @@ pub mod mock_msg_queue { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_msg = VersionedXcm::::decode(&mut &data[..]) .map(Xcm::::try_from); match maybe_msg { @@ -298,7 +305,13 @@ pub mod mock_msg_queue { Self::deposit_event(Event::UnsupportedVersion(id)); }, Ok(Ok(x)) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index bbf4f1e6cc5..c066cc5e813 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -107,10 +107,10 @@ impl configuration::Config for Runtime { } parameter_types! { - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const TokenLocation: Location = Here.into_location(); pub const ThisNetwork: NetworkId = NetworkId::ByGenesis([0; 32]); pub const AnyNetwork: Option = None; - pub const UniversalLocation: InteriorMultiLocation = Here; + pub const UniversalLocation: InteriorLocation = Here; } pub type SovereignAccountOf = @@ -129,7 +129,7 @@ type LocalOriginConverter = ( parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000); - pub KsmPerSecondPerByte: (AssetId, u128, u128) = (Concrete(TokenLocation::get()), 1, 1); + pub KsmPerSecondPerByte: (AssetId, u128, u128) = (AssetId(TokenLocation::get()), 1, 1); pub const MaxInstructions: u32 = u32::MAX; pub const MaxAssetsIntoHolding: u32 = 64; } diff --git a/polkadot/xcm/xcm-simulator/src/lib.rs b/polkadot/xcm/xcm-simulator/src/lib.rs index b38465b3d4a..7efbc658bbf 100644 --- a/polkadot/xcm/xcm-simulator/src/lib.rs +++ b/polkadot/xcm/xcm-simulator/src/lib.rs @@ -258,9 +258,9 @@ macro_rules! __impl_ext { } thread_local! { - pub static PARA_MESSAGE_BUS: RefCell)>> + pub static PARA_MESSAGE_BUS: RefCell)>> = RefCell::new(VecDeque::new()); - pub static RELAY_MESSAGE_BUS: RefCell)>> + pub static RELAY_MESSAGE_BUS: RefCell)>> = RefCell::new(VecDeque::new()); } @@ -318,8 +318,8 @@ macro_rules! decl_test_network { while let Some((para_id, destination, message)) = $crate::PARA_MESSAGE_BUS.with( |b| b.borrow_mut().pop_front()) { - match destination.interior() { - $crate::Junctions::Here if destination.parent_count() == 1 => { + match destination.unpack() { + (1, []) => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump); let mut _id = [0; 32]; let r = <$relay_chain>::process_message( @@ -336,7 +336,7 @@ macro_rules! decl_test_network { } }, $( - $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 1 => { + (1, [$crate::Parachain(id)]) if *id == $para_id => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp); let messages = vec![(para_id, 1, &encoded[..])]; let _weight = <$parachain>::handle_xcmp_messages( @@ -360,9 +360,9 @@ macro_rules! decl_test_network { while let Some((destination, message)) = $crate::RELAY_MESSAGE_BUS.with( |b| b.borrow_mut().pop_front()) { - match destination.interior() { + match destination.unpack() { $( - $crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 0 => { + (0, [$crate::Parachain(id)]) if *id == $para_id => { let encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp); // NOTE: RelayChainBlockNumber is hard-coded to 1 let messages = vec![(1, encoded)]; @@ -382,18 +382,18 @@ macro_rules! decl_test_network { pub struct ParachainXcmRouter($crate::PhantomData); impl> $crate::SendXcm for ParachainXcmRouter { - type Ticket = ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>); + type Ticket = ($crate::ParaId, $crate::Location, $crate::Xcm<()>); fn validate( - destination: &mut Option<$crate::MultiLocation>, + destination: &mut Option<$crate::Location>, message: &mut Option<$crate::Xcm<()>>, - ) -> $crate::SendResult<($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>)> { + ) -> $crate::SendResult<($crate::ParaId, $crate::Location, $crate::Xcm<()>)> { use $crate::XcmpMessageHandlerT; let d = destination.take().ok_or($crate::SendError::MissingArgument)?; - match (d.interior(), d.parent_count()) { - ($crate::Junctions::Here, 1) => {}, + match d.unpack() { + (1, []) => {}, $( - ($crate::X1($crate::Parachain(id)), 1) if id == &$para_id => {} + (1, [$crate::Parachain(id)]) if id == &$para_id => {} )* _ => { *destination = Some(d); @@ -401,10 +401,10 @@ macro_rules! decl_test_network { }, } let m = message.take().ok_or($crate::SendError::MissingArgument)?; - Ok(((T::get(), d, m), $crate::MultiAssets::new())) + Ok(((T::get(), d, m), $crate::Assets::new())) } fn deliver( - triple: ($crate::ParaId, $crate::MultiLocation, $crate::Xcm<()>), + triple: ($crate::ParaId, $crate::Location, $crate::Xcm<()>), ) -> Result<$crate::XcmHash, $crate::SendError> { let hash = $crate::fake_message_hash(&triple.2); $crate::PARA_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(triple)); @@ -415,17 +415,17 @@ macro_rules! decl_test_network { /// XCM router for relay chain. pub struct RelayChainXcmRouter; impl $crate::SendXcm for RelayChainXcmRouter { - type Ticket = ($crate::MultiLocation, $crate::Xcm<()>); + type Ticket = ($crate::Location, $crate::Xcm<()>); fn validate( - destination: &mut Option<$crate::MultiLocation>, + destination: &mut Option<$crate::Location>, message: &mut Option<$crate::Xcm<()>>, - ) -> $crate::SendResult<($crate::MultiLocation, $crate::Xcm<()>)> { + ) -> $crate::SendResult<($crate::Location, $crate::Xcm<()>)> { use $crate::DmpMessageHandlerT; let d = destination.take().ok_or($crate::SendError::MissingArgument)?; - match (d.interior(), d.parent_count()) { + match d.unpack() { $( - ($crate::X1($crate::Parachain(id)), 0) if id == &$para_id => {}, + (0, [$crate::Parachain(id)]) if id == &$para_id => {}, )* _ => { *destination = Some(d); @@ -433,10 +433,10 @@ macro_rules! decl_test_network { }, } let m = message.take().ok_or($crate::SendError::MissingArgument)?; - Ok(((d, m), $crate::MultiAssets::new())) + Ok(((d, m), $crate::Assets::new())) } fn deliver( - pair: ($crate::MultiLocation, $crate::Xcm<()>), + pair: ($crate::Location, $crate::Xcm<()>), ) -> Result<$crate::XcmHash, $crate::SendError> { let hash = $crate::fake_message_hash(&pair.1); $crate::RELAY_MESSAGE_BUS.with(|b| b.borrow_mut().push_back(pair)); diff --git a/prdoc/pr_1230.prdoc b/prdoc/pr_1230.prdoc new file mode 100644 index 00000000000..8eea1816cb5 --- /dev/null +++ b/prdoc/pr_1230.prdoc @@ -0,0 +1,20 @@ +title: XCMv4 + +doc: + - audience: Runtime Dev + description: | + A new version of the XCM format. + The main changes are: + - Removed `Multi` prefix from types + - Removed `Abstract` asset id + - `Outcome` is now a named fields struct + - Added `Reanchorable` trait, implemented for both `Location` and `Asset` + - New syntax for building `Location`s and `Junction`s using slices. + You build them like `let location = Location::new(1, [Parachain(1000), PalletInstance(50), GeneralIndex(1984)]);` + and match on them like `match location.unpack() { + (1, [Parachain(id)]) => ... + (0, Here) => ..., + (1, [_]) => ..., + }` + +crates: [] diff --git a/substrate/frame/assets/src/benchmarking.rs b/substrate/frame/assets/src/benchmarking.rs index 8fe5a7e2493..1b65bb953d7 100644 --- a/substrate/frame/assets/src/benchmarking.rs +++ b/substrate/frame/assets/src/benchmarking.rs @@ -45,7 +45,7 @@ fn create_default_asset, I: 'static>( let root = SystemOrigin::Root.into(); assert!(Assets::::force_create( root, - asset_id, + asset_id.clone(), caller_lookup.clone(), is_sufficient, 1u32.into(), @@ -64,7 +64,7 @@ pub fn create_default_minted_asset, I: 'static>( } assert!(Assets::::mint( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), caller_lookup.clone(), amount, ) @@ -91,7 +91,7 @@ fn add_sufficients, I: 'static>(minter: T::AccountId, n: u32) { let target_lookup = T::Lookup::unlookup(target); assert!(Assets::::mint( origin.clone().into(), - asset_id, + asset_id.clone(), target_lookup, 100u32.into() ) @@ -108,8 +108,13 @@ fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { ); let minter_lookup = T::Lookup::unlookup(minter.clone()); let origin = SystemOrigin::Signed(minter); - Assets::::mint(origin.clone().into(), asset_id, minter_lookup, (100 * (n + 1)).into()) - .unwrap(); + Assets::::mint( + origin.clone().into(), + asset_id.clone(), + minter_lookup, + (100 * (n + 1)).into(), + ) + .unwrap(); let enough = T::Currency::minimum_balance(); for i in 0..n { let target = account("approval", i, SEED); @@ -117,7 +122,7 @@ fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { let target_lookup = T::Lookup::unlookup(target); Assets::::approve_transfer( origin.clone().into(), - asset_id, + asset_id.clone(), target_lookup, 100u32.into(), ) @@ -136,12 +141,12 @@ fn assert_event, I: 'static>(generic_event: >::Runti benchmarks_instance_pallet! { create { let asset_id = default_asset_id::(); - let origin = T::CreateOrigin::try_successful_origin(&asset_id.into()) + let origin = T::CreateOrigin::try_successful_origin(&asset_id.clone().into()) .map_err(|_| BenchmarkError::Weightless)?; - let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.into()).unwrap(); + let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.clone().into()).unwrap(); let caller_lookup = T::Lookup::unlookup(caller.clone()); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(origin, asset_id, caller_lookup, 1u32.into()) + }: _(origin, asset_id.clone(), caller_lookup, 1u32.into()) verify { assert_last_event::(Event::Created { asset_id: asset_id.into(), creator: caller.clone(), owner: caller }.into()); } @@ -150,7 +155,7 @@ benchmarks_instance_pallet! { let asset_id = default_asset_id::(); let caller: T::AccountId = whitelisted_caller(); let caller_lookup = T::Lookup::unlookup(caller.clone()); - }: _(SystemOrigin::Root, asset_id, caller_lookup, true, 1u32.into()) + }: _(SystemOrigin::Root, asset_id.clone(), caller_lookup, true, 1u32.into()) verify { assert_last_event::(Event::ForceCreated { asset_id: asset_id.into(), owner: caller }.into()); } @@ -159,9 +164,9 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - }:_(SystemOrigin::Signed(caller), asset_id) + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::DestructionStarted { asset_id: asset_id.into() }.into()); } @@ -172,10 +177,10 @@ benchmarks_instance_pallet! { add_sufficients::(caller.clone(), c); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::AccountsDestroyed { asset_id: asset_id.into(), @@ -190,10 +195,10 @@ benchmarks_instance_pallet! { add_approvals::(caller.clone(), a); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::ApprovalsDestroyed { asset_id: asset_id.into(), @@ -206,10 +211,10 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_asset::(true); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id)?; - }:_(SystemOrigin::Signed(caller), asset_id) + Assets::::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?; + }:_(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::Destroyed { asset_id: asset_id.into(), @@ -220,7 +225,7 @@ benchmarks_instance_pallet! { mint { let (asset_id, caller, caller_lookup) = create_default_asset::(true); let amount = T::Balance::from(100u32); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount) verify { assert_last_event::(Event::Issued { asset_id: asset_id.into(), owner: caller, amount }.into()); } @@ -228,7 +233,7 @@ benchmarks_instance_pallet! { burn { let amount = T::Balance::from(100u32); let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount) verify { assert_last_event::(Event::Burned { asset_id: asset_id.into(), owner: caller, balance: amount }.into()); } @@ -238,7 +243,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount) verify { assert_last_event::(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()); } @@ -249,7 +254,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, mint_amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount) verify { assert!(frame_system::Pallet::::account_exists(&caller)); assert_last_event::(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()); @@ -260,7 +265,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, amount); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, target_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, target_lookup, amount) verify { assert_last_event::( Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into() @@ -269,7 +274,7 @@ benchmarks_instance_pallet! { freeze { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Frozen { asset_id: asset_id.into(), who: caller }.into()); } @@ -278,17 +283,17 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), caller_lookup.clone(), )?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Thawed { asset_id: asset_id.into(), who: caller }.into()); } freeze_asset { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone()) verify { assert_last_event::(Event::AssetFrozen { asset_id: asset_id.into() }.into()); } @@ -297,9 +302,9 @@ benchmarks_instance_pallet! { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); Assets::::freeze_asset( SystemOrigin::Signed(caller.clone()).into(), - asset_id, + asset_id.clone(), )?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone()) verify { assert_last_event::(Event::AssetThawed { asset_id: asset_id.into() }.into()); } @@ -308,7 +313,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, _) = create_default_asset::(true); let target: T::AccountId = account("target", 0, SEED); let target_lookup = T::Lookup::unlookup(target.clone()); - }: _(SystemOrigin::Signed(caller), asset_id, target_lookup) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), target_lookup) verify { assert_last_event::(Event::OwnerChanged { asset_id: asset_id.into(), owner: target }.into()); } @@ -318,7 +323,7 @@ benchmarks_instance_pallet! { let target0 = T::Lookup::unlookup(account("target", 0, SEED)); let target1 = T::Lookup::unlookup(account("target", 1, SEED)); let target2 = T::Lookup::unlookup(account("target", 2, SEED)); - }: _(SystemOrigin::Signed(caller), asset_id, target0, target1, target2) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), target0, target1, target2) verify { assert_last_event::(Event::TeamChanged { asset_id: asset_id.into(), @@ -338,7 +343,7 @@ benchmarks_instance_pallet! { let (asset_id, caller, _) = create_default_asset::(true); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(SystemOrigin::Signed(caller), asset_id, name.clone(), symbol.clone(), decimals) + }: _(SystemOrigin::Signed(caller), asset_id.clone(), name.clone(), symbol.clone(), decimals) verify { assert_last_event::(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into()); } @@ -348,8 +353,8 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); let dummy = vec![0u8; T::StringLimit::get() as usize]; let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?; - }: _(SystemOrigin::Signed(caller), asset_id) + Assets::::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?; + }: _(SystemOrigin::Signed(caller), asset_id.clone()) verify { assert_last_event::(Event::MetadataCleared { asset_id: asset_id.into() }.into()); } @@ -367,7 +372,7 @@ benchmarks_instance_pallet! { let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let call = Call::::force_set_metadata { - id: asset_id, + id: asset_id.clone(), name: name.clone(), symbol: symbol.clone(), decimals, @@ -383,11 +388,11 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); let dummy = vec![0u8; T::StringLimit::get() as usize]; let origin = SystemOrigin::Signed(caller).into(); - Assets::::set_metadata(origin, asset_id, dummy.clone(), dummy, 12)?; + Assets::::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?; let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - let call = Call::::force_clear_metadata { id: asset_id }; + let call = Call::::force_clear_metadata { id: asset_id.clone() }; }: { call.dispatch_bypass_filter(origin)? } verify { assert_last_event::(Event::MetadataCleared { asset_id: asset_id.into() }.into()); @@ -399,7 +404,7 @@ benchmarks_instance_pallet! { let origin = T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; let call = Call::::force_asset_status { - id: asset_id, + id: asset_id.clone(), owner: caller_lookup.clone(), issuer: caller_lookup.clone(), admin: caller_lookup.clone(), @@ -420,7 +425,7 @@ benchmarks_instance_pallet! { let delegate: T::AccountId = account("delegate", 0, SEED); let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup, amount) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup, amount) verify { assert_last_event::(Event::ApprovedTransfer { asset_id: asset_id.into(), source: caller, delegate, amount }.into()); } @@ -434,11 +439,11 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(owner.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup, amount)?; + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup, amount)?; let dest: T::AccountId = account("dest", 0, SEED); let dest_lookup = T::Lookup::unlookup(dest.clone()); - }: _(SystemOrigin::Signed(delegate.clone()), asset_id, owner_lookup, dest_lookup, amount) + }: _(SystemOrigin::Signed(delegate.clone()), asset_id.clone(), owner_lookup, dest_lookup, amount) verify { assert!(T::Currency::reserved_balance(&owner).is_zero()); assert_event::(Event::Transferred { asset_id: asset_id.into(), from: owner, to: dest, amount }.into()); @@ -452,8 +457,8 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, delegate_lookup) + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?; + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup) verify { assert_last_event::(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into()); } @@ -466,15 +471,15 @@ benchmarks_instance_pallet! { let delegate_lookup = T::Lookup::unlookup(delegate.clone()); let amount = 100u32.into(); let origin = SystemOrigin::Signed(caller.clone()).into(); - Assets::::approve_transfer(origin, asset_id, delegate_lookup.clone(), amount)?; - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, delegate_lookup) + Assets::::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?; + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, delegate_lookup) verify { assert_last_event::(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into()); } set_min_balance { let (asset_id, caller, caller_lookup) = create_default_asset::(false); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, 50u32.into()) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), 50u32.into()) verify { assert_last_event::(Event::AssetMinBalanceChanged { asset_id: asset_id.into(), new_min_balance: 50u32.into() }.into()); } @@ -484,8 +489,8 @@ benchmarks_instance_pallet! { let new_account: T::AccountId = account("newaccount", 1, SEED); T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::::max_value()); assert_ne!(asset_owner, new_account); - assert!(!Account::::contains_key(asset_id.into(), &new_account)); - }: _(SystemOrigin::Signed(new_account.clone()), asset_id) + assert!(!Account::::contains_key(asset_id.clone().into(), &new_account)); + }: _(SystemOrigin::Signed(new_account.clone()), asset_id.clone()) verify { assert!(Account::::contains_key(asset_id.into(), &new_account)); } @@ -496,8 +501,8 @@ benchmarks_instance_pallet! { let new_account_lookup = T::Lookup::unlookup(new_account.clone()); T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::::max_value()); assert_ne!(asset_owner, new_account); - assert!(!Account::::contains_key(asset_id.into(), &new_account)); - }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup) + assert!(!Account::::contains_key(asset_id.clone().into(), &new_account)); + }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id.clone(), new_account_lookup) verify { assert!(Account::::contains_key(asset_id.into(), &new_account)); } @@ -509,12 +514,12 @@ benchmarks_instance_pallet! { assert_ne!(asset_owner, new_account); assert!(Assets::::touch( SystemOrigin::Signed(new_account.clone()).into(), - asset_id + asset_id.clone() ).is_ok()); // `touch` should reserve balance of the caller according to the `AssetAccountDeposit` amount... assert_eq!(T::Currency::reserved_balance(&new_account), T::AssetAccountDeposit::get()); // ...and also create an `Account` entry. - assert!(Account::::contains_key(asset_id.into(), &new_account)); + assert!(Account::::contains_key(asset_id.clone().into(), &new_account)); }: _(SystemOrigin::Signed(new_account.clone()), asset_id, true) verify { // `refund`ing should of course repatriate the reserve @@ -529,12 +534,12 @@ benchmarks_instance_pallet! { assert_ne!(asset_owner, new_account); assert!(Assets::::touch_other( SystemOrigin::Signed(asset_owner.clone()).into(), - asset_id, + asset_id.clone(), new_account_lookup.clone() ).is_ok()); // `touch` should reserve balance of the caller according to the `AssetAccountDeposit` amount... assert_eq!(T::Currency::reserved_balance(&asset_owner), T::AssetAccountDeposit::get()); - assert!(Account::::contains_key(asset_id.into(), &new_account)); + assert!(Account::::contains_key(asset_id.clone().into(), &new_account)); }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup.clone()) verify { // this should repatriate the reserved balance of the freezer @@ -543,7 +548,7 @@ benchmarks_instance_pallet! { block { let (asset_id, caller, caller_lookup) = create_default_minted_asset::(true, 100u32.into()); - }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup) + }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup) verify { assert_last_event::(Event::Blocked { asset_id: asset_id.into(), who: caller }.into()); } diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs index f3ae03d667b..cafe7bb1a3b 100644 --- a/substrate/frame/assets/src/lib.rs +++ b/substrate/frame/assets/src/lib.rs @@ -259,11 +259,7 @@ pub mod pallet { /// This type includes the `From` bound, since tightly coupled pallets may /// want to convert an `AssetId` into a parameter for calling dispatchable functions /// directly. - type AssetIdParameter: Parameter - + Copy - + From - + Into - + MaxEncodedLen; + type AssetIdParameter: Parameter + From + Into + MaxEncodedLen; /// The currency mechanism. type Currency: ReservableCurrency; diff --git a/substrate/frame/contracts/mock-network/src/lib.rs b/substrate/frame/contracts/mock-network/src/lib.rs index 345c69541b6..eea9dde062c 100644 --- a/substrate/frame/contracts/mock-network/src/lib.rs +++ b/substrate/frame/contracts/mock-network/src/lib.rs @@ -24,7 +24,7 @@ mod tests; use crate::primitives::{AccountId, UNITS}; use sp_runtime::BuildStorage; -use xcm::latest::{prelude::*, MultiLocation}; +use xcm::latest::prelude::*; use xcm_executor::traits::ConvertLocation; use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; @@ -67,12 +67,12 @@ decl_test_network! { } pub fn relay_sovereign_account_id() -> AccountId { - let location: MultiLocation = (Parent,).into(); + let location: Location = (Parent,).into(); parachain::SovereignAccountOf::convert_location(&location).unwrap() } pub fn parachain_sovereign_account_id(para: u32) -> AccountId { - let location: MultiLocation = (Parachain(para),).into(); + let location: Location = (Parachain(para),).into(); relay_chain::SovereignAccountOf::convert_location(&location).unwrap() } @@ -80,7 +80,7 @@ pub fn parachain_account_sovereign_account_id( para: u32, who: sp_runtime::AccountId32, ) -> AccountId { - let location: MultiLocation = ( + let location: Location = ( Parachain(para), AccountId32 { network: Some(relay_chain::RelayNetwork::get()), id: who.into() }, ) diff --git a/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs b/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs index 82fb8590e26..cc81b6bd636 100644 --- a/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs +++ b/substrate/frame/contracts/mock-network/src/mocks/msg_queue.rs @@ -96,16 +96,23 @@ pub mod pallet { max_weight: Weight, ) -> Result { let hash = Encode::using_encoded(&xcm, T::Hashing::hash); - let message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); + let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256); let (result, event) = match Xcm::::try_from(xcm) { Ok(xcm) => { let location = (Parent, Parachain(sender.into())); - match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) { - Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)), - Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))), + match T::XcmExecutor::prepare_and_execute( + location, + xcm, + &mut message_hash, + max_weight, + Weight::zero(), + ) { + Outcome::Error { error } => (Err(error), Event::Fail(Some(hash), error)), + Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))), // As far as the caller is concerned, this was dispatched without error, so // we just report the weight used. - Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)), + Outcome::Incomplete { used, error } => + (Ok(used), Event::Fail(Some(hash), error)), } }, Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))), @@ -146,7 +153,7 @@ pub mod pallet { limit: Weight, ) -> Weight { for (_i, (_sent_at, data)) in iter.enumerate() { - let id = sp_io::hashing::blake2_256(&data[..]); + let mut id = sp_io::hashing::blake2_256(&data[..]); let maybe_versioned = VersionedXcm::::decode(&mut &data[..]); match maybe_versioned { Err(_) => { @@ -155,7 +162,13 @@ pub mod pallet { Ok(versioned) => match Xcm::try_from(versioned) { Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)), Ok(x) => { - let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), id, limit); + let outcome = T::XcmExecutor::prepare_and_execute( + Parent, + x.clone(), + &mut id, + limit, + Weight::zero(), + ); >::append(x); Self::deposit_event(Event::ExecutedDownward(id, outcome)); }, diff --git a/substrate/frame/contracts/mock-network/src/parachain.rs b/substrate/frame/contracts/mock-network/src/parachain.rs index a79b7e4e2d6..90fc23af48d 100644 --- a/substrate/frame/contracts/mock-network/src/parachain.rs +++ b/substrate/frame/contracts/mock-network/src/parachain.rs @@ -143,10 +143,10 @@ parameter_types! { } parameter_types! { - pub const KsmLocation: MultiLocation = MultiLocation::parent(); - pub const TokenLocation: MultiLocation = Here.into_location(); + pub const KsmLocation: Location = Location::parent(); + pub const TokenLocation: Location = Here.into_location(); pub const RelayNetwork: NetworkId = ByGenesis([0; 32]); - pub UniversalLocation: InteriorMultiLocation = Parachain(MsgQueue::parachain_id().into()).into(); + pub UniversalLocation: InteriorLocation = Parachain(MsgQueue::parachain_id().into()).into(); } pub type XcmOriginToCallOrigin = ( @@ -158,13 +158,13 @@ pub type XcmOriginToCallOrigin = ( parameter_types! { pub const XcmInstructionWeight: Weight = Weight::from_parts(1_000, 1_000); - pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = (Concrete(Parent.into()), 1_000_000_000_000, 1024 * 1024); + pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = (AssetId(Parent.into()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; - pub ForeignPrefix: MultiLocation = (Parent,).into(); + pub ForeignPrefix: Location = (Parent,).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); - pub TrustedLockPairs: (MultiLocation, MultiAssetFilter) = - (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible })); + pub TrustedLockPairs: (Location, AssetFilter) = + (Parent.into(), Wild(AllOf { id: AssetId(Parent.into()), fun: WildFungible })); } pub fn estimate_message_fee(number_of_instructions: u64) -> u128 { @@ -188,20 +188,19 @@ pub fn estimate_fee_for_weight(weight: Weight) -> u128 { pub type LocalBalancesTransactor = XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; -pub struct FromMultiLocationToAsset(PhantomData<(MultiLocation, AssetId)>); -impl MaybeEquivalence - for FromMultiLocationToAsset +pub struct FromLocationToAsset(PhantomData<(Location, AssetId)>); +impl MaybeEquivalence + for FromLocationToAsset { - fn convert(value: &MultiLocation) -> Option { - match *value { - MultiLocation { parents: 1, interior: Here } => Some(0 as AssetIdForAssets), - MultiLocation { parents: 1, interior: X1(Parachain(para_id)) } => - Some(para_id as AssetIdForAssets), + fn convert(value: &Location) -> Option { + match value.unpack() { + (1, []) => Some(0 as AssetIdForAssets), + (1, [Parachain(para_id)]) => Some(*para_id as AssetIdForAssets), _ => None, } } - fn convert_back(_id: &AssetIdForAssets) -> Option { + fn convert_back(_id: &AssetIdForAssets) -> Option { None } } @@ -211,7 +210,7 @@ pub type ForeignAssetsTransactor = FungiblesAdapter< ConvertedConcreteId< AssetIdForAssets, Balance, - FromMultiLocationToAsset, + FromLocationToAsset, JustTry, >, SovereignAccountOf, @@ -224,18 +223,15 @@ pub type ForeignAssetsTransactor = FungiblesAdapter< pub type AssetTransactors = (LocalBalancesTransactor, ForeignAssetsTransactor); pub struct ParentRelay; -impl Contains for ParentRelay { - fn contains(location: &MultiLocation) -> bool { +impl Contains for ParentRelay { + fn contains(location: &Location) -> bool { location.contains_parents_only(1) } } pub struct ThisParachain; -impl Contains for ThisParachain { - fn contains(location: &MultiLocation) -> bool { - matches!( - location, - MultiLocation { parents: 0, interior: Junctions::X1(Junction::AccountId32 { .. }) } - ) +impl Contains for ThisParachain { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Junction::AccountId32 { .. }])) } } @@ -251,12 +247,12 @@ pub type Barrier = ( ); parameter_types! { - pub NftCollectionOne: MultiAssetFilter - = Wild(AllOf { fun: WildNonFungible, id: Concrete((Parent, GeneralIndex(1)).into()) }); - pub NftCollectionOneForRelay: (MultiAssetFilter, MultiLocation) + pub NftCollectionOne: AssetFilter + = Wild(AllOf { fun: WildNonFungible, id: AssetId((Parent, GeneralIndex(1)).into()) }); + pub NftCollectionOneForRelay: (AssetFilter, Location) = (NftCollectionOne::get(), Parent.into()); - pub RelayNativeAsset: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete((Parent, Here).into()) }); - pub RelayNativeAssetForRelay: (MultiAssetFilter, MultiLocation) = (RelayNativeAsset::get(), Parent.into()); + pub RelayNativeAsset: AssetFilter = Wild(AllOf { fun: WildFungible, id: AssetId((Parent, Here).into()) }); + pub RelayNativeAssetForRelay: (AssetFilter, Location) = (RelayNativeAsset::get(), Parent.into()); } pub type TrustedTeleporters = (xcm_builder::Case, xcm_builder::Case); @@ -298,10 +294,8 @@ impl mock_msg_queue::Config for Runtime { pub type LocalOriginToLocation = SignedToAccountId32; pub struct TrustedLockerCase(PhantomData); -impl> ContainsPair - for TrustedLockerCase -{ - fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool { +impl> ContainsPair for TrustedLockerCase { + fn contains(origin: &Location, asset: &Asset) -> bool { let (o, a) = T::get(); a.matches(asset) && &o == origin } diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index 136cc2e3ed6..4e5523f7442 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -107,8 +107,8 @@ impl configuration::Config for Runtime { parameter_types! { pub RelayNetwork: NetworkId = ByGenesis([0; 32]); - pub const TokenLocation: MultiLocation = Here.into_location(); - pub UniversalLocation: InteriorMultiLocation = Here; + pub const TokenLocation: Location = Here.into_location(); + pub UniversalLocation: InteriorLocation = Here; pub UnitWeightCost: u64 = 1_000; } @@ -134,15 +134,15 @@ type LocalOriginConverter = ( parameter_types! { pub const XcmInstructionWeight: Weight = Weight::from_parts(1_000, 1_000); pub TokensPerSecondPerMegabyte: (AssetId, u128, u128) = - (Concrete(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); + (AssetId(TokenLocation::get()), 1_000_000_000_000, 1024 * 1024); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; } pub struct ChildrenParachains; -impl Contains for ChildrenParachains { - fn contains(location: &MultiLocation) -> bool { - matches!(location, MultiLocation { parents: 0, interior: X1(Parachain(_)) }) +impl Contains for ChildrenParachains { + fn contains(location: &Location) -> bool { + matches!(location.unpack(), (0, [Parachain(_)])) } } diff --git a/substrate/frame/contracts/mock-network/src/tests.rs b/substrate/frame/contracts/mock-network/src/tests.rs index a66b2b08019..c25373bcbe3 100644 --- a/substrate/frame/contracts/mock-network/src/tests.rs +++ b/substrate/frame/contracts/mock-network/src/tests.rs @@ -31,7 +31,7 @@ use frame_support::{ use pallet_balances::{BalanceLock, Reasons}; use pallet_contracts::{Code, CollectEvents, DebugInfo, Determinism}; use pallet_contracts_fixtures::compile_module; -use xcm::{v3::prelude::*, VersionedMultiLocation, VersionedXcm}; +use xcm::{v4::prelude::*, VersionedLocation, VersionedXcm}; use xcm_simulator::TestExt; type ParachainContracts = pallet_contracts::Pallet; @@ -82,7 +82,7 @@ fn test_xcm_execute() { let amount: u128 = 10 * CENTS; // The XCM used to transfer funds to Bob. - let message: xcm_simulator::Xcm<()> = Xcm(vec![ + let message: Xcm<()> = Xcm(vec![ WithdrawAsset(vec![(Here, amount).into()].into()), DepositAsset { assets: All.into(), @@ -96,7 +96,7 @@ fn test_xcm_execute() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -106,7 +106,7 @@ fn test_xcm_execute() { let mut data = &result.data[..]; let outcome = Outcome::decode(&mut data).expect("Failed to decode xcm_execute Outcome"); - assert_matches!(outcome, Outcome::Complete(_)); + assert_matches!(outcome, Outcome::Complete { .. }); // Check if the funds are subtracted from the account of Alice and added to the account of // Bob. @@ -137,7 +137,7 @@ fn test_xcm_execute_filtered_call() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -178,7 +178,7 @@ fn test_xcm_execute_reentrant_call() { 0, Weight::MAX, None, - VersionedXcm::V3(message).encode(), + VersionedXcm::V4(message).encode(), DebugInfo::UnsafeDebug, CollectEvents::UnsafeCollect, Determinism::Enforced, @@ -188,7 +188,10 @@ fn test_xcm_execute_reentrant_call() { let mut data = &result.data[..]; let outcome = Outcome::decode(&mut data).expect("Failed to decode xcm_execute Outcome"); - assert_matches!(outcome, Outcome::Incomplete(_, XcmError::ExpectationFalse)); + assert_matches!( + outcome, + Outcome::Incomplete { used: _, error: XcmError::ExpectationFalse } + ); // Funds should not change hands as the XCM transact failed. assert_eq!(ParachainBalances::free_balance(BOB), INITIAL_BALANCE); @@ -203,15 +206,15 @@ fn test_xcm_send() { // Send XCM instructions through the contract, to lock some funds on the relay chain. ParaA::execute_with(|| { - let dest = MultiLocation::from(Parent); - let dest = VersionedMultiLocation::V3(dest); + let dest = Location::from(Parent); + let dest = VersionedLocation::V4(dest); - let message: xcm_simulator::Xcm<()> = Xcm(vec![ + let message: Xcm<()> = Xcm(vec![ WithdrawAsset((Here, fee).into()), BuyExecution { fees: (Here, fee).into(), weight_limit: WeightLimit::Unlimited }, LockAsset { asset: (Here, 5 * CENTS).into(), unlocker: (Parachain(1)).into() }, ]); - let message = VersionedXcm::V3(message); + let message = VersionedXcm::V4(message); let exec = ParachainContracts::bare_call( ALICE, contract_addr.clone(), diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs index a7f329005f9..3e49b68f86b 100644 --- a/substrate/frame/contracts/src/wasm/runtime.rs +++ b/substrate/frame/contracts/src/wasm/runtime.rs @@ -2169,11 +2169,11 @@ pub mod env { msg_len: u32, output_ptr: u32, ) -> Result { - use xcm::{VersionedMultiLocation, VersionedXcm}; + use xcm::{VersionedLocation, VersionedXcm}; use xcm_builder::{SendController, SendControllerWeightInfo}; ctx.charge_gas(RuntimeCosts::CopyFromContract(msg_len))?; - let dest: VersionedMultiLocation = ctx.read_sandbox_memory_as(memory, dest_ptr)?; + let dest: VersionedLocation = ctx.read_sandbox_memory_as(memory, dest_ptr)?; let message: VersionedXcm<()> = ctx.read_sandbox_memory_as_unbounded(memory, msg_ptr, msg_len)?; diff --git a/substrate/frame/support/src/traits/tokens/pay.rs b/substrate/frame/support/src/traits/tokens/pay.rs index 4d1d80b5b50..62d7a056a3f 100644 --- a/substrate/frame/support/src/traits/tokens/pay.rs +++ b/substrate/frame/support/src/traits/tokens/pay.rs @@ -26,7 +26,7 @@ use sp_std::fmt::Debug; use super::{fungible, fungibles, Balance, Preservation::Expendable}; /// Can be implemented by `PayFromAccount` using a `fungible` impl, but can also be implemented with -/// XCM/MultiAsset and made generic over assets. +/// XCM/Asset and made generic over assets. pub trait Pay { /// The type by which we measure units of the currency in which we make payments. type Balance: Balance; -- GitLab From 33d533e1be8210d65bcbfed58fac5b659333fc77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:20:27 +0100 Subject: [PATCH 015/283] Bump futures-util from 0.3.28 to 0.3.30 (#2952) Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.30.
Release notes

Sourced from futures-util's releases.

0.3.30

  • Add {BiLock,SplitStream,SplitSink,ReadHalf,WriteHalf}::is_pair_of (#2797)
  • Fix panic in FuturesUnordered::clear (#2809)
  • Fix panic in AsyncBufReadExt::fill_buf (#2801, #2812)
  • Improve support for targets without atomic CAS (#2811)
  • Remove build scripts (#2811)

0.3.29

  • Add TryStreamExt::try_ready_chunks (#2757)
  • Add TryStreamExt::{try_all,try_any} (#2783)
  • Add UnboundedSender::{len,is_empty} (#2750)
  • Fix Sync impl of FuturesUnordered (#2788)
  • Fix infinite loop caused by invalid UTF-8 bytes (#2785)
  • Fix build error with -Z minimal-versions (#2761)
Changelog

Sourced from futures-util's changelog.

0.3.30 - 2023-12-24

  • Add {BiLock,SplitStream,SplitSink,ReadHalf,WriteHalf}::is_pair_of (#2797)
  • Fix panic in FuturesUnordered::clear (#2809)
  • Fix panic in AsyncBufReadExt::fill_buf (#2801, #2812)
  • Improve support for targets without atomic CAS (#2811)
  • Remove build scripts (#2811)

0.3.29 - 2023-10-26

  • Add TryStreamExt::try_ready_chunks (#2757)
  • Add TryStreamExt::{try_all,try_any} (#2783)
  • Add UnboundedSender::{len,is_empty} (#2750)
  • Fix Sync impl of FuturesUnordered (#2788)
  • Fix infinite loop caused by invalid UTF-8 bytes (#2785)
  • Fix build error with -Z minimal-versions (#2761)
Commits
  • de1a0fd Release 0.3.30
  • 68d2845 Remove a redundant space in example (#2816)
  • fdd2ce7 Fix broken link in CopyBufAbortable docs (#2815)
  • 272a3c7 Use cfg(target_has_atomic) on no-std targets
  • c179201 FillBuf: Do not call poll_fill_buf twice
  • e6735f3 FuturesUnordered: Fix clear implementation
  • 04d01a0 FuturesOrdered: Use 64-bit index
  • e4aa659 remove redundant impl Unpin
  • 17851c1 provide a mechanism to determine if io read/write halves are from the same st...
  • 4910799 provide a non-destructive mechanism to determine if a sink/stream are paired
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=futures-util&package-manager=cargo&previous-version=0.3.28&new-version=0.3.30)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 28 +++++++++---------- .../node/zombienet-backchannel/Cargo.toml | 2 +- substrate/client/rpc-spec-v2/Cargo.toml | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31347261151..f685fcaa702 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5918,9 +5918,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -5928,9 +5928,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" @@ -5946,9 +5946,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -5967,9 +5967,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", @@ -5989,15 +5989,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" @@ -6007,9 +6007,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", diff --git a/polkadot/node/zombienet-backchannel/Cargo.toml b/polkadot/node/zombienet-backchannel/Cargo.toml index 82c6f2532ca..6af7a8d6e38 100644 --- a/polkadot/node/zombienet-backchannel/Cargo.toml +++ b/polkadot/node/zombienet-backchannel/Cargo.toml @@ -15,7 +15,7 @@ workspace = true tokio = { version = "1.24.2", default-features = false, features = ["macros", "net", "rt-multi-thread", "sync"] } url = "2.3.1" tokio-tungstenite = "0.17" -futures-util = "0.3.23" +futures-util = "0.3.30" lazy_static = "1.4.0" parity-scale-codec = { version = "3.6.1", features = ["derive"] } reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false } diff --git a/substrate/client/rpc-spec-v2/Cargo.toml b/substrate/client/rpc-spec-v2/Cargo.toml index ba32308e678..17412f883ca 100644 --- a/substrate/client/rpc-spec-v2/Cargo.toml +++ b/substrate/client/rpc-spec-v2/Cargo.toml @@ -39,7 +39,7 @@ tokio-stream = { version = "0.1.14", features = ["sync"] } tokio = { version = "1.22.0", features = ["sync"] } array-bytes = "6.1" log = "0.4.17" -futures-util = { version = "0.3.19", default-features = false } +futures-util = { version = "0.3.30", default-features = false } [dev-dependencies] serde_json = "1.0.111" -- GitLab From c01dbebeaa6394691974de46dd2d41a582f6a4c2 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:59:00 +0100 Subject: [PATCH 016/283] Revert "pallet-core-fellowship: import an unimported member on approve" (#2956) Reverts paritytech/polkadot-sdk#2883 Code, not docs, was intended. --- prdoc/pr_2883.prdoc | 9 ------ substrate/frame/core-fellowship/src/lib.rs | 29 ++++++-------------- substrate/frame/core-fellowship/src/tests.rs | 8 ------ 3 files changed, 9 insertions(+), 37 deletions(-) delete mode 100644 prdoc/pr_2883.prdoc diff --git a/prdoc/pr_2883.prdoc b/prdoc/pr_2883.prdoc deleted file mode 100644 index e2817d16a03..00000000000 --- a/prdoc/pr_2883.prdoc +++ /dev/null @@ -1,9 +0,0 @@ -title: "pallet-core-fellowship: import an unimported on approve" - -doc: - - audience: Runtime User - description: | - To align with the documentation of the approve call, we import an untracked member on approval. - -crates: - - name: "pallet-core-fellowship" diff --git a/substrate/frame/core-fellowship/src/lib.rs b/substrate/frame/core-fellowship/src/lib.rs index ee16ae07ce6..a0a45c7c594 100644 --- a/substrate/frame/core-fellowship/src/lib.rs +++ b/substrate/frame/core-fellowship/src/lib.rs @@ -362,8 +362,7 @@ pub mod pallet { /// /// This resets `last_proof` to the current block, thereby delaying any automatic demotion. /// - /// If `who` is not already tracked by this pallet, then it will become tracked. - /// `last_promotion` will be set to zero. + /// `who` must already be tracked by this pallet for this to have an effect. /// /// - `origin`: An origin which satisfies `ApproveOrigin` or root. /// - `who`: A member (i.e. of non-zero rank). @@ -382,11 +381,7 @@ pub mod pallet { ensure!(at_rank > 0, Error::::InvalidRank); let rank = T::Members::rank_of(&who).ok_or(Error::::Unranked)?; ensure!(rank == at_rank, Error::::UnexpectedRank); - let mut member = if let Some(m) = Member::::get(&who) { - m - } else { - Self::import_member(who.clone(), rank) - }; + let mut member = Member::::get(&who).ok_or(Error::::NotTracked)?; member.last_proof = frame_system::Pallet::::block_number(); Member::::insert(&who, &member); @@ -522,7 +517,13 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(!Member::::contains_key(&who), Error::::AlreadyInducted); let rank = T::Members::rank_of(&who).ok_or(Error::::Unranked)?; - let _ = Self::import_member(who, rank); + + let now = frame_system::Pallet::::block_number(); + Member::::insert( + &who, + MemberStatus { is_active: true, last_promotion: 0u32.into(), last_proof: now }, + ); + Self::deposit_event(Event::::Imported { who, rank }); Ok(Pays::No.into()) } @@ -546,18 +547,6 @@ pub mod pallet { Self::deposit_event(e); } } - - fn import_member(who: T::AccountId, rank: RankOf) -> MemberStatusOf { - let now = frame_system::Pallet::::block_number(); - let status = MemberStatus { - is_active: true, - last_promotion: BlockNumberFor::::zero(), - last_proof: now, - }; - Member::::insert(&who, status.clone()); - Self::deposit_event(Event::::Imported { who, rank }); - status - } } impl, I: 'static> GetSalary, T::AccountId, T::Balance> for Pallet { diff --git a/substrate/frame/core-fellowship/src/tests.rs b/substrate/frame/core-fellowship/src/tests.rs index 6d9cebbf921..c9098f2171f 100644 --- a/substrate/frame/core-fellowship/src/tests.rs +++ b/substrate/frame/core-fellowship/src/tests.rs @@ -378,11 +378,3 @@ fn active_changing_get_salary_works() { } }); } - -#[test] -fn approve_imports_not_tracked_member() { - new_test_ext().execute_with(|| { - set_rank(10, 5); - assert_ok!(CoreFellowship::approve(signed(5), 10, 5)); - }); -} -- GitLab From 8b28031d16e7a9ed059aa90cb4b4488d58a7d9d9 Mon Sep 17 00:00:00 2001 From: Ignacio Palacios Date: Wed, 17 Jan 2024 12:05:44 +0100 Subject: [PATCH 017/283] Add `Storage` to `PolkadotXcm` for People Chains (#2959) After People Rococo deployment, we noticed that `safeXcmVersion` wasn't initialised. I think it is due to `Storage` missing in the pallet's declaration. This PR should fix it. --- cumulus/parachains/runtimes/people/people-rococo/src/lib.rs | 2 +- cumulus/parachains/runtimes/people/people-westend/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index f5398829c73..00dd58e4a50 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -428,7 +428,7 @@ construct_runtime!( // XCM & related XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31, + PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 33f0d511705..ee67c7419f1 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -428,7 +428,7 @@ construct_runtime!( // XCM helpers. XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31, + PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, -- GitLab From c1c0e62d33f210663c87f3170b60acb2d0cd32b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Wed, 17 Jan 2024 12:39:33 +0100 Subject: [PATCH 018/283] contracts: Update to Polkavm 0.5 (#2945) This will allow us to change to the target supporting atomics and makes the linker file no longer necessary. --- Cargo.lock | 30 +++++++++++++++---- substrate/frame/contracts/fixtures/Cargo.toml | 2 +- substrate/frame/contracts/fixtures/build.rs | 15 +++++----- .../frame/contracts/fixtures/build/Cargo.toml | 2 +- .../fixtures/build/riscv_memory_layout.ld | 4 --- 5 files changed, 35 insertions(+), 18 deletions(-) delete mode 100644 substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld diff --git a/Cargo.lock b/Cargo.lock index f685fcaa702..7f2221240cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3294,7 +3294,7 @@ dependencies = [ "gimli 0.27.3", "hashbrown 0.13.2", "log", - "regalloc2", + "regalloc2 0.6.1", "smallvec", "target-lexicon", ] @@ -13793,6 +13793,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fecd2caacfc4a7ee34243758dd7348859e6dec73f5e5df059890f5742ee46f0e" +[[package]] +name = "polkavm-common" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b4e215c80fe876147f3d58158d5dfeae7dabdd6047e175af77095b78d0035c" + [[package]] name = "polkavm-derive" version = "0.4.0" @@ -13809,7 +13815,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c99f4e7a9ff434ef9c885b874c99d824c3a5693bf5e3e8569bb1d2245a8c1b7f" dependencies = [ - "polkavm-common", + "polkavm-common 0.4.0", "proc-macro2", "quote", "syn 2.0.48", @@ -13817,15 +13823,16 @@ dependencies = [ [[package]] name = "polkavm-linker" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "550738c1b49b9279fa19d8ebed81f551b911b869227a20a190f85f6db45d5d0e" +checksum = "a5a668bb33c7f0b5f4ca91adb1e1e71cf4930fef5e6909f46c2180d65cce37d0" dependencies = [ "gimli 0.28.0", "hashbrown 0.14.3", "log", "object 0.32.2", - "polkavm-common", + "polkavm-common 0.5.0", + "regalloc2 0.9.3", "rustc-demangle", ] @@ -14597,6 +14604,19 @@ dependencies = [ "smallvec", ] +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + [[package]] name = "regex" version = "1.10.2" diff --git a/substrate/frame/contracts/fixtures/Cargo.toml b/substrate/frame/contracts/fixtures/Cargo.toml index 5ffac43d9de..7fdf56a91fc 100644 --- a/substrate/frame/contracts/fixtures/Cargo.toml +++ b/substrate/frame/contracts/fixtures/Cargo.toml @@ -21,7 +21,7 @@ parity-wasm = "0.45.0" tempfile = "3.8.1" toml = "0.8.2" twox-hash = "1.6.3" -polkavm-linker = { version = "0.4.0", optional = true } +polkavm-linker = { version = "0.5.0", optional = true } anyhow = "1.0.0" [features] diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 125ee7f3722..7b814ef77a6 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -234,11 +234,12 @@ fn post_process_wasm(input_path: &Path, output_path: &Path) -> Result<()> { /// Build contracts for RISC-V. #[cfg(feature = "riscv")] fn invoke_riscv_build(current_dir: &Path) -> Result<()> { - let encoded_rustflags = - ["-Crelocation-model=pie", "-Clink-arg=--emit-relocs", "-Clink-arg=-Tmemory.ld"] - .join("\x1f"); - - fs::write(current_dir.join("memory.ld"), include_bytes!("./build/riscv_memory_layout.ld"))?; + let encoded_rustflags = [ + "-Crelocation-model=pie", + "-Clink-arg=--emit-relocs", + "-Clink-arg=--export-dynamic-symbol=__polkavm_symbol_export_hack__*", + ] + .join("\x1f"); let build_res = Command::new(env::var("CARGO")?) .current_dir(current_dir) @@ -247,7 +248,7 @@ fn invoke_riscv_build(current_dir: &Path) -> Result<()> { .env("CARGO_ENCODED_RUSTFLAGS", encoded_rustflags) .env("RUSTUP_TOOLCHAIN", "rve-nightly") .env("RUSTUP_HOME", env::var("RUSTUP_HOME").unwrap_or_default()) - .args(["build", "--release", "--target=riscv32em-unknown-none-elf"]) + .args(["build", "--release", "--target=riscv32ema-unknown-none-elf"]) .output() .expect("failed to execute process"); @@ -288,7 +289,7 @@ fn write_output(build_dir: &Path, out_dir: &Path, entries: Vec) -> Result #[cfg(feature = "riscv")] post_process_riscv( - &build_dir.join("target/riscv32em-unknown-none-elf/release").join(entry.name()), + &build_dir.join("target/riscv32ema-unknown-none-elf/release").join(entry.name()), &out_dir.join(entry.out_riscv_filename()), )?; diff --git a/substrate/frame/contracts/fixtures/build/Cargo.toml b/substrate/frame/contracts/fixtures/build/Cargo.toml index 70bf0ba94fe..1ff6b7ae7f8 100644 --- a/substrate/frame/contracts/fixtures/build/Cargo.toml +++ b/substrate/frame/contracts/fixtures/build/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] uapi = { package = 'pallet-contracts-uapi', path = "", default-features = false } common = { package = 'pallet-contracts-fixtures-common', path = "" } -polkavm-derive = '0.4.0' +polkavm-derive = '0.5.0' [profile.release] opt-level = 3 diff --git a/substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld b/substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld deleted file mode 100644 index 89084263ada..00000000000 --- a/substrate/frame/contracts/fixtures/build/riscv_memory_layout.ld +++ /dev/null @@ -1,4 +0,0 @@ -SECTIONS { - .text : { KEEP(*(.text.polkavm_export)) } -} - -- GitLab From f80cfc22595bbb39b50d2bd39661ff9eef74cb60 Mon Sep 17 00:00:00 2001 From: Egor_P Date: Wed, 17 Jan 2024 15:40:23 +0100 Subject: [PATCH 019/283] [Backport] Version bumps from 1.6.0 release (#2965) This PR backports version bumps from release branch `release-polkadot-v1.6.0` back to `master` and also moved `prdoc` files related to the release to the appropriate folder --- Cargo.lock | 4 ++-- .../parachains/runtimes/assets/asset-hub-rococo/src/lib.rs | 4 ++-- .../parachains/runtimes/assets/asset-hub-westend/src/lib.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs | 2 +- .../runtimes/collectives/collectives-westend/src/lib.rs | 2 +- .../parachains/runtimes/contracts/contracts-rococo/src/lib.rs | 2 +- .../parachains/runtimes/coretime/coretime-westend/src/lib.rs | 2 +- .../parachains/runtimes/glutton/glutton-westend/src/lib.rs | 2 +- cumulus/parachains/runtimes/people/people-rococo/src/lib.rs | 2 +- cumulus/parachains/runtimes/people/people-westend/src/lib.rs | 2 +- .../parachains/runtimes/testing/rococo-parachain/src/lib.rs | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- polkadot/Cargo.toml | 2 +- polkadot/node/primitives/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- prdoc/{ => 1.6.0}/pr_1191.prdoc | 0 prdoc/{ => 1.6.0}/pr_1226.prdoc | 0 prdoc/{ => 1.6.0}/pr_1289.prdoc | 0 prdoc/{ => 1.6.0}/pr_1343.prdoc | 0 prdoc/{ => 1.6.0}/pr_1454.prdoc | 0 prdoc/{ => 1.6.0}/pr_1479.prdoc | 0 prdoc/{ => 1.6.0}/pr_1677.prdoc | 0 prdoc/{ => 1.6.0}/pr_1694.prdoc | 0 prdoc/{ => 1.6.0}/pr_1841.prdoc | 0 prdoc/{ => 1.6.0}/pr_2031.prdoc | 0 prdoc/{ => 1.6.0}/pr_2033.prdoc | 0 prdoc/{ => 1.6.0}/pr_2281.prdoc | 0 prdoc/{ => 1.6.0}/pr_2331.prdoc | 0 prdoc/{ => 1.6.0}/pr_2403.prdoc | 0 prdoc/{ => 1.6.0}/pr_2481.prdoc | 0 prdoc/{ => 1.6.0}/pr_2522.prdoc | 0 prdoc/{ => 1.6.0}/pr_2532.prdoc | 0 prdoc/{ => 1.6.0}/pr_2597.prdoc | 0 prdoc/{ => 1.6.0}/pr_2637.prdoc | 0 prdoc/{ => 1.6.0}/pr_2651.prdoc | 0 prdoc/{ => 1.6.0}/pr_2656.prdoc | 0 .../pr_2663-fix-could-not-create-temporary-drectory.prdoc | 0 prdoc/{ => 1.6.0}/pr_2666.prdoc | 0 prdoc/{ => 1.6.0}/pr_2682.prdoc | 0 prdoc/{ => 1.6.0}/pr_2684.prdoc | 0 prdoc/{ => 1.6.0}/pr_2687.prdoc | 0 prdoc/{ => 1.6.0}/pr_2689.prdoc | 0 prdoc/{ => 1.6.0}/pr_2694.prdoc | 0 prdoc/{ => 1.6.0}/pr_2758.prdoc | 0 prdoc/{ => 1.6.0}/pr_2764.prdoc | 0 prdoc/{ => 1.6.0}/pr_2767.prdoc | 0 prdoc/{ => 1.6.0}/pr_2771.prdoc | 0 prdoc/{ => 1.6.0}/pr_2783.prdoc | 0 prdoc/{ => 1.6.0}/pr_2799.prdoc | 0 prdoc/{ => 1.6.0}/pr_2803.prdoc | 0 prdoc/{ => 1.6.0}/pr_2804.prdoc | 0 prdoc/{ => 1.6.0}/pr_2811.prdoc | 0 prdoc/{ => 1.6.0}/pr_2813.prdoc | 0 prdoc/{ => 1.6.0}/pr_2823.prdoc | 0 prdoc/{ => 1.6.0}/pr_2834.prdoc | 0 prdoc/{ => 1.6.0}/pr_2835.prdoc | 0 prdoc/{ => 1.6.0}/pr_2862.prdoc | 0 prdoc/{ => 1.6.0}/pr_2886.prdoc | 0 prdoc/{ => 1.6.0}/pr_2899.prdoc | 0 60 files changed, 18 insertions(+), 18 deletions(-) rename prdoc/{ => 1.6.0}/pr_1191.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1226.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1289.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1343.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1454.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1479.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1677.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1694.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_1841.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2031.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2033.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2281.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2331.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2403.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2481.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2522.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2532.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2597.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2637.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2651.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2656.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2663-fix-could-not-create-temporary-drectory.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2666.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2682.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2684.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2687.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2689.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2694.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2758.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2764.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2767.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2771.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2783.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2799.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2803.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2804.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2811.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2813.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2823.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2834.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2835.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2862.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2886.prdoc (100%) rename prdoc/{ => 1.6.0}/pr_2899.prdoc (100%) diff --git a/Cargo.lock b/Cargo.lock index 7f2221240cc..849bc069d20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12065,7 +12065,7 @@ dependencies = [ [[package]] name = "polkadot" -version = "1.5.0" +version = "1.6.0" dependencies = [ "assert_cmd", "color-eyre", @@ -13038,7 +13038,7 @@ dependencies = [ [[package]] name = "polkadot-parachain-bin" -version = "1.5.0" +version = "1.6.0" dependencies = [ "assert_cmd", "asset-hub-rococo-runtime", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 53b41892685..494ca3d1240 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -115,7 +115,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_005_001, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, @@ -128,7 +128,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index cf10c0ac052..5950173d90e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westmint"), impl_name: create_runtime_str!("westmint"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 7e99b039309..09aeedfc223 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -201,7 +201,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-rococo"), impl_name: create_runtime_str!("bridge-hub-rococo"), authoring_version: 1, - spec_version: 1_005_002, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index d920f5a98cf..55a38fc8543 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -175,7 +175,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-westend"), impl_name: create_runtime_str!("bridge-hub-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index a527f620137..3aff4671636 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -116,7 +116,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("collectives-westend"), impl_name: create_runtime_str!("collectives-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 5, diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index bc7d94889a1..707766ca226 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("contracts-rococo"), impl_name: create_runtime_str!("contracts-rococo"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 59ed8d7c603..bc6b6b3caf1 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -120,7 +120,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-westend"), impl_name: create_runtime_str!("coretime-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 2c51791c074..15899e49195 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -99,7 +99,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("glutton-westend"), impl_name: create_runtime_str!("glutton-westend"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 00dd58e4a50..ba5b727484c 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -124,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-rococo"), impl_name: create_runtime_str!("people-rococo"), authoring_version: 1, - spec_version: 1_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index ee67c7419f1..4015d841b81 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -124,7 +124,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-westend"), impl_name: create_runtime_str!("people-westend"), authoring_version: 1, - spec_version: 1_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 102127479d2..795efa39247 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -108,7 +108,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("test-parachain"), impl_name: create_runtime_str!("test-parachain"), authoring_version: 1, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 9f42a265f39..84ba8a36d51 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-parachain-bin" -version = "1.5.0" +version = "1.6.0" authors.workspace = true build = "build.rs" edition.workspace = true diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml index d769957490e..8c8e9cebd41 100644 --- a/polkadot/Cargo.toml +++ b/polkadot/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.64.0" readme = "README.md" authors.workspace = true edition.workspace = true -version = "1.5.0" +version = "1.6.0" default-run = "polkadot" [lints] diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 6ac6b82c223..e7fd2c46381 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -58,7 +58,7 @@ pub use disputes::{ /// relatively rare. /// /// The associated worker binaries should use the same version as the node that spawns them. -pub const NODE_VERSION: &'static str = "1.5.0"; +pub const NODE_VERSION: &'static str = "1.6.0"; // For a 16-ary Merkle Prefix Trie, we can expect at most 16 32-byte hashes per node // plus some overhead: diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 92efdf0c0c5..28b82956a47 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -147,7 +147,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westend"), impl_name: create_runtime_str!("parity-westend"), authoring_version: 2, - spec_version: 1_005_000, + spec_version: 1_006_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, diff --git a/prdoc/pr_1191.prdoc b/prdoc/1.6.0/pr_1191.prdoc similarity index 100% rename from prdoc/pr_1191.prdoc rename to prdoc/1.6.0/pr_1191.prdoc diff --git a/prdoc/pr_1226.prdoc b/prdoc/1.6.0/pr_1226.prdoc similarity index 100% rename from prdoc/pr_1226.prdoc rename to prdoc/1.6.0/pr_1226.prdoc diff --git a/prdoc/pr_1289.prdoc b/prdoc/1.6.0/pr_1289.prdoc similarity index 100% rename from prdoc/pr_1289.prdoc rename to prdoc/1.6.0/pr_1289.prdoc diff --git a/prdoc/pr_1343.prdoc b/prdoc/1.6.0/pr_1343.prdoc similarity index 100% rename from prdoc/pr_1343.prdoc rename to prdoc/1.6.0/pr_1343.prdoc diff --git a/prdoc/pr_1454.prdoc b/prdoc/1.6.0/pr_1454.prdoc similarity index 100% rename from prdoc/pr_1454.prdoc rename to prdoc/1.6.0/pr_1454.prdoc diff --git a/prdoc/pr_1479.prdoc b/prdoc/1.6.0/pr_1479.prdoc similarity index 100% rename from prdoc/pr_1479.prdoc rename to prdoc/1.6.0/pr_1479.prdoc diff --git a/prdoc/pr_1677.prdoc b/prdoc/1.6.0/pr_1677.prdoc similarity index 100% rename from prdoc/pr_1677.prdoc rename to prdoc/1.6.0/pr_1677.prdoc diff --git a/prdoc/pr_1694.prdoc b/prdoc/1.6.0/pr_1694.prdoc similarity index 100% rename from prdoc/pr_1694.prdoc rename to prdoc/1.6.0/pr_1694.prdoc diff --git a/prdoc/pr_1841.prdoc b/prdoc/1.6.0/pr_1841.prdoc similarity index 100% rename from prdoc/pr_1841.prdoc rename to prdoc/1.6.0/pr_1841.prdoc diff --git a/prdoc/pr_2031.prdoc b/prdoc/1.6.0/pr_2031.prdoc similarity index 100% rename from prdoc/pr_2031.prdoc rename to prdoc/1.6.0/pr_2031.prdoc diff --git a/prdoc/pr_2033.prdoc b/prdoc/1.6.0/pr_2033.prdoc similarity index 100% rename from prdoc/pr_2033.prdoc rename to prdoc/1.6.0/pr_2033.prdoc diff --git a/prdoc/pr_2281.prdoc b/prdoc/1.6.0/pr_2281.prdoc similarity index 100% rename from prdoc/pr_2281.prdoc rename to prdoc/1.6.0/pr_2281.prdoc diff --git a/prdoc/pr_2331.prdoc b/prdoc/1.6.0/pr_2331.prdoc similarity index 100% rename from prdoc/pr_2331.prdoc rename to prdoc/1.6.0/pr_2331.prdoc diff --git a/prdoc/pr_2403.prdoc b/prdoc/1.6.0/pr_2403.prdoc similarity index 100% rename from prdoc/pr_2403.prdoc rename to prdoc/1.6.0/pr_2403.prdoc diff --git a/prdoc/pr_2481.prdoc b/prdoc/1.6.0/pr_2481.prdoc similarity index 100% rename from prdoc/pr_2481.prdoc rename to prdoc/1.6.0/pr_2481.prdoc diff --git a/prdoc/pr_2522.prdoc b/prdoc/1.6.0/pr_2522.prdoc similarity index 100% rename from prdoc/pr_2522.prdoc rename to prdoc/1.6.0/pr_2522.prdoc diff --git a/prdoc/pr_2532.prdoc b/prdoc/1.6.0/pr_2532.prdoc similarity index 100% rename from prdoc/pr_2532.prdoc rename to prdoc/1.6.0/pr_2532.prdoc diff --git a/prdoc/pr_2597.prdoc b/prdoc/1.6.0/pr_2597.prdoc similarity index 100% rename from prdoc/pr_2597.prdoc rename to prdoc/1.6.0/pr_2597.prdoc diff --git a/prdoc/pr_2637.prdoc b/prdoc/1.6.0/pr_2637.prdoc similarity index 100% rename from prdoc/pr_2637.prdoc rename to prdoc/1.6.0/pr_2637.prdoc diff --git a/prdoc/pr_2651.prdoc b/prdoc/1.6.0/pr_2651.prdoc similarity index 100% rename from prdoc/pr_2651.prdoc rename to prdoc/1.6.0/pr_2651.prdoc diff --git a/prdoc/pr_2656.prdoc b/prdoc/1.6.0/pr_2656.prdoc similarity index 100% rename from prdoc/pr_2656.prdoc rename to prdoc/1.6.0/pr_2656.prdoc diff --git a/prdoc/pr_2663-fix-could-not-create-temporary-drectory.prdoc b/prdoc/1.6.0/pr_2663-fix-could-not-create-temporary-drectory.prdoc similarity index 100% rename from prdoc/pr_2663-fix-could-not-create-temporary-drectory.prdoc rename to prdoc/1.6.0/pr_2663-fix-could-not-create-temporary-drectory.prdoc diff --git a/prdoc/pr_2666.prdoc b/prdoc/1.6.0/pr_2666.prdoc similarity index 100% rename from prdoc/pr_2666.prdoc rename to prdoc/1.6.0/pr_2666.prdoc diff --git a/prdoc/pr_2682.prdoc b/prdoc/1.6.0/pr_2682.prdoc similarity index 100% rename from prdoc/pr_2682.prdoc rename to prdoc/1.6.0/pr_2682.prdoc diff --git a/prdoc/pr_2684.prdoc b/prdoc/1.6.0/pr_2684.prdoc similarity index 100% rename from prdoc/pr_2684.prdoc rename to prdoc/1.6.0/pr_2684.prdoc diff --git a/prdoc/pr_2687.prdoc b/prdoc/1.6.0/pr_2687.prdoc similarity index 100% rename from prdoc/pr_2687.prdoc rename to prdoc/1.6.0/pr_2687.prdoc diff --git a/prdoc/pr_2689.prdoc b/prdoc/1.6.0/pr_2689.prdoc similarity index 100% rename from prdoc/pr_2689.prdoc rename to prdoc/1.6.0/pr_2689.prdoc diff --git a/prdoc/pr_2694.prdoc b/prdoc/1.6.0/pr_2694.prdoc similarity index 100% rename from prdoc/pr_2694.prdoc rename to prdoc/1.6.0/pr_2694.prdoc diff --git a/prdoc/pr_2758.prdoc b/prdoc/1.6.0/pr_2758.prdoc similarity index 100% rename from prdoc/pr_2758.prdoc rename to prdoc/1.6.0/pr_2758.prdoc diff --git a/prdoc/pr_2764.prdoc b/prdoc/1.6.0/pr_2764.prdoc similarity index 100% rename from prdoc/pr_2764.prdoc rename to prdoc/1.6.0/pr_2764.prdoc diff --git a/prdoc/pr_2767.prdoc b/prdoc/1.6.0/pr_2767.prdoc similarity index 100% rename from prdoc/pr_2767.prdoc rename to prdoc/1.6.0/pr_2767.prdoc diff --git a/prdoc/pr_2771.prdoc b/prdoc/1.6.0/pr_2771.prdoc similarity index 100% rename from prdoc/pr_2771.prdoc rename to prdoc/1.6.0/pr_2771.prdoc diff --git a/prdoc/pr_2783.prdoc b/prdoc/1.6.0/pr_2783.prdoc similarity index 100% rename from prdoc/pr_2783.prdoc rename to prdoc/1.6.0/pr_2783.prdoc diff --git a/prdoc/pr_2799.prdoc b/prdoc/1.6.0/pr_2799.prdoc similarity index 100% rename from prdoc/pr_2799.prdoc rename to prdoc/1.6.0/pr_2799.prdoc diff --git a/prdoc/pr_2803.prdoc b/prdoc/1.6.0/pr_2803.prdoc similarity index 100% rename from prdoc/pr_2803.prdoc rename to prdoc/1.6.0/pr_2803.prdoc diff --git a/prdoc/pr_2804.prdoc b/prdoc/1.6.0/pr_2804.prdoc similarity index 100% rename from prdoc/pr_2804.prdoc rename to prdoc/1.6.0/pr_2804.prdoc diff --git a/prdoc/pr_2811.prdoc b/prdoc/1.6.0/pr_2811.prdoc similarity index 100% rename from prdoc/pr_2811.prdoc rename to prdoc/1.6.0/pr_2811.prdoc diff --git a/prdoc/pr_2813.prdoc b/prdoc/1.6.0/pr_2813.prdoc similarity index 100% rename from prdoc/pr_2813.prdoc rename to prdoc/1.6.0/pr_2813.prdoc diff --git a/prdoc/pr_2823.prdoc b/prdoc/1.6.0/pr_2823.prdoc similarity index 100% rename from prdoc/pr_2823.prdoc rename to prdoc/1.6.0/pr_2823.prdoc diff --git a/prdoc/pr_2834.prdoc b/prdoc/1.6.0/pr_2834.prdoc similarity index 100% rename from prdoc/pr_2834.prdoc rename to prdoc/1.6.0/pr_2834.prdoc diff --git a/prdoc/pr_2835.prdoc b/prdoc/1.6.0/pr_2835.prdoc similarity index 100% rename from prdoc/pr_2835.prdoc rename to prdoc/1.6.0/pr_2835.prdoc diff --git a/prdoc/pr_2862.prdoc b/prdoc/1.6.0/pr_2862.prdoc similarity index 100% rename from prdoc/pr_2862.prdoc rename to prdoc/1.6.0/pr_2862.prdoc diff --git a/prdoc/pr_2886.prdoc b/prdoc/1.6.0/pr_2886.prdoc similarity index 100% rename from prdoc/pr_2886.prdoc rename to prdoc/1.6.0/pr_2886.prdoc diff --git a/prdoc/pr_2899.prdoc b/prdoc/1.6.0/pr_2899.prdoc similarity index 100% rename from prdoc/pr_2899.prdoc rename to prdoc/1.6.0/pr_2899.prdoc -- GitLab From f574868822d5976219d391de5acd66bb773e4964 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Thu, 18 Jan 2024 07:46:08 +0100 Subject: [PATCH 020/283] Rococo Identity Migration Part 2 + Bug Fix (#2946) Order: - [x] Start People Chain - [RPC node](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-people-rpc.polkadot.io#/explorer) - [x] Upgrade Rococo Relay (`EnsureRoot` -> `EnsureSigned`) (v1,006,002) - Done [here](https://rococo.subscan.io/extrinsic/0xef07e0f9dbb2b9e829305f132e6ce45d291239286e409177e20895e6687daa6c) - [x] Migrate all identities - Done, see extrinsics from [this account](https://rococo.subscan.io/account/5FyNYrBwndvBttTkGUqGGCRAXtBH4Mh8xELDaxaFywTsjDKb) - [x] Upgrade Rococo People (remove call filter) (v1,006,002) - Authorized [here](https://rococo.subscan.io/extrinsic/0xedf6a80229bd411b7ed8d3a489a767b0f773bed5c49239987a294c293a35b98b) With added: - [x] Upgrade Rococo People to fix `poke_deposit` bug (v1,006,001) - Authorized [here](https://rococo.subscan.io/extrinsic/0xd1dc3cd6e8274bd0196f8d9f13ed09f6e9c76e6a40f9786a1629f4cb22cf948d) Note: It's also possible to remove the Identity Migrator pallet from both the Relay Chain and the parachain at this time. I will leave them in for now to preserve the test cases until we run them on Kusama/Polkadot. We will also want a follow up to remove all Identity-related state from the Relay Chain. --- .../people-rococo/src/tests/reap_identity.rs | 2 +- .../runtimes/people/people-rococo/src/lib.rs | 14 ++--- .../people/people-rococo/src/xcm_config.rs | 18 ++++--- .../people/people-westend/src/xcm_config.rs | 18 ++++--- polkadot/runtime/rococo/src/lib.rs | 7 ++- substrate/frame/identity/src/lib.rs | 25 +++++---- substrate/frame/identity/src/tests.rs | 51 +++++++++++++++++++ 7 files changed, 95 insertions(+), 40 deletions(-) diff --git a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs index 2902f359dfb..58bb9504dbd 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/people/people-rococo/src/tests/reap_identity.rs @@ -291,7 +291,7 @@ fn assert_reap_id_relay(total_deposit: Balance, id: &Identity) { assert_eq!(reserved_balance, total_deposit); assert_ok!(RococoIdentityMigrator::reap_identity( - RococoOrigin::root(), + RococoOrigin::signed(RococoRelaySender::get()), RococoRelaySender::get() )); diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index ba5b727484c..21c24086cbe 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -30,8 +30,7 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, EverythingBut, - TransformOrigin, + ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, TransformOrigin, }, weights::{ConstantMultiplier, Weight}, PalletId, @@ -124,7 +123,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-rococo"), impl_name: create_runtime_str!("people-rococo"), authoring_version: 1, - spec_version: 1_006_000, + spec_version: 1_006_002, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, @@ -162,16 +161,9 @@ parameter_types! { pub const SS58Prefix: u8 = 42; } -pub struct IdentityCalls; -impl Contains for IdentityCalls { - fn contains(c: &RuntimeCall) -> bool { - matches!(c, RuntimeCall::Identity(_)) - } -} - #[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { - type BaseCallFilter = EverythingBut; + type BaseCallFilter = Everything; type BlockWeights = RuntimeBlockWeights; type BlockLength = RuntimeBlockLength; type AccountId = AccountId; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs index 7ef6cb2fac9..168d7eaa605 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/xcm_config.rs @@ -176,13 +176,17 @@ impl Contains for SafeCallFilter { matches!( call, - RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) | - RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } | - frame_system::Call::set_code { .. } | - frame_system::Call::set_code_without_checks { .. } | - frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) | + RuntimeCall::PolkadotXcm( + pallet_xcm::Call::force_xcm_version { .. } | + pallet_xcm::Call::force_default_xcm_version { .. } + ) | RuntimeCall::System( + frame_system::Call::set_heap_pages { .. } | + frame_system::Call::set_code { .. } | + frame_system::Call::set_code_without_checks { .. } | + frame_system::Call::authorize_upgrade { .. } | + frame_system::Call::authorize_upgrade_without_checks { .. } | + frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) | RuntimeCall::Timestamp(..) | RuntimeCall::Balances(..) | RuntimeCall::CollatorSelection( diff --git a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs index 59c00dc5ff6..18c03a968ef 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/xcm_config.rs @@ -183,13 +183,17 @@ impl Contains for SafeCallFilter { matches!( call, - RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) | - RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } | - frame_system::Call::set_code { .. } | - frame_system::Call::set_code_without_checks { .. } | - frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) | + RuntimeCall::PolkadotXcm( + pallet_xcm::Call::force_xcm_version { .. } | + pallet_xcm::Call::force_default_xcm_version { .. } + ) | RuntimeCall::System( + frame_system::Call::set_heap_pages { .. } | + frame_system::Call::set_code { .. } | + frame_system::Call::set_code_without_checks { .. } | + frame_system::Call::authorize_upgrade { .. } | + frame_system::Call::authorize_upgrade_without_checks { .. } | + frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) | RuntimeCall::Timestamp(..) | RuntimeCall::Balances(..) | RuntimeCall::CollatorSelection( diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index fec82fc86f9..0e2eaa03567 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -79,7 +79,7 @@ use frame_support::{ weights::{ConstantMultiplier, WeightMeter}, PalletId, }; -use frame_system::EnsureRoot; +use frame_system::{EnsureRoot, EnsureSigned}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use pallet_identity::legacy::IdentityInfo; use pallet_session::historical as session_historical; @@ -150,7 +150,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("rococo"), impl_name: create_runtime_str!("parity-rococo-v2.0"), authoring_version: 0, - spec_version: 1_006_001, + spec_version: 1_006_002, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, @@ -1142,8 +1142,7 @@ impl auctions::Config for Runtime { impl identity_migrator::Config for Runtime { type RuntimeEvent = RuntimeEvent; - // To be changed to `EnsureSigned` once there is a People Chain to migrate to. - type Reaper = EnsureRoot; + type Reaper = EnsureSigned; type ReapIdentityHandler = ToParachainIdentityReaper; type WeightInfo = weights::runtime_common_identity_migrator::WeightInfo; } diff --git a/substrate/frame/identity/src/lib.rs b/substrate/frame/identity/src/lib.rs index 1df0a619ea4..78d59180b3f 100644 --- a/substrate/frame/identity/src/lib.rs +++ b/substrate/frame/identity/src/lib.rs @@ -1395,16 +1395,21 @@ impl Pallet { }, )?; - // Subs Deposit - let new_subs_deposit = SubsOf::::try_mutate( - &target, - |(current_subs_deposit, subs_of)| -> Result, DispatchError> { - let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); - Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; - *current_subs_deposit = new_subs_deposit; - Ok(new_subs_deposit) - }, - )?; + let new_subs_deposit = if SubsOf::::contains_key(&target) { + SubsOf::::try_mutate( + &target, + |(current_subs_deposit, subs_of)| -> Result, DispatchError> { + let new_subs_deposit = Self::subs_deposit(subs_of.len() as u32); + Self::rejig_deposit(&target, *current_subs_deposit, new_subs_deposit)?; + *current_subs_deposit = new_subs_deposit; + Ok(new_subs_deposit) + }, + )? + } else { + // If the item doesn't exist, there is no "old" deposit, and the new one is zero, so no + // need to call rejig, it'd just be zero -> zero. + Zero::zero() + }; Ok((new_id_deposit, new_subs_deposit)) } diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index 4da31782261..e6107cda0f0 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -952,6 +952,57 @@ fn poke_deposit_works() { }); } +#[test] +fn poke_deposit_does_not_insert_new_subs_storage() { + new_test_ext().execute_with(|| { + let [_, _, _, _, ten, _, _, _] = accounts(); + let ten_info = infoof_ten(); + // Set a custom registration with 0 deposit + IdentityOf::::insert::< + _, + ( + Registration>, + Option>, + ), + >( + &ten, + ( + Registration { + judgements: Default::default(), + deposit: Zero::zero(), + info: ten_info.clone(), + }, + None::>, + ), + ); + assert!(Identity::identity(ten.clone()).is_some()); + + // Balance is free + assert_eq!(Balances::free_balance(ten.clone()), 1000); + + // poke + assert_ok!(Identity::poke_deposit(&ten)); + + // free balance reduced correctly + let id_deposit = id_deposit(&ten_info); + assert_eq!(Balances::free_balance(ten.clone()), 1000 - id_deposit); + // new registration deposit is 10 + assert_eq!( + Identity::identity(&ten), + Some(( + Registration { + judgements: Default::default(), + deposit: id_deposit, + info: infoof_ten() + }, + None + )) + ); + // No new subs storage item. + assert!(!SubsOf::::contains_key(&ten)); + }); +} + #[test] fn adding_and_removing_authorities_should_work() { new_test_ext().execute_with(|| { -- GitLab From f8954093b4226512ea63cb59aae1f6890aeffe76 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Thu, 18 Jan 2024 09:33:58 +0200 Subject: [PATCH 021/283] Filter votes from disabled validators in `BackedCandidates` in process_inherent_data (#2889) Backport of https://github.com/paritytech/polkadot-sdk/pull/1863 to master Extend candidate sanitation in paras_inherent by removing backing votes from disabled validators. Check https://github.com/paritytech/polkadot-sdk/issues/1592 for more details. This change is related to the disabling strategy implementation (https://github.com/paritytech/polkadot-sdk/pull/2226). --------- Co-authored-by: ordian Co-authored-by: ordian Co-authored-by: Maciej --- .../src/runtime/parainherent.md | 32 +++ .../runtime/common/src/assigned_slots/mod.rs | 4 +- .../runtime/common/src/integration_tests.rs | 4 +- .../runtime/common/src/paras_registrar/mod.rs | 4 +- polkadot/runtime/parachains/src/mock.rs | 27 ++- .../parachains/src/paras_inherent/mod.rs | 181 ++++++++++++++-- .../parachains/src/paras_inherent/tests.rs | 199 ++++++++++++++++-- .../src/runtime_api_impl/vstaging.rs | 19 +- polkadot/runtime/parachains/src/scheduler.rs | 5 + polkadot/runtime/parachains/src/shared.rs | 42 +++- polkadot/runtime/rococo/src/lib.rs | 4 +- polkadot/runtime/test-runtime/src/lib.rs | 4 +- polkadot/runtime/westend/src/lib.rs | 4 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 4 +- .../xcm-simulator/example/src/relay_chain.rs | 4 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 4 +- prdoc/pr_2889.prdoc | 10 + substrate/frame/aura/src/mock.rs | 4 + .../contracts/mock-network/src/relay_chain.rs | 4 +- substrate/frame/session/src/lib.rs | 4 + .../frame/support/src/traits/validation.rs | 7 + 21 files changed, 506 insertions(+), 64 deletions(-) create mode 100644 prdoc/pr_2889.prdoc diff --git a/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md b/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md index 4a771f1df64..5419ddae83d 100644 --- a/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md +++ b/polkadot/roadmap/implementers-guide/src/runtime/parainherent.md @@ -60,3 +60,35 @@ processing it, so the processed inherent data is simply dropped. This also means that the `enter` function keeps data around for no good reason. This seems acceptable though as the size of a block is rather limited. Nevertheless if we ever wanted to optimize this we can easily implement an inherent collector that has two implementations, where one clones and stores the data and the other just passes it on. + +## Sanitization + +`ParasInherent` with the entry point of `create_inherent` sanitizes the input data, while the `enter` entry point +enforces already sanitized input data. If unsanitized data is provided the module generates an error. + +Disputes are included in the block with a priority for a security reasons. It's important to include as many dispute +votes onchain as possible so that disputes conclude faster and the offenders are punished. However if there are too many +disputes to include in a block the dispute set is trimmed so that it respects max block weight. + +Dispute data is first deduplicated and sorted by block number (older first) and dispute location (local then remote). +Concluded and ancient (disputes initiated before the post conclusion acceptance period) disputes are filtered out. +Votes with invalid signatures or from unknown validators (not found in the active set for the current session) are also +filtered out. + +All dispute statements are included in the order described in the previous paragraph until the available block weight is +exhausted. After the dispute data is included all remaining weight is filled in with candidates and availability +bitfields. Bitfields are included with priority, then candidates containing code updates and finally any backed +candidates. If there is not enough weight for all backed candidates they are trimmed by random selection. Disputes are +processed in three separate functions - `deduplicate_and_sort_dispute_data`, `filter_dispute_data` and +`limit_and_sanitize_disputes`. + +Availability bitfields are also sanitized by dropping malformed ones, containing disputed cores or bad signatures. Refer +to `sanitize_bitfields` function for implementation details. + +Backed candidates sanitization removes malformed ones, candidates which have got concluded invalid disputes against them +or candidates produced by unassigned cores. Furthermore any backing votes from disabled validators for a candidate are +dropped. This is part of the validator disabling strategy. After filtering the statements from disabled validators a +backed candidate may end up with votes count less than `minimum_backing_votes` (a parameter from `HostConfiguiration`). +In this case the whole candidate is dropped otherwise it will be rejected by `process_candidates` from pallet inclusion. +All checks related to backed candidates are implemented in `sanitize_backed_candidates` and +`filter_backed_statements_from_disabled_validators`. diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index cb56cb8a118..de8c00df9dd 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -746,7 +746,9 @@ mod tests { type AssignCoretime = (); } - impl parachains_shared::Config for Test {} + impl parachains_shared::Config for Test { + type DisabledValidators = (); + } parameter_types! { pub const LeasePeriod: BlockNumber = 3; diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index cfa8f4c3ad9..b536b80e245 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -197,7 +197,9 @@ impl configuration::Config for Test { type WeightInfo = configuration::TestWeightInfo; } -impl shared::Config for Test {} +impl shared::Config for Test { + type DisabledValidators = (); +} impl origin::Config for Test {} diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 9719f02677d..448490b34a7 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -799,7 +799,9 @@ mod tests { type MaxFreezes = ConstU32<1>; } - impl shared::Config for Test {} + impl shared::Config for Test { + type DisabledValidators = (); + } impl origin::Config for Test {} diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index c08bab0ef0f..e3fcf7dd603 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -194,7 +194,22 @@ impl crate::configuration::Config for Test { type WeightInfo = crate::configuration::TestWeightInfo; } -impl crate::shared::Config for Test {} +pub struct MockDisabledValidators {} +impl frame_support::traits::DisabledValidators for MockDisabledValidators { + /// Returns true if the given validator is disabled. + fn is_disabled(index: u32) -> bool { + disabled_validators().iter().any(|v| *v == index) + } + + /// Returns a hardcoded list (`DISABLED_VALIDATORS`) of disabled validators + fn disabled_validators() -> Vec { + disabled_validators() + } +} + +impl crate::shared::Config for Test { + type DisabledValidators = MockDisabledValidators; +} impl origin::Config for Test {} @@ -564,6 +579,8 @@ thread_local! { pub static AVAILABILITY_REWARDS: RefCell> = RefCell::new(HashMap::new()); + + pub static DISABLED_VALIDATORS: RefCell> = RefCell::new(vec![]); } pub fn backing_rewards() -> HashMap { @@ -574,6 +591,10 @@ pub fn availability_rewards() -> HashMap { AVAILABILITY_REWARDS.with(|r| r.borrow().clone()) } +pub fn disabled_validators() -> Vec { + DISABLED_VALIDATORS.with(|r| r.borrow().clone()) +} + parameter_types! { pub static Processed: Vec<(ParaId, UpwardMessage)> = vec![]; } @@ -713,3 +734,7 @@ pub(crate) fn deregister_parachain(id: ParaId) { pub(crate) fn try_deregister_parachain(id: ParaId) -> crate::DispatchResult { frame_support::storage::transactional::with_storage_layer(|| Paras::schedule_para_cleanup(id)) } + +pub(crate) fn set_disabled_validators(disabled: Vec) { + DISABLED_VALIDATORS.with(|d| *d.borrow_mut() = disabled) +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/mod.rs b/polkadot/runtime/parachains/src/paras_inherent/mod.rs index 8c33199c092..81e092f0a99 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/mod.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/mod.rs @@ -30,7 +30,8 @@ use crate::{ metrics::METRICS, paras, scheduler::{self, FreedReason}, - shared, ParaId, + shared::{self, AllowedRelayParentsTracker}, + ParaId, }; use bitvec::prelude::BitVec; use frame_support::{ @@ -42,8 +43,8 @@ use frame_support::{ use frame_system::pallet_prelude::*; use pallet_babe::{self, ParentBlockRandomness}; use primitives::{ - BackedCandidate, CandidateHash, CandidateReceipt, CheckedDisputeStatementSet, - CheckedMultiDisputeStatementSet, CoreIndex, DisputeStatementSet, + effective_minimum_backing_votes, BackedCandidate, CandidateHash, CandidateReceipt, + CheckedDisputeStatementSet, CheckedMultiDisputeStatementSet, CoreIndex, DisputeStatementSet, InherentData as ParachainsInherentData, MultiDisputeStatementSet, ScrapedOnChainVotes, SessionIndex, SignedAvailabilityBitfields, SigningContext, UncheckedSignedAvailabilityBitfield, UncheckedSignedAvailabilityBitfields, ValidatorId, ValidatorIndex, ValidityAttestation, @@ -142,6 +143,8 @@ pub mod pallet { DisputeStatementsUnsortedOrDuplicates, /// A dispute statement was invalid. DisputeInvalid, + /// A candidate was backed by a disabled validator + BackedByDisabled, } /// Whether the paras inherent was included within this block. @@ -378,6 +381,7 @@ impl Pallet { let bitfields_weight = signed_bitfields_weight::(&bitfields); let disputes_weight = multi_dispute_statement_sets_weight::(&disputes); + // Weight before filtering/sanitization let all_weight_before = candidates_weight + bitfields_weight + disputes_weight; METRICS.on_before_filter(all_weight_before.ref_time()); @@ -587,17 +591,19 @@ impl Pallet { METRICS.on_candidates_processed_total(backed_candidates.len() as u64); - let backed_candidates = sanitize_backed_candidates::( - backed_candidates, - |candidate_idx: usize, - backed_candidate: &BackedCandidate<::Hash>| - -> bool { - let para_id = backed_candidate.descriptor().para_id; - let prev_context = >::para_most_recent_context(para_id); - let check_ctx = CandidateCheckContext::::new(prev_context); - - // never include a concluded-invalid candidate - current_concluded_invalid_disputes.contains(&backed_candidate.hash()) || + let SanitizedBackedCandidates { backed_candidates, votes_from_disabled_were_dropped } = + sanitize_backed_candidates::( + backed_candidates, + &allowed_relay_parents, + |candidate_idx: usize, + backed_candidate: &BackedCandidate<::Hash>| + -> bool { + let para_id = backed_candidate.descriptor().para_id; + let prev_context = >::para_most_recent_context(para_id); + let check_ctx = CandidateCheckContext::::new(prev_context); + + // never include a concluded-invalid candidate + current_concluded_invalid_disputes.contains(&backed_candidate.hash()) || // Instead of checking the candidates with code upgrades twice // move the checking up here and skip it in the training wheels fallback. // That way we avoid possible duplicate checks while assuring all @@ -607,12 +613,19 @@ impl Pallet { check_ctx .verify_backed_candidate(&allowed_relay_parents, candidate_idx, backed_candidate) .is_err() - }, - &scheduled, - ); + }, + &scheduled, + ); METRICS.on_candidates_sanitized(backed_candidates.len() as u64); + // In `Enter` context (invoked during execution) there should be no backing votes from + // disabled validators because they should have been filtered out during inherent data + // preparation (`ProvideInherent` context). Abort in such cases. + if context == ProcessInherentDataContext::Enter { + ensure!(!votes_from_disabled_were_dropped, Error::::BackedByDisabled); + } + // Process backed candidates according to scheduled cores. let inclusion::ProcessedCandidates::< as HeaderT>::Hash> { core_indices: occupied, @@ -900,7 +913,19 @@ pub(crate) fn sanitize_bitfields( bitfields } -/// Filter out any candidates that have a concluded invalid dispute. +// Result from `sanitize_backed_candidates` +#[derive(Debug, PartialEq)] +struct SanitizedBackedCandidates { + // Sanitized backed candidates. The `Vec` is sorted according to the occupied core index. + backed_candidates: Vec>, + // Set to true if any votes from disabled validators were dropped from the input. + votes_from_disabled_were_dropped: bool, +} + +/// Filter out: +/// 1. any candidates that have a concluded invalid dispute +/// 2. all backing votes from disabled validators +/// 3. any candidates that end up with less than `effective_minimum_backing_votes` backing votes /// /// `scheduled` follows the same naming scheme as provided in the /// guide: Currently `free` but might become `occupied`. @@ -910,15 +935,17 @@ pub(crate) fn sanitize_bitfields( /// `candidate_has_concluded_invalid_dispute` must return `true` if the candidate /// is disputed, false otherwise. The passed `usize` is the candidate index. /// -/// The returned `Vec` is sorted according to the occupied core index. +/// Returns struct `SanitizedBackedCandidates` where `backed_candidates` are sorted according to the +/// occupied core index. fn sanitize_backed_candidates< T: crate::inclusion::Config, F: FnMut(usize, &BackedCandidate) -> bool, >( mut backed_candidates: Vec>, + allowed_relay_parents: &AllowedRelayParentsTracker>, mut candidate_has_concluded_invalid_dispute_or_is_invalid: F, scheduled: &BTreeMap, -) -> Vec> { +) -> SanitizedBackedCandidates { // Remove any candidates that were concluded invalid. // This does not assume sorting. backed_candidates.indexed_retain(move |candidate_idx, backed_candidate| { @@ -936,6 +963,13 @@ fn sanitize_backed_candidates< scheduled.get(&desc.para_id).is_some() }); + // Filter out backing statements from disabled validators + let dropped_disabled = filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &allowed_relay_parents, + scheduled, + ); + // Sort the `Vec` last, once there is a guarantee that these // `BackedCandidates` references the expected relay chain parent, // but more importantly are scheduled for a free core. @@ -946,7 +980,10 @@ fn sanitize_backed_candidates< scheduled[&x.descriptor().para_id].cmp(&scheduled[&y.descriptor().para_id]) }); - backed_candidates + SanitizedBackedCandidates { + backed_candidates, + votes_from_disabled_were_dropped: dropped_disabled, + } } /// Derive entropy from babe provided per block randomness. @@ -1029,3 +1066,105 @@ fn limit_and_sanitize_disputes< (checked, checked_disputes_weight) } } + +// Filters statements from disabled validators in `BackedCandidate`, non-scheduled candidates and +// few more sanity checks. Returns `true` if at least one statement is removed and `false` +// otherwise. +fn filter_backed_statements_from_disabled_validators( + backed_candidates: &mut Vec::Hash>>, + allowed_relay_parents: &AllowedRelayParentsTracker>, + scheduled: &BTreeMap, +) -> bool { + let disabled_validators = + BTreeSet::<_>::from_iter(shared::Pallet::::disabled_validators().into_iter()); + + if disabled_validators.is_empty() { + // No disabled validators - nothing to do + return false + } + + let backed_len_before = backed_candidates.len(); + + // Flag which will be returned. Set to `true` if at least one vote is filtered. + let mut filtered = false; + + let minimum_backing_votes = configuration::Pallet::::config().minimum_backing_votes; + + // Process all backed candidates. `validator_indices` in `BackedCandidates` are indices within + // the validator group assigned to the parachain. To obtain this group we need: + // 1. Core index assigned to the parachain which has produced the candidate + // 2. The relay chain block number of the candidate + backed_candidates.retain_mut(|bc| { + // Get `core_idx` assigned to the `para_id` of the candidate + let core_idx = match scheduled.get(&bc.descriptor().para_id) { + Some(core_idx) => *core_idx, + None => { + log::debug!(target: LOG_TARGET, "Can't get core idx of a backed candidate for para id {:?}. Dropping the candidate.", bc.descriptor().para_id); + return false + } + }; + + // Get relay parent block number of the candidate. We need this to get the group index assigned to this core at this block number + let relay_parent_block_number = match allowed_relay_parents + .acquire_info(bc.descriptor().relay_parent, None) { + Some((_, block_num)) => block_num, + None => { + log::debug!(target: LOG_TARGET, "Relay parent {:?} for candidate is not in the allowed relay parents. Dropping the candidate.", bc.descriptor().relay_parent); + return false + } + }; + + // Get the group index for the core + let group_idx = match >::group_assigned_to_core( + core_idx, + relay_parent_block_number + One::one(), + ) { + Some(group_idx) => group_idx, + None => { + log::debug!(target: LOG_TARGET, "Can't get the group index for core idx {:?}. Dropping the candidate.", core_idx); + return false + }, + }; + + // And finally get the validator group for this group index + let validator_group = match >::group_validators(group_idx) { + Some(validator_group) => validator_group, + None => { + log::debug!(target: LOG_TARGET, "Can't get the validators from group {:?}. Dropping the candidate.", group_idx); + return false + } + }; + + // Bitmask with the disabled indices within the validator group + let disabled_indices = BitVec::::from_iter(validator_group.iter().map(|idx| disabled_validators.contains(idx))); + // The indices of statements from disabled validators in `BackedCandidate`. We have to drop these. + let indices_to_drop = disabled_indices.clone() & &bc.validator_indices; + // Apply the bitmask to drop the disabled validator from `validator_indices` + bc.validator_indices &= !disabled_indices; + // Remove the corresponding votes from `validity_votes` + for idx in indices_to_drop.iter_ones().rev() { + bc.validity_votes.remove(idx); + } + + // If at least one statement was dropped we need to return `true` + if indices_to_drop.count_ones() > 0 { + filtered = true; + } + + // By filtering votes we might render the candidate invalid and cause a failure in + // [`process_candidates`]. To avoid this we have to perform a sanity check here. If there + // are not enough backing votes after filtering we will remove the whole candidate. + if bc.validity_votes.len() < effective_minimum_backing_votes( + validator_group.len(), + minimum_backing_votes + + ) { + return false + } + + true + }); + + // Also return `true` if a whole candidate was dropped from the set + filtered || backed_len_before != backed_candidates.len() +} diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index e62d1cb68ff..6f3eac35685 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -1227,6 +1227,12 @@ mod sanitizers { } mod candidates { + use crate::{ + mock::set_disabled_validators, + scheduler::{common::Assignment, ParasEntry}, + }; + use sp_std::collections::vec_deque::VecDeque; + use super::*; // Backed candidates and scheduled parachains used for `sanitize_backed_candidates` testing @@ -1235,10 +1241,20 @@ mod sanitizers { scheduled_paras: BTreeMap, } - // Generate test data for the candidates test + // Generate test data for the candidates and assert that the evnironment is set as expected + // (check the comments for details) fn get_test_data() -> TestData { const RELAY_PARENT_NUM: u32 = 3; + // Add the relay parent to `shared` pallet. Otherwise some code (e.g. filtering backing + // votes) won't behave correctly + shared::Pallet::::add_allowed_relay_parent( + default_header().hash(), + Default::default(), + RELAY_PARENT_NUM, + 1, + ); + let header = default_header(); let relay_parent = header.hash(); let session_index = SessionIndex::from(0_u32); @@ -1252,6 +1268,7 @@ mod sanitizers { keyring::Sr25519Keyring::Bob, keyring::Sr25519Keyring::Charlie, keyring::Sr25519Keyring::Dave, + keyring::Sr25519Keyring::Eve, ]; for validator in validators.iter() { Keystore::sr25519_generate_new( @@ -1262,11 +1279,42 @@ mod sanitizers { .unwrap(); } + // Set active validators in `shared` pallet + let validator_ids = + validators.iter().map(|v| v.public().into()).collect::>(); + shared::Pallet::::set_active_validators_ascending(validator_ids); + + // Two scheduled parachains - ParaId(1) on CoreIndex(0) and ParaId(2) on CoreIndex(1) let scheduled = (0_usize..2) .into_iter() .map(|idx| (ParaId::from(1_u32 + idx as u32), CoreIndex::from(idx as u32))) .collect::>(); + // Set the validator groups in `scheduler` + scheduler::Pallet::::set_validator_groups(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2), ValidatorIndex(3)], + ]); + + // Update scheduler's claimqueue with the parachains + scheduler::Pallet::::set_claimqueue(BTreeMap::from([ + ( + CoreIndex::from(0), + VecDeque::from([ParasEntry::new( + Assignment::Pool { para_id: 1.into(), core_index: CoreIndex(1) }, + RELAY_PARENT_NUM, + )]), + ), + ( + CoreIndex::from(1), + VecDeque::from([ParasEntry::new( + Assignment::Pool { para_id: 2.into(), core_index: CoreIndex(1) }, + RELAY_PARENT_NUM, + )]), + ), + ])); + + // Callback used for backing candidates let group_validators = |group_index: GroupIndex| { match group_index { group_index if group_index == GroupIndex::from(0) => Some(vec![0, 1]), @@ -1276,6 +1324,7 @@ mod sanitizers { .map(|m| m.into_iter().map(ValidatorIndex).collect::>()) }; + // Two backed candidates from each parachain let backed_candidates = (0_usize..2) .into_iter() .map(|idx0| { @@ -1304,6 +1353,22 @@ mod sanitizers { }) .collect::>(); + // State sanity checks + assert_eq!( + >::scheduled_paras().collect::>(), + vec![(CoreIndex(0), ParaId::from(1)), (CoreIndex(1), ParaId::from(2))] + ); + assert_eq!( + shared::Pallet::::active_validator_indices(), + vec![ + ValidatorIndex(0), + ValidatorIndex(1), + ValidatorIndex(2), + ValidatorIndex(3), + ValidatorIndex(4) + ] + ); + TestData { backed_candidates, scheduled_paras: scheduled } } @@ -1318,10 +1383,14 @@ mod sanitizers { assert_eq!( sanitize_backed_candidates::( backed_candidates.clone(), + &>::allowed_relay_parents(), has_concluded_invalid, &scheduled ), - backed_candidates + SanitizedBackedCandidates { + backed_candidates, + votes_from_disabled_were_dropped: false + } ); {} @@ -1337,12 +1406,18 @@ mod sanitizers { let has_concluded_invalid = |_idx: usize, _backed_candidate: &BackedCandidate| -> bool { false }; - assert!(sanitize_backed_candidates::( + let SanitizedBackedCandidates { + backed_candidates: sanitized_backed_candidates, + votes_from_disabled_were_dropped, + } = sanitize_backed_candidates::( backed_candidates.clone(), + &>::allowed_relay_parents(), has_concluded_invalid, - &scheduled - ) - .is_empty()); + &scheduled, + ); + + assert!(sanitized_backed_candidates.is_empty()); + assert!(!votes_from_disabled_were_dropped); }); } @@ -1364,15 +1439,113 @@ mod sanitizers { }; let has_concluded_invalid = |_idx: usize, candidate: &BackedCandidate| set.contains(&candidate.hash()); + let SanitizedBackedCandidates { + backed_candidates: sanitized_backed_candidates, + votes_from_disabled_were_dropped, + } = sanitize_backed_candidates::( + backed_candidates.clone(), + &>::allowed_relay_parents(), + has_concluded_invalid, + &scheduled, + ); + + assert_eq!(sanitized_backed_candidates.len(), backed_candidates.len() / 2); + assert!(!votes_from_disabled_were_dropped); + }); + } + + #[test] + fn disabled_non_signing_validator_doesnt_get_filtered() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let TestData { mut backed_candidates, scheduled_paras } = get_test_data(); + + // Disable Eve + set_disabled_validators(vec![4]); + + let before = backed_candidates.clone(); + + // Eve is disabled but no backing statement is signed by it so nothing should be + // filtered + assert!(!filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &>::allowed_relay_parents(), + &scheduled_paras + )); + assert_eq!(backed_candidates, before); + }); + } + + #[test] + fn drop_statements_from_disabled_without_dropping_candidate() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let TestData { mut backed_candidates, scheduled_paras } = get_test_data(); + + // Disable Alice + set_disabled_validators(vec![0]); + + // Update `minimum_backing_votes` in HostConfig. We want `minimum_backing_votes` set + // to one so that the candidate will have enough backing votes even after dropping + // Alice's one. + let mut hc = configuration::Pallet::::config(); + hc.minimum_backing_votes = 1; + configuration::Pallet::::force_set_active_config(hc); + + // Verify the initial state is as expected + assert_eq!(backed_candidates.get(0).unwrap().validity_votes.len(), 2); assert_eq!( - sanitize_backed_candidates::( - backed_candidates.clone(), - has_concluded_invalid, - &scheduled - ) - .len(), - backed_candidates.len() / 2 + backed_candidates.get(0).unwrap().validator_indices.get(0).unwrap(), + true + ); + assert_eq!( + backed_candidates.get(0).unwrap().validator_indices.get(1).unwrap(), + true + ); + let untouched = backed_candidates.get(1).unwrap().clone(); + + assert!(filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &>::allowed_relay_parents(), + &scheduled_paras + )); + + // there should still be two backed candidates + assert_eq!(backed_candidates.len(), 2); + // but the first one should have only one validity vote + assert_eq!(backed_candidates.get(0).unwrap().validity_votes.len(), 1); + // Validator 0 vote should be dropped, validator 1 - retained + assert_eq!( + backed_candidates.get(0).unwrap().validator_indices.get(0).unwrap(), + false ); + assert_eq!( + backed_candidates.get(0).unwrap().validator_indices.get(1).unwrap(), + true + ); + // the second candidate shouldn't be modified + assert_eq!(*backed_candidates.get(1).unwrap(), untouched); + }); + } + + #[test] + fn drop_candidate_if_all_statements_are_from_disabled() { + new_test_ext(MockGenesisConfig::default()).execute_with(|| { + let TestData { mut backed_candidates, scheduled_paras } = get_test_data(); + + // Disable Alice and Bob + set_disabled_validators(vec![0, 1]); + + // Verify the initial state is as expected + assert_eq!(backed_candidates.get(0).unwrap().validity_votes.len(), 2); + let untouched = backed_candidates.get(1).unwrap().clone(); + + assert!(filter_backed_statements_from_disabled_validators::( + &mut backed_candidates, + &>::allowed_relay_parents(), + &scheduled_paras + )); + + assert_eq!(backed_candidates.len(), 1); + assert_eq!(*backed_candidates.get(0).unwrap(), untouched); }); } } diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs index 0da50f6a537..1fee1a4097d 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs @@ -21,29 +21,16 @@ use primitives::{ vstaging::{ApprovalVotingParams, NodeFeatures}, ValidatorIndex, }; -use sp_std::{collections::btree_map::BTreeMap, prelude::Vec}; +use sp_std::prelude::Vec; /// Implementation for `DisabledValidators` // CAVEAT: this should only be called on the node side // as it might produce incorrect results on session boundaries pub fn disabled_validators() -> Vec where - T: pallet_session::Config + shared::Config, + T: shared::Config, { - let shuffled_indices = >::active_validator_indices(); - // mapping from raw validator index to `ValidatorIndex` - // this computation is the same within a session, but should be cheap - let reverse_index = shuffled_indices - .iter() - .enumerate() - .map(|(i, v)| (v.0, ValidatorIndex(i as u32))) - .collect::>(); - - // we might have disabled validators who are not parachain validators - >::disabled_validators() - .iter() - .filter_map(|v| reverse_index.get(v).cloned()) - .collect() + >::disabled_validators() } /// Returns the current state of the node features. diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 08ce656b2b2..a666f568908 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -691,4 +691,9 @@ impl Pallet { pub(crate) fn set_validator_groups(validator_groups: Vec>) { ValidatorGroups::::set(validator_groups); } + + #[cfg(test)] + pub(crate) fn set_claimqueue(claimqueue: BTreeMap>>) { + ClaimQueue::::set(claimqueue); + } } diff --git a/polkadot/runtime/parachains/src/shared.rs b/polkadot/runtime/parachains/src/shared.rs index ad13c9e4844..bdaffcd505f 100644 --- a/polkadot/runtime/parachains/src/shared.rs +++ b/polkadot/runtime/parachains/src/shared.rs @@ -19,11 +19,14 @@ //! To avoid cyclic dependencies, it is important that this pallet is not //! dependent on any of the other pallets. -use frame_support::pallet_prelude::*; +use frame_support::{pallet_prelude::*, traits::DisabledValidators}; use frame_system::pallet_prelude::BlockNumberFor; use primitives::{SessionIndex, ValidatorId, ValidatorIndex}; use sp_runtime::traits::AtLeast32BitUnsigned; -use sp_std::{collections::vec_deque::VecDeque, vec::Vec}; +use sp_std::{ + collections::{btree_map::BTreeMap, vec_deque::VecDeque}, + vec::Vec, +}; use rand::{seq::SliceRandom, SeedableRng}; use rand_chacha::ChaCha20Rng; @@ -129,7 +132,9 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config {} + pub trait Config: frame_system::Config { + type DisabledValidators: frame_support::traits::DisabledValidators; + } /// The current session index. #[pallet::storage] @@ -216,6 +221,25 @@ impl Pallet { Self::session_index().saturating_add(SESSION_DELAY) } + /// Fetches disabled validators list from session pallet. + /// CAVEAT: this might produce incorrect results on session boundaries + pub fn disabled_validators() -> Vec { + let shuffled_indices = Pallet::::active_validator_indices(); + // mapping from raw validator index to `ValidatorIndex` + // this computation is the same within a session, but should be cheap + let reverse_index = shuffled_indices + .iter() + .enumerate() + .map(|(i, v)| (v.0, ValidatorIndex(i as u32))) + .collect::>(); + + // we might have disabled validators who are not parachain validators + T::DisabledValidators::disabled_validators() + .iter() + .filter_map(|v| reverse_index.get(v).cloned()) + .collect() + } + /// Test function for setting the current session index. #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] pub fn set_session_index(index: SessionIndex) { @@ -239,4 +263,16 @@ impl Pallet { ActiveValidatorIndices::::set(indices); ActiveValidatorKeys::::set(keys); } + + #[cfg(test)] + pub(crate) fn add_allowed_relay_parent( + relay_parent: T::Hash, + state_root: T::Hash, + number: BlockNumberFor, + max_ancestry_len: u32, + ) { + AllowedRelayParents::::mutate(|tracker| { + tracker.update(relay_parent, state_root, number, max_ancestry_len) + }) + } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 0e2eaa03567..51c00336bef 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -909,7 +909,9 @@ impl parachains_configuration::Config for Runtime { type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; } -impl parachains_shared::Config for Runtime {} +impl parachains_shared::Config for Runtime { + type DisabledValidators = Session; +} impl parachains_session_info::Config for Runtime { type ValidatorSet = Historical; diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index e80412232d0..18bcb16834e 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -478,7 +478,9 @@ impl parachains_configuration::Config for Runtime { type WeightInfo = parachains_configuration::TestWeightInfo; } -impl parachains_shared::Config for Runtime {} +impl parachains_shared::Config for Runtime { + type DisabledValidators = Session; +} impl parachains_inclusion::Config for Runtime { type RuntimeEvent = RuntimeEvent; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 28b82956a47..941193ba941 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1117,7 +1117,9 @@ impl parachains_configuration::Config for Runtime { type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; } -impl parachains_shared::Config for Runtime {} +impl parachains_shared::Config for Runtime { + type DisabledValidators = Session; +} impl parachains_session_info::Config for Runtime { type ValidatorSet = Historical; diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index e08099280ba..2e89313a68e 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -128,7 +128,9 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = ConstU32<0>; } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 1bcbe6da2cd..946b932b05e 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -120,7 +120,9 @@ impl pallet_uniques::Config for Runtime { type Helper = (); } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index c066cc5e813..d3f91b01317 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -100,7 +100,9 @@ impl pallet_balances::Config for Runtime { type MaxFreezes = ConstU32<0>; } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/prdoc/pr_2889.prdoc b/prdoc/pr_2889.prdoc new file mode 100644 index 00000000000..cbb8aafa997 --- /dev/null +++ b/prdoc/pr_2889.prdoc @@ -0,0 +1,10 @@ +title: Filter backing votes from disabled validators in paras_inherent + +doc: + - audience: Runtime User + description: | + paras_inherent drops any backing votes from disabled validators on block import and asserts + that no votes from disabled validators are included in a block during execution + +crates: + - name: polkadot-runtime-parachains diff --git a/substrate/frame/aura/src/mock.rs b/substrate/frame/aura/src/mock.rs index 14b87089ce3..d38a8583819 100644 --- a/substrate/frame/aura/src/mock.rs +++ b/substrate/frame/aura/src/mock.rs @@ -96,6 +96,10 @@ impl DisabledValidators for MockDisabledValidators { fn is_disabled(index: AuthorityIndex) -> bool { DisabledValidatorTestValue::get().binary_search(&index).is_ok() } + + fn disabled_validators() -> Vec { + DisabledValidatorTestValue::get() + } } impl pallet_aura::Config for Test { diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index 4e5523f7442..abe907839d9 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -99,7 +99,9 @@ impl pallet_balances::Config for Runtime { type RuntimeFreezeReason = RuntimeFreezeReason; } -impl shared::Config for Runtime {} +impl shared::Config for Runtime { + type DisabledValidators = (); +} impl configuration::Config for Runtime { type WeightInfo = configuration::TestWeightInfo; diff --git a/substrate/frame/session/src/lib.rs b/substrate/frame/session/src/lib.rs index bf4671a247f..178d43f596b 100644 --- a/substrate/frame/session/src/lib.rs +++ b/substrate/frame/session/src/lib.rs @@ -918,6 +918,10 @@ impl frame_support::traits::DisabledValidators for Pallet { fn is_disabled(index: u32) -> bool { >::disabled_validators().binary_search(&index).is_ok() } + + fn disabled_validators() -> Vec { + >::disabled_validators() + } } /// Wraps the author-scraping logic for consensus engines that can recover diff --git a/substrate/frame/support/src/traits/validation.rs b/substrate/frame/support/src/traits/validation.rs index 617cdb2d3f4..4b099b2c766 100644 --- a/substrate/frame/support/src/traits/validation.rs +++ b/substrate/frame/support/src/traits/validation.rs @@ -251,10 +251,17 @@ pub trait ValidatorRegistration { pub trait DisabledValidators { /// Returns true if the given validator is disabled. fn is_disabled(index: u32) -> bool; + + /// Returns all disabled validators + fn disabled_validators() -> Vec; } impl DisabledValidators for () { fn is_disabled(_index: u32) -> bool { false } + + fn disabled_validators() -> Vec { + vec![] + } } -- GitLab From d6c0f1531de5be0bcfabf8531490ff6e4804a37f Mon Sep 17 00:00:00 2001 From: Samuel Moelius <35515885+smoelius@users.noreply.github.com> Date: Thu, 18 Jan 2024 04:15:00 -0500 Subject: [PATCH 022/283] Fix typo in traits.rs (#2971) Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- substrate/primitives/runtime/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits.rs index ad82419cb8b..4213117334e 100644 --- a/substrate/primitives/runtime/src/traits.rs +++ b/substrate/primitives/runtime/src/traits.rs @@ -1790,7 +1790,7 @@ pub trait ValidateUnsigned { /// this code before the unsigned extrinsic enters the transaction pool and also periodically /// afterwards to ensure the validity. To prevent dos-ing a network with unsigned /// extrinsics, these validity checks should include some checks around uniqueness, for example, - /// like checking that the unsigned extrinsic was send by an authority in the active set. + /// checking that the unsigned extrinsic was sent by an authority in the active set. /// /// Changes made to storage should be discarded by caller. fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity; -- GitLab From 38205bf13990e3f10916ea9a973dffcf55fef4a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 18 Jan 2024 11:49:13 +0100 Subject: [PATCH 023/283] Downgrade logging to `debug` (#2980) There is no need to spawn operators with this debug log. Closes: https://github.com/paritytech/polkadot-sdk/issues/2974 --- polkadot/node/core/approval-voting/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index af76b576d7c..9116725c291 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -3343,7 +3343,7 @@ async fn issue_approval( ); } - gum::info!( + gum::debug!( target: LOG_TARGET, ?candidate_hash, ?block_hash, -- GitLab From 1113fce5fb7be393f688e8d89ca23a0ee1e4bda5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:25:24 +0100 Subject: [PATCH 024/283] Bump the known_good_semver group with 1 update (#2953) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the known_good_semver group with 1 update: [clap](https://github.com/clap-rs/clap). Updates `clap` from 4.4.16 to 4.4.18
Release notes

Sourced from clap's releases.

v4.4.18

[4.4.18] - 2024-01-16

Fixes

  • (error) When lacking usage feature, ensure the list of required arguments is unique

v4.4.17

[4.4.17] - 2024-01-15

Fixes

  • Fix panic! when mixing args_conflicts_with_subcommands with ArgGroup (which is implicit with derive) introduced in 4.4.15
Changelog

Sourced from clap's changelog.

[4.4.18] - 2024-01-16

Fixes

  • (error) When lacking usage feature, ensure the list of required arguments is unique

[4.4.17] - 2024-01-15

Fixes

  • Fix panic! when mixing args_conflicts_with_subcommands with ArgGroup (which is implicit with derive) introduced in 4.4.15
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=clap&package-manager=cargo&previous-version=4.4.16&new-version=4.4.18)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bastian Köcher Co-authored-by: Dónal Murray --- Cargo.lock | 66 +++++++++---------- cumulus/client/cli/Cargo.toml | 2 +- cumulus/parachain-template/node/Cargo.toml | 2 +- cumulus/polkadot-parachain/Cargo.toml | 2 +- cumulus/test/service/Cargo.toml | 2 +- polkadot/cli/Cargo.toml | 2 +- polkadot/node/malus/Cargo.toml | 2 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../test-parachains/adder/collator/Cargo.toml | 2 +- .../undying/collator/Cargo.toml | 2 +- polkadot/utils/generate-bags/Cargo.toml | 2 +- .../remote-ext-tests/bags-list/Cargo.toml | 2 +- substrate/bin/minimal/node/Cargo.toml | 2 +- substrate/bin/node-template/node/Cargo.toml | 2 +- substrate/bin/node/bench/Cargo.toml | 2 +- substrate/bin/node/cli/Cargo.toml | 4 +- substrate/bin/node/inspect/Cargo.toml | 2 +- .../bin/utils/chain-spec-builder/Cargo.toml | 2 +- substrate/bin/utils/subkey/Cargo.toml | 2 +- substrate/client/cli/Cargo.toml | 2 +- substrate/client/storage-monitor/Cargo.toml | 2 +- .../solution-type/fuzzer/Cargo.toml | 2 +- .../npos-elections/fuzzer/Cargo.toml | 2 +- .../ci/node-template-release/Cargo.toml | 2 +- .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- .../frame/frame-utilities-cli/Cargo.toml | 2 +- .../generate-bags/node-runtime/Cargo.toml | 2 +- .../utils/frame/try-runtime/cli/Cargo.toml | 2 +- 28 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 849bc069d20..b6f69c2daa1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2640,9 +2640,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.16" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive 4.4.7", @@ -2659,9 +2659,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.16" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -2676,7 +2676,7 @@ version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", ] [[package]] @@ -3414,7 +3414,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.16", + "clap 4.4.18", "criterion-plot", "futures", "is-terminal", @@ -3577,7 +3577,7 @@ dependencies = [ name = "cumulus-client-cli" version = "0.1.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -4317,7 +4317,7 @@ name = "cumulus-test-service" version = "0.1.0" dependencies = [ "async-trait", - "clap 4.4.16", + "clap 4.4.18", "criterion 0.5.1", "cumulus-client-cli", "cumulus-client-consensus-common", @@ -5501,7 +5501,7 @@ dependencies = [ "Inflector", "array-bytes 6.1.0", "chrono", - "clap 4.4.16", + "clap 4.4.18", "comfy-table", "frame-benchmarking", "frame-support", @@ -5593,7 +5593,7 @@ dependencies = [ name = "frame-election-solution-type-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-support", @@ -8109,7 +8109,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" name = "minimal-node" version = "4.0.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame", "futures", "futures-timer", @@ -8573,7 +8573,7 @@ name = "node-bench" version = "0.9.0-dev" dependencies = [ "array-bytes 6.1.0", - "clap 4.4.16", + "clap 4.4.18", "derive_more", "fs_extra", "futures", @@ -8650,7 +8650,7 @@ dependencies = [ name = "node-runtime-generate-bags" version = "3.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "generate-bags", "kitchensink-runtime", ] @@ -8659,7 +8659,7 @@ dependencies = [ name = "node-template" version = "4.0.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-benchmarking", "frame-benchmarking-cli", "frame-system", @@ -8703,7 +8703,7 @@ dependencies = [ name = "node-template-release" version = "3.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "flate2", "fs_extra", "glob", @@ -11247,7 +11247,7 @@ dependencies = [ name = "parachain-template-node" version = "0.1.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "color-print", "cumulus-client-cli", "cumulus-client-collator", @@ -12205,7 +12205,7 @@ name = "polkadot-cli" version = "1.1.0" dependencies = [ "cfg-if", - "clap 4.4.16", + "clap 4.4.18", "frame-benchmarking-cli", "futures", "log", @@ -13046,7 +13046,7 @@ dependencies = [ "async-trait", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", - "clap 4.4.16", + "clap 4.4.18", "collectives-westend-runtime", "color-print", "contracts-rococo-runtime", @@ -13557,7 +13557,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.16", + "clap 4.4.18", "clap-num", "color-eyre", "colored", @@ -13634,7 +13634,7 @@ version = "1.0.0" dependencies = [ "assert_matches", "async-trait", - "clap 4.4.16", + "clap 4.4.18", "color-eyre", "futures", "futures-timer", @@ -13781,7 +13781,7 @@ dependencies = [ name = "polkadot-voter-bags" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "generate-bags", "sp-io", "westend-runtime", @@ -14671,7 +14671,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" name = "remote-ext-tests-bags-list" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-system", "log", "pallet-bags-list-remote-tests", @@ -15461,7 +15461,7 @@ dependencies = [ "array-bytes 6.1.0", "bip39", "chrono", - "clap 4.4.16", + "clap 4.4.18", "fdlimit", "futures", "futures-timer", @@ -16605,7 +16605,7 @@ dependencies = [ name = "sc-storage-monitor" version = "0.1.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "fs4", "log", "sp-core", @@ -18555,7 +18555,7 @@ dependencies = [ name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "honggfuzz", "rand 0.8.5", "sp-npos-elections", @@ -19076,7 +19076,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" name = "staging-chain-spec-builder" version = "2.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "log", "sc-chain-spec", "serde_json", @@ -19089,7 +19089,7 @@ version = "3.0.0-dev" dependencies = [ "array-bytes 6.1.0", "assert_cmd", - "clap 4.4.16", + "clap 4.4.18", "clap_complete", "criterion 0.4.0", "frame-benchmarking", @@ -19198,7 +19198,7 @@ dependencies = [ name = "staging-node-inspect" version = "0.9.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "parity-scale-codec", "sc-cli", "sc-client-api", @@ -19403,7 +19403,7 @@ dependencies = [ name = "subkey" version = "3.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "sc-cli", ] @@ -19445,7 +19445,7 @@ dependencies = [ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "frame-support", "frame-system", "sc-cli", @@ -19923,7 +19923,7 @@ dependencies = [ name = "test-parachain-adder-collator" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "futures", "futures-timer", "log", @@ -19971,7 +19971,7 @@ dependencies = [ name = "test-parachain-undying-collator" version = "1.0.0" dependencies = [ - "clap 4.4.16", + "clap 4.4.18", "futures", "futures-timer", "log", @@ -20622,7 +20622,7 @@ version = "0.10.0-dev" dependencies = [ "assert_cmd", "async-trait", - "clap 4.4.16", + "clap 4.4.18", "frame-remote-externalities", "frame-try-runtime", "hex", diff --git a/cumulus/client/cli/Cargo.toml b/cumulus/client/cli/Cargo.toml index 4048c3eaecb..96016da5c9a 100644 --- a/cumulus/client/cli/Cargo.toml +++ b/cumulus/client/cli/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } url = "2.4.0" diff --git a/cumulus/parachain-template/node/Cargo.toml b/cumulus/parachain-template/node/Cargo.toml index b34478ab3dd..c12ee72f5cb 100644 --- a/cumulus/parachain-template/node/Cargo.toml +++ b/cumulus/parachain-template/node/Cargo.toml @@ -14,7 +14,7 @@ publish = false workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.20" codec = { package = "parity-scale-codec", version = "3.0.0" } serde = { version = "1.0.195", features = ["derive"] } diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 84ba8a36d51..0a40816fc0b 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } futures = "0.3.28" hex-literal = "0.4.1" diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 387d65c4931..dcd70ca97e8 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] async-trait = "0.1.74" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.0.0" } criterion = { version = "0.5.1", features = ["async_tokio"] } jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index cc96422abbc..2efb057ca28 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -19,7 +19,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] cfg-if = "1.0" -clap = { version = "4.4.16", features = ["derive"], optional = true } +clap = { version = "4.4.18", features = ["derive"], optional = true } log = "0.4.17" thiserror = "1.0.48" futures = "0.3.21" diff --git a/polkadot/node/malus/Cargo.toml b/polkadot/node/malus/Cargo.toml index 7793abfd69b..6a3dff726ed 100644 --- a/polkadot/node/malus/Cargo.toml +++ b/polkadot/node/malus/Cargo.toml @@ -43,7 +43,7 @@ assert_matches = "1.5" async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index ab3de33fe2c..f09f7fc4897 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -31,7 +31,7 @@ async-trait = "0.1.74" sp-keystore = { path = "../../../substrate/primitives/keystore" } sc-keystore = { path = "../../../substrate/client/keystore" } sp-core = { path = "../../../substrate/primitives/core" } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } diff --git a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml index 4ebeb767905..7dd0d9a563c 100644 --- a/polkadot/parachain/test-parachains/adder/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/adder/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml index 1d851218bed..001c48476b5 100644 --- a/polkadot/parachain/test-parachains/undying/collator/Cargo.toml +++ b/polkadot/parachain/test-parachains/undying/collator/Cargo.toml @@ -16,7 +16,7 @@ path = "src/main.rs" [dependencies] parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = "0.3.21" futures-timer = "3.0.2" log = "0.4.17" diff --git a/polkadot/utils/generate-bags/Cargo.toml b/polkadot/utils/generate-bags/Cargo.toml index a16ee8de496..0f5ee43d86d 100644 --- a/polkadot/utils/generate-bags/Cargo.toml +++ b/polkadot/utils/generate-bags/Cargo.toml @@ -10,7 +10,7 @@ description = "CLI to generate voter bags for Polkadot runtimes" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } generate-bags = { path = "../../../substrate/utils/frame/generate-bags" } sp-io = { path = "../../../substrate/primitives/io" } diff --git a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml index 75bfdd9d1a0..f8190e6aefa 100644 --- a/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml +++ b/polkadot/utils/remote-ext-tests/bags-list/Cargo.toml @@ -18,6 +18,6 @@ sp-tracing = { path = "../../../../substrate/primitives/tracing" } frame-system = { path = "../../../../substrate/frame/system" } sp-core = { path = "../../../../substrate/primitives/core" } -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.17" tokio = { version = "1.24.2", features = ["macros"] } diff --git a/substrate/bin/minimal/node/Cargo.toml b/substrate/bin/minimal/node/Cargo.toml index 5a2427fd4d8..cc00988dcfe 100644 --- a/substrate/bin/minimal/node/Cargo.toml +++ b/substrate/bin/minimal/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "minimal-node" [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } diff --git a/substrate/bin/node-template/node/Cargo.toml b/substrate/bin/node-template/node/Cargo.toml index f91db97985b..36c2f9f8b70 100644 --- a/substrate/bin/node-template/node/Cargo.toml +++ b/substrate/bin/node-template/node/Cargo.toml @@ -20,7 +20,7 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"] } serde_json = "1.0.111" diff --git a/substrate/bin/node/bench/Cargo.toml b/substrate/bin/node/bench/Cargo.toml index 926cdc3bfb0..42af802d716 100644 --- a/substrate/bin/node/bench/Cargo.toml +++ b/substrate/bin/node/bench/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] array-bytes = "6.1" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.17" node-primitives = { path = "../primitives" } node-testing = { path = "../testing" } diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 64b61288391..061c9684c22 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -41,7 +41,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies array-bytes = "6.1" -clap = { version = "4.4.16", features = ["derive"], optional = true } +clap = { version = "4.4.18", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } serde = { version = "1.0.195", features = ["derive"] } jsonrpsee = { version = "0.16.2", features = ["server"] } @@ -164,7 +164,7 @@ sp-trie = { path = "../../../primitives/trie" } sp-state-machine = { path = "../../../primitives/state-machine" } [build-dependencies] -clap = { version = "4.4.16", optional = true } +clap = { version = "4.4.18", optional = true } clap_complete = { version = "4.0.2", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } diff --git a/substrate/bin/node/inspect/Cargo.toml b/substrate/bin/node/inspect/Cargo.toml index ef82f16be2a..860295b0553 100644 --- a/substrate/bin/node/inspect/Cargo.toml +++ b/substrate/bin/node/inspect/Cargo.toml @@ -15,7 +15,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } thiserror = "1.0" sc-cli = { path = "../../../client/cli" } diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index a9ea0ad40b3..06a0a3a1a4a 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -23,7 +23,7 @@ name = "chain-spec-builder" crate-type = ["rlib"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } log = "0.4.17" sc-chain-spec = { path = "../../../client/chain-spec" } serde_json = "1.0.111" diff --git a/substrate/bin/utils/subkey/Cargo.toml b/substrate/bin/utils/subkey/Cargo.toml index 19eba2f1969..b53bae0b6a1 100644 --- a/substrate/bin/utils/subkey/Cargo.toml +++ b/substrate/bin/utils/subkey/Cargo.toml @@ -20,5 +20,5 @@ path = "src/main.rs" name = "subkey" [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/client/cli/Cargo.toml b/substrate/client/cli/Cargo.toml index ce9b1781686..d64973baf83 100644 --- a/substrate/client/cli/Cargo.toml +++ b/substrate/client/cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4.31" -clap = { version = "4.4.16", features = ["derive", "string", "wrap_help"] } +clap = { version = "4.4.18", features = ["derive", "string", "wrap_help"] } fdlimit = "0.3.0" futures = "0.3.21" itertools = "0.10.3" diff --git a/substrate/client/storage-monitor/Cargo.toml b/substrate/client/storage-monitor/Cargo.toml index 17f1c42bccb..6a01ef0fe2b 100644 --- a/substrate/client/storage-monitor/Cargo.toml +++ b/substrate/client/storage-monitor/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://substrate.io" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive", "string"] } +clap = { version = "4.4.18", features = ["derive", "string"] } log = "0.4.17" fs4 = "0.7.0" sp-core = { path = "../../primitives/core" } diff --git a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml index 62316b27290..7200d207aec 100644 --- a/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml +++ b/substrate/frame/election-provider-support/solution-type/fuzzer/Cargo.toml @@ -16,7 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index f98e41ae77a..93177325436 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -17,7 +17,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } honggfuzz = "0.5" rand = { version = "0.8", features = ["small_rng", "std"] } sp-npos-elections = { path = ".." } diff --git a/substrate/scripts/ci/node-template-release/Cargo.toml b/substrate/scripts/ci/node-template-release/Cargo.toml index 40ba629fb05..a0b93184546 100644 --- a/substrate/scripts/ci/node-template-release/Cargo.toml +++ b/substrate/scripts/ci/node-template-release/Cargo.toml @@ -14,7 +14,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } flate2 = "1.0" fs_extra = "1.3" glob = "0.3" diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index f7210cf768f..ba95afeeee9 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = "6.1" chrono = "0.4" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } comfy-table = { version = "7.0.1", default-features = false } handlebars = "4.2.2" diff --git a/substrate/utils/frame/frame-utilities-cli/Cargo.toml b/substrate/utils/frame/frame-utilities-cli/Cargo.toml index 899f86f3cb4..3cfb81e8c10 100644 --- a/substrate/utils/frame/frame-utilities-cli/Cargo.toml +++ b/substrate/utils/frame/frame-utilities-cli/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" workspace = true [dependencies] -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } frame-support = { path = "../../../frame/support" } frame-system = { path = "../../../frame/system" } sc-cli = { path = "../../../client/cli" } diff --git a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml index ba11fce18f8..b35e06879df 100644 --- a/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml +++ b/substrate/utils/frame/generate-bags/node-runtime/Cargo.toml @@ -17,4 +17,4 @@ kitchensink-runtime = { path = "../../../../bin/node/runtime" } generate-bags = { path = ".." } # third-party -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml index ac515315bbe..20da5c1675e 100644 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ b/substrate/utils/frame/try-runtime/cli/Cargo.toml @@ -38,7 +38,7 @@ frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } substrate-rpc-client = { path = "../../rpc/client" } async-trait = "0.1.74" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } hex = { version = "0.4.3", default-features = false } log = "0.4.17" parity-scale-codec = "3.6.1" -- GitLab From 9a8ef495bef273d23df6ca6c825e8ef145c1489f Mon Sep 17 00:00:00 2001 From: cristiantroy <154241727+cristiantroy@users.noreply.github.com> Date: Thu, 18 Jan 2024 20:30:29 +0800 Subject: [PATCH 025/283] Fix typos (#2983) --- bridges/modules/parachains/src/lib.rs | 2 +- docs/contributor/STYLE_GUIDE.md | 2 +- docs/sdk/src/meta_contributing.rs | 2 +- docs/sdk/src/reference_docs/extrinsic_encoding.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index b2ef0bf52bd..cf76e64ff9c 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -1470,7 +1470,7 @@ pub(crate) mod tests { ); // then if someone is pretending to provide updated head#10 of parachain#1 at relay - // block#30, and actualy provides it + // block#30, and actually provides it // // => we'll update value proceed(30, state_root_10_at_30); diff --git a/docs/contributor/STYLE_GUIDE.md b/docs/contributor/STYLE_GUIDE.md index 3df65d9699a..400d9f477bc 100644 --- a/docs/contributor/STYLE_GUIDE.md +++ b/docs/contributor/STYLE_GUIDE.md @@ -161,4 +161,4 @@ See the config file for the exact rules. You may find useful - [Taplo VSCode extension](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml) -- For NeoVim, [taplo is avaliable with Mason](https://github.com/williamboman/mason-lspconfig.nvim#available-lsp-servers) +- For NeoVim, [taplo is available with Mason](https://github.com/williamboman/mason-lspconfig.nvim#available-lsp-servers) diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index bff475f8e6b..7ecf8b0adfd 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -43,7 +43,7 @@ //! The following guidelines are meant to be the guiding torch of those who contribute to this //! crate. //! -//! 1. 🔺 Ground Up: Information should be layed out in the most ground-up fashion. The lowest level +//! 1. 🔺 Ground Up: Information should be laid out in the most ground-up fashion. The lowest level //! (i.e. "ground") is Rust-docs. The highest level (i.e. "up") is "outside of this crate". In //! between lies [`reference_docs`] and [`guides`], from low to high. The point of this principle //! is to document as much of the information as possible in the lower level media, as it is diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index 89c7cfe983c..9008f8f835f 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -172,7 +172,7 @@ //! } //! ``` //! -//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as descibed +//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as described //! above. `signed_extensions_additional` is constructed by SCALE encoding the //! ["additional signed" data][sp_runtime::traits::SignedExtension::AdditionalSigned] for each //! signed extension that the chain is using, in order. -- GitLab From 13f2342edd70d83377d620385610bc8dc859b64b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:43:37 +0000 Subject: [PATCH 026/283] Bump prost from 0.11.9 to 0.12.3 (#2976) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [prost](https://github.com/tokio-rs/prost) from 0.11.9 to 0.12.3.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prost&package-manager=cargo&previous-version=0.11.9&new-version=0.12.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dónal Murray --- Cargo.lock | 39 +++++++++++++++---- .../client/authority-discovery/Cargo.toml | 2 +- substrate/client/network/bitswap/Cargo.toml | 2 +- substrate/client/network/light/Cargo.toml | 2 +- substrate/client/network/sync/Cargo.toml | 2 +- .../network/sync/src/block_request_handler.rs | 2 +- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6f69c2daa1..87a2dad7549 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14213,7 +14213,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", ] [[package]] @@ -14230,7 +14240,7 @@ dependencies = [ "multimap", "petgraph", "prettyplease 0.1.25", - "prost", + "prost 0.11.9", "prost-types", "regex", "syn 1.0.109", @@ -14251,13 +14261,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "prost-types" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "prost", + "prost 0.11.9", ] [[package]] @@ -14280,7 +14303,7 @@ dependencies = [ "libflate", "log", "names", - "prost", + "prost 0.11.9", "reqwest", "thiserror", "url", @@ -15357,7 +15380,7 @@ dependencies = [ "multihash 0.18.1", "multihash-codetable", "parity-scale-codec", - "prost", + "prost 0.12.3", "prost-build", "quickcheck", "rand 0.8.5", @@ -16116,7 +16139,7 @@ dependencies = [ "futures", "libp2p-identity", "log", - "prost", + "prost 0.12.3", "prost-build", "sc-block-builder", "sc-client-api", @@ -16183,7 +16206,7 @@ dependencies = [ "libp2p-identity", "log", "parity-scale-codec", - "prost", + "prost 0.12.3", "prost-build", "sc-client-api", "sc-network", @@ -16225,7 +16248,7 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "prost", + "prost 0.12.3", "prost-build", "quickcheck", "sc-block-builder", diff --git a/substrate/client/authority-discovery/Cargo.toml b/substrate/client/authority-discovery/Cargo.toml index a8a28a501ea..e7aead99c02 100644 --- a/substrate/client/authority-discovery/Cargo.toml +++ b/substrate/client/authority-discovery/Cargo.toml @@ -30,7 +30,7 @@ multihash = { version = "0.18.1", default-features = false, features = [ "std", ] } log = "0.4.17" -prost = "0.11" +prost = "0.12" rand = "0.8.5" thiserror = "1.0" prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" } diff --git a/substrate/client/network/bitswap/Cargo.toml b/substrate/client/network/bitswap/Cargo.toml index cc919d2977e..b004c03e025 100644 --- a/substrate/client/network/bitswap/Cargo.toml +++ b/substrate/client/network/bitswap/Cargo.toml @@ -24,7 +24,7 @@ cid = "0.9.0" futures = "0.3.21" libp2p-identity = { version = "0.1.3", features = ["peerid"] } log = "0.4.17" -prost = "0.11" +prost = "0.12" thiserror = "1.0" unsigned-varint = { version = "0.7.1", features = ["asynchronous_codec", "futures"] } sc-client-api = { path = "../../api" } diff --git a/substrate/client/network/light/Cargo.toml b/substrate/client/network/light/Cargo.toml index c75d14f0deb..d59fde56430 100644 --- a/substrate/client/network/light/Cargo.toml +++ b/substrate/client/network/light/Cargo.toml @@ -27,7 +27,7 @@ codec = { package = "parity-scale-codec", version = "3.6.1", features = [ futures = "0.3.21" libp2p-identity = { version = "0.1.3", features = ["peerid"] } log = "0.4.16" -prost = "0.11" +prost = "0.12" sp-blockchain = { path = "../../../primitives/blockchain" } sc-client-api = { path = "../../api" } sc-network = { path = ".." } diff --git a/substrate/client/network/sync/Cargo.toml b/substrate/client/network/sync/Cargo.toml index dd993e7a3df..abcb4cc8e42 100644 --- a/substrate/client/network/sync/Cargo.toml +++ b/substrate/client/network/sync/Cargo.toml @@ -28,7 +28,7 @@ futures-timer = "3.0.2" libp2p = "0.51.4" log = "0.4.17" mockall = "0.11.3" -prost = "0.11" +prost = "0.12" schnellru = "0.2.1" smallvec = "1.11.0" thiserror = "1.0" diff --git a/substrate/client/network/sync/src/block_request_handler.rs b/substrate/client/network/sync/src/block_request_handler.rs index f2af7d21786..7dfa76278b8 100644 --- a/substrate/client/network/sync/src/block_request_handler.rs +++ b/substrate/client/network/sync/src/block_request_handler.rs @@ -228,7 +228,7 @@ where }; let direction = - Direction::from_i32(request.direction).ok_or(HandleRequestError::ParseDirection)?; + i32::try_into(request.direction).map_err(|_| HandleRequestError::ParseDirection)?; let attributes = BlockAttributes::from_be_u32(request.fields)?; -- GitLab From dcc76525d98a097be152293eee3389f6af5c4404 Mon Sep 17 00:00:00 2001 From: Muharem Date: Thu, 18 Jan 2024 22:04:13 +0800 Subject: [PATCH 027/283] Westend/Rococo Asset Hub: pay xcm fees with sufficient assets (#2978) Set up the `TakeFirstAssetTrader` trader for Westend and Rococo Asset Hubs to cover XCM fees with sufficient assets. This PR reintroduces previously [removed](https://github.com/paritytech/polkadot-sdk/pull/1845) trader setups, as it was decided to keep both traders, `TakeFirstAssetTrader` and `SwapFirstAssetTrader`, during the transition period. --------- Co-authored-by: Svyatoslav Nikolsky --- ...set-transfer-works-rococo-to-westend.zndsl | 4 +- ...set-transfer-works-westend-to-rococo.zndsl | 4 +- .../assets/asset-hub-rococo/src/tests/send.rs | 75 +++ .../asset-hub-westend/src/tests/send.rs | 75 +++ .../assets/asset-hub-rococo/src/xcm_config.rs | 26 + .../assets/asset-hub-rococo/tests/tests.rs | 447 +++++++++++++++++- .../asset-hub-westend/src/xcm_config.rs | 26 + .../assets/asset-hub-westend/tests/tests.rs | 446 ++++++++++++++++- 8 files changed, 1071 insertions(+), 32 deletions(-) diff --git a/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl b/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl index a61f1e039f4..fe7dc26b001 100644 --- a/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl +++ b/bridges/zombienet/tests/0001-asset-transfer-works-rococo-to-westend.zndsl @@ -14,7 +14,7 @@ bridge-hub-westend-collator1: js-script ../helpers/best-finalized-header-at-brid # step 4: send WND to //Alice on Rococo AH # (that's a required part of a sibling 0001-asset-transfer-works-westend-to-rococo.zndsl test) -asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-westend-local" within 60 seconds +asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-westend-local" within 120 seconds # step 5: elsewhere Rococo has sent ROC to //Alice - let's wait for it asset-hub-westend-collator1: js-script ../helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,0,Rococo" within 600 seconds @@ -24,7 +24,7 @@ bridge-hub-westend-collator1: js-script ../helpers/relayer-rewards.js with "5FLS bridge-hub-westend-collator1: js-script ../helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000002,0x6268726F,ThisChain,0" within 300 seconds # step 7: send wROC back to Alice at Rococo AH -asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-westend-local" within 60 seconds +asset-hub-westend-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-westend-local" within 120 seconds # step 8: elsewhere Rococo has sent wWND to //Alice - let's wait for it # (we wait until //Alice account increases here - there are no other transactionc that may increase it) diff --git a/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl b/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl index 2da5b7a772a..610b4ca7acd 100644 --- a/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl +++ b/bridges/zombienet/tests/0001-asset-transfer-works-westend-to-rococo.zndsl @@ -14,7 +14,7 @@ bridge-hub-rococo-collator1: js-script ../helpers/best-finalized-header-at-bridg # step 4: send ROC to //Alice on Westend AH # (that's a required part of a sibling 0001-asset-transfer-works-rococo-to-westend.zndsl test) -asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-rococo-local" within 60 seconds +asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "reserve-transfer-assets-from-asset-hub-rococo-local" within 120 seconds # step 5: elsewhere Westend has sent WND to //Alice - let's wait for it asset-hub-rococo-collator1: js-script ../helpers/wrapped-assets-balance.js with "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,0,Westend" within 600 seconds @@ -24,7 +24,7 @@ bridge-hub-rococo-collator1: js-script ../helpers/relayer-rewards.js with "5FLSi bridge-hub-rococo-collator1: js-script ../helpers/relayer-rewards.js with "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y,0x00000002,0x62687764,ThisChain,0" within 300 seconds # step 7: send wWND back to Alice at Westend AH -asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-rococo-local" within 60 seconds +asset-hub-rococo-collator1: run ../scripts/invoke-script.sh with "withdraw-reserve-assets-from-asset-hub-rococo-local" within 120 seconds # step 8: elsewhere Westend has sent wROC to //Alice - let's wait for it # (we wait until //Alice account increases here - there are no other transactionc that may increase it) diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs index fcf4513859e..3c9e76a34e3 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/send.rs @@ -27,3 +27,78 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } + +/// Parachain should be able to send XCM paying its fee with sufficient asset +/// in the System Parachain +#[test] +fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { + let para_sovereign_account = AssetHubRococo::sovereign_account_id_of( + AssetHubRococo::sibling_location_of(PenpalA::para_id()), + ); + + // Force create and mint assets for Parachain's sovereign account + AssetHubRococo::force_create_and_mint_asset( + ASSET_ID, + ASSET_MIN_BALANCE, + true, + para_sovereign_account.clone(), + Some(Weight::from_parts(1_019_445_000, 200_000)), + ASSET_MIN_BALANCE * 1000000000, + ); + + // We just need a call that can pass the `SafeCallFilter` + // Call values are not relevant + let call = AssetHubRococo::force_create_asset_call( + ASSET_ID, + para_sovereign_account.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let origin_kind = OriginKind::SovereignAccount; + let fee_amount = ASSET_MIN_BALANCE * 1000000; + let native_asset = + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); + + let root_origin = ::RuntimeOrigin::root(); + let system_para_destination = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + origin_kind, + native_asset, + para_sovereign_account.clone(), + ); + + PenpalA::execute_with(|| { + assert_ok!(::PolkadotXcm::send( + root_origin, + bx!(system_para_destination), + bx!(xcm), + )); + + PenpalA::assert_xcm_pallet_sent(); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubRococo::assert_xcmp_queue_success(Some(Weight::from_parts( + 15_594_564_000, + 562_893, + ))); + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { + asset_id: *asset_id == ASSET_ID, + owner: *owner == para_sovereign_account, + balance: *balance == fee_amount, + }, + RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { + asset_id: *asset_id == ASSET_ID, + }, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs index d943bafc379..a3cd5c5803e 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend/src/tests/send.rs @@ -27,3 +27,78 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() { Some(Weight::from_parts(1_019_445_000, 200_000)), ) } + +/// Parachain should be able to send XCM paying its fee with sufficient asset +/// in the System Parachain +#[test] +fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() { + let para_sovereign_account = AssetHubWestend::sovereign_account_id_of( + AssetHubWestend::sibling_location_of(PenpalB::para_id()), + ); + + // Force create and mint assets for Parachain's sovereign account + AssetHubWestend::force_create_and_mint_asset( + ASSET_ID, + ASSET_MIN_BALANCE, + true, + para_sovereign_account.clone(), + Some(Weight::from_parts(1_019_445_000, 200_000)), + ASSET_MIN_BALANCE * 1000000000, + ); + + // We just need a call that can pass the `SafeCallFilter` + // Call values are not relevant + let call = AssetHubWestend::force_create_asset_call( + ASSET_ID, + para_sovereign_account.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let origin_kind = OriginKind::SovereignAccount; + let fee_amount = ASSET_MIN_BALANCE * 1000000; + let native_asset = + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); + + let root_origin = ::RuntimeOrigin::root(); + let system_para_destination = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + origin_kind, + native_asset, + para_sovereign_account.clone(), + ); + + PenpalB::execute_with(|| { + assert_ok!(::PolkadotXcm::send( + root_origin, + bx!(system_para_destination), + bx!(xcm), + )); + + PenpalB::assert_xcm_pallet_sent(); + }); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts( + 16_290_336_000, + 562_893, + ))); + + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => { + asset_id: *asset_id == ASSET_ID, + owner: *owner == para_sovereign_account, + balance: *balance == fee_amount, + }, + RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => { + asset_id: *asset_id == ASSET_ID, + }, + ] + ); + }); +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 98b23efc06e..b9b9025b697 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -585,6 +585,32 @@ impl xcm_executor::Config for XcmConfig { ResolveAssetTo, AccountId, >, + // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated + // `pallet_assets` instance - `Assets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + AssetFeeAsExistentialDepositMultiplierFeeCharger, + TrustBackedAssetsConvertedConcreteId, + Assets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + FungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, + // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated + // `pallet_assets` instance - `ForeignAssets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, + ForeignAssetsConvertedConcreteId, + ForeignAssets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + ForeignFungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index 3da1a1e66bd..cb7ea34a057 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -20,27 +20,23 @@ use asset_hub_rococo_runtime::{ xcm_config, xcm_config::{ - bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, TokenLocation, - TokenLocationV3, + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf, + LocationToAccountId, TokenLocation, TokenLocationV3, TrustBackedAssetsPalletLocation, + TrustBackedAssetsPalletLocationV3, XcmConfig, }, - AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, - RuntimeEvent, ToWestendXcmRouterInstance, XcmpQueue, -}; -pub use asset_hub_rococo_runtime::{ - xcm_config::{ - CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, - XcmConfig, - }, - AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, - ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, - TrustBackedAssetsInstance, + AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, + ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, + MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, + ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, }; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; +use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_ok, + assert_noop, assert_ok, traits::{ fungible::{Inspect, Mutate}, fungibles::{ @@ -353,6 +349,429 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { }) } +#[test] +fn test_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let local_asset_id = 1; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + local_asset_id.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + local_asset_id.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + // get asset id as location + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + local_asset_id, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + Assets::balance(local_asset_id, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + Assets::total_supply(local_asset_id), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_foreign_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; + assert_ok!(ForeignAssets::force_create( + RuntimeHelper::root_origin(), + foreign_location.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(ForeignAssets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + foreign_location.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let asset_location_v4: Location = foreign_location.try_into().unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + foreign_location, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location_v4.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!( + unused_assets.ensure_contains(&(asset_location_v4, asset_amount_extra).into()) + ); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + ForeignAssets::balance(foreign_location, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + ForeignAssets::total_supply(foreign_location), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_with_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + // lets calculate amount needed + let amount_bought = WeightToFee::weight_to_fee(&bought); + + let asset: Asset = (asset_location.clone(), amount_bought).into(); + + // Make sure buy_weight does not return an error + assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); + + // Make sure again buy_weight does return an error + // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` + // tuple chain, which cannot be called twice + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // We actually use half of the weight + let weight_used = bought / 2; + + // Make sure refurnd works. + let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); + + assert_eq!( + trader.refund_weight(bought - weight_used, &ctx), + Some((asset_location, amount_refunded).into()) + ); + + // Drop trader + drop(trader); + + // We only should have paid for half of the bought weight + let fees_paid = WeightToFee::weight_to_fee(&weight_used); + + assert_eq!( + Assets::balance(1, AccountId::from(ALICE)), + ExistentialDeposit::get() + fees_paid + ); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_refund_not_possible_since_amount_less_than_ed() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy small amount + let bought = Weight::from_parts(500_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + let asset: Asset = (asset_location, amount_bought).into(); + + // Buy weight should return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // not credited since the ED is higher than this value + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); + + // We also need to ensure the total supply did not increase + assert_eq!(Assets::total_supply(1), 0); + }); +} + +#[test] +fn test_that_buying_ed_refund_does_not_refund_for_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are gonna buy ED + let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + // We know we will have to buy at least ED, so lets make sure first it will + // fail with a payment of less than ED + let asset: Asset = (asset_location.clone(), amount_bought).into(); + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Now lets buy ED at least + let asset: Asset = (asset_location, ExistentialDeposit::get()).into(); + + // Buy weight should work + assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); + + // Should return None. We have a specific check making sure we dont go below ED for + // drop payment + assert_eq!(trader.refund_weight(bought, &ctx), None); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); + }); +} + +#[test] +fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // Create a non-sufficient asset with specific existential deposit + let minimum_asset_balance = 1_000_000_u128; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + false, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // lets calculate amount needed + let asset_amount_needed = WeightToFee::weight_to_fee(&bought); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let asset: Asset = (asset_location, asset_amount_needed).into(); + + // Make sure again buy_weight does return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has NOT received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); + + // We also need to ensure the total supply NOT increased + assert_eq!(Assets::total_supply(1), minimum_asset_balance); + }); +} + #[test] fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index b2498418cc7..70522eda4b7 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -609,6 +609,32 @@ impl xcm_executor::Config for XcmConfig { ResolveAssetTo, AccountId, >, + // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated + // `pallet_assets` instance - `Assets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + AssetFeeAsExistentialDepositMultiplierFeeCharger, + TrustBackedAssetsConvertedConcreteId, + Assets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + FungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, + // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated + // `pallet_assets` instance - `ForeignAssets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, + ForeignAssetsConvertedConcreteId, + ForeignAssets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + ForeignFungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 28fc7ba705a..3fc9f4a9658 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -20,27 +20,24 @@ use asset_hub_westend_runtime::{ xcm_config, xcm_config::{ - bridging, ForeignCreatorsSovereignAccountOf, LocationToAccountId, WestendLocation, - WestendLocationV3, + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf, + LocationToAccountId, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, + WestendLocation, WestendLocationV3, XcmConfig, }, - AllPalletsWithoutSystem, MetadataDepositBase, MetadataDepositPerByte, PolkadotXcm, RuntimeCall, - RuntimeEvent, RuntimeOrigin, ToRococoXcmRouterInstance, XcmpQueue, -}; -pub use asset_hub_westend_runtime::{ - xcm_config::{ - CheckingAccount, TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, - XcmConfig, - }, - AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, - ForeignAssets, ForeignAssetsInstance, ParachainSystem, Runtime, SessionKeys, System, - TrustBackedAssetsInstance, + AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets, + ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, + PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, + ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, }; +pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; +use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_ok, + assert_noop, assert_ok, traits::{ fungible::{Inspect, Mutate}, fungibles::{ @@ -353,6 +350,427 @@ fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { }) } +#[test] +fn test_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let local_asset_id = 1; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + local_asset_id.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + local_asset_id.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + // get asset id as location + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + local_asset_id, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + Assets::balance(local_asset_id, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + Assets::total_supply(local_asset_id), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_foreign_asset_xcm_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; + assert_ok!(ForeignAssets::force_create( + RuntimeHelper::root_origin(), + foreign_location.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(ForeignAssets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + foreign_location.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let asset_location_v4: Location = foreign_location.try_into().unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + foreign_location, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location_v4.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!( + unused_assets.ensure_contains(&(asset_location_v4, asset_amount_extra).into()) + ); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + ForeignAssets::balance(foreign_location, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + ForeignAssets::total_supply(foreign_location), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_with_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + // lets calculate amount needed + let amount_bought = WeightToFee::weight_to_fee(&bought); + + let asset: Asset = (asset_location.clone(), amount_bought).into(); + + // Make sure buy_weight does not return an error + assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); + + // Make sure again buy_weight does return an error + // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` + // tuple chain, which cannot be called twice + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // We actually use half of the weight + let weight_used = bought / 2; + + // Make sure refurnd works. + let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); + + assert_eq!( + trader.refund_weight(bought - weight_used, &ctx), + Some((asset_location, amount_refunded).into()) + ); + + // Drop trader + drop(trader); + + // We only should have paid for half of the bought weight + let fees_paid = WeightToFee::weight_to_fee(&weight_used); + + assert_eq!( + Assets::balance(1, AccountId::from(ALICE)), + ExistentialDeposit::get() + fees_paid + ); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_refund_not_possible_since_amount_less_than_ed() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy small amount + let bought = Weight::from_parts(500_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + let asset: Asset = (asset_location, amount_bought).into(); + + // Buy weight should return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // not credited since the ED is higher than this value + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); + + // We also need to ensure the total supply did not increase + assert_eq!(Assets::total_supply(1), 0); + }); +} + +#[test] +fn test_that_buying_ed_refund_does_not_refund_for_take_first_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + let bought = Weight::from_parts(500_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + // We know we will have to buy at least ED, so lets make sure first it will + // fail with a payment of less than ED + let asset: Asset = (asset_location.clone(), amount_bought).into(); + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Now lets buy ED at least + let asset: Asset = (asset_location.clone(), ExistentialDeposit::get()).into(); + + // Buy weight should work + assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); + + // Should return None. We have a specific check making sure we dont go below ED for + // drop payment + assert_eq!(trader.refund_weight(bought, &ctx), None); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); + }); +} + +#[test] +fn test_asset_xcm_take_first_trader_not_possible_for_non_sufficient_assets() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // Create a non-sufficient asset with specific existential deposit + let minimum_asset_balance = 1_000_000_u128; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + false, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // lets calculate amount needed + let asset_amount_needed = WeightToFee::weight_to_fee(&bought); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let asset: Asset = (asset_location, asset_amount_needed).into(); + + // Make sure again buy_weight does return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has NOT received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); + + // We also need to ensure the total supply NOT increased + assert_eq!(Assets::total_supply(1), minimum_asset_balance); + }); +} + #[test] fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; -- GitLab From 0e124a05597b5575f79c90aae212fcf48a87e2ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 18 Jan 2024 18:28:19 +0100 Subject: [PATCH 028/283] pallet-contracts: Fix compilation on latest nightly (#2986) Apparently they changed detection for visibility identifiers on traits, which broke more than it should. There is an issue open: https://github.com/rust-lang/rust/issues/119924 The easy solution for us is to move the declaration of the global variable outside of the trait. Closes: https://github.com/paritytech/polkadot-sdk/issues/2960 --- substrate/frame/contracts/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index a15006e6388..533085f2b87 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -1228,6 +1228,9 @@ struct InternalOutput { result: Result, } +// Set up a global reference to the boolean flag used for the re-entrancy guard. +environmental!(executing_contract: bool); + /// Helper trait to wrap contract execution entry points into a single function /// [`Invokable::run_guarded`]. trait Invokable: Sized { @@ -1243,9 +1246,6 @@ trait Invokable: Sized { /// We enforce a re-entrancy guard here by initializing and checking a boolean flag through a /// global reference. fn run_guarded(self, common: CommonInput) -> InternalOutput { - // Set up a global reference to the boolean flag used for the re-entrancy guard. - environmental!(executing_contract: bool); - let gas_limit = common.gas_limit; // Check whether the origin is allowed here. The logic of the access rules -- GitLab From b469960461f674995d75cedbeb514afaa7e20676 Mon Sep 17 00:00:00 2001 From: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Date: Thu, 18 Jan 2024 19:28:55 +0200 Subject: [PATCH 029/283] approval-distribution: downgrade errors to debug (#2989) This is not actually an error of the node, but an issue with the incoming assignment. --------- Signed-off-by: Andrei Sandu --- polkadot/node/network/approval-distribution/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/polkadot/node/network/approval-distribution/src/lib.rs b/polkadot/node/network/approval-distribution/src/lib.rs index d520febaef5..184ccb6b042 100644 --- a/polkadot/node/network/approval-distribution/src/lib.rs +++ b/polkadot/node/network/approval-distribution/src/lib.rs @@ -2094,7 +2094,7 @@ impl State { // Punish the peer for the invalid message. modify_reputation(&mut self.reputation, sender, peer_id, COST_OVERSIZED_BITFIELD) .await; - gum::error!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, kind = ?cert.cert.kind, "Bad assignment v1"); + gum::debug!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, kind = ?cert.cert.kind, "Bad assignment v1, invalid candidate index"); } else { sanitized_assignments.push((cert.into(), candidate_index.into())) } @@ -2138,7 +2138,7 @@ impl State { modify_reputation(&mut self.reputation, sender, peer_id, COST_OVERSIZED_BITFIELD) .await; for candidate_index in candidate_bitfield.iter_ones() { - gum::error!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, "Bad assignment v2"); + gum::debug!(target: LOG_TARGET, block_hash = ?cert.block_hash, ?candidate_index, validator_index = ?cert.validator, "Bad assignment v2, oversized bitfield"); } } else { sanitized_assignments.push((cert, candidate_bitfield)) -- GitLab From f9bbe7db972c62e650ef732b36b05a55022671f6 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Thu, 18 Jan 2024 18:30:08 +0100 Subject: [PATCH 030/283] contracts: Update weights (#2969) As demanded by @athei to run benchmarks via CI. Somehow I was not able to push a PR without commits. --------- Co-authored-by: command-bot <> --- substrate/frame/contracts/src/weights.rs | 1348 +++++++++++----------- 1 file changed, 672 insertions(+), 676 deletions(-) diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 22e4f749313..622d1e8a9b7 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -18,9 +18,9 @@ //! Autogenerated weights for `pallet_contracts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-09-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-pzhd7p6z-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: @@ -141,8 +141,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_548_000 picoseconds. - Weight::from_parts(2_670_000, 1627) + // Minimum execution time: 1_991_000 picoseconds. + Weight::from_parts(2_135_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -150,12 +150,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `k` is `[0, 1024]`. fn on_initialize_per_trie_key(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + k * (69 ±0)` - // Estimated: `441 + k * (70 ±0)` - // Minimum execution time: 13_526_000 picoseconds. - Weight::from_parts(13_902_000, 441) - // Standard Error: 1_058 - .saturating_add(Weight::from_parts(1_274_724, 0).saturating_mul(k.into())) + // Measured: `452 + k * (69 ±0)` + // Estimated: `442 + k * (70 ±0)` + // Minimum execution time: 11_969_000 picoseconds. + Weight::from_parts(7_055_855, 442) + // Standard Error: 2_328 + .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -169,10 +169,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_426_000 picoseconds. - Weight::from_parts(8_591_621, 6149) + // Minimum execution time: 8_064_000 picoseconds. + Weight::from_parts(8_301_148, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_203, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -185,8 +185,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 17_008_000 picoseconds. - Weight::from_parts(17_742_000, 6450) + // Minimum execution time: 15_789_000 picoseconds. + Weight::from_parts(16_850_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -199,10 +199,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_949_000 picoseconds. - Weight::from_parts(4_062_000, 3635) - // Standard Error: 1_983 - .saturating_add(Weight::from_parts(1_173_197, 0).saturating_mul(k.into())) + // Minimum execution time: 3_369_000 picoseconds. + Weight::from_parts(3_516_000, 3635) + // Standard Error: 960 + .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -221,10 +221,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 17_094_000 picoseconds. - Weight::from_parts(17_338_591, 6263) + // Minimum execution time: 16_320_000 picoseconds. + Weight::from_parts(16_090_036, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(436, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -235,8 +235,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_704_000 picoseconds. - Weight::from_parts(13_147_000, 6380) + // Minimum execution time: 12_669_000 picoseconds. + Weight::from_parts(13_118_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -245,13 +245,13 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: - // Measured: `360` - // Estimated: `6300` - // Minimum execution time: 48_387_000 picoseconds. - Weight::from_parts(50_024_000, 6300) + // Measured: `352` + // Estimated: `6292` + // Minimum execution time: 45_403_000 picoseconds. + Weight::from_parts(46_636_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -263,8 +263,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 59_300_000 picoseconds. - Weight::from_parts(61_805_000, 6534) + // Minimum execution time: 53_622_000 picoseconds. + Weight::from_parts(55_444_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -274,8 +274,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 3_327_000 picoseconds. - Weight::from_parts(3_502_000, 1627) + // Minimum execution time: 2_444_000 picoseconds. + Weight::from_parts(2_587_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -287,8 +287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 12_759_000 picoseconds. - Weight::from_parts(13_134_000, 3631) + // Minimum execution time: 11_476_000 picoseconds. + Weight::from_parts(11_944_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -298,8 +298,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_775_000 picoseconds. - Weight::from_parts(5_084_000, 3607) + // Minimum execution time: 4_652_000 picoseconds. + Weight::from_parts(4_792_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -310,8 +310,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_663_000 picoseconds. - Weight::from_parts(6_855_000, 3632) + // Minimum execution time: 6_054_000 picoseconds. + Weight::from_parts(6_278_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -322,8 +322,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 7_212_000 picoseconds. - Weight::from_parts(7_426_000, 3607) + // Minimum execution time: 6_056_000 picoseconds. + Weight::from_parts(6_343_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -346,10 +346,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `792` // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 289_557_000 picoseconds. - Weight::from_parts(272_895_652, 6743) - // Standard Error: 80 - .saturating_add(Weight::from_parts(39_917, 0).saturating_mul(c.into())) + // Minimum execution time: 303_205_000 picoseconds. + Weight::from_parts(266_154_889, 6743) + // Standard Error: 79 + .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -359,7 +359,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -379,14 +379,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `323` // Estimated: `8747` - // Minimum execution time: 4_671_359_000 picoseconds. - Weight::from_parts(586_523_882, 8747) - // Standard Error: 206 - .saturating_add(Weight::from_parts(115_402, 0).saturating_mul(c.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_797, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(2_046, 0).saturating_mul(s.into())) + // Minimum execution time: 4_311_802_000 picoseconds. + Weight::from_parts(777_467_048, 8747) + // Standard Error: 338 + .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -407,19 +407,19 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 2_170_657_000 picoseconds. - Weight::from_parts(369_331_405, 6504) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_940, 0).saturating_mul(i.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_858, 0).saturating_mul(s.into())) + // Minimum execution time: 1_958_694_000 picoseconds. + Weight::from_parts(331_222_273, 6504) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -441,8 +441,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 204_287_000 picoseconds. - Weight::from_parts(213_239_000, 6766) + // Minimum execution time: 194_513_000 picoseconds. + Weight::from_parts(201_116_000, 6766) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -451,7 +451,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -461,10 +461,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 285_434_000 picoseconds. - Weight::from_parts(242_697_648, 3607) - // Standard Error: 128 - .saturating_add(Weight::from_parts(76_087, 0).saturating_mul(c.into())) + // Minimum execution time: 269_777_000 picoseconds. + Weight::from_parts(204_229_027, 3607) + // Standard Error: 152 + .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -473,7 +473,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -482,8 +482,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 46_486_000 picoseconds. - Weight::from_parts(48_422_000, 3780) + // Minimum execution time: 43_271_000 picoseconds. + Weight::from_parts(44_884_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -499,8 +499,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 37_568_000 picoseconds. - Weight::from_parts(38_589_000, 8967) + // Minimum execution time: 34_635_000 picoseconds. + Weight::from_parts(35_477_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -523,10 +523,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 274_513_000 picoseconds. - Weight::from_parts(288_793_403, 6806) - // Standard Error: 650 - .saturating_add(Weight::from_parts(339_309, 0).saturating_mul(r.into())) + // Minimum execution time: 266_757_000 picoseconds. + Weight::from_parts(279_787_352, 6806) + // Standard Error: 812 + .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -550,10 +550,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 260_096_000 picoseconds. - Weight::from_parts(149_954_322, 6826) - // Standard Error: 5_713 - .saturating_add(Weight::from_parts(3_788_924, 0).saturating_mul(r.into())) + // Minimum execution time: 266_442_000 picoseconds. + Weight::from_parts(86_660_390, 6826) + // Standard Error: 9_194 + .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -578,10 +578,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 277_496_000 picoseconds. - Weight::from_parts(285_839_000, 6830) - // Standard Error: 10_076 - .saturating_add(Weight::from_parts(4_720_110, 0).saturating_mul(r.into())) + // Minimum execution time: 265_608_000 picoseconds. + Weight::from_parts(273_219_000, 6830) + // Standard Error: 11_085 + .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -606,10 +606,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 275_655_000 picoseconds. - Weight::from_parts(291_386_528, 6815) - // Standard Error: 898 - .saturating_add(Weight::from_parts(428_765, 0).saturating_mul(r.into())) + // Minimum execution time: 270_033_000 picoseconds. + Weight::from_parts(288_700_795, 6815) + // Standard Error: 1_628 + .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -633,10 +633,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 260_323_000 picoseconds. - Weight::from_parts(286_371_403, 6804) - // Standard Error: 451 - .saturating_add(Weight::from_parts(183_053, 0).saturating_mul(r.into())) + // Minimum execution time: 263_789_000 picoseconds. + Weight::from_parts(275_806_968, 6804) + // Standard Error: 936 + .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -658,10 +658,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 262_974_000 picoseconds. - Weight::from_parts(276_571_502, 6693) - // Standard Error: 527 - .saturating_add(Weight::from_parts(165_364, 0).saturating_mul(r.into())) + // Minimum execution time: 257_922_000 picoseconds. + Weight::from_parts(270_842_153, 6693) + // Standard Error: 637 + .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -685,10 +685,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 272_826_000 picoseconds. - Weight::from_parts(290_963_001, 6807) - // Standard Error: 810 - .saturating_add(Weight::from_parts(343_762, 0).saturating_mul(r.into())) + // Minimum execution time: 267_214_000 picoseconds. + Weight::from_parts(273_446_444, 6807) + // Standard Error: 2_355 + .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -712,10 +712,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 277_324_000 picoseconds. - Weight::from_parts(290_872_814, 6806) - // Standard Error: 766 - .saturating_add(Weight::from_parts(371_542, 0).saturating_mul(r.into())) + // Minimum execution time: 258_860_000 picoseconds. + Weight::from_parts(286_389_737, 6806) + // Standard Error: 1_707 + .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -739,10 +739,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 274_460_000 picoseconds. - Weight::from_parts(285_748_025, 6931) - // Standard Error: 1_570 - .saturating_add(Weight::from_parts(1_656_237, 0).saturating_mul(r.into())) + // Minimum execution time: 267_852_000 picoseconds. + Weight::from_parts(279_617_620, 6931) + // Standard Error: 3_382 + .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -766,10 +766,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 278_254_000 picoseconds. - Weight::from_parts(283_893_525, 6823) - // Standard Error: 726 - .saturating_add(Weight::from_parts(347_368, 0).saturating_mul(r.into())) + // Minimum execution time: 266_379_000 picoseconds. + Weight::from_parts(287_280_653, 6823) + // Standard Error: 1_774 + .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -793,10 +793,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 279_646_000 picoseconds. - Weight::from_parts(292_505_446, 6816) - // Standard Error: 867 - .saturating_add(Weight::from_parts(337_202, 0).saturating_mul(r.into())) + // Minimum execution time: 266_417_000 picoseconds. + Weight::from_parts(291_394_038, 6816) + // Standard Error: 1_474 + .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -820,10 +820,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 274_522_000 picoseconds. - Weight::from_parts(295_135_659, 6819) - // Standard Error: 1_052 - .saturating_add(Weight::from_parts(330_788, 0).saturating_mul(r.into())) + // Minimum execution time: 269_198_000 picoseconds. + Weight::from_parts(285_025_368, 6819) + // Standard Error: 1_231 + .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -847,10 +847,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 274_228_000 picoseconds. - Weight::from_parts(289_201_593, 6804) - // Standard Error: 752 - .saturating_add(Weight::from_parts(337_860, 0).saturating_mul(r.into())) + // Minimum execution time: 257_514_000 picoseconds. + Weight::from_parts(280_424_571, 6804) + // Standard Error: 723 + .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -876,10 +876,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 277_142_000 picoseconds. - Weight::from_parts(296_736_114, 6872) - // Standard Error: 1_502 - .saturating_add(Weight::from_parts(1_446_663, 0).saturating_mul(r.into())) + // Minimum execution time: 268_221_000 picoseconds. + Weight::from_parts(282_273_629, 6872) + // Standard Error: 2_398 + .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -903,10 +903,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 276_087_000 picoseconds. - Weight::from_parts(287_863_377, 6807) - // Standard Error: 495 - .saturating_add(Weight::from_parts(282_718, 0).saturating_mul(r.into())) + // Minimum execution time: 271_541_000 picoseconds. + Weight::from_parts(276_996_569, 6807) + // Standard Error: 1_462 + .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -930,10 +930,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 277_128_000 picoseconds. - Weight::from_parts(234_478_674, 6809) - // Standard Error: 23 - .saturating_add(Weight::from_parts(1_052, 0).saturating_mul(n.into())) + // Minimum execution time: 256_410_000 picoseconds. + Weight::from_parts(206_888_877, 6809) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -956,8 +956,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 251_983_000 picoseconds. - Weight::from_parts(277_986_885, 6793) + // Minimum execution time: 248_852_000 picoseconds. + Weight::from_parts(277_852_834, 6793) + // Standard Error: 1_257_219 + .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -981,10 +983,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 275_108_000 picoseconds. - Weight::from_parts(284_552_708, 6810) - // Standard Error: 0 - .saturating_add(Weight::from_parts(391, 0).saturating_mul(n.into())) + // Minimum execution time: 269_101_000 picoseconds. + Weight::from_parts(273_407_545, 6810) + // Standard Error: 2 + .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1005,7 +1007,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. @@ -1013,10 +1015,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 281_278_000 picoseconds. - Weight::from_parts(306_800_667, 8912) - // Standard Error: 855_257 - .saturating_add(Weight::from_parts(126_508_132, 0).saturating_mul(r.into())) + // Minimum execution time: 296_318_000 picoseconds. + Weight::from_parts(322_448_344, 8912) + // Standard Error: 2_358_838 + .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1044,10 +1046,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 260_609_000 picoseconds. - Weight::from_parts(287_385_076, 6885) - // Standard Error: 2_754 - .saturating_add(Weight::from_parts(2_057_388, 0).saturating_mul(r.into())) + // Minimum execution time: 268_264_000 picoseconds. + Weight::from_parts(285_298_853, 6885) + // Standard Error: 3_238 + .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1071,10 +1073,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 254_770_000 picoseconds. - Weight::from_parts(255_105_647, 6805) - // Standard Error: 5_707 - .saturating_add(Weight::from_parts(3_808_788, 0).saturating_mul(r.into())) + // Minimum execution time: 267_417_000 picoseconds. + Weight::from_parts(290_097_452, 6805) + // Standard Error: 2_523 + .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1099,12 +1101,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 278_200_000 picoseconds. - Weight::from_parts(288_081_493, 6825) - // Standard Error: 97_535 - .saturating_add(Weight::from_parts(3_683_455, 0).saturating_mul(t.into())) - // Standard Error: 27 - .saturating_add(Weight::from_parts(731, 0).saturating_mul(n.into())) + // Minimum execution time: 269_735_000 picoseconds. + Weight::from_parts(291_680_757, 6825) + // Standard Error: 196_822 + .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) + // Standard Error: 55 + .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1130,10 +1132,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 167_181_000 picoseconds. - Weight::from_parts(178_433_475, 6807) - // Standard Error: 374 - .saturating_add(Weight::from_parts(241_240, 0).saturating_mul(r.into())) + // Minimum execution time: 161_454_000 picoseconds. + Weight::from_parts(181_662_272, 6807) + // Standard Error: 729 + .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -1157,10 +1159,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 434_456_000 picoseconds. - Weight::from_parts(400_940_450, 131755) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_102, 0).saturating_mul(i.into())) + // Minimum execution time: 418_479_000 picoseconds. + Weight::from_parts(397_691_558, 131755) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1170,11 +1172,11 @@ impl WeightInfo for SubstrateWeight { fn seal_set_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` - // Estimated: `925 + r * (293 ±0)` - // Minimum execution time: 277_825_000 picoseconds. - Weight::from_parts(159_688_263, 925) - // Standard Error: 13_610 - .saturating_add(Weight::from_parts(7_145_641, 0).saturating_mul(r.into())) + // Estimated: `926 + r * (293 ±0)` + // Minimum execution time: 268_810_000 picoseconds. + Weight::from_parts(129_545_478, 926) + // Standard Error: 21_173 + .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1186,12 +1188,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_new_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1446` - // Estimated: `1429` - // Minimum execution time: 284_745_000 picoseconds. - Weight::from_parts(345_928_316, 1429) - // Standard Error: 70 - .saturating_add(Weight::from_parts(547, 0).saturating_mul(n.into())) + // Measured: `1447` + // Estimated: `1430` + // Minimum execution time: 286_965_000 picoseconds. + Weight::from_parts(340_396_510, 1430) + // Standard Error: 90 + .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -1200,12 +1202,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_old_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1252 + n * (1 ±0)` - // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 275_328_000 picoseconds. - Weight::from_parts(300_037_010, 1252) - // Standard Error: 32 - .saturating_add(Weight::from_parts(558, 0).saturating_mul(n.into())) + // Measured: `1253 + n * (1 ±0)` + // Estimated: `1253 + n * (1 ±0)` + // Minimum execution time: 272_395_000 picoseconds. + Weight::from_parts(302_307_069, 1253) + // Standard Error: 94 + .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1215,12 +1217,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_clear_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (288 ±0)` - // Estimated: `926 + r * (289 ±0)` - // Minimum execution time: 273_742_000 picoseconds. - Weight::from_parts(169_430_806, 926) - // Standard Error: 11_821 - .saturating_add(Weight::from_parts(6_927_074, 0).saturating_mul(r.into())) + // Measured: `921 + r * (288 ±0)` + // Estimated: `927 + r * (289 ±0)` + // Minimum execution time: 269_165_000 picoseconds. + Weight::from_parts(167_174_485, 927) + // Standard Error: 23_564 + .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1232,12 +1234,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_clear_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1248 + n * (1 ±0)` - // Estimated: `1248 + n * (1 ±0)` - // Minimum execution time: 275_167_000 picoseconds. - Weight::from_parts(301_883_655, 1248) - // Standard Error: 35 - .saturating_add(Weight::from_parts(4, 0).saturating_mul(n.into())) + // Measured: `1249 + n * (1 ±0)` + // Estimated: `1249 + n * (1 ±0)` + // Minimum execution time: 270_248_000 picoseconds. + Weight::from_parts(296_573_310, 1249) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1247,12 +1247,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_get_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (296 ±0)` - // Estimated: `922 + r * (297 ±0)` - // Minimum execution time: 274_628_000 picoseconds. - Weight::from_parts(195_255_092, 922) - // Standard Error: 9_109 - .saturating_add(Weight::from_parts(5_707_060, 0).saturating_mul(r.into())) + // Measured: `921 + r * (296 ±0)` + // Estimated: `923 + r * (297 ±0)` + // Minimum execution time: 270_883_000 picoseconds. + Weight::from_parts(189_792_705, 923) + // Standard Error: 11_149 + .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1263,12 +1263,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_get_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1264 + n * (1 ±0)` - // Estimated: `1264 + n * (1 ±0)` - // Minimum execution time: 274_202_000 picoseconds. - Weight::from_parts(296_440_752, 1264) - // Standard Error: 38 - .saturating_add(Weight::from_parts(1_010, 0).saturating_mul(n.into())) + // Measured: `1265 + n * (1 ±0)` + // Estimated: `1265 + n * (1 ±0)` + // Minimum execution time: 263_833_000 picoseconds. + Weight::from_parts(290_179_222, 1265) + // Standard Error: 44 + .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1278,12 +1278,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_contains_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `931 + r * (288 ±0)` - // Estimated: `928 + r * (289 ±0)` - // Minimum execution time: 274_123_000 picoseconds. - Weight::from_parts(193_280_535, 928) - // Standard Error: 9_264 - .saturating_add(Weight::from_parts(5_548_039, 0).saturating_mul(r.into())) + // Measured: `932 + r * (288 ±0)` + // Estimated: `929 + r * (289 ±0)` + // Minimum execution time: 252_637_000 picoseconds. + Weight::from_parts(98_108_825, 929) + // Standard Error: 23_580 + .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1294,12 +1294,10 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_contains_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1251 + n * (1 ±0)` - // Estimated: `1251 + n * (1 ±0)` - // Minimum execution time: 276_425_000 picoseconds. - Weight::from_parts(300_521_806, 1251) - // Standard Error: 36 - .saturating_add(Weight::from_parts(83, 0).saturating_mul(n.into())) + // Measured: `1252 + n * (1 ±0)` + // Estimated: `1252 + n * (1 ±0)` + // Minimum execution time: 279_133_000 picoseconds. + Weight::from_parts(301_192_115, 1252) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1309,12 +1307,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 800]`. fn seal_take_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `913 + r * (296 ±0)` - // Estimated: `918 + r * (297 ±0)` - // Minimum execution time: 264_860_000 picoseconds. - Weight::from_parts(191_561_777, 918) - // Standard Error: 10_678 - .saturating_add(Weight::from_parts(6_895_457, 0).saturating_mul(r.into())) + // Measured: `914 + r * (296 ±0)` + // Estimated: `919 + r * (297 ±0)` + // Minimum execution time: 268_833_000 picoseconds. + Weight::from_parts(56_229_951, 919) + // Standard Error: 25_800 + .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1326,12 +1324,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[0, 16384]`. fn seal_take_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1265 + n * (1 ±0)` - // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 282_501_000 picoseconds. - Weight::from_parts(303_351_919, 1265) - // Standard Error: 37 - .saturating_add(Weight::from_parts(643, 0).saturating_mul(n.into())) + // Measured: `1266 + n * (1 ±0)` + // Estimated: `1266 + n * (1 ±0)` + // Minimum execution time: 288_677_000 picoseconds. + Weight::from_parts(301_986_360, 1266) + // Standard Error: 39 + .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1355,10 +1353,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 273_198_000 picoseconds. - Weight::from_parts(179_673_238, 7307) - // Standard Error: 34_990 - .saturating_add(Weight::from_parts(38_468_091, 0).saturating_mul(r.into())) + // Minimum execution time: 275_956_000 picoseconds. + Weight::from_parts(280_865_651, 7307) + // Standard Error: 28_235 + .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1384,10 +1382,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 283_869_000 picoseconds. - Weight::from_parts(288_374_000, 9440) - // Standard Error: 137_512 - .saturating_add(Weight::from_parts(248_206_665, 0).saturating_mul(r.into())) + // Minimum execution time: 269_188_000 picoseconds. + Weight::from_parts(276_038_000, 9440) + // Standard Error: 262_029 + .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1413,10 +1411,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 257_577_000 picoseconds. - Weight::from_parts(277_310_000, 6812) - // Standard Error: 150_204 - .saturating_add(Weight::from_parts(249_943_483, 0).saturating_mul(r.into())) + // Minimum execution time: 267_543_000 picoseconds. + Weight::from_parts(271_365_000, 6812) + // Standard Error: 190_454 + .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1443,12 +1441,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 471_081_000 picoseconds. - Weight::from_parts(79_081_122, 12197) - // Standard Error: 11_777_790 - .saturating_add(Weight::from_parts(357_425_411, 0).saturating_mul(t.into())) + // Minimum execution time: 453_215_000 picoseconds. + Weight::from_parts(32_029_330, 12197) + // Standard Error: 12_154_174 + .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_111, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -1472,16 +1470,16 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 672_742_000 picoseconds. - Weight::from_parts(680_025_000, 9620) - // Standard Error: 313_642 - .saturating_add(Weight::from_parts(388_311_259, 0).saturating_mul(r.into())) + // Minimum execution time: 635_304_000 picoseconds. + Weight::from_parts(645_872_000, 9620) + // Standard Error: 356_713 + .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -1505,7 +1503,7 @@ impl WeightInfo for SubstrateWeight { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. @@ -1513,12 +1511,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_733_870_000 picoseconds. - Weight::from_parts(1_001_793_458, 12211) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_963, 0).saturating_mul(i.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(2_060, 0).saturating_mul(s.into())) + // Minimum execution time: 2_225_692_000 picoseconds. + Weight::from_parts(1_292_861_603, 12211) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(11_u64)) @@ -1544,10 +1542,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 272_658_000 picoseconds. - Weight::from_parts(282_717_645, 6801) - // Standard Error: 517 - .saturating_add(Weight::from_parts(400_604, 0).saturating_mul(r.into())) + // Minimum execution time: 252_664_000 picoseconds. + Weight::from_parts(277_967_331, 6801) + // Standard Error: 723 + .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1571,10 +1569,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 260_969_000 picoseconds. - Weight::from_parts(265_206_847, 6808) + // Minimum execution time: 252_485_000 picoseconds. + Weight::from_parts(259_271_531, 6808) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_134, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1597,10 +1595,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 262_351_000 picoseconds. - Weight::from_parts(286_974_296, 6806) - // Standard Error: 514 - .saturating_add(Weight::from_parts(802_363, 0).saturating_mul(r.into())) + // Minimum execution time: 249_270_000 picoseconds. + Weight::from_parts(272_528_711, 6806) + // Standard Error: 903 + .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1624,10 +1622,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 276_907_000 picoseconds. - Weight::from_parts(277_928_418, 6814) - // Standard Error: 1 - .saturating_add(Weight::from_parts(3_410, 0).saturating_mul(n.into())) + // Minimum execution time: 249_470_000 picoseconds. + Weight::from_parts(273_317_815, 6814) + // Standard Error: 4 + .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1650,10 +1648,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 263_660_000 picoseconds. - Weight::from_parts(285_665_916, 6808) - // Standard Error: 527 - .saturating_add(Weight::from_parts(480_457, 0).saturating_mul(r.into())) + // Minimum execution time: 265_503_000 picoseconds. + Weight::from_parts(279_774_666, 6808) + // Standard Error: 1_351 + .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1677,10 +1675,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 262_071_000 picoseconds. - Weight::from_parts(270_115_341, 6813) + // Minimum execution time: 265_009_000 picoseconds. + Weight::from_parts(270_467_968, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_254, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1703,10 +1701,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 265_568_000 picoseconds. - Weight::from_parts(285_791_811, 6805) - // Standard Error: 559 - .saturating_add(Weight::from_parts(505_330, 0).saturating_mul(r.into())) + // Minimum execution time: 251_771_000 picoseconds. + Weight::from_parts(283_553_523, 6805) + // Standard Error: 1_053 + .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1730,10 +1728,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 271_336_000 picoseconds. - Weight::from_parts(272_829_313, 6811) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_252, 0).saturating_mul(n.into())) + // Minimum execution time: 253_733_000 picoseconds. + Weight::from_parts(264_277_000, 6811) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1756,10 +1754,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 351_146_000 picoseconds. - Weight::from_parts(355_368_323, 6934) - // Standard Error: 14 - .saturating_add(Weight::from_parts(6_155, 0).saturating_mul(n.into())) + // Minimum execution time: 337_326_000 picoseconds. + Weight::from_parts(346_340_758, 6934) + // Standard Error: 18 + .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1781,12 +1779,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `807 + r * (112 ±0)` + // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 277_250_000 picoseconds. - Weight::from_parts(346_490_114, 6748) - // Standard Error: 14_654 - .saturating_add(Weight::from_parts(56_127_492, 0).saturating_mul(r.into())) + // Minimum execution time: 253_852_000 picoseconds. + Weight::from_parts(335_731_679, 6748) + // Standard Error: 13_615 + .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -1810,10 +1808,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 272_697_000 picoseconds. - Weight::from_parts(345_385_667, 6801) - // Standard Error: 14_226 - .saturating_add(Weight::from_parts(46_037_637, 0).saturating_mul(r.into())) + // Minimum execution time: 256_283_000 picoseconds. + Weight::from_parts(338_634_113, 6801) + // Standard Error: 43_436 + .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -1837,10 +1835,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 271_800_000 picoseconds. - Weight::from_parts(314_891_136, 6816) - // Standard Error: 9_762 - .saturating_add(Weight::from_parts(11_949_979, 0).saturating_mul(r.into())) + // Minimum execution time: 269_144_000 picoseconds. + Weight::from_parts(331_790_138, 6816) + // Standard Error: 23_357 + .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -1864,10 +1862,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 274_238_000 picoseconds. - Weight::from_parts(278_034_000, 6807) - // Standard Error: 77_011 - .saturating_add(Weight::from_parts(27_627_005, 0).saturating_mul(r.into())) + // Minimum execution time: 262_624_000 picoseconds. + Weight::from_parts(275_865_000, 6807) + // Standard Error: 64_162 + .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1893,10 +1891,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 271_519_000 picoseconds. - Weight::from_parts(292_726_476, 6878) - // Standard Error: 23_870 - .saturating_add(Weight::from_parts(6_695_172, 0).saturating_mul(r.into())) + // Minimum execution time: 265_482_000 picoseconds. + Weight::from_parts(296_491_925, 6878) + // Standard Error: 46_681 + .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1922,10 +1920,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 274_675_000 picoseconds. - Weight::from_parts(293_727_489, 129453) - // Standard Error: 23_160 - .saturating_add(Weight::from_parts(5_895_043, 0).saturating_mul(r.into())) + // Minimum execution time: 257_532_000 picoseconds. + Weight::from_parts(299_110_930, 129453) + // Standard Error: 55_003 + .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1951,10 +1949,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 253_330_000 picoseconds. - Weight::from_parts(281_079_564, 6804) - // Standard Error: 378 - .saturating_add(Weight::from_parts(180_655, 0).saturating_mul(r.into())) + // Minimum execution time: 268_894_000 picoseconds. + Weight::from_parts(287_048_741, 6804) + // Standard Error: 1_156 + .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -1978,10 +1976,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 276_552_000 picoseconds. - Weight::from_parts(368_521_088, 7899) - // Standard Error: 2_310 - .saturating_add(Weight::from_parts(318_129, 0).saturating_mul(r.into())) + // Minimum execution time: 262_736_000 picoseconds. + Weight::from_parts(389_199_672, 7899) + // Standard Error: 2_646 + .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -2007,10 +2005,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 258_953_000 picoseconds. - Weight::from_parts(288_222_836, 6801) - // Standard Error: 367 - .saturating_add(Weight::from_parts(152_842, 0).saturating_mul(r.into())) + // Minimum execution time: 253_465_000 picoseconds. + Weight::from_parts(283_153_874, 6801) + // Standard Error: 745 + .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2020,10 +2018,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_476_000 picoseconds. - Weight::from_parts(2_119_717, 0) - // Standard Error: 28 - .saturating_add(Weight::from_parts(9_805, 0).saturating_mul(r.into())) + // Minimum execution time: 1_342_000 picoseconds. + Weight::from_parts(1_940_100, 0) + // Standard Error: 21 + .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) } } @@ -2035,8 +2033,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_548_000 picoseconds. - Weight::from_parts(2_670_000, 1627) + // Minimum execution time: 1_991_000 picoseconds. + Weight::from_parts(2_135_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -2044,12 +2042,12 @@ impl WeightInfo for () { /// The range of component `k` is `[0, 1024]`. fn on_initialize_per_trie_key(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `451 + k * (69 ±0)` - // Estimated: `441 + k * (70 ±0)` - // Minimum execution time: 13_526_000 picoseconds. - Weight::from_parts(13_902_000, 441) - // Standard Error: 1_058 - .saturating_add(Weight::from_parts(1_274_724, 0).saturating_mul(k.into())) + // Measured: `452 + k * (69 ±0)` + // Estimated: `442 + k * (70 ±0)` + // Minimum execution time: 11_969_000 picoseconds. + Weight::from_parts(7_055_855, 442) + // Standard Error: 2_328 + .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2063,10 +2061,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_426_000 picoseconds. - Weight::from_parts(8_591_621, 6149) + // Minimum execution time: 8_064_000 picoseconds. + Weight::from_parts(8_301_148, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_203, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2079,8 +2077,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 17_008_000 picoseconds. - Weight::from_parts(17_742_000, 6450) + // Minimum execution time: 15_789_000 picoseconds. + Weight::from_parts(16_850_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2093,10 +2091,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_949_000 picoseconds. - Weight::from_parts(4_062_000, 3635) - // Standard Error: 1_983 - .saturating_add(Weight::from_parts(1_173_197, 0).saturating_mul(k.into())) + // Minimum execution time: 3_369_000 picoseconds. + Weight::from_parts(3_516_000, 3635) + // Standard Error: 960 + .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -2115,10 +2113,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 17_094_000 picoseconds. - Weight::from_parts(17_338_591, 6263) + // Minimum execution time: 16_320_000 picoseconds. + Weight::from_parts(16_090_036, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(436, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2129,8 +2127,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_704_000 picoseconds. - Weight::from_parts(13_147_000, 6380) + // Minimum execution time: 12_669_000 picoseconds. + Weight::from_parts(13_118_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2139,13 +2137,13 @@ impl WeightInfo for () { /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) fn v14_migration_step() -> Weight { // Proof Size summary in bytes: - // Measured: `360` - // Estimated: `6300` - // Minimum execution time: 48_387_000 picoseconds. - Weight::from_parts(50_024_000, 6300) + // Measured: `352` + // Estimated: `6292` + // Minimum execution time: 45_403_000 picoseconds. + Weight::from_parts(46_636_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2157,8 +2155,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 59_300_000 picoseconds. - Weight::from_parts(61_805_000, 6534) + // Minimum execution time: 53_622_000 picoseconds. + Weight::from_parts(55_444_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2168,8 +2166,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 3_327_000 picoseconds. - Weight::from_parts(3_502_000, 1627) + // Minimum execution time: 2_444_000 picoseconds. + Weight::from_parts(2_587_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2181,8 +2179,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 12_759_000 picoseconds. - Weight::from_parts(13_134_000, 3631) + // Minimum execution time: 11_476_000 picoseconds. + Weight::from_parts(11_944_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2192,8 +2190,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_775_000 picoseconds. - Weight::from_parts(5_084_000, 3607) + // Minimum execution time: 4_652_000 picoseconds. + Weight::from_parts(4_792_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2204,8 +2202,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_663_000 picoseconds. - Weight::from_parts(6_855_000, 3632) + // Minimum execution time: 6_054_000 picoseconds. + Weight::from_parts(6_278_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2216,8 +2214,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 7_212_000 picoseconds. - Weight::from_parts(7_426_000, 3607) + // Minimum execution time: 6_056_000 picoseconds. + Weight::from_parts(6_343_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2240,10 +2238,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `792` // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 289_557_000 picoseconds. - Weight::from_parts(272_895_652, 6743) - // Standard Error: 80 - .saturating_add(Weight::from_parts(39_917, 0).saturating_mul(c.into())) + // Minimum execution time: 303_205_000 picoseconds. + Weight::from_parts(266_154_889, 6743) + // Standard Error: 79 + .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2253,7 +2251,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:2 w:2) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:3 w:3) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::Nonce` (r:1 w:1) @@ -2273,14 +2271,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `323` // Estimated: `8747` - // Minimum execution time: 4_671_359_000 picoseconds. - Weight::from_parts(586_523_882, 8747) - // Standard Error: 206 - .saturating_add(Weight::from_parts(115_402, 0).saturating_mul(c.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_797, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(2_046, 0).saturating_mul(s.into())) + // Minimum execution time: 4_311_802_000 picoseconds. + Weight::from_parts(777_467_048, 8747) + // Standard Error: 338 + .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) + // Standard Error: 40 + .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -2301,19 +2299,19 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `i` is `[0, 1048576]`. /// The range of component `s` is `[0, 1048576]`. fn instantiate(i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 2_170_657_000 picoseconds. - Weight::from_parts(369_331_405, 6504) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_940, 0).saturating_mul(i.into())) - // Standard Error: 7 - .saturating_add(Weight::from_parts(1_858, 0).saturating_mul(s.into())) + // Minimum execution time: 1_958_694_000 picoseconds. + Weight::from_parts(331_222_273, 6504) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) + // Standard Error: 13 + .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -2335,8 +2333,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 204_287_000 picoseconds. - Weight::from_parts(213_239_000, 6766) + // Minimum execution time: 194_513_000 picoseconds. + Weight::from_parts(201_116_000, 6766) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2345,7 +2343,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2355,10 +2353,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 285_434_000 picoseconds. - Weight::from_parts(242_697_648, 3607) - // Standard Error: 128 - .saturating_add(Weight::from_parts(76_087, 0).saturating_mul(c.into())) + // Minimum execution time: 269_777_000 picoseconds. + Weight::from_parts(204_229_027, 3607) + // Standard Error: 152 + .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2367,7 +2365,7 @@ impl WeightInfo for () { /// Storage: `Contracts::CodeInfoOf` (r:1 w:1) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `System::EventTopics` (r:1 w:1) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Contracts::PristineCode` (r:0 w:1) @@ -2376,8 +2374,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 46_486_000 picoseconds. - Weight::from_parts(48_422_000, 3780) + // Minimum execution time: 43_271_000 picoseconds. + Weight::from_parts(44_884_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2393,8 +2391,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 37_568_000 picoseconds. - Weight::from_parts(38_589_000, 8967) + // Minimum execution time: 34_635_000 picoseconds. + Weight::from_parts(35_477_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2417,10 +2415,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 274_513_000 picoseconds. - Weight::from_parts(288_793_403, 6806) - // Standard Error: 650 - .saturating_add(Weight::from_parts(339_309, 0).saturating_mul(r.into())) + // Minimum execution time: 266_757_000 picoseconds. + Weight::from_parts(279_787_352, 6806) + // Standard Error: 812 + .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2444,10 +2442,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 260_096_000 picoseconds. - Weight::from_parts(149_954_322, 6826) - // Standard Error: 5_713 - .saturating_add(Weight::from_parts(3_788_924, 0).saturating_mul(r.into())) + // Minimum execution time: 266_442_000 picoseconds. + Weight::from_parts(86_660_390, 6826) + // Standard Error: 9_194 + .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2472,10 +2470,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 277_496_000 picoseconds. - Weight::from_parts(285_839_000, 6830) - // Standard Error: 10_076 - .saturating_add(Weight::from_parts(4_720_110, 0).saturating_mul(r.into())) + // Minimum execution time: 265_608_000 picoseconds. + Weight::from_parts(273_219_000, 6830) + // Standard Error: 11_085 + .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2500,10 +2498,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 275_655_000 picoseconds. - Weight::from_parts(291_386_528, 6815) - // Standard Error: 898 - .saturating_add(Weight::from_parts(428_765, 0).saturating_mul(r.into())) + // Minimum execution time: 270_033_000 picoseconds. + Weight::from_parts(288_700_795, 6815) + // Standard Error: 1_628 + .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2527,10 +2525,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 260_323_000 picoseconds. - Weight::from_parts(286_371_403, 6804) - // Standard Error: 451 - .saturating_add(Weight::from_parts(183_053, 0).saturating_mul(r.into())) + // Minimum execution time: 263_789_000 picoseconds. + Weight::from_parts(275_806_968, 6804) + // Standard Error: 936 + .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2552,10 +2550,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 262_974_000 picoseconds. - Weight::from_parts(276_571_502, 6693) - // Standard Error: 527 - .saturating_add(Weight::from_parts(165_364, 0).saturating_mul(r.into())) + // Minimum execution time: 257_922_000 picoseconds. + Weight::from_parts(270_842_153, 6693) + // Standard Error: 637 + .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2579,10 +2577,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 272_826_000 picoseconds. - Weight::from_parts(290_963_001, 6807) - // Standard Error: 810 - .saturating_add(Weight::from_parts(343_762, 0).saturating_mul(r.into())) + // Minimum execution time: 267_214_000 picoseconds. + Weight::from_parts(273_446_444, 6807) + // Standard Error: 2_355 + .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2606,10 +2604,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 277_324_000 picoseconds. - Weight::from_parts(290_872_814, 6806) - // Standard Error: 766 - .saturating_add(Weight::from_parts(371_542, 0).saturating_mul(r.into())) + // Minimum execution time: 258_860_000 picoseconds. + Weight::from_parts(286_389_737, 6806) + // Standard Error: 1_707 + .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2633,10 +2631,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 274_460_000 picoseconds. - Weight::from_parts(285_748_025, 6931) - // Standard Error: 1_570 - .saturating_add(Weight::from_parts(1_656_237, 0).saturating_mul(r.into())) + // Minimum execution time: 267_852_000 picoseconds. + Weight::from_parts(279_617_620, 6931) + // Standard Error: 3_382 + .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2660,10 +2658,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 278_254_000 picoseconds. - Weight::from_parts(283_893_525, 6823) - // Standard Error: 726 - .saturating_add(Weight::from_parts(347_368, 0).saturating_mul(r.into())) + // Minimum execution time: 266_379_000 picoseconds. + Weight::from_parts(287_280_653, 6823) + // Standard Error: 1_774 + .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2687,10 +2685,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 279_646_000 picoseconds. - Weight::from_parts(292_505_446, 6816) - // Standard Error: 867 - .saturating_add(Weight::from_parts(337_202, 0).saturating_mul(r.into())) + // Minimum execution time: 266_417_000 picoseconds. + Weight::from_parts(291_394_038, 6816) + // Standard Error: 1_474 + .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2714,10 +2712,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 274_522_000 picoseconds. - Weight::from_parts(295_135_659, 6819) - // Standard Error: 1_052 - .saturating_add(Weight::from_parts(330_788, 0).saturating_mul(r.into())) + // Minimum execution time: 269_198_000 picoseconds. + Weight::from_parts(285_025_368, 6819) + // Standard Error: 1_231 + .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2741,10 +2739,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 274_228_000 picoseconds. - Weight::from_parts(289_201_593, 6804) - // Standard Error: 752 - .saturating_add(Weight::from_parts(337_860, 0).saturating_mul(r.into())) + // Minimum execution time: 257_514_000 picoseconds. + Weight::from_parts(280_424_571, 6804) + // Standard Error: 723 + .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2770,10 +2768,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 277_142_000 picoseconds. - Weight::from_parts(296_736_114, 6872) - // Standard Error: 1_502 - .saturating_add(Weight::from_parts(1_446_663, 0).saturating_mul(r.into())) + // Minimum execution time: 268_221_000 picoseconds. + Weight::from_parts(282_273_629, 6872) + // Standard Error: 2_398 + .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -2797,10 +2795,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 276_087_000 picoseconds. - Weight::from_parts(287_863_377, 6807) - // Standard Error: 495 - .saturating_add(Weight::from_parts(282_718, 0).saturating_mul(r.into())) + // Minimum execution time: 271_541_000 picoseconds. + Weight::from_parts(276_996_569, 6807) + // Standard Error: 1_462 + .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2824,10 +2822,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 277_128_000 picoseconds. - Weight::from_parts(234_478_674, 6809) - // Standard Error: 23 - .saturating_add(Weight::from_parts(1_052, 0).saturating_mul(n.into())) + // Minimum execution time: 256_410_000 picoseconds. + Weight::from_parts(206_888_877, 6809) + // Standard Error: 22 + .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2850,8 +2848,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 251_983_000 picoseconds. - Weight::from_parts(277_986_885, 6793) + // Minimum execution time: 248_852_000 picoseconds. + Weight::from_parts(277_852_834, 6793) + // Standard Error: 1_257_219 + .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -2875,10 +2875,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 275_108_000 picoseconds. - Weight::from_parts(284_552_708, 6810) - // Standard Error: 0 - .saturating_add(Weight::from_parts(391, 0).saturating_mul(n.into())) + // Minimum execution time: 269_101_000 picoseconds. + Weight::from_parts(273_407_545, 6810) + // Standard Error: 2 + .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2899,7 +2899,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// Storage: `Contracts::DeletionQueue` (r:0 w:1) /// Proof: `Contracts::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`) /// The range of component `r` is `[0, 1]`. @@ -2907,10 +2907,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 281_278_000 picoseconds. - Weight::from_parts(306_800_667, 8912) - // Standard Error: 855_257 - .saturating_add(Weight::from_parts(126_508_132, 0).saturating_mul(r.into())) + // Minimum execution time: 296_318_000 picoseconds. + Weight::from_parts(322_448_344, 8912) + // Standard Error: 2_358_838 + .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2938,10 +2938,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 260_609_000 picoseconds. - Weight::from_parts(287_385_076, 6885) - // Standard Error: 2_754 - .saturating_add(Weight::from_parts(2_057_388, 0).saturating_mul(r.into())) + // Minimum execution time: 268_264_000 picoseconds. + Weight::from_parts(285_298_853, 6885) + // Standard Error: 3_238 + .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2965,10 +2965,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 254_770_000 picoseconds. - Weight::from_parts(255_105_647, 6805) - // Standard Error: 5_707 - .saturating_add(Weight::from_parts(3_808_788, 0).saturating_mul(r.into())) + // Minimum execution time: 267_417_000 picoseconds. + Weight::from_parts(290_097_452, 6805) + // Standard Error: 2_523 + .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2993,12 +2993,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 278_200_000 picoseconds. - Weight::from_parts(288_081_493, 6825) - // Standard Error: 97_535 - .saturating_add(Weight::from_parts(3_683_455, 0).saturating_mul(t.into())) - // Standard Error: 27 - .saturating_add(Weight::from_parts(731, 0).saturating_mul(n.into())) + // Minimum execution time: 269_735_000 picoseconds. + Weight::from_parts(291_680_757, 6825) + // Standard Error: 196_822 + .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) + // Standard Error: 55 + .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3024,10 +3024,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 167_181_000 picoseconds. - Weight::from_parts(178_433_475, 6807) - // Standard Error: 374 - .saturating_add(Weight::from_parts(241_240, 0).saturating_mul(r.into())) + // Minimum execution time: 161_454_000 picoseconds. + Weight::from_parts(181_662_272, 6807) + // Standard Error: 729 + .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -3051,10 +3051,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 434_456_000 picoseconds. - Weight::from_parts(400_940_450, 131755) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_102, 0).saturating_mul(i.into())) + // Minimum execution time: 418_479_000 picoseconds. + Weight::from_parts(397_691_558, 131755) + // Standard Error: 12 + .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3064,11 +3064,11 @@ impl WeightInfo for () { fn seal_set_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` - // Estimated: `925 + r * (293 ±0)` - // Minimum execution time: 277_825_000 picoseconds. - Weight::from_parts(159_688_263, 925) - // Standard Error: 13_610 - .saturating_add(Weight::from_parts(7_145_641, 0).saturating_mul(r.into())) + // Estimated: `926 + r * (293 ±0)` + // Minimum execution time: 268_810_000 picoseconds. + Weight::from_parts(129_545_478, 926) + // Standard Error: 21_173 + .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3080,12 +3080,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_new_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1446` - // Estimated: `1429` - // Minimum execution time: 284_745_000 picoseconds. - Weight::from_parts(345_928_316, 1429) - // Standard Error: 70 - .saturating_add(Weight::from_parts(547, 0).saturating_mul(n.into())) + // Measured: `1447` + // Estimated: `1430` + // Minimum execution time: 286_965_000 picoseconds. + Weight::from_parts(340_396_510, 1430) + // Standard Error: 90 + .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -3094,12 +3094,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_set_storage_per_old_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1252 + n * (1 ±0)` - // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 275_328_000 picoseconds. - Weight::from_parts(300_037_010, 1252) - // Standard Error: 32 - .saturating_add(Weight::from_parts(558, 0).saturating_mul(n.into())) + // Measured: `1253 + n * (1 ±0)` + // Estimated: `1253 + n * (1 ±0)` + // Minimum execution time: 272_395_000 picoseconds. + Weight::from_parts(302_307_069, 1253) + // Standard Error: 94 + .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3109,12 +3109,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_clear_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (288 ±0)` - // Estimated: `926 + r * (289 ±0)` - // Minimum execution time: 273_742_000 picoseconds. - Weight::from_parts(169_430_806, 926) - // Standard Error: 11_821 - .saturating_add(Weight::from_parts(6_927_074, 0).saturating_mul(r.into())) + // Measured: `921 + r * (288 ±0)` + // Estimated: `927 + r * (289 ±0)` + // Minimum execution time: 269_165_000 picoseconds. + Weight::from_parts(167_174_485, 927) + // Standard Error: 23_564 + .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3126,12 +3126,10 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_clear_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1248 + n * (1 ±0)` - // Estimated: `1248 + n * (1 ±0)` - // Minimum execution time: 275_167_000 picoseconds. - Weight::from_parts(301_883_655, 1248) - // Standard Error: 35 - .saturating_add(Weight::from_parts(4, 0).saturating_mul(n.into())) + // Measured: `1249 + n * (1 ±0)` + // Estimated: `1249 + n * (1 ±0)` + // Minimum execution time: 270_248_000 picoseconds. + Weight::from_parts(296_573_310, 1249) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3141,12 +3139,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_get_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `920 + r * (296 ±0)` - // Estimated: `922 + r * (297 ±0)` - // Minimum execution time: 274_628_000 picoseconds. - Weight::from_parts(195_255_092, 922) - // Standard Error: 9_109 - .saturating_add(Weight::from_parts(5_707_060, 0).saturating_mul(r.into())) + // Measured: `921 + r * (296 ±0)` + // Estimated: `923 + r * (297 ±0)` + // Minimum execution time: 270_883_000 picoseconds. + Weight::from_parts(189_792_705, 923) + // Standard Error: 11_149 + .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3157,12 +3155,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_get_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1264 + n * (1 ±0)` - // Estimated: `1264 + n * (1 ±0)` - // Minimum execution time: 274_202_000 picoseconds. - Weight::from_parts(296_440_752, 1264) - // Standard Error: 38 - .saturating_add(Weight::from_parts(1_010, 0).saturating_mul(n.into())) + // Measured: `1265 + n * (1 ±0)` + // Estimated: `1265 + n * (1 ±0)` + // Minimum execution time: 263_833_000 picoseconds. + Weight::from_parts(290_179_222, 1265) + // Standard Error: 44 + .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3172,12 +3170,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_contains_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `931 + r * (288 ±0)` - // Estimated: `928 + r * (289 ±0)` - // Minimum execution time: 274_123_000 picoseconds. - Weight::from_parts(193_280_535, 928) - // Standard Error: 9_264 - .saturating_add(Weight::from_parts(5_548_039, 0).saturating_mul(r.into())) + // Measured: `932 + r * (288 ±0)` + // Estimated: `929 + r * (289 ±0)` + // Minimum execution time: 252_637_000 picoseconds. + Weight::from_parts(98_108_825, 929) + // Standard Error: 23_580 + .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3188,12 +3186,10 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_contains_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1251 + n * (1 ±0)` - // Estimated: `1251 + n * (1 ±0)` - // Minimum execution time: 276_425_000 picoseconds. - Weight::from_parts(300_521_806, 1251) - // Standard Error: 36 - .saturating_add(Weight::from_parts(83, 0).saturating_mul(n.into())) + // Measured: `1252 + n * (1 ±0)` + // Estimated: `1252 + n * (1 ±0)` + // Minimum execution time: 279_133_000 picoseconds. + Weight::from_parts(301_192_115, 1252) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3203,12 +3199,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 800]`. fn seal_take_storage(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `913 + r * (296 ±0)` - // Estimated: `918 + r * (297 ±0)` - // Minimum execution time: 264_860_000 picoseconds. - Weight::from_parts(191_561_777, 918) - // Standard Error: 10_678 - .saturating_add(Weight::from_parts(6_895_457, 0).saturating_mul(r.into())) + // Measured: `914 + r * (296 ±0)` + // Estimated: `919 + r * (297 ±0)` + // Minimum execution time: 268_833_000 picoseconds. + Weight::from_parts(56_229_951, 919) + // Standard Error: 25_800 + .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3220,12 +3216,12 @@ impl WeightInfo for () { /// The range of component `n` is `[0, 16384]`. fn seal_take_storage_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1265 + n * (1 ±0)` - // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 282_501_000 picoseconds. - Weight::from_parts(303_351_919, 1265) - // Standard Error: 37 - .saturating_add(Weight::from_parts(643, 0).saturating_mul(n.into())) + // Measured: `1266 + n * (1 ±0)` + // Estimated: `1266 + n * (1 ±0)` + // Minimum execution time: 288_677_000 picoseconds. + Weight::from_parts(301_986_360, 1266) + // Standard Error: 39 + .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3249,10 +3245,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 273_198_000 picoseconds. - Weight::from_parts(179_673_238, 7307) - // Standard Error: 34_990 - .saturating_add(Weight::from_parts(38_468_091, 0).saturating_mul(r.into())) + // Minimum execution time: 275_956_000 picoseconds. + Weight::from_parts(280_865_651, 7307) + // Standard Error: 28_235 + .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3278,10 +3274,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 283_869_000 picoseconds. - Weight::from_parts(288_374_000, 9440) - // Standard Error: 137_512 - .saturating_add(Weight::from_parts(248_206_665, 0).saturating_mul(r.into())) + // Minimum execution time: 269_188_000 picoseconds. + Weight::from_parts(276_038_000, 9440) + // Standard Error: 262_029 + .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3307,10 +3303,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 257_577_000 picoseconds. - Weight::from_parts(277_310_000, 6812) - // Standard Error: 150_204 - .saturating_add(Weight::from_parts(249_943_483, 0).saturating_mul(r.into())) + // Minimum execution time: 267_543_000 picoseconds. + Weight::from_parts(271_365_000, 6812) + // Standard Error: 190_454 + .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3337,12 +3333,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 471_081_000 picoseconds. - Weight::from_parts(79_081_122, 12197) - // Standard Error: 11_777_790 - .saturating_add(Weight::from_parts(357_425_411, 0).saturating_mul(t.into())) + // Minimum execution time: 453_215_000 picoseconds. + Weight::from_parts(32_029_330, 12197) + // Standard Error: 12_154_174 + .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_111, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -3366,16 +3362,16 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:803 w:803) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:800 w:800) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `r` is `[1, 800]`. fn seal_instantiate(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 672_742_000 picoseconds. - Weight::from_parts(680_025_000, 9620) - // Standard Error: 313_642 - .saturating_add(Weight::from_parts(388_311_259, 0).saturating_mul(r.into())) + // Minimum execution time: 635_304_000 picoseconds. + Weight::from_parts(645_872_000, 9620) + // Standard Error: 356_713 + .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -3399,7 +3395,7 @@ impl WeightInfo for () { /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `Measured`) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(157), added: 2632, mode: `Measured`) /// The range of component `t` is `[0, 1]`. /// The range of component `i` is `[0, 983040]`. /// The range of component `s` is `[0, 983040]`. @@ -3407,12 +3403,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_733_870_000 picoseconds. - Weight::from_parts(1_001_793_458, 12211) - // Standard Error: 12 - .saturating_add(Weight::from_parts(1_963, 0).saturating_mul(i.into())) - // Standard Error: 12 - .saturating_add(Weight::from_parts(2_060, 0).saturating_mul(s.into())) + // Minimum execution time: 2_225_692_000 picoseconds. + Weight::from_parts(1_292_861_603, 12211) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) + // Standard Error: 24 + .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(11_u64)) @@ -3438,10 +3434,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 272_658_000 picoseconds. - Weight::from_parts(282_717_645, 6801) - // Standard Error: 517 - .saturating_add(Weight::from_parts(400_604, 0).saturating_mul(r.into())) + // Minimum execution time: 252_664_000 picoseconds. + Weight::from_parts(277_967_331, 6801) + // Standard Error: 723 + .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3465,10 +3461,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 260_969_000 picoseconds. - Weight::from_parts(265_206_847, 6808) + // Minimum execution time: 252_485_000 picoseconds. + Weight::from_parts(259_271_531, 6808) // Standard Error: 2 - .saturating_add(Weight::from_parts(1_134, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3491,10 +3487,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 262_351_000 picoseconds. - Weight::from_parts(286_974_296, 6806) - // Standard Error: 514 - .saturating_add(Weight::from_parts(802_363, 0).saturating_mul(r.into())) + // Minimum execution time: 249_270_000 picoseconds. + Weight::from_parts(272_528_711, 6806) + // Standard Error: 903 + .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3518,10 +3514,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 276_907_000 picoseconds. - Weight::from_parts(277_928_418, 6814) - // Standard Error: 1 - .saturating_add(Weight::from_parts(3_410, 0).saturating_mul(n.into())) + // Minimum execution time: 249_470_000 picoseconds. + Weight::from_parts(273_317_815, 6814) + // Standard Error: 4 + .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3544,10 +3540,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 263_660_000 picoseconds. - Weight::from_parts(285_665_916, 6808) - // Standard Error: 527 - .saturating_add(Weight::from_parts(480_457, 0).saturating_mul(r.into())) + // Minimum execution time: 265_503_000 picoseconds. + Weight::from_parts(279_774_666, 6808) + // Standard Error: 1_351 + .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3571,10 +3567,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 262_071_000 picoseconds. - Weight::from_parts(270_115_341, 6813) + // Minimum execution time: 265_009_000 picoseconds. + Weight::from_parts(270_467_968, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_254, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3597,10 +3593,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 265_568_000 picoseconds. - Weight::from_parts(285_791_811, 6805) - // Standard Error: 559 - .saturating_add(Weight::from_parts(505_330, 0).saturating_mul(r.into())) + // Minimum execution time: 251_771_000 picoseconds. + Weight::from_parts(283_553_523, 6805) + // Standard Error: 1_053 + .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3624,10 +3620,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 271_336_000 picoseconds. - Weight::from_parts(272_829_313, 6811) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_252, 0).saturating_mul(n.into())) + // Minimum execution time: 253_733_000 picoseconds. + Weight::from_parts(264_277_000, 6811) + // Standard Error: 3 + .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3650,10 +3646,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 351_146_000 picoseconds. - Weight::from_parts(355_368_323, 6934) - // Standard Error: 14 - .saturating_add(Weight::from_parts(6_155, 0).saturating_mul(n.into())) + // Minimum execution time: 337_326_000 picoseconds. + Weight::from_parts(346_340_758, 6934) + // Standard Error: 18 + .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3675,12 +3671,12 @@ impl WeightInfo for () { /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `807 + r * (112 ±0)` + // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 277_250_000 picoseconds. - Weight::from_parts(346_490_114, 6748) - // Standard Error: 14_654 - .saturating_add(Weight::from_parts(56_127_492, 0).saturating_mul(r.into())) + // Minimum execution time: 253_852_000 picoseconds. + Weight::from_parts(335_731_679, 6748) + // Standard Error: 13_615 + .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -3704,10 +3700,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 272_697_000 picoseconds. - Weight::from_parts(345_385_667, 6801) - // Standard Error: 14_226 - .saturating_add(Weight::from_parts(46_037_637, 0).saturating_mul(r.into())) + // Minimum execution time: 256_283_000 picoseconds. + Weight::from_parts(338_634_113, 6801) + // Standard Error: 43_436 + .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -3731,10 +3727,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 271_800_000 picoseconds. - Weight::from_parts(314_891_136, 6816) - // Standard Error: 9_762 - .saturating_add(Weight::from_parts(11_949_979, 0).saturating_mul(r.into())) + // Minimum execution time: 269_144_000 picoseconds. + Weight::from_parts(331_790_138, 6816) + // Standard Error: 23_357 + .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -3758,10 +3754,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 274_238_000 picoseconds. - Weight::from_parts(278_034_000, 6807) - // Standard Error: 77_011 - .saturating_add(Weight::from_parts(27_627_005, 0).saturating_mul(r.into())) + // Minimum execution time: 262_624_000 picoseconds. + Weight::from_parts(275_865_000, 6807) + // Standard Error: 64_162 + .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3787,10 +3783,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 271_519_000 picoseconds. - Weight::from_parts(292_726_476, 6878) - // Standard Error: 23_870 - .saturating_add(Weight::from_parts(6_695_172, 0).saturating_mul(r.into())) + // Minimum execution time: 265_482_000 picoseconds. + Weight::from_parts(296_491_925, 6878) + // Standard Error: 46_681 + .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3816,10 +3812,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 274_675_000 picoseconds. - Weight::from_parts(293_727_489, 129453) - // Standard Error: 23_160 - .saturating_add(Weight::from_parts(5_895_043, 0).saturating_mul(r.into())) + // Minimum execution time: 257_532_000 picoseconds. + Weight::from_parts(299_110_930, 129453) + // Standard Error: 55_003 + .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3845,10 +3841,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 253_330_000 picoseconds. - Weight::from_parts(281_079_564, 6804) - // Standard Error: 378 - .saturating_add(Weight::from_parts(180_655, 0).saturating_mul(r.into())) + // Minimum execution time: 268_894_000 picoseconds. + Weight::from_parts(287_048_741, 6804) + // Standard Error: 1_156 + .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -3872,10 +3868,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 276_552_000 picoseconds. - Weight::from_parts(368_521_088, 7899) - // Standard Error: 2_310 - .saturating_add(Weight::from_parts(318_129, 0).saturating_mul(r.into())) + // Minimum execution time: 262_736_000 picoseconds. + Weight::from_parts(389_199_672, 7899) + // Standard Error: 2_646 + .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3901,10 +3897,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 258_953_000 picoseconds. - Weight::from_parts(288_222_836, 6801) - // Standard Error: 367 - .saturating_add(Weight::from_parts(152_842, 0).saturating_mul(r.into())) + // Minimum execution time: 253_465_000 picoseconds. + Weight::from_parts(283_153_874, 6801) + // Standard Error: 745 + .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -3914,9 +3910,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_476_000 picoseconds. - Weight::from_parts(2_119_717, 0) - // Standard Error: 28 - .saturating_add(Weight::from_parts(9_805, 0).saturating_mul(r.into())) + // Minimum execution time: 1_342_000 picoseconds. + Weight::from_parts(1_940_100, 0) + // Standard Error: 21 + .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) } } -- GitLab From b4b523c84c8de954e1ddabd20e3c66a0a494bd5b Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Thu, 18 Jan 2024 23:18:05 +0200 Subject: [PATCH 031/283] Fix contracts compilation with `CARGO_TARGET_DIR` set (#2927) In case `CARGO_TARGET_DIR` is set, build artifacts were in the wrong place and `build.rs` was failing. With `CARGO_TARGET_DIR=/home/nazar-pc/.cache/cargo/target`: ``` error: failed to run custom build command for `pallet-contracts-fixtures v1.0.0 (/web/subspace/polkadot-sdk/substrate/frame/contracts/fixtures)` Caused by: process didn't exit successfully: `/home/nazar-pc/.cache/cargo/target/debug/build/pallet-contracts-fixtures-35d534f7ac3009e0/build-script-build` (exit status: 1) --- stderr Error: Failed to read "/tmp/.tmpiYwXfv/target/wasm32-unknown-unknown/release/dummy.wasm" Caused by: Can't read from the file: Os { code: 2, kind: NotFound, message: "No such file or directory" } ``` The file was actually in `/home/nazar-pc/.cache/cargo/target/wasm32-unknown-unknown/release/dummy.wasm`. --- substrate/frame/contracts/fixtures/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 7b814ef77a6..8e00bbc9d09 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -203,6 +203,7 @@ fn invoke_wasm_build(current_dir: &Path) -> Result<()> { let build_res = Command::new(env::var("CARGO")?) .current_dir(current_dir) + .env("CARGO_TARGET_DIR", current_dir.join("target").display().to_string()) .env("CARGO_ENCODED_RUSTFLAGS", encoded_rustflags) .args(["build", "--release", "--target=wasm32-unknown-unknown"]) .output() -- GitLab From 87927bbd7cf556b2aea68bef4515a223e9989af6 Mon Sep 17 00:00:00 2001 From: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Date: Thu, 18 Jan 2024 21:55:50 +0100 Subject: [PATCH 032/283] `GenesisBuilder`: `arbitrary_precision` feature enabled for `serde_json` (#2987) [`arbitrary_precision`](https://github.com/serde-rs/json/blob/6d44b9fac9269b4decf76acac5d68e8ec9d10c58/Cargo.toml#L69-L75) feature allows to (de-)serialize big numbers w/o error. For some details refer also to https://github.com/paritytech/polkadot-sdk/pull/1256#discussion_r1455564450 fixes: #2963 --- substrate/primitives/genesis-builder/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/primitives/genesis-builder/Cargo.toml b/substrate/primitives/genesis-builder/Cargo.toml index 42d6c8c3d65..263b48c9efe 100644 --- a/substrate/primitives/genesis-builder/Cargo.toml +++ b/substrate/primitives/genesis-builder/Cargo.toml @@ -19,7 +19,7 @@ targets = ["x86_64-unknown-linux-gnu"] sp-api = { path = "../api", default-features = false } sp-runtime = { path = "../runtime", default-features = false } sp-std = { path = "../std", default-features = false } -serde_json = { version = "1.0.111", default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.111", default-features = false, features = ["alloc", "arbitrary_precision"] } [features] default = ["std"] -- GitLab From 9db92115d023689581e8cf49edb9500b0dcced53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Pestana?= Date: Thu, 18 Jan 2024 23:05:59 +0100 Subject: [PATCH 033/283] More tests and checks confirming that `ledger.controller` is always correct. (#2599) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bonded ledger fetched with the `StakingLedger` implementation exposes a method `ledger.controller()` that returns the controller of the ledger. However, that controller is computed and stored under the `ledger.controller` field on the fly - i.e when the ledger is fetched from storage using the `StakingLedger::get` method. The controller field is never stored in storage. This PR add a few more tests checks and improves the ledger try-state checks to make sure these invariants hold true. --------- Co-authored-by: command-bot <> Co-authored-by: Bastian Köcher Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- substrate/frame/staking/src/pallet/impls.rs | 12 +++++++++++- substrate/frame/staking/src/tests.rs | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 093cdfdb9cb..80b4079dbd6 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1853,7 +1853,17 @@ impl Pallet { fn check_ledgers() -> Result<(), TryRuntimeError> { Bonded::::iter() - .map(|(_, ctrl)| Self::ensure_ledger_consistent(ctrl)) + .map(|(stash, ctrl)| { + // `ledger.controller` is never stored in raw storage. + let raw = Ledger::::get(stash).unwrap_or_else(|| { + Ledger::::get(ctrl.clone()) + .expect("try_check: bonded stash/ctrl does not have an associated ledger") + }); + ensure!(raw.controller.is_none(), "raw storage controller should be None"); + + // ensure ledger consistency. + Self::ensure_ledger_consistent(ctrl) + }) .collect::, _>>()?; Ok(()) } diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 0e9be70ee7d..f469ace0bc4 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -255,6 +255,20 @@ fn change_controller_works() { assert_eq!(Staking::bonded(&stash), Some(stash)); mock::start_active_era(1); + // fetch the ledger from storage and check if the controller is correct. + let ledger = Staking::ledger(StakingAccount::Stash(stash)).unwrap(); + assert_eq!(ledger.controller(), Some(stash)); + + // same if we fetch the ledger by controller. + let ledger = Staking::ledger(StakingAccount::Controller(stash)).unwrap(); + assert_eq!(ledger.controller, Some(stash)); + assert_eq!(ledger.controller(), Some(stash)); + + // the raw storage ledger's controller is always `None`. however, we can still fetch the + // correct controller with `ledger.controler()`. + let raw_ledger = >::get(&stash).unwrap(); + assert_eq!(raw_ledger.controller, None); + // `controller` is no longer in control. `stash` is now controller. assert_noop!( Staking::validate(RuntimeOrigin::signed(controller), ValidatorPrefs::default()), -- GitLab From 697c2c392ebed23060ea5864e72c744ad6954821 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Fri, 19 Jan 2024 23:27:59 +1100 Subject: [PATCH 034/283] Update `translate` to use `defensive!` (#2985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1323 cc @xlc --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Bastian Köcher --- .../support/src/storage/generator/map.rs | 88 ++++++++++++++++--- .../frame/support/src/storage/types/map.rs | 3 +- 2 files changed, 79 insertions(+), 12 deletions(-) diff --git a/substrate/frame/support/src/storage/generator/map.rs b/substrate/frame/support/src/storage/generator/map.rs index b2919bff8d1..257aa7e7bcf 100644 --- a/substrate/frame/support/src/storage/generator/map.rs +++ b/substrate/frame/support/src/storage/generator/map.rs @@ -196,7 +196,10 @@ where let value = match unhashed::get::(¤t_key) { Some(value) => value, None => { - log::error!("Invalid translate: fail to decode old value"); + crate::defensive!( + "Invalid translation: failed to decode old value for key", + array_bytes::bytes2hex("0x", ¤t_key) + ); return Some(current_key) }, }; @@ -205,7 +208,10 @@ where let key = match K::decode(&mut key_material) { Ok(key) => key, Err(_) => { - log::error!("Invalid translate: fail to decode key"); + crate::defensive!( + "Invalid translation: failed to decode key", + array_bytes::bytes2hex("0x", ¤t_key) + ); return Some(current_key) }, }; @@ -389,6 +395,75 @@ mod test_iterators { }); } + #[cfg(debug_assertions)] + #[test] + #[should_panic] + fn map_translate_with_bad_key_in_debug_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong key + unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode()); + + // debug_assert should cause a + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]); + }) + } + + #[cfg(debug_assertions)] + #[test] + #[should_panic] + fn map_translate_with_bad_value_in_debug_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong value + unhashed::put( + &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(), + &vec![1], + ); + + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]); + }) + } + + #[cfg(not(debug_assertions))] + #[test] + fn map_translate_with_bad_key_in_production_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong key + unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode()); + + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![]); + }) + } + + #[cfg(not(debug_assertions))] + #[test] + fn map_translate_with_bad_value_in_production_mode() { + sp_io::TestExternalities::default().execute_with(|| { + type Map = self::frame_system::Map; + let prefix = Map::prefix_hash().to_vec(); + + // Wrong value + unhashed::put( + &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(), + &vec![1], + ); + + Map::translate(|_k1, v: u64| Some(v * 2)); + assert_eq!(Map::iter().collect::>(), vec![]); + }) + } + #[test] fn map_reversible_reversible_iteration() { sp_io::TestExternalities::default().execute_with(|| { @@ -425,15 +500,6 @@ mod test_iterators { Map::insert(i as u16, i as u64); } - // Wrong key - unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode()); - - // Wrong value - unhashed::put( - &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(), - &vec![1], - ); - Map::translate(|_k1, v: u64| Some(v * 2)); assert_eq!(Map::iter().collect::>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]); }) diff --git a/substrate/frame/support/src/storage/types/map.rs b/substrate/frame/support/src/storage/types/map.rs index d0149cf3fc8..ee5db74583b 100644 --- a/substrate/frame/support/src/storage/types/map.rs +++ b/substrate/frame/support/src/storage/types/map.rs @@ -471,7 +471,8 @@ where /// /// By returning `None` from `f` for an element, you'll remove it from the map. /// - /// NOTE: If a value fail to decode because storage is corrupted then it is skipped. + /// NOTE: If a value fails to decode because storage is corrupted, then it will log an error and + /// be skipped in production, or panic in development. pub fn translate Option>(f: F) { >::translate(f) } -- GitLab From 47a3faa41e212838349de528194402d2d415b0b8 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Fri, 19 Jan 2024 15:10:09 +0100 Subject: [PATCH 035/283] Pvf thiserror (#2958) resolve #2157 - [x] fix broken doc links - [x] fix codec macro typo https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/node/core/pvf/common/src/error.rs#L81 (see the comment below) - [x] refactor `ValidationError`, `PrepareError` and related error types to use `thiserror` crate ## `codec` issue `codec` macro was mistakenly applied two times to `Kernel` error (so it was encoded with 10 instead of 11 and the same as `JobDied`). The PR changes it to 11 because - it was an initial goal of the code author - Kernel is less frequent than JobDied so in case of existing error encoding it is more probable to have 10 as JobDied than Kernel See https://github.com/paritytech/parity-scale-codec/issues/555 ---- polkadot address: 13zCyRG2a1W2ih5SioL8byqmQ6mc8vkgFwQgVzJSdRUUmp46 --------- Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> --- polkadot/node/core/pvf/common/src/error.rs | 72 ++++++------------- .../node/core/pvf/execute-worker/src/lib.rs | 2 +- polkadot/node/core/pvf/src/error.rs | 27 +++---- polkadot/node/core/pvf/src/execute/queue.rs | 2 +- polkadot/node/core/pvf/src/host.rs | 3 +- polkadot/node/core/pvf/src/prepare/queue.rs | 4 +- .../core/pvf/src/prepare/worker_interface.rs | 2 +- 7 files changed, 43 insertions(+), 69 deletions(-) diff --git a/polkadot/node/core/pvf/common/src/error.rs b/polkadot/node/core/pvf/common/src/error.rs index 7db7f9a5945..f8faefc24e6 100644 --- a/polkadot/node/core/pvf/common/src/error.rs +++ b/polkadot/node/core/pvf/common/src/error.rs @@ -16,7 +16,6 @@ use crate::prepare::{PrepareSuccess, PrepareWorkerSuccess}; use parity_scale_codec::{Decode, Encode}; -use std::fmt; /// Result of PVF preparation from a worker, with checksum of the compiled PVF and stats of the /// preparation if successful. @@ -32,35 +31,43 @@ pub type PrecheckResult = Result<(), PrepareError>; /// An error that occurred during the prepare part of the PVF pipeline. // Codec indexes are intended to stabilize pre-encoded payloads (see `OOM_PAYLOAD`) -#[derive(Debug, Clone, Encode, Decode)] +#[derive(thiserror::Error, Debug, Clone, Encode, Decode)] pub enum PrepareError { /// During the prevalidation stage of preparation an issue was found with the PVF. #[codec(index = 0)] + #[error("prepare: prevalidation error: {0}")] Prevalidation(String), /// Compilation failed for the given PVF. #[codec(index = 1)] + #[error("prepare: preparation error: {0}")] Preparation(String), /// Instantiation of the WASM module instance failed. #[codec(index = 2)] + #[error("prepare: runtime construction: {0}")] RuntimeConstruction(String), /// An unexpected error has occurred in the preparation job. #[codec(index = 3)] + #[error("prepare: job error: {0}")] JobError(String), /// Failed to prepare the PVF due to the time limit. #[codec(index = 4)] + #[error("prepare: timeout")] TimedOut, /// An IO error occurred. This state is reported by either the validation host or by the /// worker. #[codec(index = 5)] + #[error("prepare: io error while receiving response: {0}")] IoErr(String), /// The temporary file for the artifact could not be created at the given cache path. This /// state is reported by the validation host (not by the worker). #[codec(index = 6)] + #[error("prepare: error creating tmp file: {0}")] CreateTmpFile(String), /// The response from the worker is received, but the file cannot be renamed (moved) to the /// final destination location. This state is reported by the validation host (not by the /// worker). #[codec(index = 7)] + #[error("prepare: error renaming tmp file ({src:?} -> {dest:?}): {err}")] RenameTmpFile { err: String, // Unfortunately `PathBuf` doesn't implement `Encode`/`Decode`, so we do a fallible @@ -70,17 +77,21 @@ pub enum PrepareError { }, /// Memory limit reached #[codec(index = 8)] + #[error("prepare: out of memory")] OutOfMemory, /// The response from the worker is received, but the worker cache could not be cleared. The /// worker has to be killed to avoid jobs having access to data from other jobs. This state is /// reported by the validation host (not by the worker). #[codec(index = 9)] + #[error("prepare: error clearing worker cache: {0}")] ClearWorkerDir(String), /// The preparation job process died, due to OOM, a seccomp violation, or some other factor. - JobDied { err: String, job_pid: i32 }, #[codec(index = 10)] + #[error("prepare: prepare job with pid {job_pid} died: {err}")] + JobDied { err: String, job_pid: i32 }, /// Some error occurred when interfacing with the kernel. #[codec(index = 11)] + #[error("prepare: error interfacing with the kernel: {0}")] Kernel(String), } @@ -109,41 +120,23 @@ impl PrepareError { } } -impl fmt::Display for PrepareError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use PrepareError::*; - match self { - Prevalidation(err) => write!(f, "prevalidation: {}", err), - Preparation(err) => write!(f, "preparation: {}", err), - RuntimeConstruction(err) => write!(f, "runtime construction: {}", err), - JobError(err) => write!(f, "panic: {}", err), - TimedOut => write!(f, "prepare: timeout"), - IoErr(err) => write!(f, "prepare: io error while receiving response: {}", err), - JobDied { err, job_pid } => - write!(f, "prepare: prepare job with pid {job_pid} died: {err}"), - CreateTmpFile(err) => write!(f, "prepare: error creating tmp file: {}", err), - RenameTmpFile { err, src, dest } => - write!(f, "prepare: error renaming tmp file ({:?} -> {:?}): {}", src, dest, err), - OutOfMemory => write!(f, "prepare: out of memory"), - ClearWorkerDir(err) => write!(f, "prepare: error clearing worker cache: {}", err), - Kernel(err) => write!(f, "prepare: error interfacing with the kernel: {}", err), - } - } -} - /// Some internal error occurred. /// /// Should only ever be used for validation errors independent of the candidate and PVF, or for /// errors we ruled out during pre-checking (so preparation errors are fine). -#[derive(Debug, Clone, Encode, Decode)] +#[derive(thiserror::Error, Debug, Clone, Encode, Decode)] pub enum InternalValidationError { /// Some communication error occurred with the host. + #[error("validation: some communication error occurred with the host: {0}")] HostCommunication(String), /// Host could not create a hard link to the artifact path. + #[error("validation: host could not create a hard link to the artifact path: {0}")] CouldNotCreateLink(String), /// Could not find or open compiled artifact file. + #[error("validation: could not find or open compiled artifact file: {0}")] CouldNotOpenFile(String), /// Host could not clear the worker cache after a job. + #[error("validation: host could not clear the worker cache ({path:?}) after a job: {err}")] CouldNotClearWorkerDir { err: String, // Unfortunately `PathBuf` doesn't implement `Encode`/`Decode`, so we do a fallible @@ -151,32 +144,9 @@ pub enum InternalValidationError { path: Option, }, /// Some error occurred when interfacing with the kernel. + #[error("validation: error interfacing with the kernel: {0}")] Kernel(String), - /// Some non-deterministic preparation error occurred. + #[error("validation: prepare: {0}")] NonDeterministicPrepareError(PrepareError), } - -impl fmt::Display for InternalValidationError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use InternalValidationError::*; - match self { - HostCommunication(err) => - write!(f, "validation: some communication error occurred with the host: {}", err), - CouldNotCreateLink(err) => write!( - f, - "validation: host could not create a hard link to the artifact path: {}", - err - ), - CouldNotOpenFile(err) => - write!(f, "validation: could not find or open compiled artifact file: {}", err), - CouldNotClearWorkerDir { err, path } => write!( - f, - "validation: host could not clear the worker cache ({:?}) after a job: {}", - path, err - ), - Kernel(err) => write!(f, "validation: error interfacing with the kernel: {}", err), - NonDeterministicPrepareError(err) => write!(f, "validation: prepare: {}", err), - } - } -} diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs index cff6e0ac13a..6980f913d0d 100644 --- a/polkadot/node/core/pvf/execute-worker/src/lib.rs +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -485,7 +485,7 @@ fn recv_child_response(received_data: &mut io::BufReader<&[u8]>) -> io::Result for ValidationError { - fn from(error: InternalValidationError) -> Self { - Self::Internal(error) - } -} - impl From for ValidationError { fn from(error: PrepareError) -> Self { // Here we need to classify the errors into two errors: deterministic and non-deterministic. diff --git a/polkadot/node/core/pvf/src/execute/queue.rs b/polkadot/node/core/pvf/src/execute/queue.rs index be607fe1c20..aa91d11781f 100644 --- a/polkadot/node/core/pvf/src/execute/queue.rs +++ b/polkadot/node/core/pvf/src/execute/queue.rs @@ -372,7 +372,7 @@ fn handle_job_finish( ?artifact_id, ?worker, worker_rip = idle_worker.is_none(), - "execution worker concluded, error occurred: {:?}", + "execution worker concluded, error occurred: {}", err ); } else { diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index 21e13453edf..2668ce41583 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -486,7 +486,8 @@ async fn handle_precheck_pvf( /// /// If the prepare job failed previously, we may retry it under certain conditions. /// -/// When preparing for execution, we use a more lenient timeout ([`LENIENT_PREPARATION_TIMEOUT`]) +/// When preparing for execution, we use a more lenient timeout +/// ([`DEFAULT_LENIENT_PREPARATION_TIMEOUT`](polkadot_primitives::executor_params::DEFAULT_LENIENT_PREPARATION_TIMEOUT)) /// than when prechecking. async fn handle_execute_pvf( artifacts: &mut Artifacts, diff --git a/polkadot/node/core/pvf/src/prepare/queue.rs b/polkadot/node/core/pvf/src/prepare/queue.rs index c140a6cafda..c7bfa2f3b21 100644 --- a/polkadot/node/core/pvf/src/prepare/queue.rs +++ b/polkadot/node/core/pvf/src/prepare/queue.rs @@ -45,8 +45,8 @@ pub struct FromQueue { /// Identifier of an artifact. pub(crate) artifact_id: ArtifactId, /// Outcome of the PVF processing. [`Ok`] indicates that compiled artifact - /// is successfully stored on disk. Otherwise, an [error](crate::error::PrepareError) - /// is supplied. + /// is successfully stored on disk. Otherwise, an + /// [error](polkadot_node_core_pvf_common::error::PrepareError) is supplied. pub(crate) result: PrepareResult, } diff --git a/polkadot/node/core/pvf/src/prepare/worker_interface.rs b/polkadot/node/core/pvf/src/prepare/worker_interface.rs index 45e31a5f453..d64ee1510ca 100644 --- a/polkadot/node/core/pvf/src/prepare/worker_interface.rs +++ b/polkadot/node/core/pvf/src/prepare/worker_interface.rs @@ -174,7 +174,7 @@ pub async fn start_work( gum::warn!( target: LOG_TARGET, worker_pid = %pid, - "failed to recv a prepare response: {:?}", + "failed to recv a prepare response: {}", err, ); Outcome::IoErr(err.to_string()) -- GitLab From 66b2fa2e5950950b6800dedea2f333e0ae6bc9f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:04:02 +0000 Subject: [PATCH 036/283] Bump libc from 0.2.149 to 0.2.152 (#2994) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [libc](https://github.com/rust-lang/libc) from 0.2.149 to 0.2.152.
Release notes

Sourced from libc's releases.

0.2.152

What's Changed

New Contributors

Full Changelog: https://github.com/rust-lang/libc/compare/0.2.151...0.2.152

0.2.151

What's Changed

... (truncated)

Commits
  • 3d17519 Merge pull request #3522 from JohnTitor/libc-0.2.152
  • 0f5d2c1 Prepare release for v0.2.152
  • ee500ca Merge pull request #3521 from rust-lang/main
  • 72093f3 Auto merge of #3510 - JohnTitor:prepare-libc-0.3, r=JohnTitor
  • e5612b9 Auto merge of #3520 - devnexen:fuchsia_upd, r=JohnTitor
  • 44ba265 fuchsia adding pthread_set/getname_np
  • 2f93bfb Auto merge of #3519 - JohnTitor:tweak-libc-0.2-ci, r=JohnTitor
  • 11f7c7b Auto merge of #3518 - asomers:more-sigsuspend, r=JohnTitor
  • 0b9596b Tweak libc-0.2 CI
  • 5594447 Auto merge of #3517 - shuoer86:main, r=JohnTitor
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=libc&package-manager=cargo&previous-version=0.2.149&new-version=0.2.152)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- polkadot/node/core/pvf/Cargo.toml | 2 +- polkadot/node/core/pvf/common/Cargo.toml | 2 +- polkadot/node/core/pvf/execute-worker/Cargo.toml | 2 +- polkadot/node/core/pvf/prepare-worker/Cargo.toml | 2 +- substrate/client/executor/wasmtime/Cargo.toml | 2 +- substrate/client/tracing/Cargo.toml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87a2dad7549..74d87c2afc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7218,9 +7218,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libflate" diff --git a/polkadot/node/core/pvf/Cargo.toml b/polkadot/node/core/pvf/Cargo.toml index be35dc47b8a..73facf8475a 100644 --- a/polkadot/node/core/pvf/Cargo.toml +++ b/polkadot/node/core/pvf/Cargo.toml @@ -18,7 +18,7 @@ futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../../gum" } is_executable = "1.0.1" -libc = "0.2.139" +libc = "0.2.152" pin-project = "1.0.9" rand = "0.8.5" slotmap = "1.0" diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index 974965be593..b4f6ada9dbb 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -14,7 +14,7 @@ cfg-if = "1.0" cpu-time = "1.0.0" futures = "0.3.21" gum = { package = "tracing-gum", path = "../../../gum" } -libc = "0.2.139" +libc = "0.2.152" thiserror = "1.0.31" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml index 97dde59ebc2..83118041fdf 100644 --- a/polkadot/node/core/pvf/execute-worker/Cargo.toml +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -14,7 +14,7 @@ cpu-time = "1.0.0" gum = { package = "tracing-gum", path = "../../../gum" } os_pipe = "1.1.4" nix = { version = "0.27.1", features = ["process", "resource"] } -libc = "0.2.139" +libc = "0.2.152" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml index 81e887afe4d..2ef3dfc0e74 100644 --- a/polkadot/node/core/pvf/prepare-worker/Cargo.toml +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -13,7 +13,7 @@ workspace = true blake3 = "1.5" cfg-if = "1.0" gum = { package = "tracing-gum", path = "../../../gum" } -libc = "0.2.139" +libc = "0.2.152" rayon = "1.5.1" tracking-allocator = { package = "staging-tracking-allocator", path = "../../../tracking-allocator" } tikv-jemalloc-ctl = { version = "0.5.0", optional = true } diff --git a/substrate/client/executor/wasmtime/Cargo.toml b/substrate/client/executor/wasmtime/Cargo.toml index f8df23a026e..c1e866502fc 100644 --- a/substrate/client/executor/wasmtime/Cargo.toml +++ b/substrate/client/executor/wasmtime/Cargo.toml @@ -18,7 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4.17" cfg-if = "1.0" -libc = "0.2.121" +libc = "0.2.152" parking_lot = "0.12.1" # When bumping wasmtime do not forget to also bump rustix diff --git a/substrate/client/tracing/Cargo.toml b/substrate/client/tracing/Cargo.toml index fe288474ac9..bca6110846a 100644 --- a/substrate/client/tracing/Cargo.toml +++ b/substrate/client/tracing/Cargo.toml @@ -21,7 +21,7 @@ is-terminal = "0.4.9" chrono = "0.4.31" codec = { package = "parity-scale-codec", version = "3.6.1" } lazy_static = "1.4.0" -libc = "0.2.121" +libc = "0.2.152" log = { version = "0.4.17" } parking_lot = "0.12.1" regex = "1.6.0" -- GitLab From 50a2e28b00196453966ac9858640ee1c4356ef8e Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Fri, 19 Jan 2024 16:14:26 +0100 Subject: [PATCH 037/283] Enable cross-chain NFT transfers on asset-hub (#2796) This PR introduces the following changes: - [x] Adds a `UniquesTransactor` to asset-hub-rococo - [x] Adds a `UniquesTransactor` to asset-hub-westend We can't add a transactor for `pallet-nfts` like we do for `pallet-uniques` because `pallet-nfts` uses `nonfungibles_v2::Mutate` instead of `nonfungibles::Mutate`, and making that work would be out of scope of this PR. With these modifications, reserve-based NFT cross-chain transfers can be performed on asset-hub. --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- cumulus/parachains/common/src/lib.rs | 6 +++ .../assets/asset-hub-rococo/src/lib.rs | 14 +++--- .../assets/asset-hub-rococo/src/xcm_config.rs | 46 +++++++++++++++---- .../assets/asset-hub-westend/src/lib.rs | 14 +++--- .../asset-hub-westend/src/xcm_config.rs | 45 ++++++++++++++---- .../runtimes/assets/common/src/lib.rs | 17 ++++++- prdoc/pr_2796.prdoc | 12 +++++ 7 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 prdoc/pr_2796.prdoc diff --git a/cumulus/parachains/common/src/lib.rs b/cumulus/parachains/common/src/lib.rs index eab5d7f4577..68ba10094c0 100644 --- a/cumulus/parachains/common/src/lib.rs +++ b/cumulus/parachains/common/src/lib.rs @@ -67,6 +67,12 @@ mod types { // Id used for identifying assets. pub type AssetIdForTrustBackedAssets = u32; + + // Id used for identifying non-fungible collections. + pub type CollectionId = u32; + + // Id used for identifying non-fungible items. + pub type ItemId = u32; } /// Common constants of parachains. diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 494ca3d1240..0f379a6f7bc 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -76,9 +76,9 @@ use parachains_common::{ impls::DealWithFees, message_queue::{NarrowOriginToSibling, ParaIdToSibling}, rococo::{consensus::*, currency::*, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, Hash, Header, Nonce, - Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, - NORMAL_DISPATCH_RATIO, SLOT_DURATION, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, + Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, + MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; use sp_runtime::{Perbill, RuntimeDebug}; use xcm_config::{ @@ -773,8 +773,8 @@ parameter_types! { impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type CollectionDeposit = UniquesCollectionDeposit; @@ -831,8 +831,8 @@ parameter_types! { impl pallet_nfts::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index b9b9025b697..9e1affb533a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -17,7 +17,8 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + ToWestendXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, Uniques, WeightToFee, + XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, @@ -54,12 +55,12 @@ use xcm_builder::{ AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint, - NetworkExportTableItem, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SignedToAccountId32, SovereignPaidRemoteExporter, SovereignSignedViaLocation, StartsWith, - StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, - WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, - XcmFeeToAccount, + NetworkExportTableItem, NoChecking, NonFungiblesAdapter, ParentAsSuperuser, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignPaidRemoteExporter, + SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, + XcmFeeManagerFromComponents, XcmFeeToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -80,6 +81,8 @@ parameter_types! { PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub UniquesPalletLocation: Location = + PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocationV3: xcm::v3::Location = xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); @@ -145,6 +148,26 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// Matcher for converting `ClassId`/`InstanceId` into a uniques asset. +pub type UniquesConvertedConcreteId = + assets_common::UniquesConvertedConcreteId; + +/// Means for transacting unique assets. +pub type UniquesTransactor = NonFungiblesAdapter< + // Use this non-fungibles implementation: + Uniques, + // This adapter will handle any non-fungible asset from the uniques pallet. + UniquesConvertedConcreteId, + // Convert an XCM Location into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // Does not check teleports. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// `AssetId`/`Balance` converter for `ForeignAssets`. pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< ( @@ -198,8 +221,13 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< >; /// Means for transacting assets on this chain. -pub type AssetTransactors = - (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); +pub type AssetTransactors = ( + CurrencyTransactor, + FungiblesTransactor, + ForeignFungiblesTransactor, + PoolFungiblesTransactor, + UniquesTransactor, +); /// Simple `Location` matcher for Local and Foreign asset `Location`. pub struct LocalAndForeignAssetsLocationMatcher; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5950173d90e..310726349fa 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -60,9 +60,9 @@ use parachains_common::{ impls::DealWithFees, message_queue::*, westend::{consensus::*, currency::*, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, Hash, Header, Nonce, - Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, - NORMAL_DISPATCH_RATIO, SLOT_DURATION, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, + Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, + MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; @@ -748,8 +748,8 @@ parameter_types! { impl pallet_uniques::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type ForceOrigin = AssetsForceOrigin; type CollectionDeposit = UniquesCollectionDeposit; @@ -806,8 +806,8 @@ parameter_types! { impl pallet_nfts::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u32; - type ItemId = u32; + type CollectionId = CollectionId; + type ItemId = ItemId; type Currency = Balances; type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = AssetsForceOrigin; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 70522eda4b7..0f4ce360ee4 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -17,7 +17,8 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, CollatorSelection, FeeAssetId, ForeignAssets, ForeignAssetsInstance, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + ToRococoXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, Uniques, WeightToFee, + XcmpQueue, }; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsLocation, @@ -52,11 +53,12 @@ use xcm_builder::{ AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeFamily, DescribePalletTerminal, EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, IsConcrete, LocalMint, - NetworkExportTableItem, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, - TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, - WithUniqueTopic, XcmFeeManagerFromComponents, XcmFeeToAccount, + NetworkExportTableItem, NoChecking, NonFungiblesAdapter, ParentAsSuperuser, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, StartsWith, + StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, + WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, + XcmFeeToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -77,6 +79,8 @@ parameter_types! { PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub UniquesPalletLocation: Location = + PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocationV3: xcm::v3::Location = xcm::v3::Junction::PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); @@ -139,6 +143,26 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// Matcher for converting `ClassId`/`InstanceId` into a uniques asset. +pub type UniquesConvertedConcreteId = + assets_common::UniquesConvertedConcreteId; + +/// Means for transacting unique assets. +pub type UniquesTransactor = NonFungiblesAdapter< + // Use this non-fungibles implementation: + Uniques, + // This adapter will handle any non-fungible asset from the uniques pallet. + UniquesConvertedConcreteId, + // Convert an XCM Location into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // Does not check teleports. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// `AssetId`/`Balance` converter for `ForeignAssets`. pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< ( @@ -192,8 +216,13 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< >; /// Means for transacting assets on this chain. -pub type AssetTransactors = - (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); +pub type AssetTransactors = ( + CurrencyTransactor, + FungiblesTransactor, + ForeignFungiblesTransactor, + PoolFungiblesTransactor, + UniquesTransactor, +); /// Simple `Location` matcher for Local and Foreign asset `Location`. pub struct LocalAndForeignAssetsLocationMatcher; diff --git a/cumulus/parachains/runtimes/assets/common/src/lib.rs b/cumulus/parachains/runtimes/assets/common/src/lib.rs index f21e1766436..a0c912b6f0f 100644 --- a/cumulus/parachains/runtimes/assets/common/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/common/src/lib.rs @@ -25,7 +25,7 @@ pub mod runtime_api; use crate::matching::{LocalLocationPattern, ParentLocation}; use frame_support::traits::{Equals, EverythingBut}; -use parachains_common::AssetIdForTrustBackedAssets; +use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId}; use xcm_builder::{ AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith, V4V3LocationConverter, }; @@ -43,6 +43,10 @@ pub type AssetIdForTrustBackedAssetsConvert = pub type AssetIdForTrustBackedAssetsConvertLatest = AsPrefixedGeneralIndex; +/// `Location` vs `CollectionId` converter for `Uniques` +pub type CollectionIdForUniquesConvert = + AsPrefixedGeneralIndex; + /// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets` pub type TrustBackedAssetsConvertedConcreteId = MatchedConvertedConcreteId< @@ -53,6 +57,17 @@ pub type TrustBackedAssetsConvertedConcreteId; +/// [`MatchedConvertedConcreteId`] converter dedicated for `Uniques` +pub type UniquesConvertedConcreteId = MatchedConvertedConcreteId< + CollectionId, + ItemId, + // The asset starts with the uniques pallet. The `CollectionId` of the asset is specified as a + // junction within the pallet itself. + StartsWith, + CollectionIdForUniquesConvert, + JustTry, +>; + /// [`MatchedConvertedConcreteId`] converter dedicated for storing `AssetId` as `Location`. pub type LocationConvertedConcreteId = MatchedConvertedConcreteId< xcm::v3::Location, diff --git a/prdoc/pr_2796.prdoc b/prdoc/pr_2796.prdoc new file mode 100644 index 00000000000..15cb005d286 --- /dev/null +++ b/prdoc/pr_2796.prdoc @@ -0,0 +1,12 @@ +title: Rococo and Westend Asset-Hub: XCM Transfers with Pallet-Uniques + +doc: + - audience: Runtime User + description: | + With the added `UniquesTransactor` Rococo and Westend Asset-Hub are now capable of handling + XCM transfers with pallet-uniques. + +crates: + - name: "asset-hub-rococo-runtime" + - name: "asset-hub-westend-runtime" + - name: "assets-common" -- GitLab From 2e9b4405edb4d285cc51c15da2cc4d0785e7c32d Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Fri, 19 Jan 2024 17:12:30 +0100 Subject: [PATCH 038/283] Contract fixtures tests: fixe nightly version (#3000) Using just `nightly` is too generic and can fail on different systems. Now its fixed to the nightly version of the CI. Another way would be to use a toolchain file, since this already assumes `rustup`. Signed-off-by: Oliver Tale-Yazdi --- substrate/frame/contracts/fixtures/build.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/contracts/fixtures/build.rs b/substrate/frame/contracts/fixtures/build.rs index 8e00bbc9d09..5f174d200b9 100644 --- a/substrate/frame/contracts/fixtures/build.rs +++ b/substrate/frame/contracts/fixtures/build.rs @@ -159,7 +159,7 @@ fn invoke_cargo_fmt<'a>( ) -> Result<()> { // If rustfmt is not installed, skip the check. if !Command::new("rustup") - .args(["run", "nightly", "rustfmt", "--version"]) + .args(["nightly-2023-11-01", "run", "rustfmt", "--version"]) .output() .map_or(false, |o| o.status.success()) { @@ -167,7 +167,7 @@ fn invoke_cargo_fmt<'a>( } let fmt_res = Command::new("rustup") - .args(["run", "nightly", "rustfmt", "--check", "--config-path"]) + .args(["nightly-2023-11-01", "run", "rustfmt", "--check", "--config-path"]) .arg(config_path) .args(files) .output() @@ -182,7 +182,7 @@ fn invoke_cargo_fmt<'a>( eprintln!("{}\n{}", stdout, stderr); eprintln!( "Fixtures files are not formatted.\n - Please run `rustup run nightly rustfmt --config-path {} {}/*.rs`", + Please run `rustup nightly-2023-11-01 run rustfmt --config-path {} {}/*.rs`", config_path.display(), contract_dir.display() ); -- GitLab From 320b52892e556fe687e85e01df5c425f7eef39cf Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Fri, 19 Jan 2024 17:50:24 +0100 Subject: [PATCH 039/283] Update bridges subtree (#2996) Update bridges subtree --- bridges/bin/runtime-common/src/lib.rs | 1 + bridges/bin/runtime-common/src/messages.rs | 41 +--- .../runtime-common/src/messages_call_ext.rs | 7 +- .../src/messages_xcm_extension.rs | 5 +- bridges/bin/runtime-common/src/mock.rs | 9 +- .../src/parachains_benchmarking.rs | 2 +- .../src/refund_relayer_extension.rs | 6 +- bridges/modules/grandpa/src/lib.rs | 5 +- bridges/modules/grandpa/src/mock.rs | 6 +- bridges/modules/messages/README.md | 26 +- bridges/modules/messages/src/benchmarking.rs | 4 +- bridges/modules/messages/src/lib.rs | 231 +++++++++--------- bridges/modules/messages/src/mock.rs | 36 +-- bridges/modules/messages/src/outbound_lane.rs | 58 ++--- bridges/modules/parachains/src/call_ext.rs | 2 +- bridges/modules/parachains/src/lib.rs | 34 ++- bridges/modules/parachains/src/mock.rs | 14 +- .../modules/xcm-bridge-hub/src/exporter.rs | 71 +++--- bridges/modules/xcm-bridge-hub/src/mock.rs | 22 +- .../chain-bridge-hub-cumulus/src/lib.rs | 5 + .../chain-bridge-hub-kusama/src/lib.rs | 14 +- .../chain-bridge-hub-polkadot/src/lib.rs | 15 +- .../chain-bridge-hub-rococo/src/lib.rs | 15 +- .../chain-bridge-hub-westend/Cargo.toml | 4 +- .../chain-bridge-hub-westend/src/lib.rs | 14 +- bridges/primitives/chain-kusama/src/lib.rs | 29 ++- .../chain-polkadot-bulletin/src/lib.rs | 16 +- bridges/primitives/chain-polkadot/src/lib.rs | 31 ++- bridges/primitives/chain-rococo/src/lib.rs | 35 ++- bridges/primitives/chain-westend/src/lib.rs | 35 ++- bridges/primitives/header-chain/src/lib.rs | 14 +- bridges/primitives/messages/src/lib.rs | 47 +++- .../primitives/messages/src/source_chain.rs | 58 ++--- bridges/primitives/parachains/src/lib.rs | 4 + bridges/primitives/polkadot-core/src/lib.rs | 48 ++-- .../polkadot-core/src/parachains.rs | 13 +- bridges/primitives/runtime/src/chain.rs | 8 +- bridges/primitives/runtime/src/extensions.rs | 2 + bridges/primitives/runtime/src/lib.rs | 45 +--- bridges/primitives/test-utils/src/keyring.rs | 10 +- bridges/primitives/test-utils/src/lib.rs | 6 +- .../pallets/ethereum-client/Cargo.toml | 2 +- .../pallets/inbound-queue/Cargo.toml | 2 +- .../pallets/outbound-queue/Cargo.toml | 2 +- .../parachain/primitives/beacon/Cargo.toml | 2 +- .../parachain/primitives/core/Cargo.toml | 2 +- .../parachain/primitives/router/Cargo.toml | 2 +- .../parachain/runtime/test-common/Cargo.toml | 2 +- .../src/bridge_to_bulletin_config.rs | 8 +- .../src/bridge_to_westend_config.rs | 10 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 4 +- .../src/bridge_to_rococo_config.rs | 10 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 +- 53 files changed, 565 insertions(+), 533 deletions(-) diff --git a/bridges/bin/runtime-common/src/lib.rs b/bridges/bin/runtime-common/src/lib.rs index d3b3b21061d..2722f6f1c6d 100644 --- a/bridges/bin/runtime-common/src/lib.rs +++ b/bridges/bin/runtime-common/src/lib.rs @@ -16,6 +16,7 @@ //! Common types/functions that may be used by runtimes of all bridged chains. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use crate::messages_call_ext::MessagesCallSubType; diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index ac66adae661..4aca53f3b98 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -24,7 +24,7 @@ pub use bp_runtime::{RangeInclusiveExt, UnderlyingChainOf, UnderlyingChainProvid use bp_header_chain::HeaderChain; use bp_messages::{ - source_chain::{LaneMessageVerifier, TargetHeaderChain}, + source_chain::TargetHeaderChain, target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, @@ -120,42 +120,6 @@ pub mod source { pub type ParsedMessagesDeliveryProofFromBridgedChain = (LaneId, InboundLaneData>>); - /// Message verifier that is doing all basic checks. - /// - /// This verifier assumes following: - /// - /// - all message lanes are equivalent, so all checks are the same; - /// - /// Following checks are made: - /// - /// - message is rejected if its lane is currently blocked; - /// - message is rejected if there are too many pending (undelivered) messages at the outbound - /// lane; - /// - check that the sender has rights to dispatch the call on target chain using provided - /// dispatch origin; - /// - check that the sender has paid enough funds for both message delivery and dispatch. - #[derive(RuntimeDebug)] - pub struct FromThisChainMessageVerifier(PhantomData); - - impl LaneMessageVerifier for FromThisChainMessageVerifier - where - B: MessageBridge, - { - fn verify_message( - _lane: &LaneId, - _lane_outbound_data: &OutboundLaneData, - _payload: &FromThisChainMessagePayload, - ) -> Result<(), VerificationError> { - // IMPORTANT: any error that is returned here is fatal for the bridge, because - // this code is executed at the bridge hub and message sender actually lives - // at some sibling parachain. So we are failing **after** the message has been - // sent and we can't report it back to sender (unless error report mechanism is - // embedded into message and its dispatcher). - - Ok(()) - } - } - /// Return maximal message size of This -> Bridged chain message. pub fn maximal_message_size() -> u32 { super::target::maximal_incoming_message_size( @@ -185,8 +149,7 @@ pub mod source { /// Do basic Bridged-chain specific verification of This -> Bridged chain message. /// /// Ok result from this function means that the delivery transaction with this message - /// may be 'mined' by the target chain. But the lane may have its own checks (e.g. fee - /// check) that would reject message (see `FromThisChainMessageVerifier`). + /// may be 'mined' by the target chain. pub fn verify_chain_message( payload: &FromThisChainMessagePayload, ) -> Result<(), VerificationError> { diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index 5303fcb7ba0..fb07f7b6dd6 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Signed extension for the `pallet-bridge-messages` that is able to reject obsolete +//! (and some other invalid) transactions. + use crate::messages::{ source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }; @@ -116,7 +119,9 @@ impl ReceiveMessagesDeliveryProofInfo { /// which tries to update a single lane. #[derive(PartialEq, RuntimeDebug)] pub enum CallInfo { + /// Messages delivery call info. ReceiveMessagesProof(ReceiveMessagesProofInfo), + /// Messages delivery confirmation call info. ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), } @@ -132,7 +137,7 @@ impl CallInfo { /// Helper struct that provides methods for working with a call supported by `CallInfo`. pub struct CallHelper, I: 'static> { - pub _phantom_data: sp_std::marker::PhantomData<(T, I)>, + _phantom_data: sp_std::marker::PhantomData<(T, I)>, } impl, I: 'static> CallHelper { diff --git a/bridges/bin/runtime-common/src/messages_xcm_extension.rs b/bridges/bin/runtime-common/src/messages_xcm_extension.rs index fd2c20af72a..e3da6155f08 100644 --- a/bridges/bin/runtime-common/src/messages_xcm_extension.rs +++ b/bridges/bin/runtime-common/src/messages_xcm_extension.rs @@ -40,11 +40,14 @@ use sp_std::{fmt::Debug, marker::PhantomData}; use xcm::prelude::*; use xcm_builder::{DispatchBlob, DispatchBlobError}; -/// Message dispatch result type for single message +/// Message dispatch result type for single message. #[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)] pub enum XcmBlobMessageDispatchResult { + /// We've been unable to decode message payload. InvalidPayload, + /// Message has been dispatched. Dispatched, + /// Message has **NOT** been dispatched because of given error. NotDispatched(#[codec(skip)] Option), } diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index bd47d37fc07..8877a4fd95c 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -21,7 +21,7 @@ use crate::messages::{ source::{ FromThisChainMaximalOutboundPayloadSize, FromThisChainMessagePayload, - FromThisChainMessageVerifier, TargetHeaderChainAdapter, + TargetHeaderChainAdapter, }, target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, BridgedChainWithMessages, HashOf, MessageBridge, ThisChainWithMessages, @@ -213,7 +213,6 @@ impl pallet_bridge_messages::Config for TestRuntime { type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = FromThisChainMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< TestRuntime, (), @@ -315,6 +314,8 @@ impl From pub struct ThisUnderlyingChain; impl Chain for ThisUnderlyingChain { + const ID: ChainId = *b"tuch"; + type BlockNumber = ThisChainBlockNumber; type Hash = ThisChainHash; type Hasher = ThisChainHasher; @@ -355,6 +356,8 @@ pub struct BridgedUnderlyingParachain; pub struct BridgedChainCall; impl Chain for BridgedUnderlyingChain { + const ID: ChainId = *b"buch"; + type BlockNumber = BridgedChainBlockNumber; type Hash = BridgedChainHash; type Hasher = BridgedChainHasher; @@ -381,6 +384,8 @@ impl ChainWithGrandpa for BridgedUnderlyingChain { } impl Chain for BridgedUnderlyingParachain { + const ID: ChainId = *b"bupc"; + type BlockNumber = BridgedChainBlockNumber; type Hash = BridgedChainHash; type Hasher = BridgedChainHasher; diff --git a/bridges/bin/runtime-common/src/parachains_benchmarking.rs b/bridges/bin/runtime-common/src/parachains_benchmarking.rs index 63dc78385e4..b3050b9ac0f 100644 --- a/bridges/bin/runtime-common/src/parachains_benchmarking.rs +++ b/bridges/bin/runtime-common/src/parachains_benchmarking.rs @@ -84,5 +84,5 @@ where let (relay_block_number, relay_block_hash) = insert_header_to_grandpa_pallet::(state_root); - (relay_block_number, relay_block_hash, ParaHeadsProof(proof), parachain_heads) + (relay_block_number, relay_block_hash, ParaHeadsProof { storage_proof: proof }, parachain_heads) } diff --git a/bridges/bin/runtime-common/src/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/refund_relayer_extension.rs index 6d8b2114808..27b7ff1a551 100644 --- a/bridges/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/refund_relayer_extension.rs @@ -116,7 +116,7 @@ where /// Refund calculator. pub trait RefundCalculator { - // The underlying integer type in which the refund is calculated. + /// The underlying integer type in which the refund is calculated. type Balance; /// Compute refund for given transaction. @@ -986,7 +986,7 @@ mod tests { ParaId(TestParachain::get()), [parachain_head_at_relay_header_number as u8; 32].into(), )], - parachain_heads_proof: ParaHeadsProof(vec![]), + parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, }) } @@ -1732,7 +1732,7 @@ mod tests { (ParaId(TestParachain::get()), [1u8; 32].into()), (ParaId(TestParachain::get() + 1), [1u8; 32].into()), ], - parachain_heads_proof: ParaHeadsProof(vec![]), + parachain_heads_proof: ParaHeadsProof { storage_proof: vec![] }, }), message_delivery_call(200), ], diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 22df604bf18..f58db2481ad 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -32,9 +32,8 @@ //! Shall the fork occur on the bridged chain governance intervention will be required to //! re-initialize the bridge and track the right fork. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// Runtime-generated enums -#![allow(clippy::large_enum_variant)] pub use storage_types::StoredAuthoritySet; @@ -408,7 +407,9 @@ pub mod pallet { pub enum Event, I: 'static = ()> { /// Best finalized chain header has been updated to the header with given number and hash. UpdatedBestFinalizedHeader { + /// Number of the new best finalized header. number: BridgedBlockNumber, + /// Hash of the new best finalized header. hash: BridgedBlockHash, /// The Grandpa info associated to the new best finalized header. grandpa_info: StoredHeaderGrandpaInfo>, diff --git a/bridges/modules/grandpa/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index a54f56c4a62..e41e89341b3 100644 --- a/bridges/modules/grandpa/src/mock.rs +++ b/bridges/modules/grandpa/src/mock.rs @@ -18,7 +18,7 @@ #![allow(clippy::from_over_into)] use bp_header_chain::ChainWithGrandpa; -use bp_runtime::Chain; +use bp_runtime::{Chain, ChainId}; use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::Hooks, weights::Weight, }; @@ -64,7 +64,9 @@ impl grandpa::Config for TestRuntime { pub struct TestBridgedChain; impl Chain for TestBridgedChain { - type BlockNumber = TestNumber; + const ID: ChainId = *b"tbch"; + + type BlockNumber = frame_system::pallet_prelude::BlockNumberFor; type Hash = ::Hash; type Hasher = ::Hashing; type Header = TestHeader; diff --git a/bridges/modules/messages/README.md b/bridges/modules/messages/README.md index 457d5f5facf..fe62305748c 100644 --- a/bridges/modules/messages/README.md +++ b/bridges/modules/messages/README.md @@ -116,26 +116,12 @@ maximal possible transaction size of the chain and so on. And when the relayer s implementation must be able to parse and verify the proof of messages delivery. Normally, you would reuse the same (configurable) type on all chains that are sending messages to the same bridged chain. -The `pallet_bridge_messages::Config::LaneMessageVerifier` defines a single callback to verify outbound messages. The -simplest callback may just accept all messages. But in this case you'll need to answer many questions first. Who will -pay for the delivery and confirmation transaction? Are we sure that someone will ever deliver this message to the -bridged chain? Are we sure that we don't bloat our runtime storage by accepting this message? What if the message is -improperly encoded or has some fields set to invalid values? Answering all those (and similar) questions would lead to -correct implementation. - -There's another thing to consider when implementing type for use in -`pallet_bridge_messages::Config::LaneMessageVerifier`. It is whether we treat all message lanes identically, or they'll -have different sets of verification rules? For example, you may reserve lane#1 for messages coming from some -'wrapped-token' pallet - then you may verify in your implementation that the origin is associated with this pallet. -Lane#2 may be reserved for 'system' messages and you may charge zero fee for such messages. You may have some rate -limiting for messages sent over the lane#3. Or you may just verify the same rules set for all outbound messages - it is -all up to the `pallet_bridge_messages::Config::LaneMessageVerifier` implementation. - -The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation transaction is -received, we call the `pay_reward()` method, passing the range of delivered messages. You may use the -[`pallet-bridge-relayers`](../relayers/) pallet and its -[`DeliveryConfirmationPaymentsAdapter`](../relayers/src/payment_adapter.rs) adapter as a possible implementation. It -allows you to pay fixed reward for relaying the message and some of its portion for confirming delivery. +The last type is the `pallet_bridge_messages::Config::DeliveryConfirmationPayments`. When confirmation +transaction is received, we call the `pay_reward()` method, passing the range of delivered messages. +You may use the [`pallet-bridge-relayers`](../relayers/) pallet and its +[`DeliveryConfirmationPaymentsAdapter`](../relayers/src/payment_adapter.rs) adapter as a possible +implementation. It allows you to pay fixed reward for relaying the message and some of its portion +for confirming delivery. ### I have a Messages Module in my Runtime, but I Want to Reject all Outbound Messages. What shall I do? diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 8c4e6fbf00c..4f13c440967 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -31,7 +31,7 @@ use codec::Decode; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::weights::Weight; use frame_system::RawOrigin; -use sp_runtime::traits::TrailingZeroInput; +use sp_runtime::{traits::TrailingZeroInput, BoundedVec}; use sp_std::{ops::RangeInclusive, prelude::*}; const SEED: u32 = 0; @@ -443,7 +443,7 @@ benchmarks_instance_pallet! { fn send_regular_message, I: 'static>() { let mut outbound_lane = outbound_lane::(T::bench_lane_id()); - outbound_lane.send_message(vec![]).expect("We craft valid messages"); + outbound_lane.send_message(BoundedVec::try_from(vec![]).expect("We craft valid messages")); } fn receive_messages, I: 'static>(nonce: MessageNonce) { diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index b87c64d1607..a86cb326cf0 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -33,9 +33,8 @@ //! If this test fails with your weights, then either weights are computed incorrectly, //! or some benchmarks assumptions are broken for your runtime. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// Generated by `decl_event!` -#![allow(clippy::unused_unit)] pub use inbound_lane::StoredInboundLaneData; pub use outbound_lane::StoredMessagePayload; @@ -53,8 +52,7 @@ use crate::{ use bp_messages::{ source_chain::{ - DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered, - SendMessageArtifacts, TargetHeaderChain, + DeliveryConfirmationPayments, OnMessagesDelivered, SendMessageArtifacts, TargetHeaderChain, }, target_chain::{ DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, @@ -155,8 +153,6 @@ pub mod pallet { /// Target header chain. type TargetHeaderChain: TargetHeaderChain; - /// Message payload verifier. - type LaneMessageVerifier: LaneMessageVerifier; /// Delivery confirmation payments. type DeliveryConfirmationPayments: DeliveryConfirmationPayments; /// Delivery confirmation callback. @@ -517,16 +513,28 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { /// Message has been accepted and is waiting to be delivered. - MessageAccepted { lane_id: LaneId, nonce: MessageNonce }, + MessageAccepted { + /// Lane, which has accepted the message. + lane_id: LaneId, + /// Nonce of accepted message. + nonce: MessageNonce, + }, /// Messages have been received from the bridged chain. MessagesReceived( + /// Result of received messages dispatch. Vec::DispatchLevelResult>>, ), /// Messages in the inclusive range have been delivered to the bridged chain. - MessagesDelivered { lane_id: LaneId, messages: DeliveredMessages }, + MessagesDelivered { + /// Lane for which the delivery has been confirmed. + lane_id: LaneId, + /// Delivered messages. + messages: DeliveredMessages, + }, } #[pallet::error] + #[derive(PartialEq, Eq)] pub enum Error { /// Pallet is not in Normal operating mode. NotOperatingNormally, @@ -536,8 +544,6 @@ pub mod pallet { MessageDispatchInactive, /// Message has been treated as invalid by chain verifier. MessageRejectedByChainVerifier(VerificationError), - /// Message has been treated as invalid by lane verifier. - MessageRejectedByLaneVerifier(VerificationError), /// Message has been treated as invalid by the pallet logic. MessageRejectedByPallet(VerificationError), /// Submitter has failed to pay fee for delivering and dispatching messages. @@ -683,80 +689,72 @@ pub mod pallet { } } +/// Structure, containing a validated message payload and all the info required +/// to send it on the bridge. +#[derive(Debug, PartialEq, Eq)] +pub struct SendMessageArgs, I: 'static> { + lane_id: LaneId, + payload: StoredMessagePayload, +} + impl bp_messages::source_chain::MessagesBridge for Pallet where T: Config, I: 'static, { - type Error = sp_runtime::DispatchErrorWithPostInfo; + type Error = Error; + type SendMessageArgs = SendMessageArgs; - fn send_message( + fn validate_message( lane: LaneId, - message: T::OutboundPayload, - ) -> Result { - crate::send_message::(lane, message) + message: &T::OutboundPayload, + ) -> Result, Self::Error> { + ensure_normal_operating_mode::()?; + + // let's check if outbound lane is active + ensure!(T::ActiveOutboundLanes::get().contains(&lane), Error::::InactiveOutboundLane); + + // let's first check if message can be delivered to target chain + T::TargetHeaderChain::verify_message(message).map_err(|err| { + log::trace!( + target: LOG_TARGET, + "Message to lane {:?} is rejected by target chain: {:?}", + lane, + err, + ); + + Error::::MessageRejectedByChainVerifier(err) + })?; + + Ok(SendMessageArgs { + lane_id: lane, + payload: StoredMessagePayload::::try_from(message.encode()).map_err(|_| { + Error::::MessageRejectedByPallet(VerificationError::MessageTooLarge) + })?, + }) } -} -/// Function that actually sends message. -fn send_message, I: 'static>( - lane_id: LaneId, - payload: T::OutboundPayload, -) -> sp_std::result::Result< - SendMessageArtifacts, - sp_runtime::DispatchErrorWithPostInfo, -> { - ensure_normal_operating_mode::()?; - - // let's check if outbound lane is active - ensure!(T::ActiveOutboundLanes::get().contains(&lane_id), Error::::InactiveOutboundLane,); - - // let's first check if message can be delivered to target chain - T::TargetHeaderChain::verify_message(&payload).map_err(|err| { - log::trace!( - target: LOG_TARGET, - "Message to lane {:?} is rejected by target chain: {:?}", - lane_id, - err, - ); + fn send_message(args: SendMessageArgs) -> SendMessageArtifacts { + // save message in outbound storage and emit event + let mut lane = outbound_lane::(args.lane_id); + let message_len = args.payload.len(); + let nonce = lane.send_message(args.payload); - Error::::MessageRejectedByChainVerifier(err) - })?; + // return number of messages in the queue to let sender know about its state + let enqueued_messages = lane.data().queued_messages().saturating_len(); - // now let's enforce any additional lane rules - let mut lane = outbound_lane::(lane_id); - T::LaneMessageVerifier::verify_message(&lane_id, &lane.data(), &payload).map_err(|err| { log::trace!( target: LOG_TARGET, - "Message to lane {:?} is rejected by lane verifier: {:?}", - lane_id, - err, + "Accepted message {} to lane {:?}. Message size: {:?}", + nonce, + args.lane_id, + message_len, ); - Error::::MessageRejectedByLaneVerifier(err) - })?; - - // finally, save message in outbound storage and emit event - let encoded_payload = payload.encode(); - let encoded_payload_len = encoded_payload.len(); - let nonce = lane - .send_message(encoded_payload) - .map_err(Error::::MessageRejectedByPallet)?; - - // return number of messages in the queue to let sender know about its state - let enqueued_messages = lane.data().queued_messages().saturating_len(); - - log::trace!( - target: LOG_TARGET, - "Accepted message {} to lane {:?}. Message size: {:?}", - nonce, - lane_id, - encoded_payload_len, - ); + Pallet::::deposit_event(Event::MessageAccepted { lane_id: args.lane_id, nonce }); - Pallet::::deposit_event(Event::MessageAccepted { lane_id, nonce }); - - Ok(SendMessageArtifacts { nonce, enqueued_messages }) + SendMessageArtifacts { nonce, enqueued_messages } + } } /// Ensure that the pallet is in normal operational mode. @@ -857,6 +855,8 @@ struct RuntimeOutboundLaneStorage { } impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage { + type StoredMessagePayload = StoredMessagePayload; + fn id(&self) -> LaneId { self.lane_id } @@ -870,22 +870,15 @@ impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorag } #[cfg(test)] - fn message(&self, nonce: &MessageNonce) -> Option { + fn message(&self, nonce: &MessageNonce) -> Option { OutboundMessages::::get(MessageKey { lane_id: self.lane_id, nonce: *nonce }) - .map(Into::into) } - fn save_message( - &mut self, - nonce: MessageNonce, - message_payload: MessagePayload, - ) -> Result<(), VerificationError> { + fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload) { OutboundMessages::::insert( MessageKey { lane_id: self.lane_id, nonce }, - StoredMessagePayload::::try_from(message_payload) - .map_err(|_| VerificationError::MessageTooLarge)?, + message_payload, ); - Ok(()) } fn remove_message(&mut self, nonce: &MessageNonce) { @@ -932,7 +925,10 @@ mod tests { }, outbound_lane::ReceivalConfirmationError, }; - use bp_messages::{BridgeMessagesCall, UnrewardedRelayer, UnrewardedRelayersState}; + use bp_messages::{ + source_chain::MessagesBridge, BridgeMessagesCall, UnrewardedRelayer, + UnrewardedRelayersState, + }; use bp_test_utils::generate_owned_bridge_module_tests; use frame_support::{ assert_noop, assert_ok, @@ -949,14 +945,15 @@ mod tests { System::::reset_events(); } - fn send_regular_message() { + fn send_regular_message(lane_id: LaneId) { get_ready_for_events(); - let outbound_lane = outbound_lane::(TEST_LANE_ID); + let outbound_lane = outbound_lane::(lane_id); let message_nonce = outbound_lane.data().latest_generated_nonce + 1; let prev_enqueud_messages = outbound_lane.data().queued_messages().saturating_len(); - let artifacts = send_message::(TEST_LANE_ID, REGULAR_PAYLOAD) - .expect("send_message has failed"); + let valid_message = Pallet::::validate_message(lane_id, ®ULAR_PAYLOAD) + .expect("validate_message has failed"); + let artifacts = Pallet::::send_message(valid_message); assert_eq!(artifacts.enqueued_messages, prev_enqueud_messages + 1); // check event with assigned nonce @@ -965,7 +962,7 @@ mod tests { vec![EventRecord { phase: Phase::Initialization, event: TestEvent::Messages(Event::MessageAccepted { - lane_id: TEST_LANE_ID, + lane_id, nonce: message_nonce }), topics: vec![], @@ -1016,14 +1013,14 @@ mod tests { fn pallet_rejects_transactions_if_halted() { run_test(|| { // send message first to be able to check that delivery_proof fails later - send_regular_message(); + send_regular_message(TEST_LANE_ID); PalletOperatingMode::::put(MessagesOperatingMode::Basic( BasicOperatingMode::Halted, )); assert_noop!( - send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,), + Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), Error::::NotOperatingNormally, ); @@ -1066,14 +1063,14 @@ mod tests { fn pallet_rejects_new_messages_in_rejecting_outbound_messages_operating_mode() { run_test(|| { // send message first to be able to check that delivery_proof fails later - send_regular_message(); + send_regular_message(TEST_LANE_ID); PalletOperatingMode::::put( MessagesOperatingMode::RejectingOutboundMessages, ); assert_noop!( - send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,), + Pallet::::validate_message(TEST_LANE_ID, ®ULAR_PAYLOAD), Error::::NotOperatingNormally, ); @@ -1109,7 +1106,7 @@ mod tests { #[test] fn send_message_works() { run_test(|| { - send_regular_message(); + send_regular_message(TEST_LANE_ID); }); } @@ -1123,7 +1120,7 @@ mod tests { .extra .extend_from_slice(&[0u8; MAX_OUTBOUND_PAYLOAD_SIZE as usize]); assert_noop!( - send_message::(TEST_LANE_ID, message_payload.clone(),), + Pallet::::validate_message(TEST_LANE_ID, &message_payload.clone(),), Error::::MessageRejectedByPallet( VerificationError::MessageTooLarge ), @@ -1134,7 +1131,11 @@ mod tests { message_payload.extra.pop(); } assert_eq!(message_payload.encoded_size() as u32, MAX_OUTBOUND_PAYLOAD_SIZE); - assert_ok!(send_message::(TEST_LANE_ID, message_payload,),); + + let valid_message = + Pallet::::validate_message(TEST_LANE_ID, &message_payload) + .expect("validate_message has failed"); + Pallet::::send_message(valid_message); }) } @@ -1143,7 +1144,10 @@ mod tests { run_test(|| { // messages with this payload are rejected by target chain verifier assert_noop!( - send_message::(TEST_LANE_ID, PAYLOAD_REJECTED_BY_TARGET_CHAIN,), + Pallet::::validate_message( + TEST_LANE_ID, + &PAYLOAD_REJECTED_BY_TARGET_CHAIN, + ), Error::::MessageRejectedByChainVerifier(VerificationError::Other( mock::TEST_ERROR )), @@ -1151,21 +1155,6 @@ mod tests { }); } - #[test] - fn lane_verifier_rejects_invalid_message_in_send_message() { - run_test(|| { - // messages with zero fee are rejected by lane verifier - let mut message = REGULAR_PAYLOAD; - message.reject_by_lane_verifier = true; - assert_noop!( - send_message::(TEST_LANE_ID, message,), - Error::::MessageRejectedByLaneVerifier(VerificationError::Other( - mock::TEST_ERROR - )), - ); - }); - } - #[test] fn receive_messages_proof_works() { run_test(|| { @@ -1318,7 +1307,7 @@ mod tests { #[test] fn receive_messages_delivery_proof_works() { run_test(|| { - send_regular_message(); + send_regular_message(TEST_LANE_ID); receive_messages_delivery_proof(); assert_eq!( @@ -1331,8 +1320,8 @@ mod tests { #[test] fn receive_messages_delivery_proof_rewards_relayers() { run_test(|| { - assert_ok!(send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,)); - assert_ok!(send_message::(TEST_LANE_ID, REGULAR_PAYLOAD,)); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); // this reports delivery of message 1 => reward is paid to TEST_RELAYER_A let single_message_delivery_proof = TestMessagesDeliveryProof(Ok(( @@ -1718,9 +1707,9 @@ mod tests { #[test] fn messages_delivered_callbacks_are_called() { run_test(|| { - send_regular_message(); - send_regular_message(); - send_regular_message(); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); // messages 1+2 are confirmed in 1 tx, message 3 in a separate tx // dispatch of message 2 has failed @@ -1779,7 +1768,7 @@ mod tests { ) { run_test(|| { // send message first to be able to check that delivery_proof fails later - send_regular_message(); + send_regular_message(TEST_LANE_ID); // 1) InboundLaneData declares that the `last_confirmed_nonce` is 1; // 2) InboundLaneData has no entries => `InboundLaneData::last_delivered_nonce()` @@ -1846,10 +1835,10 @@ mod tests { #[test] fn on_idle_callback_respects_remaining_weight() { run_test(|| { - send_regular_message(); - send_regular_message(); - send_regular_message(); - send_regular_message(); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); + send_regular_message(TEST_LANE_ID); assert_ok!(Pallet::::receive_messages_delivery_proof( RuntimeOrigin::signed(1), @@ -1928,10 +1917,10 @@ mod tests { fn on_idle_callback_is_rotating_lanes_to_prune() { run_test(|| { // send + receive confirmation for lane 1 - send_regular_message(); + send_regular_message(TEST_LANE_ID); receive_messages_delivery_proof(); // send + receive confirmation for lane 2 - assert_ok!(send_message::(TEST_LANE_ID_2, REGULAR_PAYLOAD,)); + send_regular_message(TEST_LANE_ID_2); assert_ok!(Pallet::::receive_messages_delivery_proof( RuntimeOrigin::signed(1), TestMessagesDeliveryProof(Ok(( @@ -2007,7 +1996,7 @@ mod tests { fn outbound_message_from_unconfigured_lane_is_rejected() { run_test(|| { assert_noop!( - send_message::(TEST_LANE_ID_3, REGULAR_PAYLOAD,), + Pallet::::validate_message(TEST_LANE_ID_3, ®ULAR_PAYLOAD,), Error::::InactiveOutboundLane, ); }); diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/mock.rs index 648acad772d..af921205398 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/mock.rs @@ -17,19 +17,17 @@ // From construct_runtime macro #![allow(clippy::from_over_into)] -use crate::Config; +use crate::{Config, StoredMessagePayload}; use bp_messages::{ calc_relayers_rewards, - source_chain::{ - DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered, TargetHeaderChain, - }, + source_chain::{DeliveryConfirmationPayments, OnMessagesDelivered, TargetHeaderChain}, target_chain::{ DeliveryPayments, DispatchMessage, DispatchMessageData, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, }, - DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, - OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, VerificationError, + DeliveredMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, + UnrewardedRelayer, UnrewardedRelayersState, VerificationError, }; use bp_runtime::{messages::MessageDispatchResult, Size}; use codec::{Decode, Encode}; @@ -50,8 +48,6 @@ pub type Balance = u64; pub struct TestPayload { /// Field that may be used to identify messages. pub id: u64, - /// Reject this message by lane verifier? - pub reject_by_lane_verifier: bool, /// Dispatch weight that is declared by the message sender. pub declared_weight: Weight, /// Message dispatch result. @@ -120,7 +116,6 @@ impl Config for TestRuntime { type DeliveryPayments = TestDeliveryPayments; type TargetHeaderChain = TestTargetHeaderChain; - type LaneMessageVerifier = TestLaneMessageVerifier; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; type OnMessagesDelivered = TestOnMessagesDelivered; @@ -268,24 +263,6 @@ impl TargetHeaderChain for TestTargetHeaderChain { } } -/// Lane message verifier that is used in tests. -#[derive(Debug, Default)] -pub struct TestLaneMessageVerifier; - -impl LaneMessageVerifier for TestLaneMessageVerifier { - fn verify_message( - _lane: &LaneId, - _lane_outbound_data: &OutboundLaneData, - payload: &TestPayload, - ) -> Result<(), VerificationError> { - if !payload.reject_by_lane_verifier { - Ok(()) - } else { - Err(VerificationError::Other(TEST_ERROR)) - } - } -} - /// Reward payments at the target chain during delivery transaction. #[derive(Debug, Default)] pub struct TestDeliveryPayments; @@ -425,8 +402,8 @@ pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message { } /// Return valid outbound message data, constructed from given payload. -pub fn outbound_message_data(payload: TestPayload) -> MessagePayload { - payload.encode() +pub fn outbound_message_data(payload: TestPayload) -> StoredMessagePayload { + StoredMessagePayload::::try_from(payload.encode()).expect("payload too large") } /// Return valid inbound (dispatch) message data, constructed from given payload. @@ -438,7 +415,6 @@ pub fn inbound_message_data(payload: TestPayload) -> DispatchMessageData TestPayload { TestPayload { id, - reject_by_lane_verifier: false, declared_weight: Weight::from_parts(declared_weight, 0), dispatch_result: dispatch_result(0), extra: Vec::new(), diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index f92e9ccfd95..431c2cfb7ee 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -18,10 +18,7 @@ use crate::{Config, LOG_TARGET}; -use bp_messages::{ - DeliveredMessages, LaneId, MessageNonce, MessagePayload, OutboundLaneData, UnrewardedRelayer, - VerificationError, -}; +use bp_messages::{DeliveredMessages, LaneId, MessageNonce, OutboundLaneData, UnrewardedRelayer}; use codec::{Decode, Encode}; use frame_support::{ weights::{RuntimeDbWeight, Weight}, @@ -34,6 +31,8 @@ use sp_std::collections::vec_deque::VecDeque; /// Outbound lane storage. pub trait OutboundLaneStorage { + type StoredMessagePayload; + /// Lane id. fn id(&self) -> LaneId; /// Get lane data from the storage. @@ -42,13 +41,9 @@ pub trait OutboundLaneStorage { fn set_data(&mut self, data: OutboundLaneData); /// Returns saved outbound message payload. #[cfg(test)] - fn message(&self, nonce: &MessageNonce) -> Option; + fn message(&self, nonce: &MessageNonce) -> Option; /// Save outbound message in the storage. - fn save_message( - &mut self, - nonce: MessageNonce, - message_payload: MessagePayload, - ) -> Result<(), VerificationError>; + fn save_message(&mut self, nonce: MessageNonce, message_payload: Self::StoredMessagePayload); /// Remove outbound message from the storage. fn remove_message(&mut self, nonce: &MessageNonce); } @@ -91,18 +86,15 @@ impl OutboundLane { /// Send message over lane. /// /// Returns new message nonce. - pub fn send_message( - &mut self, - message_payload: MessagePayload, - ) -> Result { + pub fn send_message(&mut self, message_payload: S::StoredMessagePayload) -> MessageNonce { let mut data = self.storage.data(); let nonce = data.latest_generated_nonce + 1; data.latest_generated_nonce = nonce; - self.storage.save_message(nonce, message_payload)?; + self.storage.save_message(nonce, message_payload); self.storage.set_data(data); - Ok(nonce) + nonce } /// Confirm messages delivery. @@ -218,7 +210,7 @@ mod tests { }, outbound_lane, }; - use frame_support::{assert_ok, weights::constants::RocksDbWeight}; + use frame_support::weights::constants::RocksDbWeight; use sp_std::ops::RangeInclusive; fn unrewarded_relayers( @@ -239,9 +231,9 @@ mod tests { ) -> Result, ReceivalConfirmationError> { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); let result = lane.confirm_delivery(3, latest_received_nonce, relayers); @@ -256,7 +248,7 @@ mod tests { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); assert_eq!(lane.storage.data().latest_generated_nonce, 0); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(1)); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); assert!(lane.storage.message(&1).is_some()); assert_eq!(lane.storage.data().latest_generated_nonce, 1); }); @@ -266,9 +258,9 @@ mod tests { fn confirm_delivery_works() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(1)); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(2)); - assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), Ok(3)); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 1); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 2); + assert_eq!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD)), 3); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!( @@ -284,9 +276,9 @@ mod tests { fn confirm_delivery_rejects_nonce_lesser_than_latest_received() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!(lane.storage.data().latest_generated_nonce, 3); assert_eq!(lane.storage.data().latest_received_nonce, 0); assert_eq!( @@ -368,9 +360,9 @@ mod tests { ); assert_eq!(lane.storage.data().oldest_unpruned_nonce, 1); // when nothing is confirmed, nothing is pruned - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert!(lane.storage.message(&1).is_some()); assert!(lane.storage.message(&2).is_some()); assert!(lane.storage.message(&3).is_some()); @@ -412,9 +404,9 @@ mod tests { fn confirm_delivery_detects_when_more_than_expected_messages_are_confirmed() { run_test(|| { let mut lane = outbound_lane::(TEST_LANE_ID); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); - assert_ok!(lane.send_message(outbound_message_data(REGULAR_PAYLOAD))); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); + lane.send_message(outbound_message_data(REGULAR_PAYLOAD)); assert_eq!( lane.confirm_delivery(0, 3, &unrewarded_relayers(1..=3)), Err(ReceivalConfirmationError::TryingToConfirmMoreMessagesThanExpected), diff --git a/bridges/modules/parachains/src/call_ext.rs b/bridges/modules/parachains/src/call_ext.rs index 198ff11be49..da91a40a232 100644 --- a/bridges/modules/parachains/src/call_ext.rs +++ b/bridges/modules/parachains/src/call_ext.rs @@ -178,7 +178,7 @@ mod tests { RuntimeCall::Parachains(crate::Call::::submit_parachain_heads { at_relay_block: (num, Default::default()), parachains, - parachain_heads_proof: ParaHeadsProof(Vec::new()), + parachain_heads_proof: ParaHeadsProof { storage_proof: Vec::new() }, }) .check_obsolete_submit_parachain_heads() .is_ok() diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index cf76e64ff9c..87c57e84622 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -21,6 +21,7 @@ //! accepts storage proof of some parachain `Heads` entries from bridged relay chain. //! It requires corresponding relay headers to be already synced. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use weights::WeightInfo; @@ -98,27 +99,49 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { /// The caller has provided head of parachain that the pallet is not configured to track. - UntrackedParachainRejected { parachain: ParaId }, + UntrackedParachainRejected { + /// Identifier of the parachain that is not tracked by the pallet. + parachain: ParaId, + }, /// The caller has declared that he has provided given parachain head, but it is missing /// from the storage proof. - MissingParachainHead { parachain: ParaId }, + MissingParachainHead { + /// Identifier of the parachain with missing head. + parachain: ParaId, + }, /// The caller has provided parachain head hash that is not matching the hash read from the /// storage proof. IncorrectParachainHeadHash { + /// Identifier of the parachain with incorrect head hast. parachain: ParaId, + /// Specified parachain head hash. parachain_head_hash: ParaHash, + /// Actual parachain head hash. actual_parachain_head_hash: ParaHash, }, /// The caller has provided obsolete parachain head, which is already known to the pallet. - RejectedObsoleteParachainHead { parachain: ParaId, parachain_head_hash: ParaHash }, + RejectedObsoleteParachainHead { + /// Identifier of the parachain with obsolete head. + parachain: ParaId, + /// Obsolete parachain head hash. + parachain_head_hash: ParaHash, + }, /// The caller has provided parachain head that exceeds the maximal configured head size. RejectedLargeParachainHead { + /// Identifier of the parachain with rejected head. parachain: ParaId, + /// Parachain head hash. parachain_head_hash: ParaHash, + /// Parachain head size. parachain_head_size: u32, }, /// Parachain head has been updated. - UpdatedParachainHead { parachain: ParaId, parachain_head_hash: ParaHash }, + UpdatedParachainHead { + /// Identifier of the parachain that has been updated. + parachain: ParaId, + /// Parachain head hash. + parachain_head_hash: ParaHash, + }, } #[pallet::error] @@ -137,6 +160,7 @@ pub mod pallet { pub trait BoundedBridgeGrandpaConfig: pallet_bridge_grandpa::Config { + /// Type of the bridged relay chain. type BridgedRelayChain: Chain< BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, @@ -336,7 +360,7 @@ pub mod pallet { let mut storage = GrandpaPalletOf::::storage_proof_checker( relay_block_hash, - parachain_heads_proof.0, + parachain_heads_proof.storage_proof, ) .map_err(Error::::HeaderChainStorageProof)?; diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index 1c7851364d1..143f11d9863 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -16,7 +16,7 @@ use bp_header_chain::ChainWithGrandpa; use bp_polkadot_core::parachains::ParaId; -use bp_runtime::{Chain, Parachain}; +use bp_runtime::{Chain, ChainId, Parachain}; use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::ConstU32, weights::Weight, }; @@ -49,6 +49,8 @@ pub type BigParachainHeader = sp_runtime::generic::Header; pub struct Parachain1; impl Chain for Parachain1 { + const ID: ChainId = *b"pch1"; + type BlockNumber = u64; type Hash = H256; type Hasher = RegularParachainHasher; @@ -73,6 +75,8 @@ impl Parachain for Parachain1 { pub struct Parachain2; impl Chain for Parachain2 { + const ID: ChainId = *b"pch2"; + type BlockNumber = u64; type Hash = H256; type Hasher = RegularParachainHasher; @@ -97,6 +101,8 @@ impl Parachain for Parachain2 { pub struct Parachain3; impl Chain for Parachain3 { + const ID: ChainId = *b"pch3"; + type BlockNumber = u64; type Hash = H256; type Hasher = RegularParachainHasher; @@ -122,6 +128,8 @@ impl Parachain for Parachain3 { pub struct BigParachain; impl Chain for BigParachain { + const ID: ChainId = *b"bpch"; + type BlockNumber = u128; type Hash = H256; type Hasher = RegularParachainHasher; @@ -229,6 +237,8 @@ impl pallet_bridge_parachains::benchmarking::Config<()> for TestRuntime { pub struct TestBridgedChain; impl Chain for TestBridgedChain { + const ID: ChainId = *b"tbch"; + type BlockNumber = crate::RelayBlockNumber; type Hash = crate::RelayBlockHash; type Hasher = crate::RelayBlockHasher; @@ -260,6 +270,8 @@ impl ChainWithGrandpa for TestBridgedChain { pub struct OtherBridgedChain; impl Chain for OtherBridgedChain { + const ID: ChainId = *b"obch"; + type BlockNumber = u64; type Hash = crate::RelayBlockHash; type Hasher = crate::RelayBlockHasher; diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 3dd7459d30f..94ec8b5f106 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -42,12 +42,13 @@ type MessagesPallet = BridgeMessagesPallet>::BridgeMess impl, I: 'static> ExportXcm for Pallet where - T: BridgeMessagesConfig< - >::BridgeMessagesPalletInstance, - OutboundPayload = XcmAsPlainPayload, - >, + T: BridgeMessagesConfig, { - type Ticket = (SenderAndLane, XcmAsPlainPayload, XcmHash); + type Ticket = ( + SenderAndLane, + as MessagesBridge>::SendMessageArgs, + XcmHash, + ); fn validate( network: NetworkId, @@ -74,42 +75,38 @@ where message, )?; - Ok(((sender_and_lane, blob, id), price)) - } - - fn deliver( - (sender_and_lane, blob, id): (SenderAndLane, XcmAsPlainPayload, XcmHash), - ) -> Result { - let lane_id = sender_and_lane.lane; - let send_result = MessagesPallet::::send_message(lane_id, blob); - - match send_result { - Ok(artifacts) => { - log::info!( - target: LOG_TARGET, - "XCM message {:?} has been enqueued at bridge {:?} with nonce {}", - id, - lane_id, - artifacts.nonce, - ); - - // notify XCM queue manager about updated lane state - LocalXcmQueueManager::::on_bridge_message_enqueued( - &sender_and_lane, - artifacts.enqueued_messages, - ); - }, - Err(error) => { + let bridge_message = MessagesPallet::::validate_message(sender_and_lane.lane, &blob) + .map_err(|e| { log::debug!( target: LOG_TARGET, - "XCM message {:?} has been dropped because of bridge error {:?} on bridge {:?}", + "XCM message {:?} cannot be exported because of bridge error {:?} on bridge {:?}", id, - error, - lane_id, + e, + sender_and_lane.lane, ); - return Err(SendError::Transport("BridgeSendError")) - }, - } + SendError::Transport("BridgeValidateError") + })?; + + Ok(((sender_and_lane, bridge_message, id), price)) + } + + fn deliver((sender_and_lane, bridge_message, id): Self::Ticket) -> Result { + let lane_id = sender_and_lane.lane; + let artifacts = MessagesPallet::::send_message(bridge_message); + + log::info!( + target: LOG_TARGET, + "XCM message {:?} has been enqueued at bridge {:?} with nonce {}", + id, + lane_id, + artifacts.nonce, + ); + + // notify XCM queue manager about updated lane state + LocalXcmQueueManager::::on_bridge_message_enqueued( + &sender_and_lane, + artifacts.enqueued_messages, + ); Ok(id) } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 6708d4b789a..e40e1f9fb65 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -19,11 +19,10 @@ use crate as pallet_xcm_bridge_hub; use bp_messages::{ - source_chain::LaneMessageVerifier, target_chain::{DispatchMessage, MessageDispatch}, - LaneId, OutboundLaneData, VerificationError, + LaneId, }; -use bp_runtime::{messages::MessageDispatchResult, Chain, UnderlyingChainProvider}; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, UnderlyingChainProvider}; use bridge_runtime_common::{ messages::{ source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, @@ -78,20 +77,6 @@ impl pallet_balances::Config for TestRuntime { type AccountStore = System; } -/// Lane message verifier that is used in tests. -#[derive(Debug, Default)] -pub struct TestLaneMessageVerifier; - -impl LaneMessageVerifier> for TestLaneMessageVerifier { - fn verify_message( - _lane: &LaneId, - _lane_outbound_data: &OutboundLaneData, - _payload: &Vec, - ) -> Result<(), VerificationError> { - Ok(()) - } -} - parameter_types! { pub const ActiveOutboundLanes: &'static [LaneId] = &[TEST_LANE_ID]; } @@ -110,7 +95,6 @@ impl pallet_bridge_messages::Config for TestRuntime { type InboundRelayer = (); type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = TestLaneMessageVerifier; type DeliveryConfirmationPayments = (); type OnMessagesDelivered = (); type SourceHeaderChain = SourceHeaderChainAdapter; @@ -217,6 +201,7 @@ impl XcmBlobHauler for TestXcmBlobHauler { pub struct ThisChain; impl Chain for ThisChain { + const ID: ChainId = *b"tuch"; type BlockNumber = u64; type Hash = H256; type Hasher = BlakeTwo256; @@ -240,6 +225,7 @@ pub type BridgedHeaderHash = H256; pub type BridgedChainHeader = SubstrateHeader; impl Chain for BridgedChain { + const ID: ChainId = *b"tuch"; type BlockNumber = u64; type Hash = BridgedHeaderHash; type Hasher = BlakeTwo256; diff --git a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs index cd281324ee5..285f0020481 100644 --- a/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-cumulus/src/lib.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of all Cumulus-based bridge hubs. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_polkadot_core::{ @@ -61,6 +64,7 @@ const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(constants::WEIGHT_REF_TI pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); parameter_types! { + /// Size limit of the Cumulus-based bridge hub blocks. pub BlockLength: limits::BlockLength = limits::BlockLength::max_with_normal_ratio( 5 * 1024 * 1024, NORMAL_DISPATCH_RATIO, @@ -73,6 +77,7 @@ parameter_types! { pub const ExtrinsicBaseWeight: Weight = Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS, 0) .saturating_mul(125_000); + /// Weight limit of the Cumulus-based bridge hub blocks. pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder() .base_block(BlockExecutionWeight::get()) .for_class(DispatchClass::all(), |weights| { diff --git a/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs b/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs index 66e0dad0589..576e3dbee80 100644 --- a/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-kusama/src/lib.rs @@ -17,12 +17,13 @@ //! Module with configuration which reflects BridgeHubKusama runtime setup (AccountId, Headers, //! Hashes...) +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::{ dispatch::DispatchClass, @@ -35,6 +36,8 @@ use sp_runtime::RuntimeDebug; pub struct BridgeHubKusama; impl Chain for BridgeHubKusama { + const ID: ChainId = *b"bhks"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -61,6 +64,15 @@ impl Parachain for BridgeHubKusama { const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubKusama { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Public key of the chain account that may be used to verify signatures. pub type AccountSigner = MultiSigner; diff --git a/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs b/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs index c3661c1adca..6db389c9299 100644 --- a/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-polkadot/src/lib.rs @@ -17,12 +17,13 @@ //! Module with configuration which reflects BridgeHubPolkadot runtime setup //! (AccountId, Headers, Hashes...) +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; use sp_runtime::RuntimeDebug; @@ -32,6 +33,8 @@ use sp_runtime::RuntimeDebug; pub struct BridgeHubPolkadot; impl Chain for BridgeHubPolkadot { + const ID: ChainId = *b"bhpd"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -58,6 +61,16 @@ impl Parachain for BridgeHubPolkadot { const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubPolkadot { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Identifier of BridgeHubPolkadot in the Polkadot relay chain. pub const BRIDGE_HUB_POLKADOT_PARACHAIN_ID: u32 = 1002; diff --git a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs index f79b8a8afb3..7b109f30fe0 100644 --- a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs @@ -17,12 +17,13 @@ //! Module with configuration which reflects BridgeHubRococo runtime setup (AccountId, Headers, //! Hashes...) +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug}; @@ -32,6 +33,8 @@ use sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug}; pub struct BridgeHubRococo; impl Chain for BridgeHubRococo { + const ID: ChainId = *b"bhro"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -58,6 +61,16 @@ impl Parachain for BridgeHubRococo { const PARACHAIN_ID: u32 = BRIDGE_HUB_ROCOCO_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubRococo { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Public key of the chain account that may be used to verify signatures. pub type AccountSigner = MultiSigner; diff --git a/bridges/primitives/chain-bridge-hub-westend/Cargo.toml b/bridges/primitives/chain-bridge-hub-westend/Cargo.toml index beebfa8f1a0..cfd0c84eeec 100644 --- a/bridges/primitives/chain-bridge-hub-westend/Cargo.toml +++ b/bridges/primitives/chain-bridge-hub-westend/Cargo.toml @@ -14,8 +14,8 @@ workspace = true # Bridge Dependencies bp-bridge-hub-cumulus = { path = "../chain-bridge-hub-cumulus", default-features = false } -bp-runtime = { path = "../../primitives/runtime", default-features = false } -bp-messages = { path = "../../primitives/messages", default-features = false } +bp-runtime = { path = "../runtime", default-features = false } +bp-messages = { path = "../messages", default-features = false } # Substrate Based Dependencies diff --git a/bridges/primitives/chain-bridge-hub-westend/src/lib.rs b/bridges/primitives/chain-bridge-hub-westend/src/lib.rs index f4524f719f9..83d4d6e33a7 100644 --- a/bridges/primitives/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/primitives/chain-bridge-hub-westend/src/lib.rs @@ -22,7 +22,7 @@ pub use bp_bridge_hub_cumulus::*; use bp_messages::*; use bp_runtime::{ - decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain, }; use frame_support::dispatch::DispatchClass; use sp_runtime::RuntimeDebug; @@ -32,6 +32,8 @@ use sp_runtime::RuntimeDebug; pub struct BridgeHubWestend; impl Chain for BridgeHubWestend { + const ID: ChainId = *b"bhwd"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -58,6 +60,16 @@ impl Parachain for BridgeHubWestend { const PARACHAIN_ID: u32 = BRIDGE_HUB_WESTEND_PARACHAIN_ID; } +impl ChainWithMessages for BridgeHubWestend { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_BRIDGE_HUB_WESTEND_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Identifier of BridgeHubWestend in the Westend relay chain. pub const BRIDGE_HUB_WESTEND_PARACHAIN_ID: u32 = 1002; diff --git a/bridges/primitives/chain-kusama/src/lib.rs b/bridges/primitives/chain-kusama/src/lib.rs index 5f089fbc589..e3b4d0520f6 100644 --- a/bridges/primitives/chain-kusama/src/lib.rs +++ b/bridges/primitives/chain-kusama/src/lib.rs @@ -14,36 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Kusama chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; +use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; use frame_support::weights::Weight; /// Kusama Chain pub struct Kusama; impl Chain for Kusama { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"ksma"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } diff --git a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs index fe82c9644b6..f2eebf93124 100644 --- a/bridges/primitives/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/primitives/chain-polkadot-bulletin/src/lib.rs @@ -20,14 +20,14 @@ #![cfg_attr(not(feature = "std"), no_std)] use bp_header_chain::ChainWithGrandpa; -use bp_messages::MessageNonce; +use bp_messages::{ChainWithMessages, MessageNonce}; use bp_runtime::{ decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, extensions::{ CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema, }, - Chain, TransactionEra, + Chain, ChainId, TransactionEra, }; use codec::{Decode, Encode}; use frame_support::{ @@ -177,6 +177,8 @@ parameter_types! { pub struct PolkadotBulletin; impl Chain for PolkadotBulletin { + const ID: ChainId = *b"pdbc"; + type BlockNumber = BlockNumber; type Hash = Hash; type Hasher = Hasher; @@ -211,5 +213,15 @@ impl ChainWithGrandpa for PolkadotBulletin { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } +impl ChainWithMessages for PolkadotBulletin { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + WITH_POLKADOT_BULLETIN_MESSAGES_PALLET_NAME; + + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); decl_bridge_messages_runtime_apis!(polkadot_bulletin); diff --git a/bridges/primitives/chain-polkadot/src/lib.rs b/bridges/primitives/chain-polkadot/src/lib.rs index 9a5b8970acc..fc5e10308a8 100644 --- a/bridges/primitives/chain-polkadot/src/lib.rs +++ b/bridges/primitives/chain-polkadot/src/lib.rs @@ -14,36 +14,41 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Polkadot chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain}; +use bp_runtime::{ + decl_bridge_finality_runtime_apis, extensions::PrevalidateAttests, Chain, ChainId, +}; use frame_support::weights::Weight; /// Polkadot Chain pub struct Polkadot; impl Chain for Polkadot { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"pdot"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } diff --git a/bridges/primitives/chain-rococo/src/lib.rs b/bridges/primitives/chain-rococo/src/lib.rs index 7f3e762715f..f1b256f0f09 100644 --- a/bridges/primitives/chain-rococo/src/lib.rs +++ b/bridges/primitives/chain-rococo/src/lib.rs @@ -14,36 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Rococo chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; -use frame_support::{parameter_types, weights::Weight}; +use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; +use frame_support::weights::Weight; /// Rococo Chain pub struct Rococo; impl Chain for Rococo { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"roco"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } @@ -56,10 +59,6 @@ impl ChainWithGrandpa for Rococo { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -parameter_types! { - pub const SS58Prefix: u8 = 42; -} - // The SignedExtension used by Rococo. pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; diff --git a/bridges/primitives/chain-westend/src/lib.rs b/bridges/primitives/chain-westend/src/lib.rs index 7fa5e140d57..f03fd2160a7 100644 --- a/bridges/primitives/chain-westend/src/lib.rs +++ b/bridges/primitives/chain-westend/src/lib.rs @@ -14,36 +14,39 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Westend chain. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; use bp_header_chain::ChainWithGrandpa; -use bp_runtime::{decl_bridge_finality_runtime_apis, Chain}; -use frame_support::{parameter_types, weights::Weight}; +use bp_runtime::{decl_bridge_finality_runtime_apis, Chain, ChainId}; +use frame_support::weights::Weight; /// Westend Chain pub struct Westend; impl Chain for Westend { - type BlockNumber = ::BlockNumber; - type Hash = ::Hash; - type Hasher = ::Hasher; - type Header = ::Header; + const ID: ChainId = *b"wend"; + + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; - type AccountId = ::AccountId; - type Balance = ::Balance; - type Nonce = ::Nonce; - type Signature = ::Signature; + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; fn max_extrinsic_size() -> u32 { - PolkadotLike::max_extrinsic_size() + max_extrinsic_size() } fn max_extrinsic_weight() -> Weight { - PolkadotLike::max_extrinsic_weight() + max_extrinsic_weight() } } @@ -56,10 +59,6 @@ impl ChainWithGrandpa for Westend { const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE; } -parameter_types! { - pub const SS58Prefix: u8 = 42; -} - // The SignedExtension used by Westend. pub use bp_polkadot_core::CommonSignedExtension as SignedExtension; diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index 1459b1c1994..f5485aca1ee 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -17,6 +17,7 @@ //! Defines traits which represent a common interface for Substrate pallets which want to //! incorporate bridge functionality. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use crate::justification::{ @@ -145,6 +146,7 @@ pub trait ConsensusLogReader { pub struct GrandpaConsensusLogReader(sp_std::marker::PhantomData); impl GrandpaConsensusLogReader { + /// Find and return scheduled (regular) change digest item. pub fn find_scheduled_change( digest: &Digest, ) -> Option> { @@ -158,6 +160,8 @@ impl GrandpaConsensusLogReader { }) } + /// Find and return forced change digest item. Or light client can't do anything + /// with forced changes, so we can't accept header with the forced change digest. pub fn find_forced_change( digest: &Digest, ) -> Option<(Number, sp_consensus_grandpa::ScheduledChange)> { @@ -229,12 +233,17 @@ pub enum BridgeGrandpaCall { /// `pallet-bridge-grandpa::Call::submit_finality_proof` #[codec(index = 0)] submit_finality_proof { + /// The header that we are going to finalize. finality_target: Box
, + /// Finality justification for the `finality_target`. justification: justification::GrandpaJustification
, }, /// `pallet-bridge-grandpa::Call::initialize` #[codec(index = 1)] - initialize { init_data: InitializationData
}, + initialize { + /// All data, required to initialize the pallet. + init_data: InitializationData
, + }, } /// The `BridgeGrandpaCall` used by a chain. @@ -325,12 +334,15 @@ pub fn max_expected_submit_finality_proof_arguments_size( #[cfg(test)] mod tests { use super::*; + use bp_runtime::ChainId; use frame_support::weights::Weight; use sp_runtime::{testing::H256, traits::BlakeTwo256, MultiSignature}; struct TestChain; impl Chain for TestChain { + const ID: ChainId = *b"test"; + type BlockNumber = u32; type Hash = H256; type Hasher = BlakeTwo256; diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index e48914f7591..51b3f25f715 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -16,14 +16,13 @@ //! Primitives of messages module. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -// RuntimeApi generated functions -#![allow(clippy::too_many_arguments)] use bp_header_chain::HeaderChainError; use bp_runtime::{ - messages::MessageDispatchResult, BasicOperatingMode, OperatingMode, RangeInclusiveExt, - StorageProofError, + messages::MessageDispatchResult, BasicOperatingMode, Chain, OperatingMode, RangeInclusiveExt, + StorageProofError, UnderlyingChainOf, UnderlyingChainProvider, }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::PalletError; @@ -39,6 +38,36 @@ pub mod source_chain; pub mod storage_keys; pub mod target_chain; +/// Substrate-based chain with messaging support. +pub trait ChainWithMessages: Chain { + /// Name of the bridge messages pallet (used in `construct_runtime` macro call) that is + /// deployed at some other chain to bridge with this `ChainWithMessages`. + /// + /// We assume that all chains that are bridging with this `ChainWithMessages` are using + /// the same name. + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str; + + /// Maximal number of unrewarded relayers in a single confirmation transaction at this + /// `ChainWithMessages`. + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce; + /// Maximal number of unconfirmed messages in a single confirmation transaction at this + /// `ChainWithMessages`. + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce; +} + +impl ChainWithMessages for T +where + T: Chain + UnderlyingChainProvider, + UnderlyingChainOf: ChainWithMessages, +{ + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + UnderlyingChainOf::::WITH_CHAIN_MESSAGES_PALLET_NAME; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + UnderlyingChainOf::::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + UnderlyingChainOf::::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; +} + /// Messages pallet operating mode. #[derive( Encode, @@ -264,6 +293,7 @@ pub struct ReceivedMessages { } impl ReceivedMessages { + /// Creates new `ReceivedMessages` structure from given results. pub fn new( lane: LaneId, receive_results: Vec<(MessageNonce, ReceivalResult)>, @@ -271,6 +301,7 @@ impl ReceivedMessages { ReceivedMessages { lane, receive_results } } + /// Push `result` of the `message` delivery onto `receive_results` vector. pub fn push(&mut self, message: MessageNonce, result: ReceivalResult) { self.receive_results.push((message, result)); } @@ -342,7 +373,7 @@ pub struct UnrewardedRelayersState { } impl UnrewardedRelayersState { - // Verify that the relayers state corresponds with the `InboundLaneData`. + /// Verify that the relayers state corresponds with the `InboundLaneData`. pub fn is_valid(&self, lane_data: &InboundLaneData) -> bool { self == &lane_data.into() } @@ -423,15 +454,21 @@ pub enum BridgeMessagesCall { /// `pallet-bridge-messages::Call::receive_messages_proof` #[codec(index = 2)] receive_messages_proof { + /// Account id of relayer at the **bridged** chain. relayer_id_at_bridged_chain: AccountId, + /// Messages proof. proof: MessagesProof, + /// A number of messages in the proof. messages_count: u32, + /// Total dispatch weight of messages in the proof. dispatch_weight: Weight, }, /// `pallet-bridge-messages::Call::receive_messages_delivery_proof` #[codec(index = 3)] receive_messages_delivery_proof { + /// Messages delivery proof. proof: MessagesDeliveryProof, + /// "Digest" of unrewarded relayers state at the bridged chain. relayers_state: UnrewardedRelayersState, }, } diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index 73092c3cce0..f4aefd97355 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -16,7 +16,7 @@ //! Primitives of messages module, that are used on the source chain. -use crate::{InboundLaneData, LaneId, MessageNonce, OutboundLaneData, VerificationError}; +use crate::{InboundLaneData, LaneId, MessageNonce, VerificationError}; use crate::UnrewardedRelayer; use bp_runtime::Size; @@ -64,24 +64,6 @@ pub trait TargetHeaderChain { ) -> Result<(LaneId, InboundLaneData), VerificationError>; } -/// Lane message verifier. -/// -/// Runtime developer may implement any additional validation logic over message-lane mechanism. -/// E.g. if lanes should have some security (e.g. you can only accept Lane1 messages from -/// Submitter1, Lane2 messages for those who has submitted first message to this lane, disable -/// Lane3 until some block, ...), then it may be built using this verifier. -/// -/// Any fee requirements should also be enforced here. -pub trait LaneMessageVerifier { - /// Verify message payload and return Ok(()) if message is valid and allowed to be sent over the - /// lane. - fn verify_message( - lane: &LaneId, - outbound_data: &OutboundLaneData, - payload: &Payload, - ) -> Result<(), VerificationError>; -} - /// Manages payments that are happening at the source chain during delivery confirmation /// transaction. pub trait DeliveryConfirmationPayments { @@ -143,25 +125,25 @@ pub trait MessagesBridge { /// Error type. type Error: Debug; - /// Send message over the bridge. + /// Intermediary structure returned by `validate_message()`. /// - /// Returns unique message nonce or error if send has failed. - fn send_message(lane: LaneId, message: Payload) -> Result; -} - -/// Bridge that does nothing when message is being sent. -#[derive(Eq, RuntimeDebug, PartialEq)] -pub struct NoopMessagesBridge; + /// It can than be passed to `send_message()` in order to actually send the message + /// on the bridge. + type SendMessageArgs; -impl MessagesBridge for NoopMessagesBridge { - type Error = &'static str; + /// Check if the message can be sent over the bridge. + fn validate_message( + lane: LaneId, + message: &Payload, + ) -> Result; - fn send_message(_lane: LaneId, _message: Payload) -> Result { - Ok(SendMessageArtifacts { nonce: 0, enqueued_messages: 0 }) - } + /// Send message over the bridge. + /// + /// Returns unique message nonce or error if send has failed. + fn send_message(message: Self::SendMessageArgs) -> SendMessageArtifacts; } -/// Structure that may be used in place of `TargetHeaderChain`, `LaneMessageVerifier` and +/// Structure that may be used in place of `TargetHeaderChain` and /// `MessageDeliveryAndDispatchPayment` on chains, where outbound messages are forbidden. pub struct ForbidOutboundMessages; @@ -183,16 +165,6 @@ impl TargetHeaderChain for ForbidOutboun } } -impl LaneMessageVerifier for ForbidOutboundMessages { - fn verify_message( - _lane: &LaneId, - _outbound_data: &OutboundLaneData, - _payload: &Payload, - ) -> Result<(), VerificationError> { - Err(VerificationError::Other(ALL_OUTBOUND_MESSAGES_REJECTED)) - } -} - impl DeliveryConfirmationPayments for ForbidOutboundMessages { type Error = &'static str; diff --git a/bridges/primitives/parachains/src/lib.rs b/bridges/primitives/parachains/src/lib.rs index 262b9c6f977..692bbd99ece 100644 --- a/bridges/primitives/parachains/src/lib.rs +++ b/bridges/primitives/parachains/src/lib.rs @@ -16,6 +16,7 @@ //! Primitives of parachains module. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] pub use bp_header_chain::StoredHeaderData; @@ -173,8 +174,11 @@ pub enum BridgeParachainCall { /// `pallet-bridge-parachains::Call::submit_parachain_heads` #[codec(index = 0)] submit_parachain_heads { + /// Relay chain block, for which we have submitted the `parachain_heads_proof`. at_relay_block: (RelayBlockNumber, RelayBlockHash), + /// Parachain identifiers and their head hashes. parachains: Vec<(ParaId, ParaHash)>, + /// Parachain heads proof. parachain_heads_proof: ParaHeadsProof, }, } diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs index 586cbf8cb9b..df2836495bb 100644 --- a/bridges/primitives/polkadot-core/src/lib.rs +++ b/bridges/primitives/polkadot-core/src/lib.rs @@ -14,6 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +//! Primitives of the Polkadot-like chains. + +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use bp_messages::MessageNonce; @@ -24,7 +27,7 @@ use bp_runtime::{ CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension, SignedExtensionSchema, }, - Chain, EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, + EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra, }; use frame_support::{ dispatch::DispatchClass, @@ -40,7 +43,7 @@ use sp_core::{storage::StorageKey, Hasher as HasherT}; use sp_runtime::{ generic, traits::{BlakeTwo256, IdentifyAccount, Verify}, - MultiAddress, MultiSignature, OpaqueExtrinsic, RuntimeDebug, + MultiAddress, MultiSignature, OpaqueExtrinsic, }; use sp_std::prelude::Vec; @@ -173,11 +176,16 @@ pub use time_units::*; pub mod time_units { use super::BlockNumber; + /// Milliseconds between Polkadot-like chain blocks. pub const MILLISECS_PER_BLOCK: u64 = 6000; + /// Slot duration in Polkadot-like chain consensus algorithms. pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + /// A minute, expressed in Polkadot-like chain blocks. pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); + /// A hour, expressed in Polkadot-like chain blocks. pub const HOURS: BlockNumber = MINUTES * 60; + /// A day, expressed in Polkadot-like chain blocks. pub const DAYS: BlockNumber = HOURS * 24; } @@ -227,31 +235,17 @@ pub type UncheckedExtrinsic = /// Account address, used by the Polkadot-like chain. pub type Address = MultiAddress; -/// Polkadot-like chain. -#[derive(RuntimeDebug)] -pub struct PolkadotLike; - -impl Chain for PolkadotLike { - type BlockNumber = BlockNumber; - type Hash = Hash; - type Hasher = Hasher; - type Header = Header; - - type AccountId = AccountId; - type Balance = Balance; - type Nonce = Nonce; - type Signature = Signature; - - fn max_extrinsic_size() -> u32 { - *BlockLength::get().max.get(DispatchClass::Normal) - } +/// Returns maximal extrinsic size on all Polkadot-like chains. +pub fn max_extrinsic_size() -> u32 { + *BlockLength::get().max.get(DispatchClass::Normal) +} - fn max_extrinsic_weight() -> Weight { - BlockWeights::get() - .get(DispatchClass::Normal) - .max_extrinsic - .unwrap_or(Weight::MAX) - } +/// Returns maximal extrinsic weight on all Polkadot-like chains. +pub fn max_extrinsic_weight() -> Weight { + BlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic + .unwrap_or(Weight::MAX) } /// Provides a storage key for account data. @@ -271,8 +265,10 @@ impl StorageMapKeyProvider for AccountInfoStorageMapKeyProvider { } impl AccountInfoStorageMapKeyProvider { + /// Name of the system pallet. const PALLET_NAME: &'static str = "System"; + /// Return storage key for given account data. pub fn final_key(id: &AccountId) -> StorageKey { ::final_key(Self::PALLET_NAME, id) } diff --git a/bridges/primitives/polkadot-core/src/parachains.rs b/bridges/primitives/polkadot-core/src/parachains.rs index 223956171f8..433cd2845ab 100644 --- a/bridges/primitives/polkadot-core/src/parachains.rs +++ b/bridges/primitives/polkadot-core/src/parachains.rs @@ -89,11 +89,18 @@ pub type ParaHasher = crate::Hasher; /// Raw storage proof of parachain heads, stored in polkadot-like chain runtime. #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct ParaHeadsProof(pub RawStorageProof); +pub struct ParaHeadsProof { + /// Unverified storage proof of finalized parachain heads. + pub storage_proof: RawStorageProof, +} impl Size for ParaHeadsProof { fn size(&self) -> u32 { - u32::try_from(self.0.iter().fold(0usize, |sum, node| sum.saturating_add(node.len()))) - .unwrap_or(u32::MAX) + u32::try_from( + self.storage_proof + .iter() + .fold(0usize, |sum, node| sum.saturating_add(node.len())), + ) + .unwrap_or(u32::MAX) } } diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 81a2070bece..9ba21a1cddf 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::HeaderIdProvider; +use crate::{ChainId, HeaderIdProvider}; + use codec::{Codec, Decode, Encode, MaxEncodedLen}; use frame_support::{weights::Weight, Parameter}; use num_traits::{AsPrimitive, Bounded, CheckedSub, Saturating, SaturatingAdd, Zero}; @@ -99,6 +100,9 @@ impl Encode for EncodedOrDecodedCall { /// Minimal Substrate-based chain representation that may be used from no_std environment. pub trait Chain: Send + Sync + 'static { + /// Chain id. + const ID: ChainId; + /// A type that fulfills the abstract idea of what a Substrate block number is. // Constraits come from the associated Number type of `sp_runtime::traits::Header` // See here for more info: @@ -208,6 +212,8 @@ impl Chain for T where T: Send + Sync + 'static + UnderlyingChainProvider, { + const ID: ChainId = ::ID; + type BlockNumber = ::BlockNumber; type Hash = ::Hash; type Hasher = ::Hasher; diff --git a/bridges/primitives/runtime/src/extensions.rs b/bridges/primitives/runtime/src/extensions.rs index 8a618721b23..d896bc92eff 100644 --- a/bridges/primitives/runtime/src/extensions.rs +++ b/bridges/primitives/runtime/src/extensions.rs @@ -102,6 +102,7 @@ impl SignedExtensionSchema for Tuple { /// and signed payloads in the client code. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] pub struct GenericSignedExtension { + /// A payload that is included in the transaction. pub payload: S::Payload, #[codec(skip)] // It may be set to `None` if extensions are decoded. We are never reconstructing transactions @@ -112,6 +113,7 @@ pub struct GenericSignedExtension { } impl GenericSignedExtension { + /// Create new `GenericSignedExtension` object. pub fn new(payload: S::Payload, additional_signed: Option) -> Self { Self { payload, additional_signed } } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 0513cfa2a6c..850318923dc 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -16,6 +16,7 @@ //! Primitives that may be used at (bridges) runtime level. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; @@ -61,36 +62,6 @@ pub use sp_runtime::paste; /// Use this when something must be shared among all instances. pub const NO_INSTANCE_ID: ChainId = [0, 0, 0, 0]; -/// Polkadot chain id. -pub const POLKADOT_CHAIN_ID: ChainId = *b"pdot"; - -/// Polkadot Bulletin chain id. -pub const POLKADOT_BULLETIN_CHAIN_ID: ChainId = *b"pdbc"; - -/// Kusama chain id. -pub const KUSAMA_CHAIN_ID: ChainId = *b"ksma"; - -/// Westend chain id. -pub const WESTEND_CHAIN_ID: ChainId = *b"wend"; - -/// `AssetHubWestmint` chain id. -pub const ASSET_HUB_WESTEND_CHAIN_ID: ChainId = *b"ahwe"; - -/// Rococo chain id. -pub const ROCOCO_CHAIN_ID: ChainId = *b"roco"; - -/// BridgeHubRococo chain id. -pub const BRIDGE_HUB_ROCOCO_CHAIN_ID: ChainId = *b"bhro"; - -/// BridgeHubWestend chain id. -pub const BRIDGE_HUB_WESTEND_CHAIN_ID: ChainId = *b"bhwd"; - -/// BridgeHubKusama chain id. -pub const BRIDGE_HUB_KUSAMA_CHAIN_ID: ChainId = *b"bhks"; - -/// BridgeHubPolkadot chain id. -pub const BRIDGE_HUB_POLKADOT_CHAIN_ID: ChainId = *b"bhpd"; - /// Generic header Id. #[derive( RuntimeDebug, @@ -126,10 +97,10 @@ pub type HeaderIdOf = HeaderId, BlockNumberOf>; /// Generic header id provider. pub trait HeaderIdProvider { - // Get the header id. + /// Get the header id. fn id(&self) -> HeaderId; - // Get the header id for the parent block. + /// Get the header id for the parent block. fn parent_id(&self) -> Option>; } @@ -342,7 +313,7 @@ pub trait StorageDoubleMapKeyProvider { } /// Error generated by the `OwnedBridgeModule` trait. -#[derive(Encode, Decode, TypeInfo, PalletError)] +#[derive(Encode, Decode, PartialEq, Eq, TypeInfo, PalletError)] pub enum OwnedBridgeModuleError { /// All pallet operations are halted. Halted, @@ -350,7 +321,7 @@ pub enum OwnedBridgeModuleError { /// Operating mode for a bridge module. pub trait OperatingMode: Send + Copy + Debug + FullCodec { - // Returns true if the bridge module is halted. + /// Returns true if the bridge module is halted. fn is_halted(&self) -> bool; } @@ -392,8 +363,11 @@ pub trait OwnedBridgeModule { /// The target that will be used when publishing logs related to this module. const LOG_TARGET: &'static str; + /// A storage entry that holds the module `Owner` account. type OwnerStorage: StorageValue>; + /// Operating mode type of the pallet. type OperatingMode: OperatingMode; + /// A storage value that holds the pallet operating mode. type OperatingModeStorage: StorageValue; /// Check if the module is halted. @@ -469,9 +443,11 @@ impl WeightExtraOps for Weight { /// Trait that provides a static `str`. pub trait StaticStrProvider { + /// Static string. const STR: &'static str; } +/// A macro that generates `StaticStrProvider` with the string set to its stringified argument. #[macro_export] macro_rules! generate_static_str_provider { ($str:expr) => { @@ -485,6 +461,7 @@ macro_rules! generate_static_str_provider { }; } +/// Error message that is only dispayable in `std` environment. #[derive(Encode, Decode, Clone, Eq, PartialEq, PalletError, TypeInfo)] #[scale_info(skip_type_params(T))] pub struct StrippableError { diff --git a/bridges/primitives/test-utils/src/keyring.rs b/bridges/primitives/test-utils/src/keyring.rs index eabf9c784eb..22691183acf 100644 --- a/bridges/primitives/test-utils/src/keyring.rs +++ b/bridges/primitives/test-utils/src/keyring.rs @@ -24,12 +24,17 @@ use sp_consensus_grandpa::{AuthorityId, AuthorityList, AuthorityWeight, SetId}; use sp_runtime::RuntimeDebug; use sp_std::prelude::*; -/// Set of test accounts with friendly names. +/// Set of test accounts with friendly names: Alice. pub const ALICE: Account = Account(0); +/// Set of test accounts with friendly names: Bob. pub const BOB: Account = Account(1); +/// Set of test accounts with friendly names: Charlie. pub const CHARLIE: Account = Account(2); +/// Set of test accounts with friendly names: Dave. pub const DAVE: Account = Account(3); +/// Set of test accounts with friendly names: Eve. pub const EVE: Account = Account(4); +/// Set of test accounts with friendly names: Ferdie. pub const FERDIE: Account = Account(5); /// A test account which can be used to sign messages. @@ -37,10 +42,12 @@ pub const FERDIE: Account = Account(5); pub struct Account(pub u16); impl Account { + /// Returns public key of this account. pub fn public(&self) -> VerifyingKey { self.pair().verifying_key() } + /// Returns key pair, used to sign data on behalf of this account. pub fn pair(&self) -> SigningKey { let data = self.0.encode(); let mut bytes = [0_u8; 32]; @@ -48,6 +55,7 @@ impl Account { SigningKey::from_bytes(&bytes) } + /// Generate a signature of given message. pub fn sign(&self, msg: &[u8]) -> Signature { use ed25519_dalek::Signer; self.pair().sign(msg) diff --git a/bridges/primitives/test-utils/src/lib.rs b/bridges/primitives/test-utils/src/lib.rs index 4d3b8475993..f23ddd1a10d 100644 --- a/bridges/primitives/test-utils/src/lib.rs +++ b/bridges/primitives/test-utils/src/lib.rs @@ -16,6 +16,7 @@ //! Utilities for testing runtime code. +#![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] use bp_header_chain::justification::{required_justification_precommits, GrandpaJustification}; @@ -33,8 +34,11 @@ pub use keyring::*; mod keyring; +/// GRANDPA round number used across tests. pub const TEST_GRANDPA_ROUND: u64 = 1; +/// GRANDPA validators set id used across tests. pub const TEST_GRANDPA_SET_ID: SetId = 1; +/// Name of the `Paras` pallet used across tests. pub const PARAS_PALLET_NAME: &str = "Paras"; /// Configuration parameters when generating test GRANDPA justifications. @@ -190,7 +194,7 @@ pub fn prepare_parachain_heads_proof( .map_err(|_| "record_all_trie_keys has failed") .expect("record_all_trie_keys should not fail in benchmarks"); - (root, ParaHeadsProof(storage_proof), parachains) + (root, ParaHeadsProof { storage_proof }, parachains) } /// Create signed precommit with given target. diff --git a/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml b/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml index 59efcf91fd0..2bf5bfcd12f 100644 --- a/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/ethereum-client/Cargo.toml @@ -38,7 +38,7 @@ snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } primitives = { package = "snowbridge-beacon-primitives", path = "../../primitives/beacon", default-features = false } static_assertions = { version = "1.1.0", default-features = false } -bp-runtime = { path = "../../../../../bridges/primitives/runtime", default-features = false } +bp-runtime = { path = "../../../../primitives/runtime", default-features = false } pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false, optional = true } [dev-dependencies] diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml index f645b4224d1..8101ecd5a48 100644 --- a/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/inbound-queue/Cargo.toml @@ -47,7 +47,7 @@ snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-featu frame-benchmarking = { path = "../../../../../substrate/frame/benchmarking" } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } snowbridge-beacon-primitives = { path = "../../primitives/beacon" } -snowbridge-pallet-ethereum-client = { path = "../../pallets/ethereum-client" } +snowbridge-pallet-ethereum-client = { path = "../ethereum-client" } hex-literal = { version = "0.4.1" } [features] diff --git a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml index de4487553cb..e499ab88729 100644 --- a/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/parachain/pallets/outbound-queue/Cargo.toml @@ -31,7 +31,7 @@ sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", defau bridge-hub-common = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/common", default-features = false } -snowbridge-core = { path = "../../primitives/core", features = ["serde"], default-features = false } +snowbridge-core = { path = "../../primitives/core", default-features = false, features = ["serde"] } snowbridge-outbound-queue-merkle-tree = { path = "merkle-tree", default-features = false } ethabi = { git = "https://github.com/snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } diff --git a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml index 8294e903dfb..87f13ad5f6e 100644 --- a/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/beacon/Cargo.toml @@ -29,7 +29,7 @@ ssz_rs = { version = "0.9.0", default-features = false } ssz_rs_derive = { version = "0.9.0", default-features = false } byte-slice-cast = { version = "1.2.1", default-features = false } -snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } +snowbridge-ethereum = { path = "../ethereum", default-features = false } static_assertions = { version = "1.1.0" } milagro_bls = { git = "https://github.com/snowfork/milagro_bls", default-features = false, rev = "a6d66e4eb89015e352fb1c9f7b661ecdbb5b2176" } diff --git a/bridges/snowbridge/parachain/primitives/core/Cargo.toml b/bridges/snowbridge/parachain/primitives/core/Cargo.toml index 1cb28eb3e50..a4092b4ee6f 100644 --- a/bridges/snowbridge/parachain/primitives/core/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/core/Cargo.toml @@ -29,7 +29,7 @@ sp-io = { path = "../../../../../substrate/primitives/io", default-features = fa sp-core = { path = "../../../../../substrate/primitives/core", default-features = false } sp-arithmetic = { path = "../../../../../substrate/primitives/arithmetic", default-features = false } -snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false } +snowbridge-beacon-primitives = { path = "../beacon", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } diff --git a/bridges/snowbridge/parachain/primitives/router/Cargo.toml b/bridges/snowbridge/parachain/primitives/router/Cargo.toml index 65133128ef4..ed8f68d7bc0 100644 --- a/bridges/snowbridge/parachain/primitives/router/Cargo.toml +++ b/bridges/snowbridge/parachain/primitives/router/Cargo.toml @@ -28,7 +28,7 @@ xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-f xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false } xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false } -snowbridge-core = { path = "../../primitives/core", default-features = false } +snowbridge-core = { path = "../core", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } diff --git a/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml b/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml index ae72de406fc..bf7791bbabe 100644 --- a/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/parachain/runtime/test-common/Cargo.toml @@ -90,7 +90,7 @@ snowbridge-system-runtime-api = { path = "../../pallets/system/runtime-api", def [dev-dependencies] static_assertions = "1.1" bridge-hub-test-utils = { path = "../../../../../cumulus/parachains/runtimes/bridge-hubs/test-utils" } -bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", features = ["integrity-test"] } +bridge-runtime-common = { path = "../../../../bin/runtime-common", features = ["integrity-test"] } sp-keyring = { path = "../../../../../substrate/primitives/keyring" } [features] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 1c7bdd4cbff..7630c2bf99b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -27,6 +27,7 @@ use crate::{ RuntimeEvent, XcmOverRococoBulletin, XcmRouter, }; use bp_messages::LaneId; +use bp_runtime::Chain; use bridge_runtime_common::{ messages, messages::{ @@ -63,7 +64,7 @@ parameter_types! { pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_polkadot_bulletin::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; /// Bridge specific chain (network) identifier of the Rococo Bulletin Chain. - pub const RococoBulletinChainId: bp_runtime::ChainId = bp_runtime::POLKADOT_BULLETIN_CHAIN_ID; + pub const RococoBulletinChainId: bp_runtime::ChainId = bp_polkadot_bulletin::PolkadotBulletin::ID; /// Interior location (relative to this runtime) of the with-RococoBulletin messages pallet. pub BridgeRococoToRococoBulletinMessagesPalletInstance: InteriorLocation = [ PalletInstance(::index() as u8) @@ -151,10 +152,6 @@ impl MessageBridge for WithRococoBulletinMessageBridge { type BridgedHeaderChain = BridgeRococoBulletinGrandpa; } -/// Message verifier for RococoBulletin messages sent from BridgeHubRococo. -pub type ToRococoBulletinMessageVerifier = - messages::source::FromThisChainMessageVerifier; - /// Maximal outbound payload size of BridgeHubRococo -> RococoBulletin messages. pub type ToRococoBulletinMaximalOutboundPayloadSize = messages::source::FromThisChainMaximalOutboundPayloadSize; @@ -205,7 +202,6 @@ impl pallet_bridge_messages::Config for Runt type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = ToRococoBulletinMessageVerifier; type DeliveryConfirmationPayments = (); type SourceHeaderChain = SourceHeaderChainAdapter; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 4e8fe6454cc..697386b6a7d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -26,6 +26,7 @@ use crate::{ XcmRouter, }; use bp_messages::LaneId; +use bp_runtime::Chain; use bridge_runtime_common::{ messages, messages::{ @@ -57,7 +58,7 @@ parameter_types! { bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - pub const BridgeHubWestendChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; + pub const BridgeHubWestendChainId: bp_runtime::ChainId = BridgeHubWestend::ID; pub BridgeRococoToWestendMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub WestendGlobalConsensusNetwork: NetworkId = NetworkId::Westend; pub WestendGlobalConsensusNetworkLocation: Location = Location::new( @@ -157,10 +158,6 @@ impl MessageBridge for WithBridgeHubWestendMessageBridge { >; } -/// Message verifier for BridgeHubWestend messages sent from BridgeHubRococo -pub type ToBridgeHubWestendMessageVerifier = - messages::source::FromThisChainMessageVerifier; - /// Maximal outbound payload size of BridgeHubRococo -> BridgeHubWestend messages. pub type ToBridgeHubWestendMaximalOutboundPayloadSize = messages::source::FromThisChainMaximalOutboundPayloadSize; @@ -212,7 +209,6 @@ impl pallet_bridge_messages::Config for Ru type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = ToBridgeHubWestendMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubWestendMessagesInstance, @@ -309,7 +305,7 @@ mod tests { bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, max_unconfirmed_messages_in_bridged_confirmation_tx: bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, - bridged_chain_id: bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID, + bridged_chain_id: BridgeHubWestend::ID, }, pallet_names: AssertBridgePalletNames { with_this_chain_messages_pallet_name: diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 09aeedfc223..f84ff0799b9 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -70,6 +70,8 @@ use frame_system::{ EnsureRoot, }; +#[cfg(feature = "runtime-benchmarks")] +use bp_runtime::Chain; use bp_runtime::HeaderId; use bridge_hub_common::{ message_queue::{NarrowOriginToSibling, ParaIdToSibling}, @@ -1275,7 +1277,7 @@ impl_runtime_apis! { impl BridgeMessagesConfig for Runtime { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { let bench_lane_id = >::bench_lane_id(); - let bridged_chain_id = bp_runtime::BRIDGE_HUB_WESTEND_CHAIN_ID; + let bridged_chain_id = bp_bridge_hub_westend::BridgeHubWestend::ID; pallet_bridge_relayers::Pallet::::relayer_reward( relayer, bp_relayers::RewardsAccountParams::new( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 716e01b85b4..c0c0976b52f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -23,6 +23,7 @@ use crate::{ }; use bp_messages::LaneId; use bp_parachains::SingleParaStoredHeaderDataBuilder; +use bp_runtime::Chain; use bridge_runtime_common::{ messages, messages::{ @@ -62,7 +63,7 @@ parameter_types! { bp_bridge_hub_westend::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = bp_bridge_hub_westend::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; - pub const BridgeHubRococoChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; + pub const BridgeHubRococoChainId: bp_runtime::ChainId = BridgeHubRococo::ID; pub BridgeWestendToRococoMessagesPalletInstance: InteriorLocation = [PalletInstance(::index() as u8)].into(); pub RococoGlobalConsensusNetwork: NetworkId = NetworkId::Rococo; pub RococoGlobalConsensusNetworkLocation: Location = Location::new( @@ -162,10 +163,6 @@ impl MessageBridge for WithBridgeHubRococoMessageBridge { >; } -/// Message verifier for BridgeHubRococo messages sent from BridgeHubWestend -type ToBridgeHubRococoMessageVerifier = - messages::source::FromThisChainMessageVerifier; - /// Maximal outbound payload size of BridgeHubWestend -> BridgeHubRococo messages. type ToBridgeHubRococoMaximalOutboundPayloadSize = messages::source::FromThisChainMaximalOutboundPayloadSize; @@ -249,7 +246,6 @@ impl pallet_bridge_messages::Config for Run type DeliveryPayments = (); type TargetHeaderChain = TargetHeaderChainAdapter; - type LaneMessageVerifier = ToBridgeHubRococoMessageVerifier; type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubRococoMessagesInstance, @@ -344,7 +340,7 @@ mod tests { bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, max_unconfirmed_messages_in_bridged_confirmation_tx: bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, - bridged_chain_id: bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID, + bridged_chain_id: BridgeHubRococo::ID, }, pallet_names: AssertBridgePalletNames { with_this_chain_messages_pallet_name: diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 55a38fc8543..e90b5668c03 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -69,6 +69,8 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::{MultiAddress, Perbill, Permill}; use xcm_config::{XcmOriginToTransactDispatchOrigin, XcmRouter}; +#[cfg(feature = "runtime-benchmarks")] +use bp_runtime::Chain; use bp_runtime::HeaderId; #[cfg(any(feature = "std", test))] @@ -974,7 +976,7 @@ impl_runtime_apis! { impl BridgeMessagesConfig for Runtime { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { let bench_lane_id = >::bench_lane_id(); - let bridged_chain_id = bp_runtime::BRIDGE_HUB_ROCOCO_CHAIN_ID; + let bridged_chain_id = bp_bridge_hub_rococo::BridgeHubRococo::ID; pallet_bridge_relayers::Pallet::::relayer_reward( relayer, bp_relayers::RewardsAccountParams::new( -- GitLab From e02c5204b3c26f0b4423304f027408f73e97d0ef Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Fri, 19 Jan 2024 20:36:16 +0100 Subject: [PATCH 040/283] Update Wasm benchmarks (#2957) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In https://github.com/paritytech/polkadot-sdk/pull/2941 we found out that the new Wasmi (register) is very effective at optimizing away certain benchmark bytecode constructs in a way that created an unfair advantage over Wasmi (stack) which yielded our former benchmarks to be ineffective at properly measuring the performance impact. This PR adjusts both affected benchmarks to fix the stated problems. Affected are - `instr_i64const` -> `instr_i64add`: Renamed since it now measures the performance impact of the Wasm `i64.add` instruction with locals as inputs and outputs. This makes it impossible for Wasmi (register) to aggressively optimize away the entire function body (as it previously did) but still provides a way for Wasmi (register) to shine with its register based execution model. - `call_with_code_per_byte`: Now uses `local.get` instead of `i32.const` for the `if` condition which prevents Wasmi (register) to aggressively optimizing away whole parts of the `if` creating an unfair advantage. cc @athei --------- Co-authored-by: command-bot <> Co-authored-by: Alexander Theißen Co-authored-by: Ignacio Palacios --- .../frame/contracts/src/benchmarking/code.rs | 46 +- .../frame/contracts/src/benchmarking/mod.rs | 46 +- substrate/frame/contracts/src/schedule.rs | 22 +- substrate/frame/contracts/src/weights.rs | 1240 +++++++++-------- 4 files changed, 697 insertions(+), 657 deletions(-) diff --git a/substrate/frame/contracts/src/benchmarking/code.rs b/substrate/frame/contracts/src/benchmarking/code.rs index 2f50611b41c..0b6ab6b3c0e 100644 --- a/substrate/frame/contracts/src/benchmarking/code.rs +++ b/substrate/frame/contracts/src/benchmarking/code.rs @@ -31,8 +31,8 @@ use sp_std::{borrow::ToOwned, prelude::*}; use wasm_instrument::parity_wasm::{ builder, elements::{ - self, BlockType, CustomSection, External, FuncBody, Instruction, Instructions, Module, - Section, ValueType, + self, BlockType, CustomSection, External, FuncBody, Instruction, Instructions, Local, + Module, Section, ValueType, }, }; @@ -281,17 +281,21 @@ impl WasmModule { /// instrumentation runtime by nesting blocks as deeply as possible given the byte budget. /// `code_location`: Whether to place the code into `deploy` or `call`. pub fn sized(target_bytes: u32, code_location: Location) -> Self { - use self::elements::Instruction::{End, I32Const, If, Return}; + use self::elements::Instruction::{End, GetLocal, If, Return}; // Base size of a contract is 63 bytes and each expansion adds 6 bytes. // We do one expansion less to account for the code section and function body // size fields inside the binary wasm module representation which are leb128 encoded // and therefore grow in size when the contract grows. We are not allowed to overshoot // because of the maximum code size that is enforced by `instantiate_with_code`. let expansions = (target_bytes.saturating_sub(63) / 6).saturating_sub(1); - const EXPANSION: [Instruction; 4] = [I32Const(0), If(BlockType::NoResult), Return, End]; + const EXPANSION: [Instruction; 4] = [GetLocal(0), If(BlockType::NoResult), Return, End]; let mut module = ModuleDefinition { memory: Some(ImportedMemory::max::()), ..Default::default() }; - let body = Some(body::repeated(expansions, &EXPANSION)); + let body = Some(body::repeated_with_locals( + &[Local::new(1, ValueType::I32)], + expansions, + &EXPANSION, + )); match code_location { Location::Call => module.call_body = body, Location::Deploy => module.deploy_body = body, @@ -373,8 +377,6 @@ pub mod body { /// Insert a I32Const with incrementing value for each insertion. /// (start_at, increment_by) Counter(u32, u32), - /// Insert the specified amount of I64Const with a random value. - RandomI64Repeated(usize), } pub fn plain(instructions: Vec) -> FuncBody { @@ -382,6 +384,14 @@ pub mod body { } pub fn repeated(repetitions: u32, instructions: &[Instruction]) -> FuncBody { + repeated_with_locals(&[], repetitions, instructions) + } + + pub fn repeated_with_locals( + locals: &[Local], + repetitions: u32, + instructions: &[Instruction], + ) -> FuncBody { let instructions = Instructions::new( instructions .iter() @@ -391,15 +401,23 @@ pub mod body { .chain(sp_std::iter::once(Instruction::End)) .collect(), ); - FuncBody::new(Vec::new(), instructions) + FuncBody::new(locals.to_vec(), instructions) } - pub fn repeated_dyn(repetitions: u32, mut instructions: Vec) -> FuncBody { - use rand::{distributions::Standard, prelude::*}; - - // We do not need to be secure here. - let mut rng = rand_pcg::Pcg32::seed_from_u64(8446744073709551615); + pub fn repeated_with_locals_using( + locals: &[Local], + repetitions: u32, + mut f: impl FnMut() -> [Instruction; N], + ) -> FuncBody { + let mut instructions = Vec::new(); + for _ in 0..repetitions { + instructions.extend(f()); + } + instructions.push(Instruction::End); + FuncBody::new(locals.to_vec(), Instructions::new(instructions)) + } + pub fn repeated_dyn(repetitions: u32, mut instructions: Vec) -> FuncBody { // We need to iterate over indices because we cannot cycle over mutable references let body = (0..instructions.len()) .cycle() @@ -411,8 +429,6 @@ pub mod body { *offset += *increment_by; vec![Instruction::I32Const(current as i32)] }, - DynInstr::RandomI64Repeated(num) => - (&mut rng).sample_iter(Standard).take(*num).map(Instruction::I64Const).collect(), }) .chain(sp_std::iter::once(Instruction::End)) .collect(); diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index 3ab76d6112a..f68f51c2906 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -48,7 +48,7 @@ use pallet_balances; use pallet_contracts_uapi::CallFlags; use sp_runtime::traits::{Bounded, Hash}; use sp_std::prelude::*; -use wasm_instrument::parity_wasm::elements::{BlockType, Instruction, ValueType}; +use wasm_instrument::parity_wasm::elements::{BlockType, Instruction, Local, ValueType}; /// How many runs we do per API benchmark. /// @@ -2582,19 +2582,45 @@ benchmarks! { let origin = RawOrigin::Signed(instance.caller.clone()); }: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![]) - // We make the assumption that pushing a constant and dropping a value takes roughly - // the same amount of time. We call this weight `w_base`. - // The weight that would result from the respective benchmark we call: `w_bench`. + // We load `i64` values from random linear memory locations and store the loaded + // values back into yet another random linear memory location. + // The random addresses are uniformely distributed across the entire span of the linear memory. + // We do this to enforce random memory accesses which are particularly expensive. // - // w_base = w_i{32,64}const = w_drop = w_bench / 2 + // The combination of this computation is our weight base `w_base`. #[pov_mode = Ignored] - instr_i64const { + instr_i64_load_store { let r in 0 .. INSTR_BENCHMARK_RUNS; + + use rand::prelude::*; + + // We do not need to be secure here. Fixed seed allows for determinstic results. + let mut rng = rand_pcg::Pcg32::seed_from_u64(8446744073709551615); + + let memory = ImportedMemory::max::(); + let bytes_per_page = 65536; + let bytes_per_memory = memory.max_pages * bytes_per_page; let mut sbox = Sandbox::from(&WasmModule::::from(ModuleDefinition { - call_body: Some(body::repeated_dyn(r, vec![ - RandomI64Repeated(1), - Regular(Instruction::Drop), - ])), + memory: Some(memory), + call_body: Some(body::repeated_with_locals_using( + &[Local::new(1, ValueType::I64)], + r, + || { + // Instruction sequence to load a `i64` from linear memory + // at a random memory location and store it back into another + // location of the linear memory. + let c0: i32 = rng.gen_range(0..bytes_per_memory as i32); + let c1: i32 = rng.gen_range(0..bytes_per_memory as i32); + [ + Instruction::I32Const(c0), // address for `i64.load_8s` + Instruction::I64Load8S(0, 0), + Instruction::SetLocal(0), // temporarily store value loaded in `i64.load_8s` + Instruction::I32Const(c1), // address for `i64.store8` + Instruction::GetLocal(0), // value to be stores in `i64.store8` + Instruction::I64Store8(0, 0), + ] + } + )), .. Default::default() })); }: { diff --git a/substrate/frame/contracts/src/schedule.rs b/substrate/frame/contracts/src/schedule.rs index 5ca18af026a..9fa5217da43 100644 --- a/substrate/frame/contracts/src/schedule.rs +++ b/substrate/frame/contracts/src/schedule.rs @@ -358,25 +358,12 @@ macro_rules! cost_args { } } -macro_rules! cost_instr_no_params { - ($name:ident) => { - cost_args!($name, 1).ref_time() as u32 - }; -} - macro_rules! cost { ($name:ident) => { cost_args!($name, 1) }; } -macro_rules! cost_instr { - ($name:ident, $num_params:expr) => { - cost_instr_no_params!($name) - .saturating_sub((cost_instr_no_params!(instr_i64const) / 2).saturating_mul($num_params)) - }; -} - impl Default for Limits { fn default() -> Self { Self { @@ -396,10 +383,13 @@ impl Default for Limits { } impl Default for InstructionWeights { - /// We price both `i64.const` and `drop` as `instr_i64const / 2`. The reason - /// for that is that we cannot benchmark either of them on its own. + /// We execute 6 different instructions therefore we have to divide the actual + /// computed gas costs by 6 to have a rough estimate as to how expensive each + /// single executed instruction is going to be. fn default() -> Self { - Self { base: cost_instr!(instr_i64const, 1), _phantom: PhantomData } + let instr_cost = cost!(instr_i64_load_store).ref_time() as u32; + let base = instr_cost / 6; + Self { base, _phantom: PhantomData } } } diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index 622d1e8a9b7..fa9df922a7c 100644 --- a/substrate/frame/contracts/src/weights.rs +++ b/substrate/frame/contracts/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_contracts` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-01-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` @@ -129,7 +129,7 @@ pub trait WeightInfo { fn seal_reentrance_count(r: u32, ) -> Weight; fn seal_account_reentrance_count(r: u32, ) -> Weight; fn seal_instantiation_nonce(r: u32, ) -> Weight; - fn instr_i64const(r: u32, ) -> Weight; + fn instr_i64_load_store(r: u32, ) -> Weight; } /// Weights for `pallet_contracts` using the Substrate node and recommended hardware. @@ -141,8 +141,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 1_991_000 picoseconds. - Weight::from_parts(2_135_000, 1627) + // Minimum execution time: 1_997_000 picoseconds. + Weight::from_parts(2_130_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -152,10 +152,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 11_969_000 picoseconds. - Weight::from_parts(7_055_855, 442) - // Standard Error: 2_328 - .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) + // Minimum execution time: 12_276_000 picoseconds. + Weight::from_parts(1_593_881, 442) + // Standard Error: 1_135 + .saturating_add(Weight::from_parts(1_109_302, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -169,10 +169,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_064_000 picoseconds. - Weight::from_parts(8_301_148, 6149) + // Minimum execution time: 8_176_000 picoseconds. + Weight::from_parts(8_555_388, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -185,8 +185,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 15_789_000 picoseconds. - Weight::from_parts(16_850_000, 6450) + // Minimum execution time: 16_270_000 picoseconds. + Weight::from_parts(16_779_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -199,10 +199,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_369_000 picoseconds. - Weight::from_parts(3_516_000, 3635) - // Standard Error: 960 - .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) + // Minimum execution time: 3_572_000 picoseconds. + Weight::from_parts(1_950_905, 3635) + // Standard Error: 1_597 + .saturating_add(Weight::from_parts(1_123_190, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -221,10 +221,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 16_320_000 picoseconds. - Weight::from_parts(16_090_036, 6263) + // Minimum execution time: 16_873_000 picoseconds. + Weight::from_parts(16_790_402, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(396, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -235,8 +235,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_669_000 picoseconds. - Weight::from_parts(13_118_000, 6380) + // Minimum execution time: 11_904_000 picoseconds. + Weight::from_parts(12_785_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -250,8 +250,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 45_403_000 picoseconds. - Weight::from_parts(46_636_000, 6292) + // Minimum execution time: 44_920_000 picoseconds. + Weight::from_parts(46_163_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -263,8 +263,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 53_622_000 picoseconds. - Weight::from_parts(55_444_000, 6534) + // Minimum execution time: 53_864_000 picoseconds. + Weight::from_parts(55_139_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -274,8 +274,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_444_000 picoseconds. - Weight::from_parts(2_587_000, 1627) + // Minimum execution time: 2_375_000 picoseconds. + Weight::from_parts(2_487_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -287,8 +287,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 11_476_000 picoseconds. - Weight::from_parts(11_944_000, 3631) + // Minimum execution time: 11_580_000 picoseconds. + Weight::from_parts(11_980_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -298,8 +298,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_652_000 picoseconds. - Weight::from_parts(4_792_000, 3607) + // Minimum execution time: 4_557_000 picoseconds. + Weight::from_parts(4_807_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -310,8 +310,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_054_000 picoseconds. - Weight::from_parts(6_278_000, 3632) + // Minimum execution time: 6_253_000 picoseconds. + Weight::from_parts(6_479_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -322,8 +322,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_056_000 picoseconds. - Weight::from_parts(6_343_000, 3607) + // Minimum execution time: 6_166_000 picoseconds. + Weight::from_parts(6_545_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -344,12 +344,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `c` is `[0, 125952]`. fn call_with_code_per_byte(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `792` - // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 303_205_000 picoseconds. - Weight::from_parts(266_154_889, 6743) - // Standard Error: 79 - .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) + // Measured: `801 + c * (1 ±0)` + // Estimated: `6739 + c * (1 ±0)` + // Minimum execution time: 282_232_000 picoseconds. + Weight::from_parts(266_148_573, 6739) + // Standard Error: 69 + .saturating_add(Weight::from_parts(34_592, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -378,15 +378,15 @@ impl WeightInfo for SubstrateWeight { fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `323` - // Estimated: `8747` - // Minimum execution time: 4_311_802_000 picoseconds. - Weight::from_parts(777_467_048, 8747) - // Standard Error: 338 - .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) + // Estimated: `8737` + // Minimum execution time: 3_760_879_000 picoseconds. + Weight::from_parts(794_812_431, 8737) + // Standard Error: 149 + .saturating_add(Weight::from_parts(101_881, 0).saturating_mul(c.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_404, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_544, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -414,12 +414,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 1_958_694_000 picoseconds. - Weight::from_parts(331_222_273, 6504) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) + // Minimum execution time: 1_953_162_000 picoseconds. + Weight::from_parts(374_252_840, 6504) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_630, 0).saturating_mul(i.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -441,8 +441,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 194_513_000 picoseconds. - Weight::from_parts(201_116_000, 6766) + // Minimum execution time: 187_899_000 picoseconds. + Weight::from_parts(195_510_000, 6766) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -461,10 +461,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 269_777_000 picoseconds. - Weight::from_parts(204_229_027, 3607) - // Standard Error: 152 - .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) + // Minimum execution time: 254_800_000 picoseconds. + Weight::from_parts(285_603_050, 3607) + // Standard Error: 62 + .saturating_add(Weight::from_parts(66_212, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -482,8 +482,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 43_271_000 picoseconds. - Weight::from_parts(44_884_000, 3780) + // Minimum execution time: 43_553_000 picoseconds. + Weight::from_parts(45_036_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -499,8 +499,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 34_635_000 picoseconds. - Weight::from_parts(35_477_000, 8967) + // Minimum execution time: 33_223_000 picoseconds. + Weight::from_parts(34_385_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -523,10 +523,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 266_757_000 picoseconds. - Weight::from_parts(279_787_352, 6806) - // Standard Error: 812 - .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) + // Minimum execution time: 254_213_000 picoseconds. + Weight::from_parts(273_464_980, 6806) + // Standard Error: 1_362 + .saturating_add(Weight::from_parts(322_619, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -550,10 +550,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 266_442_000 picoseconds. - Weight::from_parts(86_660_390, 6826) - // Standard Error: 9_194 - .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) + // Minimum execution time: 250_273_000 picoseconds. + Weight::from_parts(122_072_782, 6826) + // Standard Error: 5_629 + .saturating_add(Weight::from_parts(3_490_256, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -578,10 +578,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 265_608_000 picoseconds. - Weight::from_parts(273_219_000, 6830) - // Standard Error: 11_085 - .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) + // Minimum execution time: 255_187_000 picoseconds. + Weight::from_parts(118_082_505, 6830) + // Standard Error: 6_302 + .saturating_add(Weight::from_parts(4_246_968, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -606,10 +606,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 270_033_000 picoseconds. - Weight::from_parts(288_700_795, 6815) - // Standard Error: 1_628 - .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) + // Minimum execution time: 256_833_000 picoseconds. + Weight::from_parts(273_330_216, 6815) + // Standard Error: 881 + .saturating_add(Weight::from_parts(400_105, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -633,10 +633,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 263_789_000 picoseconds. - Weight::from_parts(275_806_968, 6804) - // Standard Error: 936 - .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) + // Minimum execution time: 244_193_000 picoseconds. + Weight::from_parts(271_221_908, 6804) + // Standard Error: 442 + .saturating_add(Weight::from_parts(176_480, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -658,10 +658,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 257_922_000 picoseconds. - Weight::from_parts(270_842_153, 6693) - // Standard Error: 637 - .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) + // Minimum execution time: 232_603_000 picoseconds. + Weight::from_parts(260_577_368, 6693) + // Standard Error: 365 + .saturating_add(Weight::from_parts(158_126, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -685,10 +685,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 267_214_000 picoseconds. - Weight::from_parts(273_446_444, 6807) - // Standard Error: 2_355 - .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) + // Minimum execution time: 247_564_000 picoseconds. + Weight::from_parts(275_108_914, 6807) + // Standard Error: 505 + .saturating_add(Weight::from_parts(315_065, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -712,10 +712,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 258_860_000 picoseconds. - Weight::from_parts(286_389_737, 6806) - // Standard Error: 1_707 - .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) + // Minimum execution time: 258_799_000 picoseconds. + Weight::from_parts(274_338_256, 6806) + // Standard Error: 632 + .saturating_add(Weight::from_parts(355_032, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -739,10 +739,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 267_852_000 picoseconds. - Weight::from_parts(279_617_620, 6931) - // Standard Error: 3_382 - .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) + // Minimum execution time: 253_335_000 picoseconds. + Weight::from_parts(273_013_859, 6931) + // Standard Error: 2_007 + .saturating_add(Weight::from_parts(1_540_735, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -766,10 +766,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 266_379_000 picoseconds. - Weight::from_parts(287_280_653, 6823) - // Standard Error: 1_774 - .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) + // Minimum execution time: 252_325_000 picoseconds. + Weight::from_parts(274_733_944, 6823) + // Standard Error: 603 + .saturating_add(Weight::from_parts(314_467, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -793,10 +793,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 266_417_000 picoseconds. - Weight::from_parts(291_394_038, 6816) - // Standard Error: 1_474 - .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) + // Minimum execution time: 250_698_000 picoseconds. + Weight::from_parts(271_707_578, 6816) + // Standard Error: 952 + .saturating_add(Weight::from_parts(318_412, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -820,10 +820,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 269_198_000 picoseconds. - Weight::from_parts(285_025_368, 6819) - // Standard Error: 1_231 - .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) + // Minimum execution time: 251_854_000 picoseconds. + Weight::from_parts(272_002_212, 6819) + // Standard Error: 622 + .saturating_add(Weight::from_parts(313_353, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -847,10 +847,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 257_514_000 picoseconds. - Weight::from_parts(280_424_571, 6804) - // Standard Error: 723 - .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) + // Minimum execution time: 252_010_000 picoseconds. + Weight::from_parts(270_387_000, 6804) + // Standard Error: 659 + .saturating_add(Weight::from_parts(325_856, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -876,10 +876,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 268_221_000 picoseconds. - Weight::from_parts(282_273_629, 6872) - // Standard Error: 2_398 - .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) + // Minimum execution time: 247_933_000 picoseconds. + Weight::from_parts(281_550_162, 6872) + // Standard Error: 660 + .saturating_add(Weight::from_parts(1_090_869, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -903,10 +903,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 271_541_000 picoseconds. - Weight::from_parts(276_996_569, 6807) - // Standard Error: 1_462 - .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) + // Minimum execution time: 251_158_000 picoseconds. + Weight::from_parts(274_623_152, 6807) + // Standard Error: 491 + .saturating_add(Weight::from_parts(263_916, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -930,10 +930,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 256_410_000 picoseconds. - Weight::from_parts(206_888_877, 6809) - // Standard Error: 22 - .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) + // Minimum execution time: 263_205_000 picoseconds. + Weight::from_parts(216_792_893, 6809) + // Standard Error: 23 + .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -956,10 +956,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 248_852_000 picoseconds. - Weight::from_parts(277_852_834, 6793) - // Standard Error: 1_257_219 - .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) + // Minimum execution time: 239_663_000 picoseconds. + Weight::from_parts(266_124_565, 6793) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -983,10 +981,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 269_101_000 picoseconds. - Weight::from_parts(273_407_545, 6810) - // Standard Error: 2 - .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) + // Minimum execution time: 241_763_000 picoseconds. + Weight::from_parts(266_535_552, 6810) + // Standard Error: 0 + .saturating_add(Weight::from_parts(320, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1015,10 +1013,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 296_318_000 picoseconds. - Weight::from_parts(322_448_344, 8912) - // Standard Error: 2_358_838 - .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) + // Minimum execution time: 265_888_000 picoseconds. + Weight::from_parts(291_232_232, 8912) + // Standard Error: 845_475 + .saturating_add(Weight::from_parts(104_398_867, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1046,10 +1044,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 268_264_000 picoseconds. - Weight::from_parts(285_298_853, 6885) - // Standard Error: 3_238 - .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) + // Minimum execution time: 248_500_000 picoseconds. + Weight::from_parts(282_353_053, 6885) + // Standard Error: 1_144 + .saturating_add(Weight::from_parts(1_193_841, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1073,10 +1071,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 267_417_000 picoseconds. - Weight::from_parts(290_097_452, 6805) - // Standard Error: 2_523 - .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) + // Minimum execution time: 248_130_000 picoseconds. + Weight::from_parts(279_583_178, 6805) + // Standard Error: 971 + .saturating_add(Weight::from_parts(1_987_941, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -1101,12 +1099,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 269_735_000 picoseconds. - Weight::from_parts(291_680_757, 6825) - // Standard Error: 196_822 - .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) - // Standard Error: 55 - .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) + // Minimum execution time: 258_594_000 picoseconds. + Weight::from_parts(276_734_422, 6825) + // Standard Error: 102_093 + .saturating_add(Weight::from_parts(2_559_383, 0).saturating_mul(t.into())) + // Standard Error: 28 + .saturating_add(Weight::from_parts(501, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1132,10 +1130,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 161_454_000 picoseconds. - Weight::from_parts(181_662_272, 6807) - // Standard Error: 729 - .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) + // Minimum execution time: 154_564_000 picoseconds. + Weight::from_parts(168_931_365, 6807) + // Standard Error: 349 + .saturating_add(Weight::from_parts(226_848, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -1159,10 +1157,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 418_479_000 picoseconds. - Weight::from_parts(397_691_558, 131755) + // Minimum execution time: 394_382_000 picoseconds. + Weight::from_parts(376_780_500, 131755) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_026, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1173,10 +1171,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` // Estimated: `926 + r * (293 ±0)` - // Minimum execution time: 268_810_000 picoseconds. - Weight::from_parts(129_545_478, 926) - // Standard Error: 21_173 - .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) + // Minimum execution time: 249_757_000 picoseconds. + Weight::from_parts(177_324_374, 926) + // Standard Error: 9_512 + .saturating_add(Weight::from_parts(6_176_717, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1190,10 +1188,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1447` // Estimated: `1430` - // Minimum execution time: 286_965_000 picoseconds. - Weight::from_parts(340_396_510, 1430) - // Standard Error: 90 - .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) + // Minimum execution time: 267_564_000 picoseconds. + Weight::from_parts(328_701_080, 1430) + // Standard Error: 61 + .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(8_u64)) } @@ -1204,10 +1202,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1253 + n * (1 ±0)` // Estimated: `1253 + n * (1 ±0)` - // Minimum execution time: 272_395_000 picoseconds. - Weight::from_parts(302_307_069, 1253) - // Standard Error: 94 - .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) + // Minimum execution time: 266_347_000 picoseconds. + Weight::from_parts(289_824_718, 1253) + // Standard Error: 34 + .saturating_add(Weight::from_parts(184, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1219,10 +1217,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (288 ±0)` // Estimated: `927 + r * (289 ±0)` - // Minimum execution time: 269_165_000 picoseconds. - Weight::from_parts(167_174_485, 927) - // Standard Error: 23_564 - .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) + // Minimum execution time: 247_207_000 picoseconds. + Weight::from_parts(179_856_075, 927) + // Standard Error: 9_383 + .saturating_add(Weight::from_parts(6_053_198, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1236,8 +1234,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1249 + n * (1 ±0)` // Estimated: `1249 + n * (1 ±0)` - // Minimum execution time: 270_248_000 picoseconds. - Weight::from_parts(296_573_310, 1249) + // Minimum execution time: 262_655_000 picoseconds. + Weight::from_parts(289_482_543, 1249) + // Standard Error: 35 + .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1249,10 +1249,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `921 + r * (296 ±0)` // Estimated: `923 + r * (297 ±0)` - // Minimum execution time: 270_883_000 picoseconds. - Weight::from_parts(189_792_705, 923) - // Standard Error: 11_149 - .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) + // Minimum execution time: 247_414_000 picoseconds. + Weight::from_parts(203_317_182, 923) + // Standard Error: 7_191 + .saturating_add(Weight::from_parts(4_925_154, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1265,10 +1265,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1265 + n * (1 ±0)` // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 263_833_000 picoseconds. - Weight::from_parts(290_179_222, 1265) - // Standard Error: 44 - .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) + // Minimum execution time: 258_910_000 picoseconds. + Weight::from_parts(283_086_514, 1265) + // Standard Error: 39 + .saturating_add(Weight::from_parts(980, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1280,10 +1280,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `932 + r * (288 ±0)` // Estimated: `929 + r * (289 ±0)` - // Minimum execution time: 252_637_000 picoseconds. - Weight::from_parts(98_108_825, 929) - // Standard Error: 23_580 - .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) + // Minimum execution time: 252_410_000 picoseconds. + Weight::from_parts(201_227_879, 929) + // Standard Error: 6_899 + .saturating_add(Weight::from_parts(4_774_983, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1296,8 +1296,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1252 + n * (1 ±0)` // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 279_133_000 picoseconds. - Weight::from_parts(301_192_115, 1252) + // Minimum execution time: 259_053_000 picoseconds. + Weight::from_parts(283_392_084, 1252) + // Standard Error: 41 + .saturating_add(Weight::from_parts(213, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1309,10 +1311,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `914 + r * (296 ±0)` // Estimated: `919 + r * (297 ±0)` - // Minimum execution time: 268_833_000 picoseconds. - Weight::from_parts(56_229_951, 919) - // Standard Error: 25_800 - .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) + // Minimum execution time: 251_371_000 picoseconds. + Weight::from_parts(177_119_717, 919) + // Standard Error: 9_421 + .saturating_add(Weight::from_parts(6_226_005, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1326,10 +1328,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1266 + n * (1 ±0)` // Estimated: `1266 + n * (1 ±0)` - // Minimum execution time: 288_677_000 picoseconds. - Weight::from_parts(301_986_360, 1266) - // Standard Error: 39 - .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) + // Minimum execution time: 263_350_000 picoseconds. + Weight::from_parts(284_323_917, 1266) + // Standard Error: 31 + .saturating_add(Weight::from_parts(921, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1353,10 +1355,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 275_956_000 picoseconds. - Weight::from_parts(280_865_651, 7307) - // Standard Error: 28_235 - .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) + // Minimum execution time: 248_701_000 picoseconds. + Weight::from_parts(17_811_969, 7307) + // Standard Error: 35_154 + .saturating_add(Weight::from_parts(31_809_738, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1382,10 +1384,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 269_188_000 picoseconds. - Weight::from_parts(276_038_000, 9440) - // Standard Error: 262_029 - .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) + // Minimum execution time: 247_335_000 picoseconds. + Weight::from_parts(264_025_000, 9440) + // Standard Error: 121_299 + .saturating_add(Weight::from_parts(234_770_827, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1411,10 +1413,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 267_543_000 picoseconds. - Weight::from_parts(271_365_000, 6812) - // Standard Error: 190_454 - .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) + // Minimum execution time: 261_011_000 picoseconds. + Weight::from_parts(264_554_000, 6812) + // Standard Error: 104_415 + .saturating_add(Weight::from_parts(231_627_084, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1441,12 +1443,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 453_215_000 picoseconds. - Weight::from_parts(32_029_330, 12197) - // Standard Error: 12_154_174 - .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) + // Minimum execution time: 445_561_000 picoseconds. + Weight::from_parts(62_287_490, 12197) + // Standard Error: 11_797_697 + .saturating_add(Weight::from_parts(357_530_529, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(970, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -1476,10 +1478,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 635_304_000 picoseconds. - Weight::from_parts(645_872_000, 9620) - // Standard Error: 356_713 - .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) + // Minimum execution time: 621_897_000 picoseconds. + Weight::from_parts(631_687_000, 9620) + // Standard Error: 215_241 + .saturating_add(Weight::from_parts(350_527_831, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -1511,12 +1513,14 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_225_692_000 picoseconds. - Weight::from_parts(1_292_861_603, 12211) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) + // Minimum execution time: 2_181_184_000 picoseconds. + Weight::from_parts(1_194_190_111, 12211) + // Standard Error: 11_578_766 + .saturating_add(Weight::from_parts(6_361_884, 0).saturating_mul(t.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_158, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(11_u64)) @@ -1542,10 +1546,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 252_664_000 picoseconds. - Weight::from_parts(277_967_331, 6801) - // Standard Error: 723 - .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) + // Minimum execution time: 241_609_000 picoseconds. + Weight::from_parts(268_716_874, 6801) + // Standard Error: 617 + .saturating_add(Weight::from_parts(377_753, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1569,10 +1573,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 252_485_000 picoseconds. - Weight::from_parts(259_271_531, 6808) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) + // Minimum execution time: 261_296_000 picoseconds. + Weight::from_parts(255_531_654, 6808) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_081, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1595,10 +1599,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 249_270_000 picoseconds. - Weight::from_parts(272_528_711, 6806) - // Standard Error: 903 - .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) + // Minimum execution time: 243_583_000 picoseconds. + Weight::from_parts(270_025_058, 6806) + // Standard Error: 560 + .saturating_add(Weight::from_parts(767_519, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1622,10 +1626,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 249_470_000 picoseconds. - Weight::from_parts(273_317_815, 6814) - // Standard Error: 4 - .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) + // Minimum execution time: 253_798_000 picoseconds. + Weight::from_parts(265_542_351, 6814) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_343, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1648,10 +1652,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 265_503_000 picoseconds. - Weight::from_parts(279_774_666, 6808) - // Standard Error: 1_351 - .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) + // Minimum execution time: 247_332_000 picoseconds. + Weight::from_parts(269_183_656, 6808) + // Standard Error: 665 + .saturating_add(Weight::from_parts(443_386, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1675,10 +1679,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 265_009_000 picoseconds. - Weight::from_parts(270_467_968, 6813) + // Minimum execution time: 250_855_000 picoseconds. + Weight::from_parts(258_752_975, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_202, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1701,10 +1705,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 251_771_000 picoseconds. - Weight::from_parts(283_553_523, 6805) - // Standard Error: 1_053 - .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) + // Minimum execution time: 240_733_000 picoseconds. + Weight::from_parts(269_134_358, 6805) + // Standard Error: 512 + .saturating_add(Weight::from_parts(440_043, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -1728,10 +1732,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 253_733_000 picoseconds. - Weight::from_parts(264_277_000, 6811) - // Standard Error: 3 - .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) + // Minimum execution time: 247_377_000 picoseconds. + Weight::from_parts(261_077_322, 6811) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_195, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -1754,10 +1758,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 337_326_000 picoseconds. - Weight::from_parts(346_340_758, 6934) - // Standard Error: 18 - .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) + // Minimum execution time: 307_337_000 picoseconds. + Weight::from_parts(326_710_473, 6934) + // Standard Error: 9 + .saturating_add(Weight::from_parts(5_765, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1781,10 +1785,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 253_852_000 picoseconds. - Weight::from_parts(335_731_679, 6748) - // Standard Error: 13_615 - .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) + // Minimum execution time: 245_432_000 picoseconds. + Weight::from_parts(294_206_377, 6748) + // Standard Error: 7_229 + .saturating_add(Weight::from_parts(41_480_485, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -1807,11 +1811,11 @@ impl WeightInfo for SubstrateWeight { fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` - // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 256_283_000 picoseconds. - Weight::from_parts(338_634_113, 6801) - // Standard Error: 43_436 - .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) + // Estimated: `6802 + r * (77 ±0)` + // Minimum execution time: 247_788_000 picoseconds. + Weight::from_parts(303_940_062, 6802) + // Standard Error: 10_671 + .saturating_add(Weight::from_parts(45_730_772, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -1835,10 +1839,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 269_144_000 picoseconds. - Weight::from_parts(331_790_138, 6816) - // Standard Error: 23_357 - .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) + // Minimum execution time: 248_825_000 picoseconds. + Weight::from_parts(286_832_225, 6816) + // Standard Error: 5_274 + .saturating_add(Weight::from_parts(11_889_262, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -1861,11 +1865,11 @@ impl WeightInfo for SubstrateWeight { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` - // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 262_624_000 picoseconds. - Weight::from_parts(275_865_000, 6807) - // Standard Error: 64_162 - .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) + // Estimated: `6807 + r * (3090 ±7)` + // Minimum execution time: 244_982_000 picoseconds. + Weight::from_parts(265_297_000, 6807) + // Standard Error: 39_895 + .saturating_add(Weight::from_parts(22_435_888, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1891,10 +1895,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 265_482_000 picoseconds. - Weight::from_parts(296_491_925, 6878) - // Standard Error: 46_681 - .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) + // Minimum execution time: 246_455_000 picoseconds. + Weight::from_parts(275_334_919, 6878) + // Standard Error: 20_911 + .saturating_add(Weight::from_parts(6_427_525, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1920,10 +1924,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 257_532_000 picoseconds. - Weight::from_parts(299_110_930, 129453) - // Standard Error: 55_003 - .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) + // Minimum execution time: 254_472_000 picoseconds. + Weight::from_parts(280_657_909, 129453) + // Standard Error: 20_131 + .saturating_add(Weight::from_parts(5_644_006, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -1949,10 +1953,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 268_894_000 picoseconds. - Weight::from_parts(287_048_741, 6804) - // Standard Error: 1_156 - .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) + // Minimum execution time: 250_535_000 picoseconds. + Weight::from_parts(270_318_376, 6804) + // Standard Error: 386 + .saturating_add(Weight::from_parts(174_627, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -1976,10 +1980,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 262_736_000 picoseconds. - Weight::from_parts(389_199_672, 7899) - // Standard Error: 2_646 - .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) + // Minimum execution time: 248_174_000 picoseconds. + Weight::from_parts(301_826_520, 7899) + // Standard Error: 801 + .saturating_add(Weight::from_parts(248_479, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -2005,23 +2009,23 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 253_465_000 picoseconds. - Weight::from_parts(283_153_874, 6801) - // Standard Error: 745 - .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) + // Minimum execution time: 246_540_000 picoseconds. + Weight::from_parts(268_913_509, 6801) + // Standard Error: 378 + .saturating_add(Weight::from_parts(154_950, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. - fn instr_i64const(r: u32, ) -> Weight { + fn instr_i64_load_store(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_342_000 picoseconds. - Weight::from_parts(1_940_100, 0) - // Standard Error: 21 - .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) + // Minimum execution time: 1_777_000 picoseconds. + Weight::from_parts(1_707_601, 0) + // Standard Error: 14 + .saturating_add(Weight::from_parts(15_392, 0).saturating_mul(r.into())) } } @@ -2033,8 +2037,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 1_991_000 picoseconds. - Weight::from_parts(2_135_000, 1627) + // Minimum execution time: 1_997_000 picoseconds. + Weight::from_parts(2_130_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -2044,10 +2048,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 11_969_000 picoseconds. - Weight::from_parts(7_055_855, 442) - // Standard Error: 2_328 - .saturating_add(Weight::from_parts(1_212_989, 0).saturating_mul(k.into())) + // Minimum execution time: 12_276_000 picoseconds. + Weight::from_parts(1_593_881, 442) + // Standard Error: 1_135 + .saturating_add(Weight::from_parts(1_109_302, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2061,10 +2065,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_064_000 picoseconds. - Weight::from_parts(8_301_148, 6149) + // Minimum execution time: 8_176_000 picoseconds. + Weight::from_parts(8_555_388, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_180, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_184, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2077,8 +2081,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 15_789_000 picoseconds. - Weight::from_parts(16_850_000, 6450) + // Minimum execution time: 16_270_000 picoseconds. + Weight::from_parts(16_779_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2091,10 +2095,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_369_000 picoseconds. - Weight::from_parts(3_516_000, 3635) - // Standard Error: 960 - .saturating_add(Weight::from_parts(1_139_317, 0).saturating_mul(k.into())) + // Minimum execution time: 3_572_000 picoseconds. + Weight::from_parts(1_950_905, 3635) + // Standard Error: 1_597 + .saturating_add(Weight::from_parts(1_123_190, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -2113,10 +2117,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `325 + c * (1 ±0)` // Estimated: `6263 + c * (1 ±0)` - // Minimum execution time: 16_320_000 picoseconds. - Weight::from_parts(16_090_036, 6263) + // Minimum execution time: 16_873_000 picoseconds. + Weight::from_parts(16_790_402, 6263) // Standard Error: 1 - .saturating_add(Weight::from_parts(417, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(396, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2127,8 +2131,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_669_000 picoseconds. - Weight::from_parts(13_118_000, 6380) + // Minimum execution time: 11_904_000 picoseconds. + Weight::from_parts(12_785_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2142,8 +2146,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 45_403_000 picoseconds. - Weight::from_parts(46_636_000, 6292) + // Minimum execution time: 44_920_000 picoseconds. + Weight::from_parts(46_163_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2155,8 +2159,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 53_622_000 picoseconds. - Weight::from_parts(55_444_000, 6534) + // Minimum execution time: 53_864_000 picoseconds. + Weight::from_parts(55_139_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2166,8 +2170,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_444_000 picoseconds. - Weight::from_parts(2_587_000, 1627) + // Minimum execution time: 2_375_000 picoseconds. + Weight::from_parts(2_487_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2179,8 +2183,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 11_476_000 picoseconds. - Weight::from_parts(11_944_000, 3631) + // Minimum execution time: 11_580_000 picoseconds. + Weight::from_parts(11_980_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -2190,8 +2194,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_652_000 picoseconds. - Weight::from_parts(4_792_000, 3607) + // Minimum execution time: 4_557_000 picoseconds. + Weight::from_parts(4_807_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2202,8 +2206,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_054_000 picoseconds. - Weight::from_parts(6_278_000, 3632) + // Minimum execution time: 6_253_000 picoseconds. + Weight::from_parts(6_479_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -2214,8 +2218,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_056_000 picoseconds. - Weight::from_parts(6_343_000, 3607) + // Minimum execution time: 6_166_000 picoseconds. + Weight::from_parts(6_545_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2236,12 +2240,12 @@ impl WeightInfo for () { /// The range of component `c` is `[0, 125952]`. fn call_with_code_per_byte(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `792` - // Estimated: `6743 + c * (1 ±0)` - // Minimum execution time: 303_205_000 picoseconds. - Weight::from_parts(266_154_889, 6743) - // Standard Error: 79 - .saturating_add(Weight::from_parts(35_195, 0).saturating_mul(c.into())) + // Measured: `801 + c * (1 ±0)` + // Estimated: `6739 + c * (1 ±0)` + // Minimum execution time: 282_232_000 picoseconds. + Weight::from_parts(266_148_573, 6739) + // Standard Error: 69 + .saturating_add(Weight::from_parts(34_592, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -2270,15 +2274,15 @@ impl WeightInfo for () { fn instantiate_with_code(c: u32, i: u32, s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `323` - // Estimated: `8747` - // Minimum execution time: 4_311_802_000 picoseconds. - Weight::from_parts(777_467_048, 8747) - // Standard Error: 338 - .saturating_add(Weight::from_parts(105_862, 0).saturating_mul(c.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_856, 0).saturating_mul(i.into())) - // Standard Error: 40 - .saturating_add(Weight::from_parts(1_443, 0).saturating_mul(s.into())) + // Estimated: `8737` + // Minimum execution time: 3_760_879_000 picoseconds. + Weight::from_parts(794_812_431, 8737) + // Standard Error: 149 + .saturating_add(Weight::from_parts(101_881, 0).saturating_mul(c.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_404, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_544, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -2306,12 +2310,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `560` // Estimated: `6504` - // Minimum execution time: 1_958_694_000 picoseconds. - Weight::from_parts(331_222_273, 6504) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_954, 0).saturating_mul(i.into())) - // Standard Error: 13 - .saturating_add(Weight::from_parts(1_685, 0).saturating_mul(s.into())) + // Minimum execution time: 1_953_162_000 picoseconds. + Weight::from_parts(374_252_840, 6504) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_630, 0).saturating_mul(i.into())) + // Standard Error: 7 + .saturating_add(Weight::from_parts(1_650, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -2333,8 +2337,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `826` // Estimated: `6766` - // Minimum execution time: 194_513_000 picoseconds. - Weight::from_parts(201_116_000, 6766) + // Minimum execution time: 187_899_000 picoseconds. + Weight::from_parts(195_510_000, 6766) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2353,10 +2357,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 269_777_000 picoseconds. - Weight::from_parts(204_229_027, 3607) - // Standard Error: 152 - .saturating_add(Weight::from_parts(72_184, 0).saturating_mul(c.into())) + // Minimum execution time: 254_800_000 picoseconds. + Weight::from_parts(285_603_050, 3607) + // Standard Error: 62 + .saturating_add(Weight::from_parts(66_212, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2374,8 +2378,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 43_271_000 picoseconds. - Weight::from_parts(44_884_000, 3780) + // Minimum execution time: 43_553_000 picoseconds. + Weight::from_parts(45_036_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -2391,8 +2395,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 34_635_000 picoseconds. - Weight::from_parts(35_477_000, 8967) + // Minimum execution time: 33_223_000 picoseconds. + Weight::from_parts(34_385_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -2415,10 +2419,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `866 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 266_757_000 picoseconds. - Weight::from_parts(279_787_352, 6806) - // Standard Error: 812 - .saturating_add(Weight::from_parts(329_166, 0).saturating_mul(r.into())) + // Minimum execution time: 254_213_000 picoseconds. + Weight::from_parts(273_464_980, 6806) + // Standard Error: 1_362 + .saturating_add(Weight::from_parts(322_619, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2442,10 +2446,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `922 + r * (209 ±0)` // Estimated: `6826 + r * (2684 ±0)` - // Minimum execution time: 266_442_000 picoseconds. - Weight::from_parts(86_660_390, 6826) - // Standard Error: 9_194 - .saturating_add(Weight::from_parts(3_744_648, 0).saturating_mul(r.into())) + // Minimum execution time: 250_273_000 picoseconds. + Weight::from_parts(122_072_782, 6826) + // Standard Error: 5_629 + .saturating_add(Weight::from_parts(3_490_256, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2470,10 +2474,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (213 ±0)` // Estimated: `6830 + r * (2688 ±0)` - // Minimum execution time: 265_608_000 picoseconds. - Weight::from_parts(273_219_000, 6830) - // Standard Error: 11_085 - .saturating_add(Weight::from_parts(4_542_778, 0).saturating_mul(r.into())) + // Minimum execution time: 255_187_000 picoseconds. + Weight::from_parts(118_082_505, 6830) + // Standard Error: 6_302 + .saturating_add(Weight::from_parts(4_246_968, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2498,10 +2502,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `873 + r * (6 ±0)` // Estimated: `6815 + r * (6 ±0)` - // Minimum execution time: 270_033_000 picoseconds. - Weight::from_parts(288_700_795, 6815) - // Standard Error: 1_628 - .saturating_add(Weight::from_parts(428_991, 0).saturating_mul(r.into())) + // Minimum execution time: 256_833_000 picoseconds. + Weight::from_parts(273_330_216, 6815) + // Standard Error: 881 + .saturating_add(Weight::from_parts(400_105, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2525,10 +2529,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 263_789_000 picoseconds. - Weight::from_parts(275_806_968, 6804) - // Standard Error: 936 - .saturating_add(Weight::from_parts(182_805, 0).saturating_mul(r.into())) + // Minimum execution time: 244_193_000 picoseconds. + Weight::from_parts(271_221_908, 6804) + // Standard Error: 442 + .saturating_add(Weight::from_parts(176_480, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2550,10 +2554,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `753 + r * (3 ±0)` // Estimated: `6693 + r * (3 ±0)` - // Minimum execution time: 257_922_000 picoseconds. - Weight::from_parts(270_842_153, 6693) - // Standard Error: 637 - .saturating_add(Weight::from_parts(156_567, 0).saturating_mul(r.into())) + // Minimum execution time: 232_603_000 picoseconds. + Weight::from_parts(260_577_368, 6693) + // Standard Error: 365 + .saturating_add(Weight::from_parts(158_126, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2577,10 +2581,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `867 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 267_214_000 picoseconds. - Weight::from_parts(273_446_444, 6807) - // Standard Error: 2_355 - .saturating_add(Weight::from_parts(356_663, 0).saturating_mul(r.into())) + // Minimum execution time: 247_564_000 picoseconds. + Weight::from_parts(275_108_914, 6807) + // Standard Error: 505 + .saturating_add(Weight::from_parts(315_065, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2604,10 +2608,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6806 + r * (6 ±0)` - // Minimum execution time: 258_860_000 picoseconds. - Weight::from_parts(286_389_737, 6806) - // Standard Error: 1_707 - .saturating_add(Weight::from_parts(366_148, 0).saturating_mul(r.into())) + // Minimum execution time: 258_799_000 picoseconds. + Weight::from_parts(274_338_256, 6806) + // Standard Error: 632 + .saturating_add(Weight::from_parts(355_032, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2631,10 +2635,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1007 + r * (6 ±0)` // Estimated: `6931 + r * (6 ±0)` - // Minimum execution time: 267_852_000 picoseconds. - Weight::from_parts(279_617_620, 6931) - // Standard Error: 3_382 - .saturating_add(Weight::from_parts(1_586_170, 0).saturating_mul(r.into())) + // Minimum execution time: 253_335_000 picoseconds. + Weight::from_parts(273_013_859, 6931) + // Standard Error: 2_007 + .saturating_add(Weight::from_parts(1_540_735, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2658,10 +2662,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (6 ±0)` // Estimated: `6823 + r * (6 ±0)` - // Minimum execution time: 266_379_000 picoseconds. - Weight::from_parts(287_280_653, 6823) - // Standard Error: 1_774 - .saturating_add(Weight::from_parts(323_724, 0).saturating_mul(r.into())) + // Minimum execution time: 252_325_000 picoseconds. + Weight::from_parts(274_733_944, 6823) + // Standard Error: 603 + .saturating_add(Weight::from_parts(314_467, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2685,10 +2689,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `875 + r * (6 ±0)` // Estimated: `6816 + r * (6 ±0)` - // Minimum execution time: 266_417_000 picoseconds. - Weight::from_parts(291_394_038, 6816) - // Standard Error: 1_474 - .saturating_add(Weight::from_parts(328_306, 0).saturating_mul(r.into())) + // Minimum execution time: 250_698_000 picoseconds. + Weight::from_parts(271_707_578, 6816) + // Standard Error: 952 + .saturating_add(Weight::from_parts(318_412, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2712,10 +2716,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872 + r * (6 ±0)` // Estimated: `6819 + r * (6 ±0)` - // Minimum execution time: 269_198_000 picoseconds. - Weight::from_parts(285_025_368, 6819) - // Standard Error: 1_231 - .saturating_add(Weight::from_parts(324_814, 0).saturating_mul(r.into())) + // Minimum execution time: 251_854_000 picoseconds. + Weight::from_parts(272_002_212, 6819) + // Standard Error: 622 + .saturating_add(Weight::from_parts(313_353, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2739,10 +2743,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (6 ±0)` // Estimated: `6804 + r * (6 ±0)` - // Minimum execution time: 257_514_000 picoseconds. - Weight::from_parts(280_424_571, 6804) - // Standard Error: 723 - .saturating_add(Weight::from_parts(325_607, 0).saturating_mul(r.into())) + // Minimum execution time: 252_010_000 picoseconds. + Weight::from_parts(270_387_000, 6804) + // Standard Error: 659 + .saturating_add(Weight::from_parts(325_856, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2768,10 +2772,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `937 + r * (14 ±0)` // Estimated: `6872 + r * (14 ±0)` - // Minimum execution time: 268_221_000 picoseconds. - Weight::from_parts(282_273_629, 6872) - // Standard Error: 2_398 - .saturating_add(Weight::from_parts(1_117_278, 0).saturating_mul(r.into())) + // Minimum execution time: 247_933_000 picoseconds. + Weight::from_parts(281_550_162, 6872) + // Standard Error: 660 + .saturating_add(Weight::from_parts(1_090_869, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 14).saturating_mul(r.into())) @@ -2795,10 +2799,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `865 + r * (6 ±0)` // Estimated: `6807 + r * (6 ±0)` - // Minimum execution time: 271_541_000 picoseconds. - Weight::from_parts(276_996_569, 6807) - // Standard Error: 1_462 - .saturating_add(Weight::from_parts(282_119, 0).saturating_mul(r.into())) + // Minimum execution time: 251_158_000 picoseconds. + Weight::from_parts(274_623_152, 6807) + // Standard Error: 491 + .saturating_add(Weight::from_parts(263_916, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 6).saturating_mul(r.into())) @@ -2822,10 +2826,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `869` // Estimated: `6809` - // Minimum execution time: 256_410_000 picoseconds. - Weight::from_parts(206_888_877, 6809) - // Standard Error: 22 - .saturating_add(Weight::from_parts(1_154, 0).saturating_mul(n.into())) + // Minimum execution time: 263_205_000 picoseconds. + Weight::from_parts(216_792_893, 6809) + // Standard Error: 23 + .saturating_add(Weight::from_parts(989, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2848,10 +2852,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `853 + r * (45 ±0)` // Estimated: `6793 + r * (45 ±0)` - // Minimum execution time: 248_852_000 picoseconds. - Weight::from_parts(277_852_834, 6793) - // Standard Error: 1_257_219 - .saturating_add(Weight::from_parts(1_394_065, 0).saturating_mul(r.into())) + // Minimum execution time: 239_663_000 picoseconds. + Weight::from_parts(266_124_565, 6793) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 45).saturating_mul(r.into())) @@ -2875,10 +2877,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863` // Estimated: `6810` - // Minimum execution time: 269_101_000 picoseconds. - Weight::from_parts(273_407_545, 6810) - // Standard Error: 2 - .saturating_add(Weight::from_parts(339, 0).saturating_mul(n.into())) + // Minimum execution time: 241_763_000 picoseconds. + Weight::from_parts(266_535_552, 6810) + // Standard Error: 0 + .saturating_add(Weight::from_parts(320, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2907,10 +2909,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2972 + r * (316 ±0)` // Estimated: `8912 + r * (5266 ±0)` - // Minimum execution time: 296_318_000 picoseconds. - Weight::from_parts(322_448_344, 8912) - // Standard Error: 2_358_838 - .saturating_add(Weight::from_parts(107_092_455, 0).saturating_mul(r.into())) + // Minimum execution time: 265_888_000 picoseconds. + Weight::from_parts(291_232_232, 8912) + // Standard Error: 845_475 + .saturating_add(Weight::from_parts(104_398_867, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((7_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2938,10 +2940,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `944 + r * (10 ±0)` // Estimated: `6885 + r * (10 ±0)` - // Minimum execution time: 268_264_000 picoseconds. - Weight::from_parts(285_298_853, 6885) - // Standard Error: 3_238 - .saturating_add(Weight::from_parts(1_238_513, 0).saturating_mul(r.into())) + // Minimum execution time: 248_500_000 picoseconds. + Weight::from_parts(282_353_053, 6885) + // Standard Error: 1_144 + .saturating_add(Weight::from_parts(1_193_841, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2965,10 +2967,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `863 + r * (10 ±0)` // Estimated: `6805 + r * (10 ±0)` - // Minimum execution time: 267_417_000 picoseconds. - Weight::from_parts(290_097_452, 6805) - // Standard Error: 2_523 - .saturating_add(Weight::from_parts(2_012_375, 0).saturating_mul(r.into())) + // Minimum execution time: 248_130_000 picoseconds. + Weight::from_parts(279_583_178, 6805) + // Standard Error: 971 + .saturating_add(Weight::from_parts(1_987_941, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 10).saturating_mul(r.into())) @@ -2993,12 +2995,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `880 + t * (32 ±0)` // Estimated: `6825 + t * (2508 ±0)` - // Minimum execution time: 269_735_000 picoseconds. - Weight::from_parts(291_680_757, 6825) - // Standard Error: 196_822 - .saturating_add(Weight::from_parts(2_827_797, 0).saturating_mul(t.into())) - // Standard Error: 55 - .saturating_add(Weight::from_parts(262, 0).saturating_mul(n.into())) + // Minimum execution time: 258_594_000 picoseconds. + Weight::from_parts(276_734_422, 6825) + // Standard Error: 102_093 + .saturating_add(Weight::from_parts(2_559_383, 0).saturating_mul(t.into())) + // Standard Error: 28 + .saturating_add(Weight::from_parts(501, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3024,10 +3026,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (7 ±0)` // Estimated: `6807 + r * (7 ±0)` - // Minimum execution time: 161_454_000 picoseconds. - Weight::from_parts(181_662_272, 6807) - // Standard Error: 729 - .saturating_add(Weight::from_parts(221_968, 0).saturating_mul(r.into())) + // Minimum execution time: 154_564_000 picoseconds. + Weight::from_parts(168_931_365, 6807) + // Standard Error: 349 + .saturating_add(Weight::from_parts(226_848, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into())) @@ -3051,10 +3053,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `125813` // Estimated: `131755` - // Minimum execution time: 418_479_000 picoseconds. - Weight::from_parts(397_691_558, 131755) + // Minimum execution time: 394_382_000 picoseconds. + Weight::from_parts(376_780_500, 131755) // Standard Error: 12 - .saturating_add(Weight::from_parts(1_099, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(1_026, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3065,10 +3067,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `924 + r * (292 ±0)` // Estimated: `926 + r * (293 ±0)` - // Minimum execution time: 268_810_000 picoseconds. - Weight::from_parts(129_545_478, 926) - // Standard Error: 21_173 - .saturating_add(Weight::from_parts(7_118_874, 0).saturating_mul(r.into())) + // Minimum execution time: 249_757_000 picoseconds. + Weight::from_parts(177_324_374, 926) + // Standard Error: 9_512 + .saturating_add(Weight::from_parts(6_176_717, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3082,10 +3084,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1447` // Estimated: `1430` - // Minimum execution time: 286_965_000 picoseconds. - Weight::from_parts(340_396_510, 1430) - // Standard Error: 90 - .saturating_add(Weight::from_parts(455, 0).saturating_mul(n.into())) + // Minimum execution time: 267_564_000 picoseconds. + Weight::from_parts(328_701_080, 1430) + // Standard Error: 61 + .saturating_add(Weight::from_parts(576, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(8_u64)) } @@ -3096,10 +3098,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1253 + n * (1 ±0)` // Estimated: `1253 + n * (1 ±0)` - // Minimum execution time: 272_395_000 picoseconds. - Weight::from_parts(302_307_069, 1253) - // Standard Error: 94 - .saturating_add(Weight::from_parts(156, 0).saturating_mul(n.into())) + // Minimum execution time: 266_347_000 picoseconds. + Weight::from_parts(289_824_718, 1253) + // Standard Error: 34 + .saturating_add(Weight::from_parts(184, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3111,10 +3113,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (288 ±0)` // Estimated: `927 + r * (289 ±0)` - // Minimum execution time: 269_165_000 picoseconds. - Weight::from_parts(167_174_485, 927) - // Standard Error: 23_564 - .saturating_add(Weight::from_parts(6_921_525, 0).saturating_mul(r.into())) + // Minimum execution time: 247_207_000 picoseconds. + Weight::from_parts(179_856_075, 927) + // Standard Error: 9_383 + .saturating_add(Weight::from_parts(6_053_198, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3128,8 +3130,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1249 + n * (1 ±0)` // Estimated: `1249 + n * (1 ±0)` - // Minimum execution time: 270_248_000 picoseconds. - Weight::from_parts(296_573_310, 1249) + // Minimum execution time: 262_655_000 picoseconds. + Weight::from_parts(289_482_543, 1249) + // Standard Error: 35 + .saturating_add(Weight::from_parts(92, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3141,10 +3145,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `921 + r * (296 ±0)` // Estimated: `923 + r * (297 ±0)` - // Minimum execution time: 270_883_000 picoseconds. - Weight::from_parts(189_792_705, 923) - // Standard Error: 11_149 - .saturating_add(Weight::from_parts(5_232_100, 0).saturating_mul(r.into())) + // Minimum execution time: 247_414_000 picoseconds. + Weight::from_parts(203_317_182, 923) + // Standard Error: 7_191 + .saturating_add(Weight::from_parts(4_925_154, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3157,10 +3161,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1265 + n * (1 ±0)` // Estimated: `1265 + n * (1 ±0)` - // Minimum execution time: 263_833_000 picoseconds. - Weight::from_parts(290_179_222, 1265) - // Standard Error: 44 - .saturating_add(Weight::from_parts(831, 0).saturating_mul(n.into())) + // Minimum execution time: 258_910_000 picoseconds. + Weight::from_parts(283_086_514, 1265) + // Standard Error: 39 + .saturating_add(Weight::from_parts(980, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3172,10 +3176,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `932 + r * (288 ±0)` // Estimated: `929 + r * (289 ±0)` - // Minimum execution time: 252_637_000 picoseconds. - Weight::from_parts(98_108_825, 929) - // Standard Error: 23_580 - .saturating_add(Weight::from_parts(5_408_076, 0).saturating_mul(r.into())) + // Minimum execution time: 252_410_000 picoseconds. + Weight::from_parts(201_227_879, 929) + // Standard Error: 6_899 + .saturating_add(Weight::from_parts(4_774_983, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3188,8 +3192,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1252 + n * (1 ±0)` // Estimated: `1252 + n * (1 ±0)` - // Minimum execution time: 279_133_000 picoseconds. - Weight::from_parts(301_192_115, 1252) + // Minimum execution time: 259_053_000 picoseconds. + Weight::from_parts(283_392_084, 1252) + // Standard Error: 41 + .saturating_add(Weight::from_parts(213, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3201,10 +3207,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `914 + r * (296 ±0)` // Estimated: `919 + r * (297 ±0)` - // Minimum execution time: 268_833_000 picoseconds. - Weight::from_parts(56_229_951, 919) - // Standard Error: 25_800 - .saturating_add(Weight::from_parts(7_607_143, 0).saturating_mul(r.into())) + // Minimum execution time: 251_371_000 picoseconds. + Weight::from_parts(177_119_717, 919) + // Standard Error: 9_421 + .saturating_add(Weight::from_parts(6_226_005, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3218,10 +3224,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1266 + n * (1 ±0)` // Estimated: `1266 + n * (1 ±0)` - // Minimum execution time: 288_677_000 picoseconds. - Weight::from_parts(301_986_360, 1266) - // Standard Error: 39 - .saturating_add(Weight::from_parts(867, 0).saturating_mul(n.into())) + // Minimum execution time: 263_350_000 picoseconds. + Weight::from_parts(284_323_917, 1266) + // Standard Error: 31 + .saturating_add(Weight::from_parts(921, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3245,10 +3251,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1415 + r * (45 ±0)` // Estimated: `7307 + r * (2520 ±0)` - // Minimum execution time: 275_956_000 picoseconds. - Weight::from_parts(280_865_651, 7307) - // Standard Error: 28_235 - .saturating_add(Weight::from_parts(32_233_352, 0).saturating_mul(r.into())) + // Minimum execution time: 248_701_000 picoseconds. + Weight::from_parts(17_811_969, 7307) + // Standard Error: 35_154 + .saturating_add(Weight::from_parts(31_809_738, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3274,10 +3280,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1260 + r * (245 ±0)` // Estimated: `9440 + r * (2721 ±0)` - // Minimum execution time: 269_188_000 picoseconds. - Weight::from_parts(276_038_000, 9440) - // Standard Error: 262_029 - .saturating_add(Weight::from_parts(250_766_832, 0).saturating_mul(r.into())) + // Minimum execution time: 247_335_000 picoseconds. + Weight::from_parts(264_025_000, 9440) + // Standard Error: 121_299 + .saturating_add(Weight::from_parts(234_770_827, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -3303,10 +3309,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + r * (576 ±0)` // Estimated: `6812 + r * (2637 ±3)` - // Minimum execution time: 267_543_000 picoseconds. - Weight::from_parts(271_365_000, 6812) - // Standard Error: 190_454 - .saturating_add(Weight::from_parts(242_627_807, 0).saturating_mul(r.into())) + // Minimum execution time: 261_011_000 picoseconds. + Weight::from_parts(264_554_000, 6812) + // Standard Error: 104_415 + .saturating_add(Weight::from_parts(231_627_084, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3333,12 +3339,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1307 + t * (277 ±0)` // Estimated: `12197 + t * (5227 ±0)` - // Minimum execution time: 453_215_000 picoseconds. - Weight::from_parts(32_029_330, 12197) - // Standard Error: 12_154_174 - .saturating_add(Weight::from_parts(392_862_355, 0).saturating_mul(t.into())) + // Minimum execution time: 445_561_000 picoseconds. + Weight::from_parts(62_287_490, 12197) + // Standard Error: 11_797_697 + .saturating_add(Weight::from_parts(357_530_529, 0).saturating_mul(t.into())) // Standard Error: 17 - .saturating_add(Weight::from_parts(1_059, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(970, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -3368,10 +3374,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1278 + r * (255 ±0)` // Estimated: `9620 + r * (2731 ±0)` - // Minimum execution time: 635_304_000 picoseconds. - Weight::from_parts(645_872_000, 9620) - // Standard Error: 356_713 - .saturating_add(Weight::from_parts(371_999_658, 0).saturating_mul(r.into())) + // Minimum execution time: 621_897_000 picoseconds. + Weight::from_parts(631_687_000, 9620) + // Standard Error: 215_241 + .saturating_add(Weight::from_parts(350_527_831, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -3403,12 +3409,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1303 + t * (104 ±0)` // Estimated: `12211 + t * (2549 ±1)` - // Minimum execution time: 2_225_692_000 picoseconds. - Weight::from_parts(1_292_861_603, 12211) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_075, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_278, 0).saturating_mul(s.into())) + // Minimum execution time: 2_181_184_000 picoseconds. + Weight::from_parts(1_194_190_111, 12211) + // Standard Error: 11_578_766 + .saturating_add(Weight::from_parts(6_361_884, 0).saturating_mul(t.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_025, 0).saturating_mul(i.into())) + // Standard Error: 18 + .saturating_add(Weight::from_parts(1_158, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(16_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(11_u64)) @@ -3434,10 +3442,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `862 + r * (8 ±0)` // Estimated: `6801 + r * (8 ±0)` - // Minimum execution time: 252_664_000 picoseconds. - Weight::from_parts(277_967_331, 6801) - // Standard Error: 723 - .saturating_add(Weight::from_parts(370_111, 0).saturating_mul(r.into())) + // Minimum execution time: 241_609_000 picoseconds. + Weight::from_parts(268_716_874, 6801) + // Standard Error: 617 + .saturating_add(Weight::from_parts(377_753, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3461,10 +3469,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `870` // Estimated: `6808` - // Minimum execution time: 252_485_000 picoseconds. - Weight::from_parts(259_271_531, 6808) - // Standard Error: 2 - .saturating_add(Weight::from_parts(1_091, 0).saturating_mul(n.into())) + // Minimum execution time: 261_296_000 picoseconds. + Weight::from_parts(255_531_654, 6808) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_081, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3487,10 +3495,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6806 + r * (8 ±0)` - // Minimum execution time: 249_270_000 picoseconds. - Weight::from_parts(272_528_711, 6806) - // Standard Error: 903 - .saturating_add(Weight::from_parts(793_299, 0).saturating_mul(r.into())) + // Minimum execution time: 243_583_000 picoseconds. + Weight::from_parts(270_025_058, 6806) + // Standard Error: 560 + .saturating_add(Weight::from_parts(767_519, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3514,10 +3522,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6814` - // Minimum execution time: 249_470_000 picoseconds. - Weight::from_parts(273_317_815, 6814) - // Standard Error: 4 - .saturating_add(Weight::from_parts(3_400, 0).saturating_mul(n.into())) + // Minimum execution time: 253_798_000 picoseconds. + Weight::from_parts(265_542_351, 6814) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_343, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3540,10 +3548,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6808 + r * (8 ±0)` - // Minimum execution time: 265_503_000 picoseconds. - Weight::from_parts(279_774_666, 6808) - // Standard Error: 1_351 - .saturating_add(Weight::from_parts(439_734, 0).saturating_mul(r.into())) + // Minimum execution time: 247_332_000 picoseconds. + Weight::from_parts(269_183_656, 6808) + // Standard Error: 665 + .saturating_add(Weight::from_parts(443_386, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3567,10 +3575,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6813` - // Minimum execution time: 265_009_000 picoseconds. - Weight::from_parts(270_467_968, 6813) + // Minimum execution time: 250_855_000 picoseconds. + Weight::from_parts(258_752_975, 6813) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_202, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3593,10 +3601,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `864 + r * (8 ±0)` // Estimated: `6805 + r * (8 ±0)` - // Minimum execution time: 251_771_000 picoseconds. - Weight::from_parts(283_553_523, 6805) - // Standard Error: 1_053 - .saturating_add(Weight::from_parts(445_715, 0).saturating_mul(r.into())) + // Minimum execution time: 240_733_000 picoseconds. + Weight::from_parts(269_134_358, 6805) + // Standard Error: 512 + .saturating_add(Weight::from_parts(440_043, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into())) @@ -3620,10 +3628,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `6811` - // Minimum execution time: 253_733_000 picoseconds. - Weight::from_parts(264_277_000, 6811) - // Standard Error: 3 - .saturating_add(Weight::from_parts(1_226, 0).saturating_mul(n.into())) + // Minimum execution time: 247_377_000 picoseconds. + Weight::from_parts(261_077_322, 6811) + // Standard Error: 0 + .saturating_add(Weight::from_parts(1_195, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -3646,10 +3654,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `997 + n * (1 ±0)` // Estimated: `6934 + n * (1 ±0)` - // Minimum execution time: 337_326_000 picoseconds. - Weight::from_parts(346_340_758, 6934) - // Standard Error: 18 - .saturating_add(Weight::from_parts(6_110, 0).saturating_mul(n.into())) + // Minimum execution time: 307_337_000 picoseconds. + Weight::from_parts(326_710_473, 6934) + // Standard Error: 9 + .saturating_add(Weight::from_parts(5_765, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -3673,10 +3681,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `805 + r * (112 ±0)` // Estimated: `6748 + r * (112 ±0)` - // Minimum execution time: 253_852_000 picoseconds. - Weight::from_parts(335_731_679, 6748) - // Standard Error: 13_615 - .saturating_add(Weight::from_parts(41_557_258, 0).saturating_mul(r.into())) + // Minimum execution time: 245_432_000 picoseconds. + Weight::from_parts(294_206_377, 6748) + // Standard Error: 7_229 + .saturating_add(Weight::from_parts(41_480_485, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 112).saturating_mul(r.into())) @@ -3699,11 +3707,11 @@ impl WeightInfo for () { fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `907 + r * (76 ±0)` - // Estimated: `6801 + r * (77 ±0)` - // Minimum execution time: 256_283_000 picoseconds. - Weight::from_parts(338_634_113, 6801) - // Standard Error: 43_436 - .saturating_add(Weight::from_parts(46_607_112, 0).saturating_mul(r.into())) + // Estimated: `6802 + r * (77 ±0)` + // Minimum execution time: 247_788_000 picoseconds. + Weight::from_parts(303_940_062, 6802) + // Standard Error: 10_671 + .saturating_add(Weight::from_parts(45_730_772, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 77).saturating_mul(r.into())) @@ -3727,10 +3735,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `877 + r * (42 ±0)` // Estimated: `6816 + r * (42 ±0)` - // Minimum execution time: 269_144_000 picoseconds. - Weight::from_parts(331_790_138, 6816) - // Standard Error: 23_357 - .saturating_add(Weight::from_parts(12_213_638, 0).saturating_mul(r.into())) + // Minimum execution time: 248_825_000 picoseconds. + Weight::from_parts(286_832_225, 6816) + // Standard Error: 5_274 + .saturating_add(Weight::from_parts(11_889_262, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 42).saturating_mul(r.into())) @@ -3753,11 +3761,11 @@ impl WeightInfo for () { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (965 ±0)` - // Estimated: `6807 + r * (3090 ±10)` - // Minimum execution time: 262_624_000 picoseconds. - Weight::from_parts(275_865_000, 6807) - // Standard Error: 64_162 - .saturating_add(Weight::from_parts(26_205_387, 0).saturating_mul(r.into())) + // Estimated: `6807 + r * (3090 ±7)` + // Minimum execution time: 244_982_000 picoseconds. + Weight::from_parts(265_297_000, 6807) + // Standard Error: 39_895 + .saturating_add(Weight::from_parts(22_435_888, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3783,10 +3791,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `928 + r * (131 ±0)` // Estimated: `6878 + r * (2606 ±0)` - // Minimum execution time: 265_482_000 picoseconds. - Weight::from_parts(296_491_925, 6878) - // Standard Error: 46_681 - .saturating_add(Weight::from_parts(6_572_162, 0).saturating_mul(r.into())) + // Minimum execution time: 246_455_000 picoseconds. + Weight::from_parts(275_334_919, 6878) + // Standard Error: 20_911 + .saturating_add(Weight::from_parts(6_427_525, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3812,10 +3820,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `969 + r * (183 ±0)` // Estimated: `129453 + r * (2568 ±0)` - // Minimum execution time: 257_532_000 picoseconds. - Weight::from_parts(299_110_930, 129453) - // Standard Error: 55_003 - .saturating_add(Weight::from_parts(6_130_357, 0).saturating_mul(r.into())) + // Minimum execution time: 254_472_000 picoseconds. + Weight::from_parts(280_657_909, 129453) + // Standard Error: 20_131 + .saturating_add(Weight::from_parts(5_644_006, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -3841,10 +3849,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `858 + r * (3 ±0)` // Estimated: `6804 + r * (3 ±0)` - // Minimum execution time: 268_894_000 picoseconds. - Weight::from_parts(287_048_741, 6804) - // Standard Error: 1_156 - .saturating_add(Weight::from_parts(172_596, 0).saturating_mul(r.into())) + // Minimum execution time: 250_535_000 picoseconds. + Weight::from_parts(270_318_376, 6804) + // Standard Error: 386 + .saturating_add(Weight::from_parts(174_627, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -3868,10 +3876,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `2109 + r * (39 ±0)` // Estimated: `7899 + r * (40 ±0)` - // Minimum execution time: 262_736_000 picoseconds. - Weight::from_parts(389_199_672, 7899) - // Standard Error: 2_646 - .saturating_add(Weight::from_parts(290_309, 0).saturating_mul(r.into())) + // Minimum execution time: 248_174_000 picoseconds. + Weight::from_parts(301_826_520, 7899) + // Standard Error: 801 + .saturating_add(Weight::from_parts(248_479, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 40).saturating_mul(r.into())) @@ -3897,22 +3905,22 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `6801 + r * (3 ±0)` - // Minimum execution time: 253_465_000 picoseconds. - Weight::from_parts(283_153_874, 6801) - // Standard Error: 745 - .saturating_add(Weight::from_parts(148_864, 0).saturating_mul(r.into())) + // Minimum execution time: 246_540_000 picoseconds. + Weight::from_parts(268_913_509, 6801) + // Standard Error: 378 + .saturating_add(Weight::from_parts(154_950, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) } /// The range of component `r` is `[0, 5000]`. - fn instr_i64const(r: u32, ) -> Weight { + fn instr_i64_load_store(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_342_000 picoseconds. - Weight::from_parts(1_940_100, 0) - // Standard Error: 21 - .saturating_add(Weight::from_parts(11_117, 0).saturating_mul(r.into())) + // Minimum execution time: 1_777_000 picoseconds. + Weight::from_parts(1_707_601, 0) + // Standard Error: 14 + .saturating_add(Weight::from_parts(15_392, 0).saturating_mul(r.into())) } } -- GitLab From 4fb2a559046b98be1e1b67464cd90442bbe76063 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi Date: Fri, 19 Jan 2024 23:20:18 +0200 Subject: [PATCH 041/283] Make `Slot` and `SlotDuration` transparent (#2999) I have a use case that for safety requires all contained data structures to be `#[repr(C)]` or `#[repr(transparent)]` and it seemed like non-invasive change. --- substrate/primitives/consensus/slots/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substrate/primitives/consensus/slots/src/lib.rs b/substrate/primitives/consensus/slots/src/lib.rs index b9a032c1bcf..23cb7f7365a 100644 --- a/substrate/primitives/consensus/slots/src/lib.rs +++ b/substrate/primitives/consensus/slots/src/lib.rs @@ -26,6 +26,7 @@ use sp_timestamp::Timestamp; /// Unit type wrapper that represents a slot. #[derive(Debug, Encode, MaxEncodedLen, Decode, Eq, Clone, Copy, Default, Ord, Hash, TypeInfo)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[repr(transparent)] pub struct Slot(u64); impl core::ops::Deref for Slot { @@ -135,6 +136,7 @@ impl From for u64 { Eq, TypeInfo, )] +#[repr(transparent)] pub struct SlotDuration(u64); impl SlotDuration { -- GitLab From f2336d32f274e815ebd80e671492fa5f4107cdb9 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Fri, 19 Jan 2024 21:54:39 +0100 Subject: [PATCH 042/283] better debugging for accountid32 in debug build (#2990) --- substrate/primitives/core/src/crypto.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/substrate/primitives/core/src/crypto.rs b/substrate/primitives/core/src/crypto.rs index 2da38d44be4..58d8616368e 100644 --- a/substrate/primitives/core/src/crypto.rs +++ b/substrate/primitives/core/src/crypto.rs @@ -593,14 +593,16 @@ impl std::fmt::Display for AccountId32 { } impl sp_std::fmt::Debug for AccountId32 { - #[cfg(feature = "std")] fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) - } + #[cfg(feature = "serde")] + { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.0), &s[0..8])?; + } + + #[cfg(not(feature = "serde"))] + write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0))?; - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { Ok(()) } } -- GitLab From 84ff0a974daece89b3c56adb0a5430351bb3d1f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:41:55 +0100 Subject: [PATCH 043/283] Bump h2 from 0.3.21 to 0.3.24 (#3004) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [h2](https://github.com/hyperium/h2) from 0.3.21 to 0.3.24.
Release notes

Sourced from h2's releases.

v0.3.24

Fixed

  • Limit error resets for misbehaving connections.

v0.3.23

What's Changed

v0.3.22

What's Changed

  • Add header_table_size(usize) option to client and server builders.
  • Improve throughput when vectored IO is not available.
  • Update indexmap to 2.

New Contributors

Changelog

Sourced from h2's changelog.

0.3.24 (January 17, 2024)

  • Limit error resets for misbehaving connections.

0.3.23 (January 10, 2024)

  • Backport fix from 0.4.1 for stream capacity assignment.

0.3.22 (November 15, 2023)

  • Add header_table_size(usize) option to client and server builders.
  • Improve throughput when vectored IO is not available.
  • Update indexmap to 2.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=h2&package-manager=cargo&previous-version=0.3.21&new-version=0.3.24)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/paritytech/polkadot-sdk/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74d87c2afc8..941f16b68eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6225,9 +6225,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -6235,7 +6235,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.0.0", "slab", "tokio", "tokio-util", -- GitLab From 3b7a8c75bbad9be07d655890571b659238a29679 Mon Sep 17 00:00:00 2001 From: Doordashcon Date: Sat, 20 Jan 2024 10:51:25 +0100 Subject: [PATCH 044/283] Adding `try_state` hook for Tips pallet (#1871) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of https://github.com/paritytech/polkadot-sdk/issues/239. Invariant 1. The number of entries in `Tips` should be equal to `Reasons`. 2. If `OpenTip.finders_fee` is true, then `OpenTip.deposit` should be greater than zero. 3. Reasons exists for each Tip[`OpenTip.reason`], implying equal length of storage. polkadot address: 12zsKEDVcHpKEWb99iFt3xrTCQQXZMu477nJQsTBBrof5k2h --------- Co-authored-by: Gonçalo Pestana Co-authored-by: Oliver Tale-Yazdi --- prdoc/pr_1871.prdoc | 12 +++ substrate/frame/tips/src/lib.rs | 59 ++++++++++++++- substrate/frame/tips/src/tests.rs | 122 ++++++++++++++++++++++++++---- 3 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 prdoc/pr_1871.prdoc diff --git a/prdoc/pr_1871.prdoc b/prdoc/pr_1871.prdoc new file mode 100644 index 00000000000..d1850509afb --- /dev/null +++ b/prdoc/pr_1871.prdoc @@ -0,0 +1,12 @@ +title: Adding `try-state` hook to tips pallet + +doc: + - audience: Runtime User + description: | + Enforces the following invariants; + 1. The number of entries in Tips should be equal to Reasons. + 2. If OpenTip.finders_fee is true, then OpenTip.deposit should be greater than zero. + 3. Reasons exists for each Tip[OpenTip.reason], implying equal length of storage. + +crates: +- name: pallet-tips diff --git a/substrate/frame/tips/src/lib.rs b/substrate/frame/tips/src/lib.rs index 8764486d5f4..4c7cfc3028a 100644 --- a/substrate/frame/tips/src/lib.rs +++ b/substrate/frame/tips/src/lib.rs @@ -68,6 +68,7 @@ use sp_std::prelude::*; use codec::{Decode, Encode}; use frame_support::{ + ensure, traits::{ ContainsLengthBound, Currency, EnsureOrigin, ExistenceRequirement::KeepAlive, Get, OnUnbalanced, ReservableCurrency, SortedMembers, @@ -76,6 +77,9 @@ use frame_support::{ }; use frame_system::pallet_prelude::BlockNumberFor; +#[cfg(any(feature = "try-runtime", test))] +use sp_runtime::TryRuntimeError; + pub use pallet::*; pub use weights::WeightInfo; @@ -150,7 +154,7 @@ pub mod pallet { #[pallet::constant] type TipFindersFee: Get; - /// The amount held on deposit for placing a tip report. + /// The non-zero amount held on deposit for placing a tip report. #[pallet::constant] type TipReportDepositBase: Get>; @@ -465,6 +469,21 @@ pub mod pallet { Ok(()) } } + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn integrity_test() { + assert!( + !T::TipReportDepositBase::get().is_zero(), + "`TipReportDepositBase` should not be zero", + ); + } + + #[cfg(feature = "try-runtime")] + fn try_state(_n: BlockNumberFor) -> Result<(), TryRuntimeError> { + Self::do_try_state() + } + } } impl, I: 'static> Pallet { @@ -611,4 +630,42 @@ impl, I: 'static> Pallet { Tips::::insert(hash, new_tip) } } + + /// Ensure the correctness of the state of this pallet. + /// + /// This should be valid before and after each state transition of this pallet. + /// + /// ## Invariants: + /// 1. The number of entries in `Tips` should be equal to `Reasons`. + /// 2. Reasons exists for each Tip[`OpenTip.reason`]. + /// 3. If `OpenTip.finders_fee` is true, then OpenTip.deposit should be greater than zero. + #[cfg(any(feature = "try-runtime", test))] + pub fn do_try_state() -> Result<(), TryRuntimeError> { + let reasons = Reasons::::iter_keys().collect::>(); + let tips = Tips::::iter_keys().collect::>(); + + ensure!( + reasons.len() == tips.len(), + TryRuntimeError::Other("Equal length of entries in `Tips` and `Reasons` Storage") + ); + + for tip in Tips::::iter_keys() { + let open_tip = Tips::::get(&tip).expect("All map keys are valid; qed"); + + if open_tip.finders_fee { + ensure!( + !open_tip.deposit.is_zero(), + TryRuntimeError::Other( + "Tips with `finders_fee` should have non-zero `deposit`." + ) + ) + } + + ensure!( + reasons.contains(&open_tip.reason), + TryRuntimeError::Other("no reason for this tip") + ); + } + Ok(()) + } } diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index d5c8e17a396..63ac8e37cdd 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -31,7 +31,7 @@ use frame_support::{ storage::StoragePrefixedMap, traits::{ tokens::{PayFromAccount, UnityAssetBalanceConversion}, - ConstU32, ConstU64, SortedMembers, StorageVersion, + ConstU32, ConstU64, IntegrityTest, SortedMembers, StorageVersion, }, PalletId, }; @@ -189,13 +189,14 @@ impl pallet_treasury::Config for Test { parameter_types! { pub const TipFindersFee: Percent = Percent::from_percent(20); + pub static TipReportDepositBase: u64 = 1; } impl Config for Test { type MaximumReasonLength = ConstU32<16384>; type Tippers = TenToFourteen; type TipCountdown = ConstU64<1>; type TipFindersFee = TipFindersFee; - type TipReportDepositBase = ConstU64<1>; + type TipReportDepositBase = TipReportDepositBase; type DataDepositPerByte = ConstU64<1>; type MaxTipAmount = ConstU64<10_000_000>; type RuntimeEvent = RuntimeEvent; @@ -207,7 +208,7 @@ impl Config for Test { type Tippers = TenToFourteen; type TipCountdown = ConstU64<1>; type TipFindersFee = TipFindersFee; - type TipReportDepositBase = ConstU64<1>; + type TipReportDepositBase = TipReportDepositBase; type DataDepositPerByte = ConstU64<1>; type MaxTipAmount = ConstU64<10_000_000>; type RuntimeEvent = RuntimeEvent; @@ -228,6 +229,14 @@ pub fn new_test_ext() -> sp_io::TestExternalities { ext } +/// Run the function pointer inside externalities and asserts the try_state hook at the end. +pub fn build_and_execute(test: impl FnOnce() -> ()) { + new_test_ext().execute_with(|| { + test(); + Tips::do_try_state().expect("All invariants must hold after a test"); + }); +} + fn last_event() -> TipEvent { System::events() .into_iter() @@ -239,7 +248,7 @@ fn last_event() -> TipEvent { #[test] fn genesis_config_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { assert_eq!(Treasury::pot(), 0); assert_eq!(Treasury::proposal_count(), 0); }); @@ -251,7 +260,7 @@ fn tip_hash() -> H256 { #[test] fn tip_new_cannot_be_used_twice() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 10)); assert_noop!( @@ -263,7 +272,7 @@ fn tip_new_cannot_be_used_twice() { #[test] fn report_awesome_and_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 3)); assert_eq!(Balances::reserved_balance(0), 12); @@ -290,7 +299,7 @@ fn report_awesome_and_tip_works() { #[test] fn report_awesome_from_beneficiary_and_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 0)); assert_eq!(Balances::reserved_balance(0), 12); @@ -308,7 +317,7 @@ fn report_awesome_from_beneficiary_and_tip_works() { #[test] fn close_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { System::set_block_number(1); Balances::make_free_balance_be(&Treasury::account_id(), 101); @@ -346,7 +355,7 @@ fn close_tip_works() { #[test] fn slash_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { System::set_block_number(1); Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_eq!(Treasury::pot(), 100); @@ -377,7 +386,7 @@ fn slash_tip_works() { #[test] fn retract_tip_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { // with report awesome Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 3)); @@ -411,7 +420,7 @@ fn retract_tip_works() { #[test] fn tip_median_calculation_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 0)); let h = tip_hash(); @@ -425,7 +434,7 @@ fn tip_median_calculation_works() { #[test] fn tip_large_should_fail() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 0)); let h = tip_hash(); @@ -442,7 +451,7 @@ fn tip_large_should_fail() { #[test] fn tip_changing_works() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Tips::tip_new(RuntimeOrigin::signed(10), b"awesome.dot".to_vec(), 3, 10000)); let h = tip_hash(); @@ -627,7 +636,7 @@ fn genesis_funding_works() { #[test] fn report_awesome_and_tip_works_second_instance() { - new_test_ext().execute_with(|| { + build_and_execute(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); Balances::make_free_balance_be(&Treasury1::account_id(), 201); assert_eq!(Balances::free_balance(&Treasury::account_id()), 101); @@ -657,3 +666,88 @@ fn report_awesome_and_tip_works_second_instance() { assert_eq!(Balances::free_balance(&Treasury1::account_id()), 191); }); } + +#[test] +fn equal_entries_invariant() { + new_test_ext().execute_with(|| { + use frame_support::pallet_prelude::DispatchError::Other; + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 3)); + + let reason1 = BlakeTwo256::hash(b"reason1"); + let hash1 = BlakeTwo256::hash_of(&(reason1, 10u64)); + + let tip = OpenTip:: { + reason: reason1, + who: 10, + finder: 20, + deposit: 30, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: true, + }; + + // Breaks invariant by adding an entry to only `Tips` Storage. + pallet_tips::Tips::::insert(hash1, tip); + + // Invariant violated + assert_eq!( + Tips::do_try_state(), + Err(Other("Equal length of entries in `Tips` and `Reasons` Storage")) + ); + }) +} + +#[test] +fn finders_fee_invariant() { + new_test_ext().execute_with(|| { + use frame_support::pallet_prelude::DispatchError::Other; + + // Breaks invariant by having a zero deposit. + TipReportDepositBase::set(0); + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"".to_vec(), 3)); + + // Invariant violated + assert_eq!( + Tips::do_try_state(), + Err(Other("Tips with `finders_fee` should have non-zero `deposit`.")) + ); + }) +} + +#[test] +fn reasons_invariant() { + new_test_ext().execute_with(|| { + use frame_support::pallet_prelude::DispatchError::Other; + + Balances::make_free_balance_be(&Treasury::account_id(), 101); + + assert_ok!(Tips::report_awesome(RuntimeOrigin::signed(0), b"awesome.dot".to_vec(), 0)); + + let hash: Vec<_> = pallet_tips::Tips::::iter_keys().collect(); + + let mut open_tip = pallet_tips::Tips::::take(hash[0]).unwrap(); + + // Breaks invariant by changing value `open_tip.reason` in `Tips` Storage. + open_tip.reason = ::Hashing::hash(&b"".to_vec()); + + pallet_tips::Tips::::insert(hash[0], open_tip); + + // Invariant violated + assert_eq!(Tips::do_try_state(), Err(Other("no reason for this tip"))); + }) +} + +#[test] +#[should_panic = "`TipReportDepositBase` should not be zero"] +fn zero_base_deposit_prohibited() { + new_test_ext().execute_with(|| { + TipReportDepositBase::set(0); + Tips::integrity_test(); + }); +} -- GitLab From a5370fb1877cc9672cb47fea36a27cfed3f4da63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 20 Jan 2024 23:24:48 +1100 Subject: [PATCH 045/283] Bump comfy-table from 7.0.1 to 7.1.0 (#2993) Bumps [comfy-table](https://github.com/nukesor/comfy-table) from 7.0.1 to 7.1.0.
Release notes

Sourced from comfy-table's releases.

v7.1.0

[7.1.0] - 2023-10-21

Added

  • Add helper methods (col,row)_count and is_empty. The first set of methods return the number of columns and rows respectively. The method is_empty returns if the table is empty (contains no data rows). Implemented by Techassi in #119.

Chore

  • Bump crossterm dependency
Changelog

Sourced from comfy-table's changelog.

[7.1.0] - 2023-10-21

Added

  • Add helper methods (col,row)_count and is_empty. The first set of methods return the number of columns and rows respectively. The method is_empty returns if the table is empty (contains no data rows). Implemented by Techassi in #119.

Chore

  • Bump crossterm dependency
Commits
  • ef14a13 chore: Release comfy-table version 7.1.0
  • 3f0563e docs: Update changelog
  • fb636c9 Merge pull request #125 from Nukesor/dependabot/github_actions/actions/checko...
  • f3c9e1d build(deps): bump actions/checkout from 3 to 4
  • ec99e06 Merge pull request #128 from Nukesor/updates
  • 329f4c9 change: Use 1.70 in CI for criterion
  • 1b6d452 bump: Crossterm
  • af3924c chore: Clippy issues
  • aebf4ef Merge pull request #119 from Techassi/feature/row-col-count
  • 9f45a5e Merge pull request #122 from ip1981/ip1981/cell-hash
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=comfy-table&package-manager=cargo&previous-version=7.0.1&new-version=7.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 45 +++++++++++++------ .../utils/frame/benchmarking-cli/Cargo.toml | 2 +- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 941f16b68eb..0a004b3a736 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2883,12 +2883,12 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.0.1" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab77dbd8adecaf3f0db40581631b995f312a8a5ae3aa9993188bb8f23d83a5b" +checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" dependencies = [ - "strum", - "strum_macros", + "strum 0.25.0", + "strum_macros 0.25.3", "unicode-width", ] @@ -9826,7 +9826,7 @@ dependencies = [ "sp-runtime", "sp-std 8.0.0", "sp-tracing 10.0.0", - "strum", + "strum 0.24.1", ] [[package]] @@ -12882,7 +12882,7 @@ dependencies = [ "rand_chacha 0.3.1", "sc-authority-discovery", "sc-network", - "strum", + "strum 0.24.1", "thiserror", "tracing-gum", ] @@ -18215,7 +18215,7 @@ dependencies = [ "sp-mmr-primitives", "sp-runtime", "sp-std 8.0.0", - "strum", + "strum 0.24.1", "w3f-bls", ] @@ -18496,7 +18496,7 @@ version = "24.0.0" dependencies = [ "sp-core", "sp-runtime", - "strum", + "strum 0.24.1", ] [[package]] @@ -19038,7 +19038,7 @@ checksum = "08615eea740067d9899969bc2891c68a19c315cb1f66640af9a9ecb91b13bcab" dependencies = [ "lazy_static", "maplit", - "strum", + "strum 0.24.1", ] [[package]] @@ -19406,9 +19406,15 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "strum_macros", + "strum_macros 0.24.3", ] +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + [[package]] name = "strum_macros" version = "0.24.3" @@ -19422,6 +19428,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.48", +] + [[package]] name = "subkey" version = "3.0.0" @@ -19685,7 +19704,7 @@ dependencies = [ "filetime", "parity-wasm", "sp-maybe-compressed-blob", - "strum", + "strum 0.24.1", "tempfile", "toml 0.8.8", "walkdir", @@ -21132,8 +21151,8 @@ checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52" dependencies = [ "anyhow", "libc", - "strum", - "strum_macros", + "strum 0.24.1", + "strum_macros 0.24.3", "tempfile", "thiserror", "wasm-opt-cxx-sys", diff --git a/substrate/utils/frame/benchmarking-cli/Cargo.toml b/substrate/utils/frame/benchmarking-cli/Cargo.toml index ba95afeeee9..d6a96abb23f 100644 --- a/substrate/utils/frame/benchmarking-cli/Cargo.toml +++ b/substrate/utils/frame/benchmarking-cli/Cargo.toml @@ -20,7 +20,7 @@ array-bytes = "6.1" chrono = "0.4" clap = { version = "4.4.18", features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.6.1" } -comfy-table = { version = "7.0.1", default-features = false } +comfy-table = { version = "7.1.0", default-features = false } handlebars = "4.2.2" Inflector = "0.11.4" itertools = "0.10.3" -- GitLab From caa987d26d14bbdbfbc9be08a1da4c2b117fcaa3 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Sun, 21 Jan 2024 06:51:04 +0800 Subject: [PATCH 046/283] Adder Parachain: Accept output file argument to `export-genesis-*` subcommands (#2370) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR makes a small change the the adder parachain's CLI. It allows the user to specify an output file explicitly when generating the genesis wasm and head data. Now we no longer have to rely on redirecting the output to a file at the shell level. This change is nice because if you have any debugging lines enabled, shell redirection does not work. More to the point, this makes the adder parachain's CLI match the cumulus collator's CLI. And that will allow tools like Zombienet (that support both cumulus and the adder) to use the positional argument. cc @pepoviola --------- Co-authored-by: Joshy Orndorff Co-authored-by: Bastian Köcher --- .../test-parachains/adder/collator/src/cli.rs | 13 ++++++++-- .../adder/collator/src/main.rs | 26 ++++++++++++++++--- .../undying/collator/src/main.rs | 4 +-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs index f81e4cc0fff..5e9b4f584d4 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/cli.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/cli.rs @@ -18,6 +18,7 @@ use clap::Parser; use sc_cli::SubstrateCli; +use std::path::PathBuf; /// Sub-commands supported by the collator. #[derive(Debug, Parser)] @@ -33,11 +34,19 @@ pub enum Subcommand { /// Command for exporting the genesis head data of the parachain #[derive(Debug, Parser)] -pub struct ExportGenesisHeadCommand {} +pub struct ExportGenesisHeadCommand { + /// Output file name or stdout if unspecified. + #[arg()] + pub output: Option, +} /// Command for exporting the genesis wasm file. #[derive(Debug, Parser)] -pub struct ExportGenesisWasmCommand {} +pub struct ExportGenesisWasmCommand { + /// Output file name or stdout if unspecified. + #[arg()] + pub output: Option, +} #[allow(missing_docs)] #[derive(Debug, Parser)] diff --git a/polkadot/parachain/test-parachains/adder/collator/src/main.rs b/polkadot/parachain/test-parachains/adder/collator/src/main.rs index 6ce93ef4ad1..5d9384d4956 100644 --- a/polkadot/parachain/test-parachains/adder/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/adder/collator/src/main.rs @@ -22,6 +22,10 @@ use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProt use polkadot_primitives::Id as ParaId; use sc_cli::{Error as SubstrateCliError, SubstrateCli}; use sp_core::hexdisplay::HexDisplay; +use std::{ + fs, + io::{self, Write}, +}; use test_parachain_adder_collator::Collator; /// The parachain ID to collate for in case it wasn't set explicitly through CLI. @@ -34,15 +38,29 @@ fn main() -> Result<()> { let cli = Cli::from_args(); match cli.subcommand { - Some(cli::Subcommand::ExportGenesisState(_params)) => { + Some(cli::Subcommand::ExportGenesisState(params)) => { let collator = Collator::new(); - println!("0x{:?}", HexDisplay::from(&collator.genesis_head())); + let output_buf = + format!("0x{:?}", HexDisplay::from(&collator.genesis_head())).into_bytes(); + + if let Some(output) = params.output { + std::fs::write(output, output_buf)?; + } else { + std::io::stdout().write_all(&output_buf)?; + } Ok::<_, Error>(()) }, - Some(cli::Subcommand::ExportGenesisWasm(_params)) => { + Some(cli::Subcommand::ExportGenesisWasm(params)) => { let collator = Collator::new(); - println!("0x{:?}", HexDisplay::from(&collator.validation_code())); + let output_buf = + format!("0x{:?}", HexDisplay::from(&collator.validation_code())).into_bytes(); + + if let Some(output) = params.output { + fs::write(output, output_buf)?; + } else { + io::stdout().write_all(&output_buf)?; + } Ok(()) }, diff --git a/polkadot/parachain/test-parachains/undying/collator/src/main.rs b/polkadot/parachain/test-parachains/undying/collator/src/main.rs index 4a15cdd697c..d6fb9a04ab3 100644 --- a/polkadot/parachain/test-parachains/undying/collator/src/main.rs +++ b/polkadot/parachain/test-parachains/undying/collator/src/main.rs @@ -54,9 +54,9 @@ fn main() -> Result<()> { Some(cli::Subcommand::ExportGenesisWasm(params)) => { // We pass some dummy values for `pov_size` and `pvf_complexity` as these don't // matter for `wasm` export. + let collator = Collator::default(); let output_buf = - format!("0x{:?}", HexDisplay::from(&Collator::default().validation_code())) - .into_bytes(); + format!("0x{:?}", HexDisplay::from(&collator.validation_code())).into_bytes(); if let Some(output) = params.output { fs::write(output, output_buf)?; -- GitLab From 21ef949b6e36e6962c88597dae708e550917a619 Mon Sep 17 00:00:00 2001 From: jserrat <35823283+Jpserrat@users.noreply.github.com> Date: Sun, 21 Jan 2024 11:15:36 +0000 Subject: [PATCH 047/283] Use clone instead of fork on pvf (#2477) @mrcnski Done the change on the prepare worker, once the prepare worker part is good I'll do the same for the execute worker. This is based on https://github.com/koute/polkavm/blob/11beebd06276ce9b84f335350138479e714f6caf/crates/polkavm/src/sandbox/linux.rs#L711. ## TODO - [x] Add a check for this capability at startup - [x] Add prdoc mentioning the new Secure Validator Mode (optional) requirement. ## Related Closes #2162 --------- Co-authored-by: Marcin S --- Cargo.lock | 14 +- polkadot/node/core/pvf/common/Cargo.toml | 1 + polkadot/node/core/pvf/common/src/execute.rs | 5 +- .../core/pvf/common/src/executor_interface.rs | 13 +- polkadot/node/core/pvf/common/src/lib.rs | 2 + .../node/core/pvf/common/src/worker/mod.rs | 160 ++++++-- .../common/src/worker/security/change_root.rs | 10 +- .../pvf/common/src/worker/security/clone.rs | 93 +++++ .../common/src/worker/security/landlock.rs | 8 +- .../pvf/common/src/worker/security/mod.rs | 6 +- .../pvf/common/src/worker/security/seccomp.rs | 4 +- .../node/core/pvf/execute-worker/Cargo.toml | 4 +- .../node/core/pvf/execute-worker/src/lib.rs | 376 ++++++++++++------ .../node/core/pvf/prepare-worker/Cargo.toml | 3 +- .../node/core/pvf/prepare-worker/src/lib.rs | 286 ++++++++----- polkadot/node/core/pvf/src/host.rs | 2 +- polkadot/node/core/pvf/src/security.rs | 226 ++++++----- polkadot/node/core/pvf/tests/it/main.rs | 3 + polkadot/node/core/pvf/tests/it/process.rs | 16 +- ...477-use-clone-instead-of-fork-on-pvf.prdoc | 22 + 20 files changed, 860 insertions(+), 394 deletions(-) create mode 100644 polkadot/node/core/pvf/common/src/worker/security/clone.rs create mode 100644 prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc diff --git a/Cargo.lock b/Cargo.lock index 0a004b3a736..73d5acd6f6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9028,16 +9028,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "os_pipe" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "os_str_bytes" version = "6.5.1" @@ -12744,6 +12734,7 @@ dependencies = [ "futures", "landlock", "libc", + "nix 0.27.1", "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-primitives", @@ -12764,10 +12755,10 @@ dependencies = [ name = "polkadot-node-core-pvf-execute-worker" version = "1.0.0" dependencies = [ + "cfg-if", "cpu-time", "libc", "nix 0.27.1", - "os_pipe", "parity-scale-codec", "polkadot-node-core-pvf-common", "polkadot-parachain-primitives", @@ -12784,7 +12775,6 @@ dependencies = [ "criterion 0.4.0", "libc", "nix 0.27.1", - "os_pipe", "parity-scale-codec", "polkadot-node-core-pvf-common", "polkadot-primitives", diff --git a/polkadot/node/core/pvf/common/Cargo.toml b/polkadot/node/core/pvf/common/Cargo.toml index b4f6ada9dbb..f2ec505e623 100644 --- a/polkadot/node/core/pvf/common/Cargo.toml +++ b/polkadot/node/core/pvf/common/Cargo.toml @@ -33,6 +33,7 @@ sp-tracing = { path = "../../../../../substrate/primitives/tracing" } [target.'cfg(target_os = "linux")'.dependencies] landlock = "0.3.0" +nix = { version = "0.27.1", features = ["sched"] } seccompiler = "0.4.0" [dev-dependencies] diff --git a/polkadot/node/core/pvf/common/src/execute.rs b/polkadot/node/core/pvf/common/src/execute.rs index 5ba5b443e6a..6b3becf524d 100644 --- a/polkadot/node/core/pvf/common/src/execute.rs +++ b/polkadot/node/core/pvf/common/src/execute.rs @@ -92,10 +92,11 @@ pub enum JobError { TimedOut, #[error("An unexpected panic has occurred in the execution job: {0}")] Panic(String), + /// Some error occurred when interfacing with the kernel. + #[error("Error interfacing with the kernel: {0}")] + Kernel(String), #[error("Could not spawn the requested thread: {0}")] CouldNotSpawnThread(String), #[error("An error occurred in the CPU time monitor thread: {0}")] CpuTimeMonitorThread(String), - #[error("Could not set pdeathsig: {0}")] - CouldNotSetPdeathsig(String), } diff --git a/polkadot/node/core/pvf/common/src/executor_interface.rs b/polkadot/node/core/pvf/common/src/executor_interface.rs index e634940dbe6..4cd2f5c85ee 100644 --- a/polkadot/node/core/pvf/common/src/executor_interface.rs +++ b/polkadot/node/core/pvf/common/src/executor_interface.rs @@ -140,7 +140,7 @@ pub unsafe fn create_runtime_from_artifact_bytes( executor_params: &ExecutorParams, ) -> Result { let mut config = DEFAULT_CONFIG.clone(); - config.semantics = params_to_wasmtime_semantics(executor_params); + config.semantics = params_to_wasmtime_semantics(executor_params).0; sc_executor_wasmtime::create_runtime_from_artifact_bytes::( compiled_artifact_blob, @@ -148,7 +148,10 @@ pub unsafe fn create_runtime_from_artifact_bytes( ) } -pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> Semantics { +/// Takes the default config and overwrites any settings with existing executor parameters. +/// +/// Returns the semantics as well as the stack limit (since we are guaranteed to have it). +pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> (Semantics, DeterministicStackLimit) { let mut sem = DEFAULT_CONFIG.semantics.clone(); let mut stack_limit = sem .deterministic_stack_limit @@ -169,8 +172,8 @@ pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> Semantics { ExecutorParam::PvfExecTimeout(_, _) => (), /* Not used here */ } } - sem.deterministic_stack_limit = Some(stack_limit); - sem + sem.deterministic_stack_limit = Some(stack_limit.clone()); + (sem, stack_limit) } /// Runs the prevalidation on the given code. Returns a [`RuntimeBlob`] if it succeeds. @@ -187,7 +190,7 @@ pub fn prepare( blob: RuntimeBlob, executor_params: &ExecutorParams, ) -> Result, sc_executor_common::error::WasmError> { - let semantics = params_to_wasmtime_semantics(executor_params); + let (semantics, _) = params_to_wasmtime_semantics(executor_params); sc_executor_wasmtime::prepare_runtime_artifact(blob, &semantics) } diff --git a/polkadot/node/core/pvf/common/src/lib.rs b/polkadot/node/core/pvf/common/src/lib.rs index af4a7526e55..d891c06bf2a 100644 --- a/polkadot/node/core/pvf/common/src/lib.rs +++ b/polkadot/node/core/pvf/common/src/lib.rs @@ -57,6 +57,8 @@ pub struct SecurityStatus { pub can_enable_seccomp: bool, /// Whether we are able to unshare the user namespace and change the filesystem root. pub can_unshare_user_namespace_and_change_root: bool, + /// Whether we are able to call `clone` with all sandboxing flags. + pub can_do_secure_clone: bool, } /// A handshake with information for the worker. diff --git a/polkadot/node/core/pvf/common/src/worker/mod.rs b/polkadot/node/core/pvf/common/src/worker/mod.rs index 9dcd535d533..d7c95d9e704 100644 --- a/polkadot/node/core/pvf/common/src/worker/mod.rs +++ b/polkadot/node/core/pvf/common/src/worker/mod.rs @@ -18,14 +18,19 @@ pub mod security; -use crate::{framed_recv_blocking, WorkerHandshake, LOG_TARGET}; +use crate::{framed_recv_blocking, SecurityStatus, WorkerHandshake, LOG_TARGET}; use cpu_time::ProcessTime; use futures::never::Never; use parity_scale_codec::Decode; use std::{ any::Any, - fmt, io, - os::unix::net::UnixStream, + fmt::{self}, + fs::File, + io::{self, Read, Write}, + os::{ + fd::{AsRawFd, FromRawFd, RawFd}, + unix::net::UnixStream, + }, path::PathBuf, sync::mpsc::{Receiver, RecvTimeoutError}, time::Duration, @@ -78,7 +83,7 @@ macro_rules! decl_worker_main { "--check-can-enable-landlock" => { #[cfg(target_os = "linux")] - let status = if let Err(err) = security::landlock::check_is_fully_enabled() { + let status = if let Err(err) = security::landlock::check_can_fully_enable() { // Write the error to stderr, log it on the host-side. eprintln!("{}", err); -1 @@ -91,7 +96,7 @@ macro_rules! decl_worker_main { }, "--check-can-enable-seccomp" => { #[cfg(all(target_os = "linux", target_arch = "x86_64"))] - let status = if let Err(err) = security::seccomp::check_is_fully_enabled() { + let status = if let Err(err) = security::seccomp::check_can_fully_enable() { // Write the error to stderr, log it on the host-side. eprintln!("{}", err); -1 @@ -107,7 +112,7 @@ macro_rules! decl_worker_main { let cache_path_tempdir = std::path::Path::new(&args[2]); #[cfg(target_os = "linux")] let status = if let Err(err) = - security::change_root::check_is_fully_enabled(&cache_path_tempdir) + security::change_root::check_can_fully_enable(&cache_path_tempdir) { // Write the error to stderr, log it on the host-side. eprintln!("{}", err); @@ -119,6 +124,21 @@ macro_rules! decl_worker_main { let status = -1; std::process::exit(status) }, + "--check-can-do-secure-clone" => { + #[cfg(target_os = "linux")] + // SAFETY: new process is spawned within a single threaded process. This + // invariant is enforced by tests. + let status = if let Err(err) = unsafe { security::clone::check_can_fully_clone() } { + // Write the error to stderr, log it on the host-side. + eprintln!("{}", err); + -1 + } else { + 0 + }; + #[cfg(not(target_os = "linux"))] + let status = -1; + std::process::exit(status) + }, "test-sleep" => { std::thread::sleep(std::time::Duration::from_secs(5)); @@ -171,6 +191,84 @@ macro_rules! decl_worker_main { }; } +//taken from the os_pipe crate. Copied here to reduce one dependency and +// because its type-safe abstractions do not play well with nix's clone +#[cfg(not(target_os = "macos"))] +pub fn pipe2_cloexec() -> io::Result<(libc::c_int, libc::c_int)> { + let mut fds: [libc::c_int; 2] = [0; 2]; + let res = unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + Ok((fds[0], fds[1])) +} + +#[cfg(target_os = "macos")] +pub fn pipe2_cloexec() -> io::Result<(libc::c_int, libc::c_int)> { + let mut fds: [libc::c_int; 2] = [0; 2]; + let res = unsafe { libc::pipe(fds.as_mut_ptr()) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + let res = unsafe { libc::fcntl(fds[0], libc::F_SETFD, libc::FD_CLOEXEC) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + let res = unsafe { libc::fcntl(fds[1], libc::F_SETFD, libc::FD_CLOEXEC) }; + if res != 0 { + return Err(io::Error::last_os_error()) + } + Ok((fds[0], fds[1])) +} + +/// A wrapper around a file descriptor used to encapsulate and restrict +/// functionality for pipe operations. +pub struct PipeFd { + file: File, +} + +impl AsRawFd for PipeFd { + /// Returns the raw file descriptor associated with this `PipeFd` + fn as_raw_fd(&self) -> RawFd { + self.file.as_raw_fd() + } +} + +impl FromRawFd for PipeFd { + /// Creates a new `PipeFd` instance from a raw file descriptor. + /// + /// # Safety + /// + /// The fd passed in must be an owned file descriptor; in particular, it must be open. + unsafe fn from_raw_fd(fd: RawFd) -> Self { + PipeFd { file: File::from_raw_fd(fd) } + } +} + +impl Read for PipeFd { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.file.read(buf) + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.file.read_to_end(buf) + } +} + +impl Write for PipeFd { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.file.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.file.flush() + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.file.write_all(buf) + } +} + /// Some allowed overhead that we account for in the "CPU time monitor" thread's sleeps, on the /// child process. pub const JOB_TIMEOUT_OVERHEAD: Duration = Duration::from_millis(50); @@ -192,14 +290,12 @@ impl fmt::Display for WorkerKind { } } -// Some fields are only used for logging, and dead-code analysis ignores Debug. -#[allow(dead_code)] #[derive(Debug)] pub struct WorkerInfo { - pid: u32, - kind: WorkerKind, - version: Option, - worker_dir_path: PathBuf, + pub pid: u32, + pub kind: WorkerKind, + pub version: Option, + pub worker_dir_path: PathBuf, } // NOTE: The worker version must be passed in so that we accurately get the version of the worker, @@ -218,7 +314,7 @@ pub fn run_worker( worker_version: Option<&str>, mut event_loop: F, ) where - F: FnMut(UnixStream, PathBuf) -> io::Result, + F: FnMut(UnixStream, &WorkerInfo, SecurityStatus) -> io::Result, { #[cfg_attr(not(target_os = "linux"), allow(unused_mut))] let mut worker_info = WorkerInfo { @@ -250,11 +346,8 @@ pub fn run_worker( } // Make sure that we can read the worker dir path, and log its contents. - let entries = || -> Result, io::Error> { - std::fs::read_dir(&worker_info.worker_dir_path)? - .map(|res| res.map(|e| e.file_name())) - .collect() - }(); + let entries: io::Result> = std::fs::read_dir(&worker_info.worker_dir_path) + .and_then(|d| d.map(|res| res.map(|e| e.file_name())).collect()); match entries { Ok(entries) => gum::trace!(target: LOG_TARGET, ?worker_info, "content of worker dir: {:?}", entries), @@ -284,6 +377,22 @@ pub fn run_worker( { gum::trace!(target: LOG_TARGET, ?security_status, "Enabling security features"); + // First, make sure env vars were cleared, to match the environment we perform the checks + // within. (In theory, running checks with different env vars could result in different + // outcomes of the checks.) + if !security::check_env_vars_were_cleared(&worker_info) { + let err = "not all env vars were cleared when spawning the process"; + gum::error!( + target: LOG_TARGET, + ?worker_info, + "{}", + err + ); + if security_status.secure_validator_mode { + worker_shutdown(worker_info, err); + } + } + // Call based on whether we can change root. Error out if it should work but fails. // // NOTE: This should not be called in a multi-threaded context (i.e. inside the tokio @@ -337,23 +446,10 @@ pub fn run_worker( } } } - - if !security::check_env_vars_were_cleared(&worker_info) { - let err = "not all env vars were cleared when spawning the process"; - gum::error!( - target: LOG_TARGET, - ?worker_info, - "{}", - err - ); - if security_status.secure_validator_mode { - worker_shutdown(worker_info, err); - } - } } // Run the main worker loop. - let err = event_loop(stream, worker_info.worker_dir_path.clone()) + let err = event_loop(stream, &worker_info, security_status) // It's never `Ok` because it's `Ok(Never)`. .unwrap_err(); diff --git a/polkadot/node/core/pvf/common/src/worker/security/change_root.rs b/polkadot/node/core/pvf/common/src/worker/security/change_root.rs index 375cc8ff6f2..9ec66906819 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/change_root.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/change_root.rs @@ -54,8 +54,7 @@ pub fn enable_for_worker(worker_info: &WorkerInfo) -> Result<()> { /// /// NOTE: This should not be called in a multi-threaded context. `unshare(2)`: /// "CLONE_NEWUSER requires that the calling process is not threaded." -#[cfg(target_os = "linux")] -pub fn check_is_fully_enabled(tempdir: &Path) -> Result<()> { +pub fn check_can_fully_enable(tempdir: &Path) -> Result<()> { let worker_dir_path = tempdir.to_owned(); try_restrict(&WorkerInfo { pid: std::process::id(), @@ -69,7 +68,6 @@ pub fn check_is_fully_enabled(tempdir: &Path) -> Result<()> { /// /// NOTE: This should not be called in a multi-threaded context. `unshare(2)`: /// "CLONE_NEWUSER requires that the calling process is not threaded." -#[cfg(target_os = "linux")] fn try_restrict(worker_info: &WorkerInfo) -> Result<()> { // TODO: Remove this once this is stable: https://github.com/rust-lang/rust/issues/105723 macro_rules! cstr_ptr { @@ -78,12 +76,6 @@ fn try_restrict(worker_info: &WorkerInfo) -> Result<()> { }; } - gum::trace!( - target: LOG_TARGET, - ?worker_info, - "unsharing the user namespace and calling pivot_root", - ); - let worker_dir_path_c = CString::new(worker_info.worker_dir_path.as_os_str().as_bytes()) .expect("on unix; the path will never contain 0 bytes; qed"); diff --git a/polkadot/node/core/pvf/common/src/worker/security/clone.rs b/polkadot/node/core/pvf/common/src/worker/security/clone.rs new file mode 100644 index 00000000000..707f68d1859 --- /dev/null +++ b/polkadot/node/core/pvf/common/src/worker/security/clone.rs @@ -0,0 +1,93 @@ +// 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 . + +//! Functionality for securing the job processes spawned by the workers using `clone`. If +//! unsupported, falls back to `fork`. + +use crate::{worker::WorkerInfo, LOG_TARGET}; +use nix::{ + errno::Errno, + sched::{CloneCb, CloneFlags}, + unistd::Pid, +}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("could not clone, errno: {0}")] + Clone(Errno), +} + +pub type Result = std::result::Result; + +/// Try to run clone(2) on the current worker. +/// +/// SAFETY: new process should be either spawned within a single threaded process, or use only +/// async-signal-safe functions. +pub unsafe fn clone_on_worker( + worker_info: &WorkerInfo, + have_unshare_newuser: bool, + cb: CloneCb, +) -> Result { + let flags = clone_flags(have_unshare_newuser); + + gum::trace!( + target: LOG_TARGET, + ?worker_info, + "calling clone with flags: {:?}", + flags + ); + + try_clone(cb, flags) +} + +/// Runs a check for clone(2) with all sandboxing flags and returns an error indicating whether it +/// can be fully enabled on the current Linux environment. +/// +/// SAFETY: new process should be either spawned within a single threaded process, or use only +/// async-signal-safe functions. +pub unsafe fn check_can_fully_clone() -> Result<()> { + try_clone(Box::new(|| 0), clone_flags(false)).map(|_pid| ()) +} + +/// Runs clone(2) with all sandboxing flags. +/// +/// SAFETY: new process should be either spawned within a single threaded process, or use only +/// async-signal-safe functions. +unsafe fn try_clone(cb: CloneCb, flags: CloneFlags) -> Result { + let mut stack = [0u8; 2 * 1024 * 1024]; + + nix::sched::clone(cb, stack.as_mut_slice(), flags, None).map_err(|errno| Error::Clone(errno)) +} + +/// Returns flags for `clone(2)`, including all the sandbox-related ones. +fn clone_flags(have_unshare_newuser: bool) -> CloneFlags { + // NOTE: CLONE_NEWUSER does not work in `clone` if we previously called `unshare` with this + // flag. On the other hand, if we did not call `unshare` we need this flag for the CAP_SYS_ADMIN + // capability. + let maybe_clone_newuser = + if have_unshare_newuser { CloneFlags::empty() } else { CloneFlags::CLONE_NEWUSER }; + // SIGCHLD flag is used to inform clone that the parent process is + // expecting a child termination signal, without this flag `waitpid` function + // return `ECHILD` error. + maybe_clone_newuser | + CloneFlags::CLONE_NEWCGROUP | + CloneFlags::CLONE_NEWIPC | + CloneFlags::CLONE_NEWNET | + CloneFlags::CLONE_NEWNS | + CloneFlags::CLONE_NEWPID | + CloneFlags::CLONE_NEWUTS | + CloneFlags::from_bits_retain(libc::SIGCHLD) +} diff --git a/polkadot/node/core/pvf/common/src/worker/security/landlock.rs b/polkadot/node/core/pvf/common/src/worker/security/landlock.rs index 211d12c2e44..10d00a0e2c6 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/landlock.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/landlock.rs @@ -112,7 +112,7 @@ pub fn enable_for_worker(worker_info: &WorkerInfo) -> Result<()> { // TODO: /// Runs a check for landlock in its own thread, and returns an error indicating whether the given /// landlock ABI is fully enabled on the current Linux environment. -pub fn check_is_fully_enabled() -> Result<()> { +pub fn check_can_fully_enable() -> Result<()> { match std::thread::spawn(|| try_restrict(std::iter::empty::<(PathBuf, AccessFs)>())).join() { Ok(Ok(())) => Ok(()), Ok(Err(err)) => Err(err), @@ -165,7 +165,7 @@ mod tests { #[test] fn restricted_thread_cannot_read_file() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } @@ -230,7 +230,7 @@ mod tests { #[test] fn restricted_thread_cannot_write_file() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } @@ -289,7 +289,7 @@ mod tests { #[test] fn restricted_thread_can_truncate_file() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } diff --git a/polkadot/node/core/pvf/common/src/worker/security/mod.rs b/polkadot/node/core/pvf/common/src/worker/security/mod.rs index ff4c712f6bd..72d47235d47 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/mod.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/mod.rs @@ -27,15 +27,17 @@ //! - Restrict networking by blocking socket creation and io_uring. //! - Remove env vars -use crate::{worker::WorkerInfo, LOG_TARGET}; - #[cfg(target_os = "linux")] pub mod change_root; #[cfg(target_os = "linux")] +pub mod clone; +#[cfg(target_os = "linux")] pub mod landlock; #[cfg(all(target_os = "linux", target_arch = "x86_64"))] pub mod seccomp; +use crate::{worker::WorkerInfo, LOG_TARGET}; + /// Require env vars to have been removed when spawning the process, to prevent malicious code from /// accessing them. pub fn check_env_vars_were_cleared(worker_info: &WorkerInfo) -> bool { diff --git a/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs b/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs index 4f270f75b34..f6100d236c8 100644 --- a/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs +++ b/polkadot/node/core/pvf/common/src/worker/security/seccomp.rs @@ -110,7 +110,7 @@ pub fn enable_for_worker(worker_info: &WorkerInfo) -> Result<()> { /// Runs a check for seccomp in its own thread, and returns an error indicating whether seccomp with /// our rules is fully enabled on the current Linux environment. -pub fn check_is_fully_enabled() -> Result<()> { +pub fn check_can_fully_enable() -> Result<()> { match std::thread::spawn(|| try_restrict()).join() { Ok(Ok(())) => Ok(()), Ok(Err(err)) => Err(err), @@ -161,7 +161,7 @@ mod tests { #[test] fn sandboxed_thread_cannot_use_sockets() { // TODO: This would be nice: . - if check_is_fully_enabled().is_err() { + if check_can_fully_enable().is_err() { return } diff --git a/polkadot/node/core/pvf/execute-worker/Cargo.toml b/polkadot/node/core/pvf/execute-worker/Cargo.toml index 83118041fdf..a0a987fb439 100644 --- a/polkadot/node/core/pvf/execute-worker/Cargo.toml +++ b/polkadot/node/core/pvf/execute-worker/Cargo.toml @@ -12,8 +12,8 @@ workspace = true [dependencies] cpu-time = "1.0.0" gum = { package = "tracing-gum", path = "../../../gum" } -os_pipe = "1.1.4" -nix = { version = "0.27.1", features = ["process", "resource"] } +cfg-if = "1.0" +nix = { version = "0.27.1", features = ["process", "resource", "sched"] } libc = "0.2.152" parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs index 6980f913d0d..0cfa5a78694 100644 --- a/polkadot/node/core/pvf/execute-worker/src/lib.rs +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -16,7 +16,7 @@ //! Contains the logic for executing PVFs. Used by the polkadot-execute-worker binary. -pub use polkadot_node_core_pvf_common::{executor_interface::execute_artifact, worker_dir}; +pub use polkadot_node_core_pvf_common::executor_interface::execute_artifact; // NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are // separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-execute-worker=trace`. @@ -31,64 +31,41 @@ use nix::{ }, unistd::{ForkResult, Pid}, }; -use os_pipe::{self, PipeReader, PipeWriter}; use parity_scale_codec::{Decode, Encode}; use polkadot_node_core_pvf_common::{ error::InternalValidationError, execute::{Handshake, JobError, JobResponse, JobResult, WorkerResponse}, + executor_interface::params_to_wasmtime_semantics, framed_recv_blocking, framed_send_blocking, worker::{ - cpu_time_monitor_loop, run_worker, stringify_panic_payload, + cpu_time_monitor_loop, pipe2_cloexec, run_worker, stringify_panic_payload, thread::{self, WaitOutcome}, - WorkerKind, + PipeFd, WorkerInfo, WorkerKind, }, + worker_dir, }; use polkadot_parachain_primitives::primitives::ValidationResult; -use polkadot_primitives::{executor_params::DEFAULT_NATIVE_STACK_MAX, ExecutorParams}; +use polkadot_primitives::ExecutorParams; use std::{ io::{self, Read}, - os::unix::net::UnixStream, + os::{ + fd::{AsRawFd, FromRawFd}, + unix::net::UnixStream, + }, path::PathBuf, process, sync::{mpsc::channel, Arc}, time::Duration, }; -// Wasmtime powers the Substrate Executor. It compiles the wasm bytecode into native code. -// That native code does not create any stacks and just reuses the stack of the thread that -// wasmtime was invoked from. -// -// Also, we configure the executor to provide the deterministic stack and that requires -// supplying the amount of the native stack space that wasm is allowed to use. This is -// realized by supplying the limit into `wasmtime::Config::max_wasm_stack`. -// -// There are quirks to that configuration knob: -// -// 1. It only limits the amount of stack space consumed by wasm but does not ensure nor check that -// the stack space is actually available. -// -// That means, if the calling thread has 1 MiB of stack space left and the wasm code consumes -// more, then the wasmtime limit will **not** trigger. Instead, the wasm code will hit the -// guard page and the Rust stack overflow handler will be triggered. That leads to an -// **abort**. -// -// 2. It cannot and does not limit the stack space consumed by Rust code. -// -// Meaning that if the wasm code leaves no stack space for Rust code, then the Rust code -// will abort and that will abort the process as well. -// -// Typically on Linux the main thread gets the stack size specified by the `ulimit` and -// typically it's configured to 8 MiB. Rust's spawned threads are 2 MiB. OTOH, the -// DEFAULT_NATIVE_STACK_MAX is set to 256 MiB. Not nearly enough. -// -// Hence we need to increase it. The simplest way to fix that is to spawn a thread with the desired -// stack limit. -// -// The reasoning why we pick this particular size is: -// -// The default Rust thread stack limit 2 MiB + 256 MiB wasm stack. -/// The stack size for the execute thread. -pub const EXECUTE_THREAD_STACK_SIZE: usize = 2 * 1024 * 1024 + DEFAULT_NATIVE_STACK_MAX as usize; +/// The number of threads for the child process: +/// 1 - Main thread +/// 2 - Cpu monitor thread +/// 3 - Execute thread +/// +/// NOTE: The correctness of this value is enforced by a test. If the number of threads inside +/// the child process changes in the future, this value must be changed as well. +pub const EXECUTE_WORKER_THREAD_NUMBER: u32 = 3; /// Receives a handshake with information specific to the execute worker. fn recv_execute_handshake(stream: &mut UnixStream) -> io::Result { @@ -145,17 +122,20 @@ pub fn worker_entrypoint( worker_dir_path, node_version, worker_version, - |mut stream, worker_dir_path| { - let worker_pid = process::id(); - let artifact_path = worker_dir::execute_artifact(&worker_dir_path); + |mut stream, worker_info, security_status| { + let artifact_path = worker_dir::execute_artifact(&worker_info.worker_dir_path); let Handshake { executor_params } = recv_execute_handshake(&mut stream)?; + let executor_params: Arc = Arc::new(executor_params); + let execute_thread_stack_size = max_stack_size(&executor_params); + loop { let (params, execution_timeout) = recv_request(&mut stream)?; gum::debug!( target: LOG_TARGET, - %worker_pid, + ?worker_info, + ?security_status, "worker: validating artifact {}", artifact_path.display(), ); @@ -172,7 +152,7 @@ pub fn worker_entrypoint( }, }; - let (pipe_reader, pipe_writer) = os_pipe::pipe()?; + let (pipe_read_fd, pipe_write_fd) = pipe2_cloexec()?; let usage_before = match nix::sys::resource::getrusage(UsageWho::RUSAGE_CHILDREN) { Ok(usage) => usage, @@ -182,44 +162,65 @@ pub fn worker_entrypoint( continue }, }; - - // SAFETY: new process is spawned within a single threaded process. This invariant - // is enforced by tests. - let response = match unsafe { nix::unistd::fork() } { - Err(errno) => internal_error_from_errno("fork", errno), - Ok(ForkResult::Child) => { - // Dropping the stream closes the underlying socket. We want to make sure - // that the sandboxed child can't get any kind of information from the - // outside world. The only IPC it should be able to do is sending its - // response over the pipe. - drop(stream); - // Drop the read end so we don't have too many FDs open. - drop(pipe_reader); - - handle_child_process( - pipe_writer, - compiled_artifact_blob, - executor_params, - params, + let stream_fd = stream.as_raw_fd(); + + let compiled_artifact_blob = Arc::new(compiled_artifact_blob); + let params = Arc::new(params); + + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + let result = if security_status.can_do_secure_clone { + handle_clone( + pipe_write_fd, + pipe_read_fd, + stream_fd, + &compiled_artifact_blob, + &executor_params, + ¶ms, + execution_timeout, + execute_thread_stack_size, + worker_info, + security_status.can_unshare_user_namespace_and_change_root, + usage_before, + )? + } else { + // Fall back to using fork. + handle_fork( + pipe_write_fd, + pipe_read_fd, + stream_fd, + &compiled_artifact_blob, + &executor_params, + ¶ms, + execution_timeout, + execute_thread_stack_size, + worker_info, + usage_before, + )? + }; + } else { + let result = handle_fork( + pipe_write_fd, + pipe_read_fd, + stream_fd, + &compiled_artifact_blob, + &executor_params, + ¶ms, execution_timeout, - ) - }, - Ok(ForkResult::Parent { child }) => { - // the read end will wait until all write ends have been closed, - // this drop is necessary to avoid deadlock - drop(pipe_writer); - - handle_parent_process( - pipe_reader, - child, - worker_pid, + execute_thread_stack_size, + worker_info, usage_before, - execution_timeout, - )? - }, - }; + )?; + } + } - send_response(&mut stream, response)?; + gum::trace!( + target: LOG_TARGET, + ?worker_info, + "worker: sending result to host: {:?}", + result + ); + send_response(&mut stream, result)?; } }, ); @@ -252,39 +253,122 @@ fn validate_using_artifact( JobResponse::Ok { result_descriptor } } +#[cfg(target_os = "linux")] +fn handle_clone( + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + compiled_artifact_blob: &Arc>, + executor_params: &Arc, + params: &Arc>, + execution_timeout: Duration, + execute_stack_size: usize, + worker_info: &WorkerInfo, + have_unshare_newuser: bool, + usage_before: Usage, +) -> io::Result { + use polkadot_node_core_pvf_common::worker::security; + + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. Stack size being specified to ensure child doesn't overflow + match unsafe { + security::clone::clone_on_worker( + worker_info, + have_unshare_newuser, + Box::new(|| { + handle_child_process( + pipe_write_fd, + pipe_read_fd, + stream_fd, + Arc::clone(compiled_artifact_blob), + Arc::clone(executor_params), + Arc::clone(params), + execution_timeout, + execute_stack_size, + ) + }), + ) + } { + Ok(child) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + usage_before, + execution_timeout, + ), + Err(security::clone::Error::Clone(errno)) => Ok(internal_error_from_errno("clone", errno)), + } +} + +fn handle_fork( + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + compiled_artifact_blob: &Arc>, + executor_params: &Arc, + params: &Arc>, + execution_timeout: Duration, + execute_worker_stack_size: usize, + worker_info: &WorkerInfo, + usage_before: Usage, +) -> io::Result { + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. + match unsafe { nix::unistd::fork() } { + Ok(ForkResult::Child) => handle_child_process( + pipe_write_fd, + pipe_read_fd, + stream_fd, + Arc::clone(compiled_artifact_blob), + Arc::clone(executor_params), + Arc::clone(params), + execution_timeout, + execute_worker_stack_size, + ), + Ok(ForkResult::Parent { child }) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + usage_before, + execution_timeout, + ), + Err(errno) => Ok(internal_error_from_errno("fork", errno)), + } +} + /// This is used to handle child process during pvf execute worker. -/// It execute the artifact and pipes back the response to the parent process -/// -/// # Arguments -/// -/// - `pipe_write`: A `PipeWriter` structure, the writing end of a pipe. -/// -/// - `compiled_artifact_blob`: The artifact bytes from compiled by the prepare worker`. -/// -/// - `executor_params`: Deterministically serialized execution environment semantics. -/// -/// - `params`: Validation parameters. -/// -/// - `execution_timeout`: The timeout in `Duration`. +/// It executes the artifact and pipes back the response to the parent process. /// /// # Returns /// /// - pipe back `JobResponse` to the parent process. fn handle_child_process( - mut pipe_write: PipeWriter, - compiled_artifact_blob: Vec, - executor_params: ExecutorParams, - params: Vec, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + compiled_artifact_blob: Arc>, + executor_params: Arc, + params: Arc>, execution_timeout: Duration, + execute_thread_stack_size: usize, ) -> ! { - // Terminate if the parent thread dies. Parent thread == worker process (it is single-threaded). - // - // RACE: the worker may die before we install the death signal. In practice this is unlikely, - // and most of the time the job process should terminate on its own when it completes. - #[cfg(target_os = "linux")] - nix::sys::prctl::set_pdeathsig(nix::sys::signal::Signal::SIGTERM).unwrap_or_else(|err| { - send_child_response(&mut pipe_write, Err(JobError::CouldNotSetPdeathsig(err.to_string()))) - }); + // SAFETY: this is an open and owned file descriptor at this point. + let mut pipe_write = unsafe { PipeFd::from_raw_fd(pipe_write_fd) }; + + // Drop the read end so we don't have too many FDs open. + if let Err(errno) = nix::unistd::close(pipe_read_fd) { + send_child_response(&mut pipe_write, job_error_from_errno("closing pipe", errno)); + } + + // Dropping the stream closes the underlying socket. We want to make sure + // that the sandboxed child can't get any kind of information from the + // outside world. The only IPC it should be able to do is sending its + // response over the pipe. + if let Err(errno) = nix::unistd::close(stream_fd) { + send_child_response(&mut pipe_write, job_error_from_errno("closing stream", errno)); + } gum::debug!( target: LOG_TARGET, @@ -308,13 +392,12 @@ fn handle_child_process( send_child_response(&mut pipe_write, Err(JobError::CouldNotSpawnThread(err.to_string()))) }); - let executor_params_2 = executor_params.clone(); let execute_thread = thread::spawn_worker_thread_with_stack_size( "execute thread", - move || validate_using_artifact(&compiled_artifact_blob, &executor_params_2, ¶ms), + move || validate_using_artifact(&compiled_artifact_blob, &executor_params, ¶ms), Arc::clone(&condvar), WaitOutcome::Finished, - EXECUTE_THREAD_STACK_SIZE, + execute_thread_stack_size, ) .unwrap_or_else(|err| { send_child_response(&mut pipe_write, Err(JobError::CouldNotSpawnThread(err.to_string()))) @@ -343,28 +426,69 @@ fn handle_child_process( send_child_response(&mut pipe_write, response); } -/// Waits for child process to finish and handle child response from pipe. +/// Returns stack size based on the number of threads. +/// The stack size is represented by 2MiB * number_of_threads + native stack; /// -/// # Arguments +/// # Background /// -/// - `pipe_read`: A `PipeReader` used to read data from the child process. +/// Wasmtime powers the Substrate Executor. It compiles the wasm bytecode into native code. +/// That native code does not create any stacks and just reuses the stack of the thread that +/// wasmtime was invoked from. /// -/// - `child`: The child pid. +/// Also, we configure the executor to provide the deterministic stack and that requires +/// supplying the amount of the native stack space that wasm is allowed to use. This is +/// realized by supplying the limit into `wasmtime::Config::max_wasm_stack`. /// -/// - `usage_before`: Resource usage statistics before executing the child process. +/// There are quirks to that configuration knob: /// -/// - `timeout`: The maximum allowed time for the child process to finish, in `Duration`. +/// 1. It only limits the amount of stack space consumed by wasm but does not ensure nor check that +/// the stack space is actually available. +/// +/// That means, if the calling thread has 1 MiB of stack space left and the wasm code consumes +/// more, then the wasmtime limit will **not** trigger. Instead, the wasm code will hit the +/// guard page and the Rust stack overflow handler will be triggered. That leads to an +/// **abort**. +/// +/// 2. It cannot and does not limit the stack space consumed by Rust code. +/// +/// Meaning that if the wasm code leaves no stack space for Rust code, then the Rust code +/// will abort and that will abort the process as well. +/// +/// Typically on Linux the main thread gets the stack size specified by the `ulimit` and +/// typically it's configured to 8 MiB. Rust's spawned threads are 2 MiB. OTOH, the +/// DEFAULT_NATIVE_STACK_MAX is set to 256 MiB. Not nearly enough. +/// +/// Hence we need to increase it. The simplest way to fix that is to spawn an execute thread with +/// the desired stack limit. We must also make sure the job process has enough stack for *all* its +/// threads. This function can be used to get the stack size of either the execute thread or execute +/// job process. +fn max_stack_size(executor_params: &ExecutorParams) -> usize { + let (_sem, deterministic_stack_limit) = params_to_wasmtime_semantics(executor_params); + return (2 * 1024 * 1024 + deterministic_stack_limit.native_stack_max) as usize; +} + +/// Waits for child process to finish and handle child response from pipe. /// /// # Returns /// /// - The response, either `Ok` or some error state. fn handle_parent_process( - mut pipe_read: PipeReader, + pipe_read_fd: i32, + pipe_write_fd: i32, + worker_info: &WorkerInfo, job_pid: Pid, - worker_pid: u32, usage_before: Usage, timeout: Duration, ) -> io::Result { + // the read end will wait until all write ends have been closed, + // this drop is necessary to avoid deadlock + if let Err(errno) = nix::unistd::close(pipe_write_fd) { + return Ok(internal_error_from_errno("closing pipe write fd", errno)); + }; + + // SAFETY: pipe_read_fd is an open and owned file descriptor at this point. + let mut pipe_read = unsafe { PipeFd::from_raw_fd(pipe_read_fd) }; + // Read from the child. Don't decode unless the process exited normally, which we check later. let mut received_data = Vec::new(); pipe_read @@ -376,7 +500,7 @@ fn handle_parent_process( let status = nix::sys::wait::waitpid(job_pid, None); gum::trace!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "execute worker received wait status from job: {:?}", status, @@ -396,7 +520,7 @@ fn handle_parent_process( if cpu_tv >= timeout { gum::warn!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "execute job took {}ms cpu time, exceeded execute timeout {}ms", cpu_tv.as_millis(), @@ -429,7 +553,7 @@ fn handle_parent_process( Err(job_error) => { gum::warn!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "execute job error: {}", job_error, @@ -490,14 +614,14 @@ fn recv_child_response(received_data: &mut io::BufReader<&[u8]>) -> io::Result ! { +/// - `response`: Child process response +fn send_child_response(pipe_write: &mut PipeFd, response: JobResult) -> ! { framed_send_blocking(pipe_write, response.encode().as_slice()) .unwrap_or_else(|_| process::exit(libc::EXIT_FAILURE)); @@ -516,3 +640,7 @@ fn internal_error_from_errno(context: &'static str, errno: Errno) -> WorkerRespo io::Error::last_os_error() ))) } + +fn job_error_from_errno(context: &'static str, errno: Errno) -> JobResult { + Err(JobError::Kernel(format!("{}: {}: {}", context, errno, io::Error::last_os_error()))) +} diff --git a/polkadot/node/core/pvf/prepare-worker/Cargo.toml b/polkadot/node/core/pvf/prepare-worker/Cargo.toml index 2ef3dfc0e74..7ed7d329506 100644 --- a/polkadot/node/core/pvf/prepare-worker/Cargo.toml +++ b/polkadot/node/core/pvf/prepare-worker/Cargo.toml @@ -18,8 +18,7 @@ rayon = "1.5.1" tracking-allocator = { package = "staging-tracking-allocator", path = "../../../tracking-allocator" } tikv-jemalloc-ctl = { version = "0.5.0", optional = true } tikv-jemallocator = { version = "0.5.0", optional = true } -os_pipe = "1.1.4" -nix = { version = "0.27.1", features = ["process", "resource"] } +nix = { version = "0.27.1", features = ["process", "resource", "sched"] } parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] } diff --git a/polkadot/node/core/pvf/prepare-worker/src/lib.rs b/polkadot/node/core/pvf/prepare-worker/src/lib.rs index f77eed871ec..82a56107ef5 100644 --- a/polkadot/node/core/pvf/prepare-worker/src/lib.rs +++ b/polkadot/node/core/pvf/prepare-worker/src/lib.rs @@ -18,8 +18,6 @@ mod memory_stats; -use polkadot_node_core_pvf_common::executor_interface::{prepare, prevalidate}; - // NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are // separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-prepare-worker=trace`. const LOG_TARGET: &str = "parachain::pvf-prepare-worker"; @@ -37,7 +35,11 @@ use nix::{ }, unistd::{ForkResult, Pid}, }; -use os_pipe::{self, PipeReader, PipeWriter}; +use polkadot_node_core_pvf_common::{ + executor_interface::{prepare, prevalidate}, + worker::{pipe2_cloexec, PipeFd, WorkerInfo}, +}; + use parity_scale_codec::{Decode, Encode}; use polkadot_node_core_pvf_common::{ error::{PrepareError, PrepareWorkerResult}, @@ -57,10 +59,10 @@ use std::{ fs, io::{self, Read}, os::{ - fd::{AsRawFd, RawFd}, + fd::{AsRawFd, FromRawFd, RawFd}, unix::net::UnixStream, }, - path::PathBuf, + path::{Path, PathBuf}, process, sync::{mpsc::channel, Arc}, time::Duration, @@ -76,6 +78,16 @@ static ALLOC: TrackingAllocator = #[global_allocator] static ALLOC: TrackingAllocator = TrackingAllocator(std::alloc::System); +/// The number of threads for the child process: +/// 1 - Main thread +/// 2 - Cpu monitor thread +/// 3 - Memory tracker thread +/// 4 - Prepare thread +/// +/// NOTE: The correctness of this value is enforced by a test. If the number of threads inside +/// the child process changes in the future, this value must be changed as well. +pub const PREPARE_WORKER_THREAD_NUMBER: u32 = 4; + /// Contains the bytes for a successfully compiled artifact. #[derive(Encode, Decode)] pub struct CompiledArtifact(Vec); @@ -200,15 +212,15 @@ pub fn worker_entrypoint( worker_dir_path, node_version, worker_version, - |mut stream, worker_dir_path| { - let worker_pid = process::id(); - let temp_artifact_dest = worker_dir::prepare_tmp_artifact(&worker_dir_path); + |mut stream, worker_info, security_status| { + let temp_artifact_dest = worker_dir::prepare_tmp_artifact(&worker_info.worker_dir_path); loop { let pvf = recv_request(&mut stream)?; gum::debug!( target: LOG_TARGET, - %worker_pid, + ?worker_info, + ?security_status, "worker: preparing artifact", ); @@ -216,7 +228,7 @@ pub fn worker_entrypoint( let prepare_job_kind = pvf.prep_kind(); let executor_params = pvf.executor_params(); - let (pipe_reader, pipe_writer) = os_pipe::pipe()?; + let (pipe_read_fd, pipe_write_fd) = pipe2_cloexec()?; let usage_before = match nix::sys::resource::getrusage(UsageWho::RUSAGE_CHILDREN) { Ok(usage) => usage, @@ -227,46 +239,58 @@ pub fn worker_entrypoint( }, }; - // SAFETY: new process is spawned within a single threaded process. This invariant - // is enforced by tests. - let result = match unsafe { nix::unistd::fork() } { - Err(errno) => Err(error_from_errno("fork", errno)), - Ok(ForkResult::Child) => { - // Dropping the stream closes the underlying socket. We want to make sure - // that the sandboxed child can't get any kind of information from the - // outside world. The only IPC it should be able to do is sending its - // response over the pipe. - drop(stream); - // Drop the read end so we don't have too many FDs open. - drop(pipe_reader); - - handle_child_process( - pvf, - pipe_writer, + let stream_fd = stream.as_raw_fd(); + + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + let result = if security_status.can_do_secure_clone { + handle_clone( + &pvf, + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + &executor_params, + worker_info, + security_status.can_unshare_user_namespace_and_change_root, + &temp_artifact_dest, + usage_before, + ) + } else { + // Fall back to using fork. + handle_fork( + &pvf, + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + &executor_params, + worker_info, + &temp_artifact_dest, + usage_before, + ) + }; + } else { + let result = handle_fork( + &pvf, + pipe_write_fd, + pipe_read_fd, + stream_fd, preparation_timeout, prepare_job_kind, - executor_params, - ) - }, - Ok(ForkResult::Parent { child }) => { - // the read end will wait until all write ends have been closed, - // this drop is necessary to avoid deadlock - drop(pipe_writer); - - handle_parent_process( - pipe_reader, - worker_pid, - child, - temp_artifact_dest.clone(), + &executor_params, + worker_info, + &temp_artifact_dest, usage_before, - preparation_timeout, - ) - }, - }; + ); + } + } gum::trace!( target: LOG_TARGET, - %worker_pid, + ?worker_info, "worker: sending result to host: {:?}", result ); @@ -306,21 +330,94 @@ struct JobResponse { memory_stats: MemoryStats, } +#[cfg(target_os = "linux")] +fn handle_clone( + pvf: &PvfPrepData, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + preparation_timeout: Duration, + prepare_job_kind: PrepareJobKind, + executor_params: &Arc, + worker_info: &WorkerInfo, + have_unshare_newuser: bool, + temp_artifact_dest: &Path, + usage_before: Usage, +) -> Result { + use polkadot_node_core_pvf_common::worker::security; + + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. Stack size being specified to ensure child doesn't overflow + match unsafe { + security::clone::clone_on_worker( + worker_info, + have_unshare_newuser, + Box::new(|| { + handle_child_process( + pvf.clone(), + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + Arc::clone(&executor_params), + ) + }), + ) + } { + Ok(child) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + temp_artifact_dest, + usage_before, + preparation_timeout, + ), + Err(security::clone::Error::Clone(errno)) => Err(error_from_errno("clone", errno)), + } +} + +fn handle_fork( + pvf: &PvfPrepData, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, + preparation_timeout: Duration, + prepare_job_kind: PrepareJobKind, + executor_params: &Arc, + worker_info: &WorkerInfo, + temp_artifact_dest: &Path, + usage_before: Usage, +) -> Result { + // SAFETY: new process is spawned within a single threaded process. This invariant + // is enforced by tests. + match unsafe { nix::unistd::fork() } { + Ok(ForkResult::Child) => handle_child_process( + pvf.clone(), + pipe_write_fd, + pipe_read_fd, + stream_fd, + preparation_timeout, + prepare_job_kind, + Arc::clone(executor_params), + ), + Ok(ForkResult::Parent { child }) => handle_parent_process( + pipe_read_fd, + pipe_write_fd, + worker_info, + child, + temp_artifact_dest, + usage_before, + preparation_timeout, + ), + Err(errno) => Err(error_from_errno("fork", errno)), + } +} + /// This is used to handle child process during pvf prepare worker. /// It prepares the artifact and tracks memory stats during preparation -/// and pipes back the response to the parent process -/// -/// # Arguments -/// -/// - `pvf`: `PvfPrepData` structure, containing data to prepare the artifact -/// -/// - `pipe_write`: A `PipeWriter` structure, the writing end of a pipe. -/// -/// - `preparation_timeout`: The timeout in `Duration`. -/// -/// - `prepare_job_kind`: The kind of prepare job. -/// -/// - `executor_params`: Deterministically serialized execution environment semantics. +/// and pipes back the response to the parent process. /// /// # Returns /// @@ -329,19 +426,34 @@ struct JobResponse { /// - If success, pipe back `JobResponse`. fn handle_child_process( pvf: PvfPrepData, - mut pipe_write: PipeWriter, + pipe_write_fd: i32, + pipe_read_fd: i32, + stream_fd: i32, preparation_timeout: Duration, prepare_job_kind: PrepareJobKind, executor_params: Arc, ) -> ! { - // Terminate if the parent thread dies. Parent thread == worker process (it is single-threaded). - // - // RACE: the worker may die before we install the death signal. In practice this is unlikely, - // and most of the time the job process should terminate on its own when it completes. - #[cfg(target_os = "linux")] - nix::sys::prctl::set_pdeathsig(nix::sys::signal::Signal::SIGTERM).unwrap_or_else(|err| { - send_child_response(&mut pipe_write, Err(PrepareError::IoErr(err.to_string()))) - }); + // SAFETY: pipe_writer is an open and owned file descriptor at this point. + let mut pipe_write = unsafe { PipeFd::from_raw_fd(pipe_write_fd) }; + + // Drop the read end so we don't have too many FDs open. + if let Err(errno) = nix::unistd::close(pipe_read_fd) { + send_child_response( + &mut pipe_write, + JobResult::Err(error_from_errno("closing pipe", errno)), + ); + } + + // Dropping the stream closes the underlying socket. We want to make sure + // that the sandboxed child can't get any kind of information from the + // outside world. The only IPC it should be able to do is sending its + // response over the pipe. + if let Err(errno) = nix::unistd::close(stream_fd) { + send_child_response( + &mut pipe_write, + JobResult::Err(error_from_errno("error closing stream", errno)), + ); + } let worker_job_pid = process::id(); gum::debug!( @@ -489,20 +601,6 @@ fn handle_child_process( /// Waits for child process to finish and handle child response from pipe. /// -/// # Arguments -/// -/// - `pipe_read`: A `PipeReader` used to read data from the child process. -/// -/// - `child`: The child pid. -/// -/// - `temp_artifact_dest`: The destination `PathBuf` to write the temporary artifact file. -/// -/// - `worker_pid`: The PID of the child process. -/// -/// - `usage_before`: Resource usage statistics before executing the child process. -/// -/// - `timeout`: The maximum allowed time for the child process to finish, in `Duration`. -/// /// # Returns /// /// - If the child send response without an error, this function returns `Ok(PrepareStats)` @@ -512,13 +610,23 @@ fn handle_child_process( /// /// - If the child process timeout, it returns `PrepareError::TimedOut`. fn handle_parent_process( - mut pipe_read: PipeReader, - worker_pid: u32, + pipe_read_fd: i32, + pipe_write_fd: i32, + worker_info: &WorkerInfo, job_pid: Pid, - temp_artifact_dest: PathBuf, + temp_artifact_dest: &Path, usage_before: Usage, timeout: Duration, ) -> Result { + // the read end will wait until all write ends have been closed, + // this drop is necessary to avoid deadlock + if let Err(errno) = nix::unistd::close(pipe_write_fd) { + return Err(error_from_errno("closing pipe write fd", errno)); + }; + + // SAFETY: this is an open and owned file descriptor at this point. + let mut pipe_read = unsafe { PipeFd::from_raw_fd(pipe_read_fd) }; + // Read from the child. Don't decode unless the process exited normally, which we check later. let mut received_data = Vec::new(); pipe_read @@ -528,7 +636,7 @@ fn handle_parent_process( let status = nix::sys::wait::waitpid(job_pid, None); gum::trace!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "prepare worker received wait status from job: {:?}", status, @@ -546,7 +654,7 @@ fn handle_parent_process( if cpu_tv >= timeout { gum::warn!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "prepare job took {}ms cpu time, exceeded prepare timeout {}ms", cpu_tv.as_millis(), @@ -581,13 +689,13 @@ fn handle_parent_process( // success. gum::debug!( target: LOG_TARGET, - %worker_pid, + ?worker_info, %job_pid, "worker: writing artifact to {}", temp_artifact_dest.display(), ); // Write to the temp file created by the host. - if let Err(err) = fs::write(&temp_artifact_dest, &artifact) { + if let Err(err) = fs::write(temp_artifact_dest, &artifact) { return Err(PrepareError::IoErr(err.to_string())) }; @@ -651,10 +759,10 @@ fn recv_child_response(received_data: &mut io::BufReader<&[u8]>) -> io::Result ! { +fn send_child_response(pipe_write: &mut PipeFd, response: JobResult) -> ! { framed_send_blocking(pipe_write, response.encode().as_slice()) .unwrap_or_else(|_| process::exit(libc::EXIT_FAILURE)); diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index 2668ce41583..b07b3da4c26 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -906,7 +906,7 @@ pub(crate) mod tests { let _ = pulse.next().await.unwrap(); let el = start.elapsed().as_millis(); - assert!(el > 50 && el < 150, "{}", el); + assert!(el > 50 && el < 150, "pulse duration: {}", el); } } diff --git a/polkadot/node/core/pvf/src/security.rs b/polkadot/node/core/pvf/src/security.rs index 9d0d4cf49af..f62a232abf2 100644 --- a/polkadot/node/core/pvf/src/security.rs +++ b/polkadot/node/core/pvf/src/security.rs @@ -32,14 +32,20 @@ use std::{fmt, path::Path}; pub async fn check_security_status(config: &Config) -> Result { let Config { prepare_worker_program_path, secure_validator_mode, cache_path, .. } = config; - let (landlock, seccomp, change_root) = join!( + let (landlock, seccomp, change_root, secure_clone) = join!( check_landlock(prepare_worker_program_path), check_seccomp(prepare_worker_program_path), - check_can_unshare_user_namespace_and_change_root(prepare_worker_program_path, cache_path) + check_can_unshare_user_namespace_and_change_root(prepare_worker_program_path, cache_path), + check_can_do_secure_clone(prepare_worker_program_path), ); - let full_security_status = - FullSecurityStatus::new(*secure_validator_mode, landlock, seccomp, change_root); + let full_security_status = FullSecurityStatus::new( + *secure_validator_mode, + landlock, + seccomp, + change_root, + secure_clone, + ); let security_status = full_security_status.as_partial(); if full_security_status.err_occurred() { @@ -73,6 +79,7 @@ impl FullSecurityStatus { landlock: SecureModeResult, seccomp: SecureModeResult, change_root: SecureModeResult, + secure_clone: SecureModeResult, ) -> Self { Self { partial: SecurityStatus { @@ -80,8 +87,9 @@ impl FullSecurityStatus { can_enable_landlock: landlock.is_ok(), can_enable_seccomp: seccomp.is_ok(), can_unshare_user_namespace_and_change_root: change_root.is_ok(), + can_do_secure_clone: secure_clone.is_ok(), }, - errs: [landlock, seccomp, change_root] + errs: [landlock, seccomp, change_root, secure_clone] .into_iter() .filter_map(|result| result.err()) .collect(), @@ -120,9 +128,10 @@ type SecureModeResult = std::result::Result<(), SecureModeError>; /// Errors related to enabling Secure Validator Mode. #[derive(Debug)] enum SecureModeError { - CannotEnableLandlock(String), + CannotEnableLandlock { err: String, abi: u8 }, CannotEnableSeccomp(String), CannotUnshareUserNamespaceAndChangeRoot(String), + CannotDoSecureClone(String), } impl SecureModeError { @@ -132,12 +141,16 @@ impl SecureModeError { match self { // Landlock is present on relatively recent Linuxes. This is optional if the unshare // capability is present, providing FS sandboxing a different way. - CannotEnableLandlock(_) => security_status.can_unshare_user_namespace_and_change_root, + CannotEnableLandlock { .. } => + security_status.can_unshare_user_namespace_and_change_root, // seccomp should be present on all modern Linuxes unless it's been disabled. CannotEnableSeccomp(_) => false, // Should always be present on modern Linuxes. If not, Landlock also provides FS // sandboxing, so don't enforce this. CannotUnshareUserNamespaceAndChangeRoot(_) => security_status.can_enable_landlock, + // We have not determined the kernel requirements for this capability, and it's also not + // necessary for FS or networking restrictions. + CannotDoSecureClone(_) => true, } } } @@ -146,9 +159,10 @@ impl fmt::Display for SecureModeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use SecureModeError::*; match self { - CannotEnableLandlock(err) => write!(f, "Cannot enable landlock, a Linux 5.13+ kernel security feature: {err}"), + CannotEnableLandlock{err, abi} => write!(f, "Cannot enable landlock (ABI {abi}), a Linux 5.13+ kernel security feature: {err}"), CannotEnableSeccomp(err) => write!(f, "Cannot enable seccomp, a Linux-specific kernel security feature: {err}"), CannotUnshareUserNamespaceAndChangeRoot(err) => write!(f, "Cannot unshare user namespace and change root, which are Linux-specific kernel security features: {err}"), + CannotDoSecureClone(err) => write!(f, "Cannot call clone with all sandboxing flags, a Linux-specific kernel security features: {err}"), } } } @@ -208,32 +222,11 @@ async fn check_can_unshare_user_namespace_and_change_root( .map_err(|err| SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( format!("could not create a temporary directory in {:?}: {}", cache_path, err) ))?; - match tokio::process::Command::new(prepare_worker_program_path) - .arg("--check-can-unshare-user-namespace-and-change-root") - .arg(cache_dir_tempdir.path()) - .output() - .await - { - Ok(output) if output.status.success() => Ok(()), - Ok(output) => { - let stderr = std::str::from_utf8(&output.stderr) - .expect("child process writes a UTF-8 string to stderr; qed") - .trim(); - if stderr.is_empty() { - Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( - "not available".into() - )) - } else { - Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( - format!("not available: {}", stderr) - )) - } - }, - Err(err) => - Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( - format!("could not start child process: {}", err) - )), - } + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-unshare-user-namespace-and-change-root", + &[cache_dir_tempdir.path()], + ).await.map_err(|err| SecureModeError::CannotUnshareUserNamespaceAndChangeRoot(err)) } else { Err(SecureModeError::CannotUnshareUserNamespaceAndChangeRoot( "only available on Linux".into() @@ -253,37 +246,17 @@ async fn check_landlock( ) -> SecureModeResult { cfg_if::cfg_if! { if #[cfg(target_os = "linux")] { - match tokio::process::Command::new(prepare_worker_program_path) - .arg("--check-can-enable-landlock") - .output() - .await - { - Ok(output) if output.status.success() => Ok(()), - Ok(output) => { - let abi = - polkadot_node_core_pvf_common::worker::security::landlock::LANDLOCK_ABI as u8; - let stderr = std::str::from_utf8(&output.stderr) - .expect("child process writes a UTF-8 string to stderr; qed") - .trim(); - if stderr.is_empty() { - Err(SecureModeError::CannotEnableLandlock( - format!("landlock ABI {} not available", abi) - )) - } else { - Err(SecureModeError::CannotEnableLandlock( - format!("not available: {}", stderr) - )) - } - }, - Err(err) => - Err(SecureModeError::CannotEnableLandlock( - format!("could not start child process: {}", err) - )), - } + let abi = polkadot_node_core_pvf_common::worker::security::landlock::LANDLOCK_ABI as u8; + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-enable-landlock", + std::iter::empty::<&str>(), + ).await.map_err(|err| SecureModeError::CannotEnableLandlock { err, abi }) } else { - Err(SecureModeError::CannotEnableLandlock( - "only available on Linux".into() - )) + Err(SecureModeError::CannotEnableLandlock { + err: "only available on Linux".into(), + abi: 0, + }) } } } @@ -301,31 +274,11 @@ async fn check_seccomp( if #[cfg(target_os = "linux")] { cfg_if::cfg_if! { if #[cfg(target_arch = "x86_64")] { - match tokio::process::Command::new(prepare_worker_program_path) - .arg("--check-can-enable-seccomp") - .output() - .await - { - Ok(output) if output.status.success() => Ok(()), - Ok(output) => { - let stderr = std::str::from_utf8(&output.stderr) - .expect("child process writes a UTF-8 string to stderr; qed") - .trim(); - if stderr.is_empty() { - Err(SecureModeError::CannotEnableSeccomp( - "not available".into() - )) - } else { - Err(SecureModeError::CannotEnableSeccomp( - format!("not available: {}", stderr) - )) - } - }, - Err(err) => - Err(SecureModeError::CannotEnableSeccomp( - format!("could not start child process: {}", err) - )), - } + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-enable-seccomp", + std::iter::empty::<&str>(), + ).await.map_err(|err| SecureModeError::CannotEnableSeccomp(err)) } else { Err(SecureModeError::CannotEnableSeccomp( "only supported on CPUs from the x86_64 family (usually Intel or AMD)".into() @@ -348,24 +301,85 @@ async fn check_seccomp( } } +/// Check if we can call `clone` with all sandboxing flags, and return an error if not. +/// +/// We do this check by spawning a new process and trying to sandbox it. To get as close as possible +/// to running the check in a worker, we try it... in a worker. The expected return status is 0 on +/// success and -1 on failure. +async fn check_can_do_secure_clone( + #[cfg_attr(not(target_os = "linux"), allow(unused_variables))] + prepare_worker_program_path: &Path, +) -> SecureModeResult { + cfg_if::cfg_if! { + if #[cfg(target_os = "linux")] { + spawn_process_for_security_check( + prepare_worker_program_path, + "--check-can-do-secure-clone", + std::iter::empty::<&str>(), + ).await.map_err(|err| SecureModeError::CannotDoSecureClone(err)) + } else { + Err(SecureModeError::CannotDoSecureClone( + "only available on Linux".into() + )) + } + } +} + +#[cfg(target_os = "linux")] +async fn spawn_process_for_security_check( + prepare_worker_program_path: &Path, + check_arg: &'static str, + extra_args: I, +) -> Result<(), String> +where + I: IntoIterator, + S: AsRef, +{ + let mut command = tokio::process::Command::new(prepare_worker_program_path); + // Clear env vars. (In theory, running checks with different env vars could result in different + // outcomes of the checks.) + command.env_clear(); + // Add back any env vars we want to keep. + if let Ok(value) = std::env::var("RUST_LOG") { + command.env("RUST_LOG", value); + } + + match command.arg(check_arg).args(extra_args).output().await { + Ok(output) if output.status.success() => Ok(()), + Ok(output) => { + let stderr = std::str::from_utf8(&output.stderr) + .expect("child process writes a UTF-8 string to stderr; qed") + .trim(); + if stderr.is_empty() { + Err("not available".into()) + } else { + Err(format!("not available: {}", stderr)) + } + }, + Err(err) => Err(format!("could not start child process: {}", err)), + } +} + #[cfg(test)] mod tests { use super::*; #[test] fn test_secure_mode_error_optionality() { - let err = SecureModeError::CannotEnableLandlock(String::new()); + let err = SecureModeError::CannotEnableLandlock { err: String::new(), abi: 3 }; assert!(err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: false, - can_unshare_user_namespace_and_change_root: true + can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, })); assert!(!err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: true, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); let err = SecureModeError::CannotEnableSeccomp(String::new()); @@ -373,13 +387,15 @@ mod tests { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: false, - can_unshare_user_namespace_and_change_root: true + can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, })); assert!(!err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: true, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); let err = SecureModeError::CannotUnshareUserNamespaceAndChangeRoot(String::new()); @@ -387,13 +403,31 @@ mod tests { secure_validator_mode: true, can_enable_landlock: true, can_enable_seccomp: false, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); assert!(!err.is_allowed_in_secure_mode(&SecurityStatus { secure_validator_mode: true, can_enable_landlock: false, can_enable_seccomp: true, - can_unshare_user_namespace_and_change_root: false + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, + })); + + let err = SecureModeError::CannotDoSecureClone(String::new()); + assert!(err.is_allowed_in_secure_mode(&SecurityStatus { + secure_validator_mode: true, + can_enable_landlock: true, + can_enable_seccomp: true, + can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, + })); + assert!(err.is_allowed_in_secure_mode(&SecurityStatus { + secure_validator_mode: false, + can_enable_landlock: false, + can_enable_seccomp: false, + can_unshare_user_namespace_and_change_root: false, + can_do_secure_clone: false, })); } } diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs index 15b341dc094..bcc10749e74 100644 --- a/polkadot/node/core/pvf/tests/it/main.rs +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -457,10 +457,13 @@ async fn all_security_features_work() { assert_eq!( host.security_status().await, SecurityStatus { + // Disabled in tests to not enforce the presence of security features. This CI-only test + // is the only one that tests them. secure_validator_mode: false, can_enable_landlock, can_enable_seccomp: true, can_unshare_user_namespace_and_change_root: true, + can_do_secure_clone: true, } ); } diff --git a/polkadot/node/core/pvf/tests/it/process.rs b/polkadot/node/core/pvf/tests/it/process.rs index 3ea03339a83..e989eb874ba 100644 --- a/polkadot/node/core/pvf/tests/it/process.rs +++ b/polkadot/node/core/pvf/tests/it/process.rs @@ -94,7 +94,7 @@ fn find_process_by_sid_and_name( found } -/// Sets up the test and makes sure everything gets cleaned up after. +/// Sets up the test. /// /// We run the runtime manually because `#[tokio::test]` doesn't work in `rusty_fork_test!`. fn test_wrapper(f: F) @@ -112,14 +112,6 @@ where // Pass a clone of the host so that it does not get dropped after. f(host.clone(), sid).await; - - // Sleep to give processes a chance to get cleaned up, preventing races in the next step. - tokio::time::sleep(Duration::from_millis(500)).await; - - // Make sure job processes got cleaned up. Pass `is_direct_child: false` to target the - // job processes. - assert!(find_process_by_sid_and_name(sid, PREPARE_PROCESS_NAME, false).is_none()); - assert!(find_process_by_sid_and_name(sid, EXECUTE_PROCESS_NAME, false).is_none()); }); } @@ -127,7 +119,7 @@ where // then finding the child process that matches the session ID and expected process name and doing // something with that child. rusty_fork_test! { - // Everything succeeded. All created subprocesses for jobs should get cleaned up, to avoid memory leaks. + // Everything succeeds. #[test] fn successful_prepare_and_validate() { test_wrapper(|host, _sid| async move { @@ -331,7 +323,7 @@ rusty_fork_test! { // monitor, and memory tracking. assert_eq!( get_num_threads_by_sid_and_name(sid, PREPARE_PROCESS_NAME, false), - 4 + polkadot_node_core_pvf_prepare_worker::PREPARE_WORKER_THREAD_NUMBER as i64, ); // End the test. @@ -374,7 +366,7 @@ rusty_fork_test! { // time monitor. assert_eq!( get_num_threads_by_sid_and_name(sid, EXECUTE_PROCESS_NAME, false), - 3 + polkadot_node_core_pvf_execute_worker::EXECUTE_WORKER_THREAD_NUMBER as i64, ); // End the test. diff --git a/prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc b/prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc new file mode 100644 index 00000000000..ac9a0a501b6 --- /dev/null +++ b/prdoc/pr_2477-use-clone-instead-of-fork-on-pvf.prdoc @@ -0,0 +1,22 @@ +title: "Use clone instead of fork on pvf" + +doc: + - audience: Node Operator + description: | + For validators: Adds a new, optional security capability. + Most modern Linux machines should support it, otherwise you will get a warning like: + "- Optional: Cannot call clone with all sandboxing flags, a Linux-specific kernel security features: not available" + If you are already running in a secure environment such as a container, this may conflict with our security features; your only option may be to ignore the warning. + Otherwise, it is recommended to upgrade your Linux version! + +migrations: + db: [] + + runtime: [] + +crates: + - name: polkadot-node-core-pvf + - name: polkadot-node-core-pvf-prepare-worker + - name: polkadot-node-core-pvf-execute-worker + +host_functions: [] -- GitLab From d37a45650e112d3ddcc705ef5f642ba075b14e61 Mon Sep 17 00:00:00 2001 From: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> Date: Sun, 21 Jan 2024 14:56:44 +0100 Subject: [PATCH 048/283] Make candidate validation bounded again (#2125) This PR aims to channel the backpressure of the PVF host's preparation and execution queues to the candidate validation subsystem consumers. Related: #708 --- Cargo.lock | 12 +- .../Cargo.toml | 2 +- .../node/core/candidate-validation/src/lib.rs | 221 ++++++++++-------- polkadot/node/core/pvf/src/host.rs | 5 +- polkadot/node/core/pvf/src/lib.rs | 5 +- polkadot/node/malus/src/interceptor.rs | 21 +- polkadot/node/metrics/Cargo.toml | 2 +- polkadot/node/overseer/Cargo.toml | 4 +- polkadot/node/subsystem-bench/Cargo.toml | 2 +- .../node/subsystem-test-helpers/src/lib.rs | 24 ++ polkadot/node/subsystem-types/Cargo.toml | 2 +- polkadot/node/subsystem-util/Cargo.toml | 2 +- prdoc/pr_2125.prdoc | 14 ++ 13 files changed, 201 insertions(+), 115 deletions(-) create mode 100644 prdoc/pr_2125.prdoc diff --git a/Cargo.lock b/Cargo.lock index 73d5acd6f6d..1d404a2c231 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8988,9 +8988,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchestra" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d78e1deb2a8d54fc1f063a544130db4da31dfe4d5d3b493186424910222a76" +checksum = "5edee0c1917703f8a28cd229cf6a5c91a7ee34be139ced16509ac5b53b9d0c51" dependencies = [ "async-trait", "dyn-clonable", @@ -9005,9 +9005,9 @@ dependencies = [ [[package]] name = "orchestra-proc-macro" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d035b1f968d91a826f2e34a9d6d02cb2af5aa7ca39ebd27922d850ab4b2dd2c6" +checksum = "4f60e64a3808b5bb2786b9da09fc70714952aabcdd0eeba6f1718e3dbc34ad5b" dependencies = [ "expander 2.0.0", "indexmap 2.0.0", @@ -14018,9 +14018,9 @@ dependencies = [ [[package]] name = "prioritized-metered-channel" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e99f0c89bd88f393aab44a4ab949351f7bc7e7e1179d11ecbfe50cbe4c47e342" +checksum = "a172e6cc603231f2cf004232eabcecccc0da53ba576ab286ef7baa0cfc7927ad" dependencies = [ "coarsetime", "crossbeam-queue", diff --git a/cumulus/client/relay-chain-inprocess-interface/Cargo.toml b/cumulus/client/relay-chain-inprocess-interface/Cargo.toml index 63f4c915474..7c7edc502d4 100644 --- a/cumulus/client/relay-chain-inprocess-interface/Cargo.toml +++ b/cumulus/client/relay-chain-inprocess-interface/Cargo.toml @@ -42,7 +42,7 @@ sp-keyring = { path = "../../../substrate/primitives/keyring" } # Polkadot polkadot-primitives = { path = "../../../polkadot/primitives" } polkadot-test-client = { path = "../../../polkadot/node/test/client" } -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } # Cumulus cumulus-test-service = { path = "../../test/service" } diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index 18c27968915..bf6e09fd1b6 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -55,10 +55,11 @@ use polkadot_primitives::{ use parity_scale_codec::Encode; -use futures::{channel::oneshot, prelude::*}; +use futures::{channel::oneshot, prelude::*, stream::FuturesUnordered}; use std::{ path::PathBuf, + pin::Pin, sync::Arc, time::{Duration, Instant}, }; @@ -81,6 +82,11 @@ const PVF_APPROVAL_EXECUTION_RETRY_DELAY: Duration = Duration::from_secs(3); #[cfg(test)] const PVF_APPROVAL_EXECUTION_RETRY_DELAY: Duration = Duration::from_millis(200); +// The task queue size is chosen to be somewhat bigger than the PVF host incoming queue size +// to allow exhaustive validation messages to fall through in case the tasks are clogged with +// `ValidateFromChainState` messages awaiting data from the runtime +const TASK_LIMIT: usize = 30; + /// Configuration for the candidate validation subsystem #[derive(Clone)] pub struct Config { @@ -130,6 +136,83 @@ impl CandidateValidationSubsystem { } } +fn handle_validation_message( + mut sender: S, + validation_host: ValidationHost, + metrics: Metrics, + msg: CandidateValidationMessage, +) -> Pin + Send>> +where + S: SubsystemSender, +{ + match msg { + CandidateValidationMessage::ValidateFromChainState { + candidate_receipt, + pov, + executor_params, + exec_kind, + response_sender, + .. + } => async move { + let _timer = metrics.time_validate_from_chain_state(); + let res = validate_from_chain_state( + &mut sender, + validation_host, + candidate_receipt, + pov, + executor_params, + exec_kind, + &metrics, + ) + .await; + + metrics.on_validation_event(&res); + let _ = response_sender.send(res); + } + .boxed(), + CandidateValidationMessage::ValidateFromExhaustive { + validation_data, + validation_code, + candidate_receipt, + pov, + executor_params, + exec_kind, + response_sender, + .. + } => async move { + let _timer = metrics.time_validate_from_exhaustive(); + let res = validate_candidate_exhaustive( + validation_host, + validation_data, + validation_code, + candidate_receipt, + pov, + executor_params, + exec_kind, + &metrics, + ) + .await; + + metrics.on_validation_event(&res); + let _ = response_sender.send(res); + } + .boxed(), + CandidateValidationMessage::PreCheck { + relay_parent, + validation_code_hash, + response_sender, + .. + } => async move { + let precheck_result = + precheck_pvf(&mut sender, validation_host, relay_parent, validation_code_hash) + .await; + + let _ = response_sender.send(precheck_result); + } + .boxed(), + } +} + #[overseer::contextbounds(CandidateValidation, prefix = self::overseer)] async fn run( mut ctx: Context, @@ -156,106 +239,48 @@ async fn run( .await?; ctx.spawn_blocking("pvf-validation-host", task.boxed())?; + let mut tasks = FuturesUnordered::new(); + loop { - match ctx.recv().await? { - FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_)) => {}, - FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {}, - FromOrchestra::Signal(OverseerSignal::Conclude) => return Ok(()), - FromOrchestra::Communication { msg } => match msg { - CandidateValidationMessage::ValidateFromChainState { - candidate_receipt, - pov, - executor_params, - exec_kind, - response_sender, - .. - } => { - let bg = { - let mut sender = ctx.sender().clone(); - let metrics = metrics.clone(); - let validation_host = validation_host.clone(); - - async move { - let _timer = metrics.time_validate_from_chain_state(); - let res = validate_from_chain_state( - &mut sender, - validation_host, - candidate_receipt, - pov, - executor_params, - exec_kind, - &metrics, - ) - .await; - - metrics.on_validation_event(&res); - let _ = response_sender.send(res); - } - }; - - ctx.spawn("validate-from-chain-state", bg.boxed())?; - }, - CandidateValidationMessage::ValidateFromExhaustive { - validation_data, - validation_code, - candidate_receipt, - pov, - executor_params, - exec_kind, - response_sender, - .. - } => { - let bg = { - let metrics = metrics.clone(); - let validation_host = validation_host.clone(); - - async move { - let _timer = metrics.time_validate_from_exhaustive(); - let res = validate_candidate_exhaustive( - validation_host, - validation_data, - validation_code, - candidate_receipt, - pov, - executor_params, - exec_kind, - &metrics, - ) - .await; - - metrics.on_validation_event(&res); - let _ = response_sender.send(res); - } - }; - - ctx.spawn("validate-from-exhaustive", bg.boxed())?; + loop { + futures::select! { + comm = ctx.recv().fuse() => { + match comm { + Ok(FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_))) => {}, + Ok(FromOrchestra::Signal(OverseerSignal::BlockFinalized(..))) => {}, + Ok(FromOrchestra::Signal(OverseerSignal::Conclude)) => return Ok(()), + Ok(FromOrchestra::Communication { msg }) => { + let task = handle_validation_message(ctx.sender().clone(), validation_host.clone(), metrics.clone(), msg); + tasks.push(task); + if tasks.len() >= TASK_LIMIT { + break + } + }, + Err(e) => return Err(SubsystemError::from(e)), + } }, - CandidateValidationMessage::PreCheck { - relay_parent, - validation_code_hash, - response_sender, - .. - } => { - let bg = { - let mut sender = ctx.sender().clone(); - let validation_host = validation_host.clone(); - - async move { - let precheck_result = precheck_pvf( - &mut sender, - validation_host, - relay_parent, - validation_code_hash, - ) - .await; - - let _ = response_sender.send(precheck_result); - } - }; - - ctx.spawn("candidate-validation-pre-check", bg.boxed())?; + _ = tasks.select_next_some() => () + } + } + + gum::debug!(target: LOG_TARGET, "Validation task limit hit"); + + loop { + futures::select! { + signal = ctx.recv_signal().fuse() => { + match signal { + Ok(OverseerSignal::ActiveLeaves(_)) => {}, + Ok(OverseerSignal::BlockFinalized(..)) => {}, + Ok(OverseerSignal::Conclude) => return Ok(()), + Err(e) => return Err(SubsystemError::from(e)), + } }, - }, + _ = tasks.select_next_some() => { + if tasks.len() < TASK_LIMIT { + break + } + } + } } } } diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index b07b3da4c26..e215f11b91d 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -60,6 +60,9 @@ pub const PREPARE_BINARY_NAME: &str = "polkadot-prepare-worker"; /// The name of binary spawned to execute a PVF pub const EXECUTE_BINARY_NAME: &str = "polkadot-execute-worker"; +/// The size of incoming message queue +pub const HOST_MESSAGE_QUEUE_SIZE: usize = 10; + /// An alias to not spell the type for the oneshot sender for the PVF execution result. pub(crate) type ResultSender = oneshot::Sender>; @@ -227,7 +230,7 @@ pub async fn start( Err(err) => return Err(SubsystemError::Context(err)), }; - let (to_host_tx, to_host_rx) = mpsc::channel(10); + let (to_host_tx, to_host_rx) = mpsc::channel(HOST_MESSAGE_QUEUE_SIZE); let validation_host = ValidationHost { to_host_tx, security_status: security_status.clone() }; diff --git a/polkadot/node/core/pvf/src/lib.rs b/polkadot/node/core/pvf/src/lib.rs index 79391630b2d..92263281eea 100644 --- a/polkadot/node/core/pvf/src/lib.rs +++ b/polkadot/node/core/pvf/src/lib.rs @@ -104,7 +104,10 @@ mod worker_interface; pub mod testing; pub use error::{InvalidCandidate, PossiblyInvalidError, ValidationError}; -pub use host::{start, Config, ValidationHost, EXECUTE_BINARY_NAME, PREPARE_BINARY_NAME}; +pub use host::{ + start, Config, ValidationHost, EXECUTE_BINARY_NAME, HOST_MESSAGE_QUEUE_SIZE, + PREPARE_BINARY_NAME, +}; pub use metrics::Metrics; pub use priority::Priority; pub use worker_interface::{framed_recv, framed_send, JOB_TIMEOUT_WALL_CLOCK_FACTOR}; diff --git a/polkadot/node/malus/src/interceptor.rs b/polkadot/node/malus/src/interceptor.rs index e994319beb9..b44ffc8956b 100644 --- a/polkadot/node/malus/src/interceptor.rs +++ b/polkadot/node/malus/src/interceptor.rs @@ -22,7 +22,7 @@ use polkadot_node_subsystem::*; pub use polkadot_node_subsystem::{messages::*, overseer, FromOrchestra}; -use std::{future::Future, pin::Pin}; +use std::{collections::VecDeque, future::Future, pin::Pin}; /// Filter incoming and outgoing messages. pub trait MessageInterceptor: Send + Sync + Clone + 'static @@ -170,6 +170,7 @@ where inner: Context, message_filter: Fil, sender: InterceptedSender<::Sender, Fil>, + message_buffer: VecDeque::Message>>, } impl InterceptedContext @@ -189,7 +190,7 @@ where inner: inner.sender().clone(), message_filter: message_filter.clone(), }; - Self { inner, message_filter, sender } + Self { inner, message_filter, sender, message_buffer: VecDeque::new() } } } @@ -233,6 +234,9 @@ where } async fn recv(&mut self) -> SubsystemResult> { + if let Some(msg) = self.message_buffer.pop_front() { + return Ok(msg) + } loop { let msg = self.inner.recv().await?; if let Some(msg) = self.message_filter.intercept_incoming(self.inner.sender(), msg) { @@ -241,6 +245,19 @@ where } } + async fn recv_signal(&mut self) -> SubsystemResult { + loop { + let msg = self.inner.recv().await?; + if let Some(msg) = self.message_filter.intercept_incoming(self.inner.sender(), msg) { + if let FromOrchestra::Signal(sig) = msg { + return Ok(sig) + } else { + self.message_buffer.push_back(msg) + } + } + } + } + fn spawn( &mut self, name: &'static str, diff --git a/polkadot/node/metrics/Cargo.toml b/polkadot/node/metrics/Cargo.toml index e9a4d463f4d..90d95a6e50a 100644 --- a/polkadot/node/metrics/Cargo.toml +++ b/polkadot/node/metrics/Cargo.toml @@ -14,7 +14,7 @@ futures = "0.3.21" futures-timer = "3.0.2" gum = { package = "tracing-gum", path = "../gum" } -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } # Both `sc-service` and `sc-cli` are required by runtime metrics `logger_hook()`. sc-service = { path = "../../../substrate/client/service" } sc-cli = { path = "../../../substrate/client/cli" } diff --git a/polkadot/node/overseer/Cargo.toml b/polkadot/node/overseer/Cargo.toml index f168bdd0807..f39f0661aa1 100644 --- a/polkadot/node/overseer/Cargo.toml +++ b/polkadot/node/overseer/Cargo.toml @@ -20,14 +20,14 @@ polkadot-node-primitives = { path = "../primitives" } polkadot-node-subsystem-types = { path = "../subsystem-types" } polkadot-node-metrics = { path = "../metrics" } polkadot-primitives = { path = "../../primitives" } -orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } +orchestra = { version = "0.3.4", default-features = false, features = ["futures_channel"] } gum = { package = "tracing-gum", path = "../gum" } sp-core = { path = "../../../substrate/primitives/core" } async-trait = "0.1.74" tikv-jemalloc-ctl = { version = "0.5.0", optional = true } [dev-dependencies] -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } sp-core = { path = "../../../substrate/primitives/core" } futures = { version = "0.3.21", features = ["thread-pool"] } femme = "2.2.1" diff --git a/polkadot/node/subsystem-bench/Cargo.toml b/polkadot/node/subsystem-bench/Cargo.toml index f09f7fc4897..750f7a7e2f8 100644 --- a/polkadot/node/subsystem-bench/Cargo.toml +++ b/polkadot/node/subsystem-bench/Cargo.toml @@ -55,7 +55,7 @@ prometheus = { version = "0.13.0", default-features = false } serde = "1.0.195" serde_yaml = "0.9" paste = "1.0.14" -orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } +orchestra = { version = "0.3.4", default-features = false, features = ["futures_channel"] } pyroscope = "0.5.7" pyroscope_pprofrs = "0.2.7" diff --git a/polkadot/node/subsystem-test-helpers/src/lib.rs b/polkadot/node/subsystem-test-helpers/src/lib.rs index dfa78e04b8c..6c1ac86c450 100644 --- a/polkadot/node/subsystem-test-helpers/src/lib.rs +++ b/polkadot/node/subsystem-test-helpers/src/lib.rs @@ -32,6 +32,7 @@ use parking_lot::Mutex; use sp_core::testing::TaskExecutor; use std::{ + collections::VecDeque, convert::Infallible, future::Future, pin::Pin, @@ -190,6 +191,7 @@ pub struct TestSubsystemContext { tx: TestSubsystemSender, rx: mpsc::Receiver>, spawn: S, + message_buffer: VecDeque>, } #[async_trait::async_trait] @@ -207,6 +209,9 @@ where type Error = SubsystemError; async fn try_recv(&mut self) -> Result>, ()> { + if let Some(msg) = self.message_buffer.pop_front() { + return Ok(Some(msg)) + } match poll!(self.rx.next()) { Poll::Ready(Some(msg)) => Ok(Some(msg)), Poll::Ready(None) => Err(()), @@ -215,12 +220,30 @@ where } async fn recv(&mut self) -> SubsystemResult> { + if let Some(msg) = self.message_buffer.pop_front() { + return Ok(msg) + } self.rx .next() .await .ok_or_else(|| SubsystemError::Context("Receiving end closed".to_owned())) } + async fn recv_signal(&mut self) -> SubsystemResult { + loop { + let msg = self + .rx + .next() + .await + .ok_or_else(|| SubsystemError::Context("Receiving end closed".to_owned()))?; + if let FromOrchestra::Signal(sig) = msg { + return Ok(sig) + } else { + self.message_buffer.push_back(msg) + } + } + } + fn spawn( &mut self, name: &'static str, @@ -314,6 +337,7 @@ pub fn make_buffered_subsystem_context( tx: TestSubsystemSender { tx: all_messages_tx }, rx: overseer_rx, spawn: SpawnGlue(spawner), + message_buffer: VecDeque::new(), }, TestSubsystemContextHandle { tx: overseer_tx, rx: all_messages_rx }, ) diff --git a/polkadot/node/subsystem-types/Cargo.toml b/polkadot/node/subsystem-types/Cargo.toml index 6713e903123..181ef54b4c6 100644 --- a/polkadot/node/subsystem-types/Cargo.toml +++ b/polkadot/node/subsystem-types/Cargo.toml @@ -17,7 +17,7 @@ polkadot-node-primitives = { path = "../primitives" } polkadot-node-network-protocol = { path = "../network/protocol" } polkadot-statement-table = { path = "../../statement-table" } polkadot-node-jaeger = { path = "../jaeger" } -orchestra = { version = "0.3.3", default-features = false, features = ["futures_channel"] } +orchestra = { version = "0.3.4", default-features = false, features = ["futures_channel"] } sc-network = { path = "../../../substrate/client/network" } sp-api = { path = "../../../substrate/primitives/api" } sp-blockchain = { path = "../../../substrate/primitives/blockchain" } diff --git a/polkadot/node/subsystem-util/Cargo.toml b/polkadot/node/subsystem-util/Cargo.toml index 3147a4f64f4..68a834d46e3 100644 --- a/polkadot/node/subsystem-util/Cargo.toml +++ b/polkadot/node/subsystem-util/Cargo.toml @@ -32,7 +32,7 @@ polkadot-node-network-protocol = { path = "../network/protocol" } polkadot-primitives = { path = "../../primitives" } polkadot-node-primitives = { path = "../primitives" } polkadot-overseer = { path = "../overseer" } -metered = { package = "prioritized-metered-channel", version = "0.5.1", default-features = false, features = ["futures_channel"] } +metered = { package = "prioritized-metered-channel", version = "0.6.1", default-features = false, features = ["futures_channel"] } sp-core = { path = "../../../substrate/primitives/core" } sp-application-crypto = { path = "../../../substrate/primitives/application-crypto" } diff --git a/prdoc/pr_2125.prdoc b/prdoc/pr_2125.prdoc new file mode 100644 index 00000000000..ee81975d2d0 --- /dev/null +++ b/prdoc/pr_2125.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: Introduce bounds for the number of candidate validation subsystem simultaneously processed tasks + +doc: + - audience: Node Dev + description: | + Makes it possible for the candidate validation subsystem to create backpressure on subsystems + requesting to validate a candidate through limiting the number of simultaneously processed + validation tasks. + +crates: + - name: polkadot-node-core-candidate-validation -- GitLab From 757ae372f7f07d9a7a4f62f646baa5e388ec5531 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Mon, 22 Jan 2024 08:15:53 +0100 Subject: [PATCH 049/283] Switch All `construct_runtime`s to New Syntax (#2979) Clean up all the old syntax. --------- Co-authored-by: command-bot <> Co-authored-by: gupnik Co-authored-by: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Co-authored-by: Maksym H <1177472+mordamax@users.noreply.github.com> --- cumulus/parachain-template/runtime/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/lib.rs | 57 ++++---- .../assets/asset-hub-westend/src/lib.rs | 58 ++++---- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 72 +++++----- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 46 +++--- .../collectives-westend/src/lib.rs | 72 +++++----- .../contracts/contracts-rococo/src/lib.rs | 42 +++--- .../glutton/glutton-westend/src/lib.rs | 22 ++- .../runtimes/people/people-rococo/src/lib.rs | 40 +++--- .../runtimes/people/people-westend/src/lib.rs | 40 +++--- .../runtimes/starters/seedling/src/lib.rs | 20 ++- .../runtimes/starters/shell/src/lib.rs | 18 ++- .../runtimes/testing/penpal/src/lib.rs | 40 +++--- .../testing/rococo-parachain/src/lib.rs | 32 ++--- docs/sdk/src/guides/your_first_pallet/mod.rs | 6 +- docs/sdk/src/polkadot_sdk/cumulus.rs | 2 +- docs/sdk/src/polkadot_sdk/frame_runtime.rs | 4 +- .../runtime/common/src/assigned_slots/mod.rs | 14 +- polkadot/runtime/common/src/auctions.rs | 6 +- polkadot/runtime/common/src/claims.rs | 8 +- polkadot/runtime/common/src/crowdloan/mod.rs | 6 +- polkadot/runtime/common/src/impls.rs | 8 +- .../runtime/common/src/integration_tests.rs | 26 ++-- .../runtime/common/src/paras_registrar/mod.rs | 14 +- polkadot/runtime/common/src/purchase.rs | 8 +- polkadot/runtime/common/src/slots/mod.rs | 6 +- polkadot/runtime/rococo/src/lib.rs | 132 +++++++++--------- polkadot/runtime/test-runtime/src/lib.rs | 70 +++++----- polkadot/runtime/westend/src/lib.rs | 120 ++++++++-------- .../src/fungible/mock.rs | 6 +- .../pallet-xcm-benchmarks/src/generic/mock.rs | 6 +- polkadot/xcm/pallet-xcm/src/mock.rs | 12 +- .../xcm/xcm-builder/src/tests/pay/mock.rs | 2 +- polkadot/xcm/xcm-builder/tests/mock/mod.rs | 8 +- .../xcm-simulator/example/src/parachain.rs | 10 +- .../xcm-simulator/example/src/relay_chain.rs | 12 +- .../xcm/xcm-simulator/fuzzer/src/parachain.rs | 8 +- .../xcm-simulator/fuzzer/src/relay_chain.rs | 10 +- substrate/bin/minimal/runtime/src/lib.rs | 2 +- .../bin/node-template/runtime/src/lib.rs | 2 +- substrate/bin/node/runtime/src/lib.rs | 11 +- substrate/frame/assets/src/mock.rs | 6 +- substrate/frame/atomic-swap/src/tests.rs | 6 +- substrate/frame/aura/src/mock.rs | 6 +- .../frame/authority-discovery/src/lib.rs | 6 +- substrate/frame/authorship/src/lib.rs | 4 +- substrate/frame/bags-list/src/mock.rs | 7 +- substrate/frame/balances/src/tests/mod.rs | 9 +- substrate/frame/beefy-mmr/src/mock.rs | 10 +- .../benchmarking/pov/src/benchmarking.rs | 4 +- substrate/frame/benchmarking/pov/src/tests.rs | 4 +- substrate/frame/benchmarking/src/baseline.rs | 2 +- substrate/frame/benchmarking/src/tests.rs | 4 +- .../frame/benchmarking/src/tests_instance.rs | 4 +- substrate/frame/bounties/src/tests.rs | 12 +- substrate/frame/child-bounties/src/tests.rs | 10 +- substrate/frame/collective/src/tests.rs | 11 +- .../contracts/mock-network/src/relay_chain.rs | 10 +- substrate/frame/contracts/src/tests.rs | 14 +- .../frame/conviction-voting/src/tests.rs | 6 +- substrate/frame/core-fellowship/src/tests.rs | 4 +- substrate/frame/democracy/src/tests.rs | 8 +- .../election-provider-multi-phase/src/mock.rs | 9 +- .../election-provider-support/src/onchain.rs | 5 +- substrate/frame/elections-phragmen/src/lib.rs | 7 +- substrate/frame/examples/basic/src/tests.rs | 6 +- .../frame/examples/default-config/src/lib.rs | 2 +- .../frame/examples/dev-mode/src/tests.rs | 6 +- .../frame/examples/frame-crate/src/lib.rs | 2 +- .../examples/offchain-worker/src/tests.rs | 4 +- substrate/frame/examples/tasks/src/mock.rs | 2 +- substrate/frame/executive/src/lib.rs | 11 +- substrate/frame/fast-unstake/src/mock.rs | 2 +- substrate/frame/glutton/src/mock.rs | 4 +- substrate/frame/identity/src/tests.rs | 6 +- substrate/frame/im-online/src/mock.rs | 11 +- substrate/frame/indices/src/mock.rs | 6 +- .../src/lib.rs | 4 +- substrate/frame/lottery/src/mock.rs | 6 +- substrate/frame/membership/src/lib.rs | 4 +- .../frame/merkle-mountain-range/src/mock.rs | 4 +- .../message-queue/src/integration_test.rs | 4 +- substrate/frame/message-queue/src/mock.rs | 4 +- substrate/frame/multisig/src/tests.rs | 6 +- substrate/frame/nfts/src/mock.rs | 6 +- .../frame/node-authorization/src/mock.rs | 6 +- .../nomination-pools/benchmarking/src/mock.rs | 15 +- substrate/frame/nomination-pools/src/mock.rs | 9 +- .../nomination-pools/test-staking/src/mock.rs | 15 +- .../frame/offences/benchmarking/src/mock.rs | 6 +- substrate/frame/offences/src/mock.rs | 7 +- substrate/frame/proxy/src/tests.rs | 8 +- .../frame/ranked-collective/src/tests.rs | 4 +- substrate/frame/recovery/src/mock.rs | 6 +- substrate/frame/remark/src/mock.rs | 4 +- substrate/frame/root-offences/src/mock.rs | 14 +- substrate/frame/salary/src/tests.rs | 4 +- substrate/frame/scheduler/src/mock.rs | 8 +- substrate/frame/scored-pool/src/mock.rs | 6 +- .../frame/session/benchmarking/src/mock.rs | 8 +- substrate/frame/session/src/mock.rs | 10 +- substrate/frame/society/src/mock.rs | 6 +- .../frame/state-trie-migration/src/lib.rs | 6 +- substrate/frame/sudo/src/mock.rs | 6 +- .../procedural/src/construct_runtime/mod.rs | 6 +- substrate/frame/support/src/lib.rs | 2 +- substrate/frame/support/src/migrations.rs | 6 +- .../support/test/compile_pass/src/lib.rs | 2 +- .../support/test/stg_frame_crate/src/lib.rs | 4 +- .../missing_system_module.stderr | 2 +- .../pass/composite_enum_instance.rs | 2 +- .../frame/support/test/tests/final_keys.rs | 1 - .../frame/support/test/tests/instance.rs | 27 ++-- .../frame/support/test/tests/issue2219.rs | 2 +- .../pallet_ui/pass/no_std_genesis_config.rs | 4 +- .../support/test/tests/storage_layers.rs | 2 +- .../support/test/tests/versioned_migration.rs | 4 +- substrate/frame/system/benches/bench.rs | 7 +- .../frame/system/benchmarking/src/mock.rs | 2 +- substrate/frame/system/src/mock.rs | 2 +- substrate/frame/timestamp/src/mock.rs | 4 +- substrate/frame/tips/src/tests.rs | 12 +- .../asset-tx-payment/src/mock.rs | 2 +- .../skip-feeless-payment/src/mock.rs | 2 +- .../frame/transaction-payment/src/mock.rs | 4 +- .../frame/transaction-storage/src/mock.rs | 8 +- substrate/frame/treasury/src/tests.rs | 6 +- substrate/frame/uniques/src/mock.rs | 6 +- substrate/frame/utility/src/tests.rs | 14 +- substrate/frame/vesting/src/mock.rs | 6 +- substrate/primitives/api/src/lib.rs | 4 +- .../api/test/tests/decl_and_impl.rs | 2 +- substrate/utils/frame/rpc/support/src/lib.rs | 4 +- 133 files changed, 795 insertions(+), 850 deletions(-) diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index 1ef018a8ca3..0ab36eba315 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -493,7 +493,7 @@ impl pallet_parachain_template::Config for Runtime { // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub struct Runtime { + pub enum Runtime { // System support stuff. System: frame_system = 0, ParachainSystem: cumulus_pallet_parachain_system = 1, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 0f379a6f7bc..a812e747f00 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -895,48 +895,45 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 3, + ParachainInfo: parachain_info = 4, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, - AssetTxPayment: pallet_asset_conversion_tx_payment::{Pallet, Event} = 13, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, + AssetTxPayment: pallet_asset_conversion_tx_payment = 13, // Collator support. the order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 42, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, + Proxy: pallet_proxy = 42, // Bridge utilities. - ToWestendXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 45, + ToWestendXcmRouter: pallet_xcm_bridge_hub_router:: = 45, // The main stage. - Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, - Nfts: pallet_nfts::{Pallet, Call, Storage, Event} = 52, - ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 53, - NftFractionalization: pallet_nft_fractionalization::{Pallet, Call, Storage, Event, HoldReason} = 54, - - PoolAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 55, - AssetConversion: pallet_asset_conversion::{Pallet, Call, Storage, Event} = 56, + Assets: pallet_assets:: = 50, + Uniques: pallet_uniques = 51, + Nfts: pallet_nfts = 52, + ForeignAssets: pallet_assets:: = 53, + NftFractionalization: pallet_nft_fractionalization = 54, + PoolAssets: pallet_assets:: = 55, + AssetConversion: pallet_asset_conversion = 56, #[cfg(feature = "state-trie-version-1")] StateTrieMigration: pallet_state_trie_migration = 70, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 310726349fa..b4bcc716513 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -870,48 +870,46 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, // RandomnessCollectiveFlip = 2 removed - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4, + Timestamp: pallet_timestamp = 3, + ParachainInfo: parachain_info = 4, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, - // AssetTxPayment: pallet_asset_tx_payment::{Pallet, Event} = 12, - AssetTxPayment: pallet_asset_conversion_tx_payment::{Pallet, Event} = 13, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, + // AssetTxPayment: pallet_asset_tx_payment = 12, + AssetTxPayment: pallet_asset_conversion_tx_payment = 13, // Collator support. the order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, // Bridge utilities. - ToRococoXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 34, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 35, + ToRococoXcmRouter: pallet_xcm_bridge_hub_router:: = 34, + MessageQueue: pallet_message_queue = 35, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 42, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, + Proxy: pallet_proxy = 42, // The main stage. - Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, - Nfts: pallet_nfts::{Pallet, Call, Storage, Event} = 52, - ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 53, - NftFractionalization: pallet_nft_fractionalization::{Pallet, Call, Storage, Event, HoldReason} = 54, - PoolAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 55, - AssetConversion: pallet_asset_conversion::{Pallet, Call, Storage, Event} = 56, + Assets: pallet_assets:: = 50, + Uniques: pallet_uniques = 51, + Nfts: pallet_nfts = 52, + ForeignAssets: pallet_assets:: = 53, + NftFractionalization: pallet_nft_fractionalization = 54, + PoolAssets: pallet_assets:: = 55, + AssetConversion: pallet_asset_conversion = 56, } ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index f84ff0799b9..4a3ef8ac4e8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -666,68 +666,66 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 36, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 36, // Bridge relayers pallet, used by several bridges here. - BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event} = 47, + BridgeRelayers: pallet_bridge_relayers = 47, // With-Westend GRANDPA bridge module. - BridgeWestendGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 48, + BridgeWestendGrandpa: pallet_bridge_grandpa:: = 48, // With-Westend parachain bridge module. - BridgeWestendParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event} = 49, + BridgeWestendParachains: pallet_bridge_parachains:: = 49, // With-Westend messaging bridge module. - BridgeWestendMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 51, + BridgeWestendMessages: pallet_bridge_messages:: = 51, // With-Westend bridge hub pallet. - XcmOverBridgeHubWestend: pallet_xcm_bridge_hub::::{Pallet} = 52, + XcmOverBridgeHubWestend: pallet_xcm_bridge_hub:: = 52, // With-Rococo Bulletin GRANDPA bridge module. // - // we can't use `BridgeRococoBulletinGrandpa` name here, because the same Bulletin runtime will be - // used for both Rococo and Polkadot Bulletin chains AND this name affects runtime storage keys, used - // by the relayer process - BridgePolkadotBulletinGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 60, + // we can't use `BridgeRococoBulletinGrandpa` name here, because the same Bulletin runtime + // will be used for both Rococo and Polkadot Bulletin chains AND this name affects runtime + // storage keys, used by the relayer process. + BridgePolkadotBulletinGrandpa: pallet_bridge_grandpa:: = 60, // With-Rococo Bulletin messaging bridge module. // - // we can't use `BridgeRococoBulletinMessages` name here, because the same Bulletin runtime will be - // used for both Rococo and Polkadot Bulletin chains AND this name affects runtime storage keys, used - // by this runtime and the relayer process - BridgePolkadotBulletinMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 61, + // we can't use `BridgeRococoBulletinMessages` name here, because the same Bulletin runtime + // will be used for both Rococo and Polkadot Bulletin chains AND this name affects runtime + // storage keys, used by this runtime and the relayer process. + BridgePolkadotBulletinMessages: pallet_bridge_messages:: = 61, // With-Rococo Bulletin bridge hub pallet. - XcmOverPolkadotBulletin: pallet_xcm_bridge_hub::::{Pallet} = 62, + XcmOverPolkadotBulletin: pallet_xcm_bridge_hub:: = 62, - EthereumInboundQueue: snowbridge_pallet_inbound_queue::{Pallet, Call, Storage, Event} = 80, - EthereumOutboundQueue: snowbridge_pallet_outbound_queue::{Pallet, Call, Storage, Event} = 81, - EthereumBeaconClient: snowbridge_pallet_ethereum_client::{Pallet, Call, Storage, Event} = 82, - EthereumSystem: snowbridge_pallet_system::{Pallet, Call, Storage, Config, Event} = 83, + EthereumInboundQueue: snowbridge_pallet_inbound_queue = 80, + EthereumOutboundQueue: snowbridge_pallet_outbound_queue = 81, + EthereumBeaconClient: snowbridge_pallet_ethereum_client = 82, + EthereumSystem: snowbridge_pallet_system = 83, // Message Queue. Importantly, is registered last so that messages are processed after // the `on_initialize` hooks of bridging pallets. - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 250, + MessageQueue: pallet_message_queue = 250, } ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index e90b5668c03..08dd129d84b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -460,43 +460,41 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 36, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 36, // Bridging stuff. - BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event} = 41, - BridgeRococoGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 42, - BridgeRococoParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event} = 43, - BridgeRococoMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 44, - XcmOverBridgeHubRococo: pallet_xcm_bridge_hub::::{Pallet} = 45, + BridgeRelayers: pallet_bridge_relayers = 41, + BridgeRococoGrandpa: pallet_bridge_grandpa:: = 42, + BridgeRococoParachains: pallet_bridge_parachains:: = 43, + BridgeRococoMessages: pallet_bridge_messages:: = 44, + XcmOverBridgeHubRococo: pallet_xcm_bridge_hub:: = 45, // Message Queue. Importantly, is registered last so that messages are processed after // the `on_initialize` hooks of bridging pallets. - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 250, + MessageQueue: pallet_message_queue = 250, } ); diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 3aff4671636..be7beafc89a 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -635,64 +635,62 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. the order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 42, - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 43, - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 44, - AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 45, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, + Proxy: pallet_proxy = 42, + Preimage: pallet_preimage = 43, + Scheduler: pallet_scheduler = 44, + AssetRate: pallet_asset_rate = 45, // The main stage. // The Alliance. - Alliance: pallet_alliance::{Pallet, Call, Storage, Event, Config} = 50, - AllianceMotion: pallet_collective::::{Pallet, Call, Storage, Origin, Event, Config} = 51, + Alliance: pallet_alliance = 50, + AllianceMotion: pallet_collective:: = 51, // The Fellowship. // pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; - FellowshipCollective: pallet_ranked_collective::::{Pallet, Call, Storage, Event} = 60, + FellowshipCollective: pallet_ranked_collective:: = 60, // pub type FellowshipReferendaInstance = pallet_referenda::Instance1; - FellowshipReferenda: pallet_referenda::::{Pallet, Call, Storage, Event} = 61, - FellowshipOrigins: pallet_fellowship_origins::{Origin} = 62, + FellowshipReferenda: pallet_referenda:: = 61, + FellowshipOrigins: pallet_fellowship_origins = 62, // pub type FellowshipCoreInstance = pallet_core_fellowship::Instance1; - FellowshipCore: pallet_core_fellowship::::{Pallet, Call, Storage, Event} = 63, + FellowshipCore: pallet_core_fellowship:: = 63, // pub type FellowshipSalaryInstance = pallet_salary::Instance1; - FellowshipSalary: pallet_salary::::{Pallet, Call, Storage, Event} = 64, + FellowshipSalary: pallet_salary:: = 64, // pub type FellowshipTreasuryInstance = pallet_treasury::Instance1; - FellowshipTreasury: pallet_treasury::::{Pallet, Call, Storage, Event} = 65, + FellowshipTreasury: pallet_treasury:: = 65, // Ambassador Program. - AmbassadorCollective: pallet_ranked_collective::::{Pallet, Call, Storage, Event} = 70, - AmbassadorReferenda: pallet_referenda::::{Pallet, Call, Storage, Event} = 71, - AmbassadorOrigins: pallet_ambassador_origins::{Origin} = 72, - AmbassadorCore: pallet_core_fellowship::::{Pallet, Call, Storage, Event} = 73, - AmbassadorSalary: pallet_salary::::{Pallet, Call, Storage, Event} = 74, - AmbassadorContent: pallet_collective_content::::{Pallet, Call, Storage, Event} = 75, + AmbassadorCollective: pallet_ranked_collective:: = 70, + AmbassadorReferenda: pallet_referenda:: = 71, + AmbassadorOrigins: pallet_ambassador_origins = 72, + AmbassadorCore: pallet_core_fellowship:: = 73, + AmbassadorSalary: pallet_salary:: = 74, + AmbassadorContent: pallet_collective_content:: = 75, } ); diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 707766ca226..f1c5acb4952 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -376,40 +376,38 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip::{Pallet, Storage} = 2, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 4, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip = 2, + Timestamp: pallet_timestamp = 3, + ParachainInfo: parachain_info = 4, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Smart Contracts. - Contracts: pallet_contracts::{Pallet, Call, Storage, Event, HoldReason} = 40, + Contracts: pallet_contracts = 40, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 50, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 51, + Utility: pallet_utility = 50, + Multisig: pallet_multisig = 51, // Sudo - Sudo: pallet_sudo::{Pallet, Call, Config, Event, Storage} = 100, + Sudo: pallet_sudo = 100, } ); diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 15899e49195..9fbbdc61fea 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -274,26 +274,24 @@ impl pallet_sudo::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 2, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + ParachainInfo: parachain_info = 2, + Timestamp: pallet_timestamp = 3, // DMP handler. - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Storage, Event, Origin} = 10, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 11, + CumulusXcm: cumulus_pallet_xcm = 10, + MessageQueue: pallet_message_queue = 11, // The main stage. - Glutton: pallet_glutton::{Pallet, Call, Storage, Event, Config} = 20, + Glutton: pallet_glutton = 20, // Collator support - Aura: pallet_aura::{Pallet, Storage, Config} = 30, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 31, + Aura: pallet_aura = 30, + AuraExt: cumulus_pallet_aura_ext = 31, // Sudo. - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + Sudo: pallet_sudo = 255, } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 21c24086cbe..7836208eb62 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -400,39 +400,37 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM & related - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, // The main stage. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 50, + Identity: pallet_identity = 50, // To migrate deposits - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, } ); diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 4015d841b81..750bf5b2c3e 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -408,39 +408,37 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, // Collator support. The order of these 5 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // Handy utilities. - Utility: pallet_utility::{Pallet, Call, Event} = 40, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, + Utility: pallet_utility = 40, + Multisig: pallet_multisig = 41, // The main stage. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 50, + Identity: pallet_identity = 50, // To migrate deposits - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, } ); diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index cb868627e79..ba077ef8879 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -230,17 +230,15 @@ impl pallet_timestamp::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - }, - ParachainInfo: parachain_info::{Pallet, Storage, Config}, - SoloToPara: cumulus_pallet_solo_to_para::{Pallet, Call, Storage, Event}, - Aura: pallet_aura::{Pallet, Storage, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config}, + System: frame_system, + Sudo: pallet_sudo, + Timestamp: pallet_timestamp, + + ParachainSystem: cumulus_pallet_parachain_system, + ParachainInfo: parachain_info, + SoloToPara: cumulus_pallet_solo_to_para, + Aura: pallet_aura, + AuraExt: cumulus_pallet_aura_ext, } } diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index de95969f71d..457394760d9 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -258,19 +258,17 @@ impl pallet_timestamp::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + System: frame_system, + Timestamp: pallet_timestamp, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - }, - ParachainInfo: parachain_info::{Pallet, Storage, Config}, + ParachainSystem: cumulus_pallet_parachain_system, + ParachainInfo: parachain_info, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event}, + CumulusXcm: cumulus_pallet_xcm, + MessageQueue: pallet_message_queue, - Aura: pallet_aura::{Pallet, Storage, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config}, + Aura: pallet_aura, + AuraExt: cumulus_pallet_aura_ext, } } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 37a8454d62a..d33f51df5a9 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -634,36 +634,34 @@ construct_runtime!( pub enum Runtime { // System support stuff. - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 3, + System: frame_system = 0, + ParachainSystem: cumulus_pallet_parachain_system = 1, + Timestamp: pallet_timestamp = 2, + ParachainInfo: parachain_info = 3, // Monetary stuff. - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 10, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 11, - AssetTxPayment: pallet_asset_tx_payment::{Pallet, Event} = 12, + Balances: pallet_balances = 10, + TransactionPayment: pallet_transaction_payment = 11, + AssetTxPayment: pallet_asset_tx_payment = 12, // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship::{Pallet, Storage} = 20, - CollatorSelection: pallet_collator_selection::{Pallet, Call, Storage, Event, Config} = 21, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, - Aura: pallet_aura::{Pallet, Storage, Config} = 23, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + Authorship: pallet_authorship = 20, + CollatorSelection: pallet_collator_selection = 21, + Session: pallet_session = 22, + Aura: pallet_aura = 23, + AuraExt: cumulus_pallet_aura_ext = 24, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 30, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 31, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 34, + XcmpQueue: cumulus_pallet_xcmp_queue = 30, + PolkadotXcm: pallet_xcm = 31, + CumulusXcm: cumulus_pallet_xcm = 32, + MessageQueue: pallet_message_queue = 34, // The main stage. - Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, - ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 51, + Assets: pallet_assets:: = 50, + ForeignAssets: pallet_assets:: = 51, - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + Sudo: pallet_sudo = 255, } ); diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 795efa39247..999cc480ce0 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -603,30 +603,28 @@ impl pallet_aura::Config for Runtime { construct_runtime! { pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + System: frame_system, + Timestamp: pallet_timestamp, + Sudo: pallet_sudo, + TransactionPayment: pallet_transaction_payment, - ParachainSystem: cumulus_pallet_parachain_system::{ - Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, - } = 20, - ParachainInfo: parachain_info::{Pallet, Storage, Config} = 21, + ParachainSystem: cumulus_pallet_parachain_system = 20, + ParachainInfo: parachain_info = 21, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 30, - Assets: pallet_assets::{Pallet, Call, Storage, Event} = 31, + Balances: pallet_balances = 30, + Assets: pallet_assets = 31, - Aura: pallet_aura::{Pallet, Config}, - AuraExt: cumulus_pallet_aura_ext::{Pallet, Config}, + Aura: pallet_aura, + AuraExt: cumulus_pallet_aura_ext, // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event} = 50, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin, Config} = 51, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Event, Origin} = 52, + XcmpQueue: cumulus_pallet_xcmp_queue = 50, + PolkadotXcm: pallet_xcm = 51, + CumulusXcm: cumulus_pallet_xcm = 52, // RIP DmpQueue 53 - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 54, + MessageQueue: pallet_message_queue = 54, - Spambot: cumulus_ping::{Pallet, Call, Storage, Event} = 99, + Spambot: cumulus_ping = 99, } } diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index 24eada44a83..ea23af51ec9 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -428,8 +428,8 @@ pub mod pallet { use crate::guides::your_first_pallet::pallet as pallet_currency; construct_runtime!( - pub struct Runtime { - // ---^^^^^^ This is where `struct Runtime` is defined. + pub enum Runtime { + // ---^^^^^^ This is where `enum Runtime` is defined. System: frame_system, Currency: pallet_currency, } @@ -708,7 +708,7 @@ pub mod pallet_v2 { use crate::guides::your_first_pallet::pallet_v2 as pallet_currency; construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Currency: pallet_currency, } diff --git a/docs/sdk/src/polkadot_sdk/cumulus.rs b/docs/sdk/src/polkadot_sdk/cumulus.rs index 07a48c92d80..60c4839f9e2 100644 --- a/docs/sdk/src/polkadot_sdk/cumulus.rs +++ b/docs/sdk/src/polkadot_sdk/cumulus.rs @@ -55,7 +55,7 @@ mod tests { #[docify::export(CR)] construct_runtime!( - pub struct Runtime { + pub enum Runtime { // system-level pallets. System: frame_system, Timestamp: pallet_timestamp, diff --git a/docs/sdk/src/polkadot_sdk/frame_runtime.rs b/docs/sdk/src/polkadot_sdk/frame_runtime.rs index 32dc2045e3a..c9eba7d64bd 100644 --- a/docs/sdk/src/polkadot_sdk/frame_runtime.rs +++ b/docs/sdk/src/polkadot_sdk/frame_runtime.rs @@ -156,9 +156,9 @@ mod tests { use super::pallet as pallet_example; use frame::{prelude::*, testing_prelude::*}; - // The major macro that amalgamates pallets into `struct Runtime` + // The major macro that amalgamates pallets into `enum Runtime` construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Example: pallet_example, } diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index de8c00df9dd..9976a7be548 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -658,13 +658,13 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, - ParasShared: parachains_shared::{Pallet, Call, Storage}, - Parachains: parachains_paras::{Pallet, Call, Storage, Config, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, - AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Configuration: parachains_configuration, + ParasShared: parachains_shared, + Parachains: parachains_paras, + Slots: slots, + AssignedSlots: assigned_slots, } ); diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs index baa66d83a3f..0bd5ed1e733 100644 --- a/polkadot/runtime/common/src/auctions.rs +++ b/polkadot/runtime/common/src/auctions.rs @@ -697,9 +697,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Auctions: auctions::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Auctions: auctions, } ); diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 4cddab969c0..5b87cc9619e 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -727,10 +727,10 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, - Claims: claims::{Pallet, Call, Storage, Config, Event, ValidateUnsigned}, + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, + Claims: claims, } ); diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs index 77ef406e579..b7dd06aee3a 100644 --- a/polkadot/runtime/common/src/crowdloan/mod.rs +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -888,9 +888,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Crowdloan: crowdloan, } ); diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index a9edb196627..79ace0972ad 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -242,10 +242,10 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Authorship: pallet_authorship::{Pallet, Storage}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Authorship: pallet_authorship, + Balances: pallet_balances, + Treasury: pallet_treasury, } ); diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index b536b80e245..2bf21bbde95 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -74,25 +74,25 @@ frame_support::construct_runtime!( pub enum Test { // System Stuff - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned}, + System: frame_system, + Balances: pallet_balances, + Babe: pallet_babe, // Parachains Runtime - Configuration: configuration::{Pallet, Call, Storage, Config}, - Paras: paras::{Pallet, Call, Storage, Event, Config}, - ParasShared: shared::{Pallet, Call, Storage}, - ParachainsOrigin: origin::{Pallet, Origin}, + Configuration: configuration, + Paras: paras, + ParasShared: shared, + ParachainsOrigin: origin, // Para Onboarding Pallets - Registrar: paras_registrar::{Pallet, Call, Storage, Event}, - Auctions: auctions::{Pallet, Call, Storage, Event}, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + Registrar: paras_registrar, + Auctions: auctions, + Crowdloan: crowdloan, + Slots: slots, // Migrators - Identity: pallet_identity::{Pallet, Call, Storage, Event}, - IdentityMigrator: identity_migrator::{Pallet, Call, Event}, + Identity: pallet_identity, + IdentityMigrator: identity_migrator, } ); diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 448490b34a7..a3bdc1b1b0f 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -724,13 +724,13 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Configuration: configuration::{Pallet, Call, Storage, Config}, - Parachains: paras::{Pallet, Call, Storage, Config, Event}, - ParasShared: shared::{Pallet, Call, Storage}, - Registrar: paras_registrar::{Pallet, Call, Storage, Event}, - ParachainsOrigin: origin::{Pallet, Origin}, + System: frame_system, + Balances: pallet_balances, + Configuration: configuration, + Parachains: paras, + ParasShared: shared, + Registrar: paras_registrar, + ParachainsOrigin: origin, } ); diff --git a/polkadot/runtime/common/src/purchase.rs b/polkadot/runtime/common/src/purchase.rs index f43f16b838c..146a90fca86 100644 --- a/polkadot/runtime/common/src/purchase.rs +++ b/polkadot/runtime/common/src/purchase.rs @@ -499,10 +499,10 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, - Purchase: purchase::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, + Purchase: purchase, } ); diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs index 58bd1d53aed..be02aa9961c 100644 --- a/polkadot/runtime/common/src/slots/mod.rs +++ b/polkadot/runtime/common/src/slots/mod.rs @@ -520,9 +520,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Slots: slots::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Slots: slots, } ); diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 51c00336bef..2d49f0b99e9 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1315,135 +1315,131 @@ construct_runtime! { pub enum Runtime { // Basic stuff; balances is uncallable initially. - System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + System: frame_system = 0, // Babe must be before session. - Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + Babe: pallet_babe = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 33, + Timestamp: pallet_timestamp = 2, + Indices: pallet_indices = 3, + Balances: pallet_balances = 4, + TransactionPayment: pallet_transaction_payment = 33, // Consensus support. // Authorship must be before session in order to note author in the correct session and era. - Authorship: pallet_authorship::{Pallet, Storage} = 5, - Offences: pallet_offences::{Pallet, Storage, Event} = 7, - Historical: session_historical::{Pallet} = 34, + Authorship: pallet_authorship = 5, + Offences: pallet_offences = 7, + Historical: session_historical = 34, // BEEFY Bridges support. - Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 240, + Beefy: pallet_beefy = 240, // MMR leaf construction must be before session in order to have leaf contents // refer to block consistently. see substrate issue #11797 for details. - Mmr: pallet_mmr::{Pallet, Storage} = 241, - MmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 242, + Mmr: pallet_mmr = 241, + MmrLeaf: pallet_beefy_mmr = 242, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, - Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + Session: pallet_session = 8, + Grandpa: pallet_grandpa = 10, + AuthorityDiscovery: pallet_authority_discovery = 12, // Governance stuff; uncallable initially. - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 18, - ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 20, - Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 21, + Treasury: pallet_treasury = 18, + ConvictionVoting: pallet_conviction_voting = 20, + Referenda: pallet_referenda = 21, // pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; - FellowshipCollective: pallet_ranked_collective::::{ - Pallet, Call, Storage, Event - } = 22, + FellowshipCollective: pallet_ranked_collective:: = 22, // pub type FellowshipReferendaInstance = pallet_referenda::Instance2; - FellowshipReferenda: pallet_referenda::::{ - Pallet, Call, Storage, Event - } = 23, - Origins: pallet_custom_origins::{Origin} = 43, - Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 44, + FellowshipReferenda: pallet_referenda:: = 23, + Origins: pallet_custom_origins = 43, + Whitelist: pallet_whitelist = 44, // Claims. Usable initially. - Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 19, + Claims: claims = 19, // Utility module. - Utility: pallet_utility::{Pallet, Call, Event} = 24, + Utility: pallet_utility = 24, // Less simple identity module. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 25, + Identity: pallet_identity = 25, // Society module. - Society: pallet_society::{Pallet, Call, Storage, Event} = 26, + Society: pallet_society = 26, // Social recovery module. - Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 27, + Recovery: pallet_recovery = 27, // Vesting. Usable initially, but removed once all vesting is finished. - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 28, + Vesting: pallet_vesting = 28, // System scheduler. - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 29, + Scheduler: pallet_scheduler = 29, // Proxy module. Late addition. - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 30, + Proxy: pallet_proxy = 30, // Multisig module. Late addition. - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 31, + Multisig: pallet_multisig = 31, // Preimage registrar. - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 32, + Preimage: pallet_preimage = 32, // Asset rate. - AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 39, + AssetRate: pallet_asset_rate = 39, // Bounties modules. - Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 35, + Bounties: pallet_bounties = 35, ChildBounties: pallet_child_bounties = 40, // NIS pallet. - Nis: pallet_nis::{Pallet, Call, Storage, Event, HoldReason} = 38, + Nis: pallet_nis = 38, // pub type NisCounterpartInstance = pallet_balances::Instance2; NisCounterpartBalances: pallet_balances:: = 45, // Parachains pallets. Start indices at 50 to leave room. - ParachainsOrigin: parachains_origin::{Pallet, Origin} = 50, - Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 51, - ParasShared: parachains_shared::{Pallet, Call, Storage} = 52, - ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 53, - ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 54, - ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, - Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, - Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, - Dmp: parachains_dmp::{Pallet, Storage} = 58, - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, - ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, - ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 62, - ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 63, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 64, - OnDemandAssignmentProvider: parachains_assigner_on_demand::{Pallet, Call, Storage, Event} = 66, - ParachainsAssignmentProvider: parachains_assigner_parachains::{Pallet} = 67, - CoretimeAssignmentProvider: parachains_assigner_coretime::{Pallet, Storage} = 68, + ParachainsOrigin: parachains_origin = 50, + Configuration: parachains_configuration = 51, + ParasShared: parachains_shared = 52, + ParaInclusion: parachains_inclusion = 53, + ParaInherent: parachains_paras_inherent = 54, + ParaScheduler: parachains_scheduler = 55, + Paras: parachains_paras = 56, + Initializer: parachains_initializer = 57, + Dmp: parachains_dmp = 58, + Hrmp: parachains_hrmp = 60, + ParaSessionInfo: parachains_session_info = 61, + ParasDisputes: parachains_disputes = 62, + ParasSlashing: parachains_slashing = 63, + MessageQueue: pallet_message_queue = 64, + OnDemandAssignmentProvider: parachains_assigner_on_demand = 66, + ParachainsAssignmentProvider: parachains_assigner_parachains = 67, + CoretimeAssignmentProvider: parachains_assigner_coretime = 68, // Parachain Onboarding Pallets. Start indices at 70 to leave room. - Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 70, - Slots: slots::{Pallet, Call, Storage, Event} = 71, - Auctions: auctions::{Pallet, Call, Storage, Event} = 72, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 73, - Coretime: coretime::{Pallet, Call, Event} = 74, + Registrar: paras_registrar = 70, + Slots: slots = 71, + Auctions: auctions = 72, + Crowdloan: crowdloan = 73, + Coretime: coretime = 74, // Pallet for sending XCM. - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + XcmPallet: pallet_xcm = 99, // Pallet for migrating Identity to a parachain. To be removed post-migration. - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, - ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 250, - AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 251, + ParasSudoWrapper: paras_sudo_wrapper = 250, + AssignedSlots: assigned_slots = 251, // Validator Manager pallet. - ValidatorManager: validator_manager::{Pallet, Call, Storage, Event} = 252, + ValidatorManager: validator_manager = 252, // State trie migration pallet, only temporary. StateTrieMigration: pallet_state_trie_migration = 254, // Root testing pallet. - RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event} = 249, + RootTesting: pallet_root_testing = 249, // Sudo. - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, + Sudo: pallet_sudo = 255, } } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 18bcb16834e..51c199b7a05 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -670,52 +670,52 @@ construct_runtime! { pub enum Runtime { // Basic stuff; balances is uncallable initially. - System: frame_system::{Pallet, Call, Storage, Config, Event}, + System: frame_system, // Must be before session. - Babe: pallet_babe::{Pallet, Call, Storage, Config}, + Babe: pallet_babe, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + Timestamp: pallet_timestamp, + Indices: pallet_indices, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, // Consensus support. - Authorship: pallet_authorship::{Pallet, Storage}, - Staking: pallet_staking::{Pallet, Call, Storage, Config, Event}, - Offences: pallet_offences::{Pallet, Storage, Event}, - Historical: session_historical::{Pallet}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event}, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config}, + Authorship: pallet_authorship, + Staking: pallet_staking, + Offences: pallet_offences, + Historical: session_historical, + Session: pallet_session, + Grandpa: pallet_grandpa, + AuthorityDiscovery: pallet_authority_discovery, // Claims. Usable initially. - Claims: claims::{Pallet, Call, Storage, Event, Config, ValidateUnsigned}, + Claims: claims, // Vesting. Usable initially, but removed once all vesting is finished. - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, + Vesting: pallet_vesting, // Parachains runtime modules - Configuration: parachains_configuration::{Pallet, Call, Storage, Config}, - ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event}, - ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent}, - Initializer: parachains_initializer::{Pallet, Call, Storage}, - Paras: parachains_paras::{Pallet, Call, Storage, Event, ValidateUnsigned}, - ParasShared: parachains_shared::{Pallet, Call, Storage}, - Scheduler: parachains_scheduler::{Pallet, Storage}, - ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call}, - ParasOrigin: parachains_origin::{Pallet, Origin}, - ParaSessionInfo: parachains_session_info::{Pallet, Storage}, - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event}, - Dmp: parachains_dmp::{Pallet, Storage}, - Xcm: pallet_xcm::{Pallet, Call, Event, Origin}, - ParasDisputes: parachains_disputes::{Pallet, Storage, Event}, - ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned}, - ParaAssignmentProvider: parachains_assigner_parachains::{Pallet}, - - Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event}, - - TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, + Configuration: parachains_configuration, + ParaInclusion: parachains_inclusion, + ParaInherent: parachains_paras_inherent, + Initializer: parachains_initializer, + Paras: parachains_paras, + ParasShared: parachains_shared, + Scheduler: parachains_scheduler, + ParasSudoWrapper: paras_sudo_wrapper, + ParasOrigin: parachains_origin, + ParaSessionInfo: parachains_session_info, + Hrmp: parachains_hrmp, + Dmp: parachains_dmp, + Xcm: pallet_xcm, + ParasDisputes: parachains_disputes, + ParasSlashing: parachains_slashing, + ParaAssignmentProvider: parachains_assigner_parachains, + + Sudo: pallet_sudo, + + TestNotifier: pallet_test_notifier, } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 941193ba941..adfb2083254 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1397,121 +1397,121 @@ construct_runtime! { pub enum Runtime { // Basic stuff; balances is uncallable initially. - System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, + System: frame_system = 0, // Babe must be before session. - Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned} = 1, + Babe: pallet_babe = 1, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 2, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event} = 3, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event} = 4, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event} = 26, + Timestamp: pallet_timestamp = 2, + Indices: pallet_indices = 3, + Balances: pallet_balances = 4, + TransactionPayment: pallet_transaction_payment = 26, // Consensus support. // Authorship must be before session in order to note author in the correct session and era. - Authorship: pallet_authorship::{Pallet, Storage} = 5, - Staking: pallet_staking::{Pallet, Call, Storage, Config, Event} = 6, - Offences: pallet_offences::{Pallet, Storage, Event} = 7, - Historical: session_historical::{Pallet} = 27, + Authorship: pallet_authorship = 5, + Staking: pallet_staking = 6, + Offences: pallet_offences = 7, + Historical: session_historical = 27, // BEEFY Bridges support. - Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned} = 200, - // MMR leaf construction must be before session in order to have leaf contents - // refer to block consistently. see substrate issue #11797 for details. - Mmr: pallet_mmr::{Pallet, Storage} = 201, - BeefyMmrLeaf: pallet_beefy_mmr::{Pallet, Storage} = 202, + Beefy: pallet_beefy = 200, + // MMR leaf construction must be before session in order to have leaf contents refer to + // block consistently. see substrate issue #11797 for details. + Mmr: pallet_mmr = 201, + BeefyMmrLeaf: pallet_beefy_mmr = 202, - Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 8, - Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned} = 10, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12, + Session: pallet_session = 8, + Grandpa: pallet_grandpa = 10, + AuthorityDiscovery: pallet_authority_discovery = 12, // Utility module. - Utility: pallet_utility::{Pallet, Call, Event} = 16, + Utility: pallet_utility = 16, // Less simple identity module. - Identity: pallet_identity::{Pallet, Call, Storage, Event} = 17, + Identity: pallet_identity = 17, // Social recovery module. - Recovery: pallet_recovery::{Pallet, Call, Storage, Event} = 18, + Recovery: pallet_recovery = 18, // Vesting. Usable initially, but removed once all vesting is finished. - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config} = 19, + Vesting: pallet_vesting = 19, // System scheduler. - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event} = 20, + Scheduler: pallet_scheduler = 20, // Preimage registrar. - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason} = 28, + Preimage: pallet_preimage = 28, // Sudo. - Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 21, + Sudo: pallet_sudo = 21, // Proxy module. Late addition. - Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 22, + Proxy: pallet_proxy = 22, // Multisig module. Late addition. - Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 23, + Multisig: pallet_multisig = 23, // Election pallet. Only works with staking, but placed here to maintain indices. - ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event, ValidateUnsigned} = 24, + ElectionProviderMultiPhase: pallet_election_provider_multi_phase = 24, // Provides a semi-sorted list of nominators for staking. - VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event} = 25, + VoterList: pallet_bags_list:: = 25, // Nomination pools for staking. - NominationPools: pallet_nomination_pools::{Pallet, Call, Storage, Event, Config, FreezeReason} = 29, + NominationPools: pallet_nomination_pools = 29, // Fast unstake pallet: extension to staking. FastUnstake: pallet_fast_unstake = 30, // OpenGov - ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 31, - Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 32, - Origins: pallet_custom_origins::{Origin} = 35, - Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 36, + ConvictionVoting: pallet_conviction_voting = 31, + Referenda: pallet_referenda = 32, + Origins: pallet_custom_origins = 35, + Whitelist: pallet_whitelist = 36, // Treasury - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event} = 37, + Treasury: pallet_treasury = 37, // Parachains pallets. Start indices at 40 to leave room. - ParachainsOrigin: parachains_origin::{Pallet, Origin} = 41, - Configuration: parachains_configuration::{Pallet, Call, Storage, Config} = 42, - ParasShared: parachains_shared::{Pallet, Call, Storage} = 43, - ParaInclusion: parachains_inclusion::{Pallet, Call, Storage, Event} = 44, - ParaInherent: parachains_paras_inherent::{Pallet, Call, Storage, Inherent} = 45, - ParaScheduler: parachains_scheduler::{Pallet, Storage} = 46, - Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 47, - Initializer: parachains_initializer::{Pallet, Call, Storage} = 48, - Dmp: parachains_dmp::{Pallet, Storage} = 49, + ParachainsOrigin: parachains_origin = 41, + Configuration: parachains_configuration = 42, + ParasShared: parachains_shared = 43, + ParaInclusion: parachains_inclusion = 44, + ParaInherent: parachains_paras_inherent = 45, + ParaScheduler: parachains_scheduler = 46, + Paras: parachains_paras = 47, + Initializer: parachains_initializer = 48, + Dmp: parachains_dmp = 49, // RIP Ump 50 - Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 51, - ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 52, - ParasDisputes: parachains_disputes::{Pallet, Call, Storage, Event} = 53, - ParasSlashing: parachains_slashing::{Pallet, Call, Storage, ValidateUnsigned} = 54, - ParachainsAssignmentProvider: parachains_assigner_parachains::{Pallet} = 55, + Hrmp: parachains_hrmp = 51, + ParaSessionInfo: parachains_session_info = 52, + ParasDisputes: parachains_disputes = 53, + ParasSlashing: parachains_slashing = 54, + ParachainsAssignmentProvider: parachains_assigner_parachains = 55, // Parachain Onboarding Pallets. Start indices at 60 to leave room. - Registrar: paras_registrar::{Pallet, Call, Storage, Event, Config} = 60, - Slots: slots::{Pallet, Call, Storage, Event} = 61, - ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call} = 62, - Auctions: auctions::{Pallet, Call, Storage, Event} = 63, - Crowdloan: crowdloan::{Pallet, Call, Storage, Event} = 64, - AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event, Config} = 65, + Registrar: paras_registrar = 60, + Slots: slots = 61, + ParasSudoWrapper: paras_sudo_wrapper = 62, + Auctions: auctions = 63, + Crowdloan: crowdloan = 64, + AssignedSlots: assigned_slots = 65, // Pallet for sending XCM. - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 99, + XcmPallet: pallet_xcm = 99, // Generalized message queue - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 100, + MessageQueue: pallet_message_queue = 100, // Asset rate. - AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 101, + AssetRate: pallet_asset_rate = 101, // Root testing pallet. - RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event} = 102, + RootTesting: pallet_root_testing = 102, // Pallet for migrating Identity to a parachain. To be removed post-migration. - IdentityMigrator: identity_migrator::{Pallet, Call, Event} = 248, + IdentityMigrator: identity_migrator = 248, } } diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs index bb4b7ff6276..f1d1b2fdef3 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -34,9 +34,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - XcmBalancesBenchmark: xcm_balances_benchmark::{Pallet}, + System: frame_system, + Balances: pallet_balances, + XcmBalancesBenchmark: xcm_balances_benchmark, } ); diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs index 4dd677217fc..656c675b630 100644 --- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs +++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -39,9 +39,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - XcmGenericBenchmarks: generic::{Pallet}, + System: frame_system, + Balances: pallet_balances, + XcmGenericBenchmarks: generic, } ); diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 3ce32fa46d3..1ca30963d59 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -139,12 +139,12 @@ pub mod pallet_test_notifier { construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - AssetsPallet: pallet_assets::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config}, - TestNotifier: pallet_test_notifier::{Pallet, Call, Event}, + System: frame_system, + Balances: pallet_balances, + AssetsPallet: pallet_assets, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + TestNotifier: pallet_test_notifier, } ); diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs index 01ff8c29f3d..76198f84ed6 100644 --- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs +++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs @@ -40,7 +40,7 @@ pub type BlockNumber = u32; pub type AccountId = AccountId32; construct_runtime!( - pub struct Test { + pub enum Test { System: frame_system, Balances: pallet_balances, Assets: pallet_assets, diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs index 2e89313a68e..73df22561d1 100644 --- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs +++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs @@ -250,10 +250,10 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, } ); diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs index 0b6c573f464..3adfa95d2e8 100644 --- a/polkadot/xcm/xcm-simulator/example/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs @@ -457,10 +457,10 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - ForeignUniques: pallet_uniques::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + MsgQueue: mock_msg_queue, + PolkadotXcm: pallet_xcm, + ForeignUniques: pallet_uniques, } ); diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs index 946b932b05e..d9ed6e800aa 100644 --- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs @@ -281,11 +281,11 @@ impl pallet_message_queue::Config for Runtime { construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, - MessageQueue: pallet_message_queue::{Pallet, Event}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + Uniques: pallet_uniques, + MessageQueue: pallet_message_queue, } ); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs index 41fc5af9708..8a89f8cb0e7 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs @@ -360,9 +360,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - MsgQueue: mock_msg_queue::{Pallet, Storage, Event}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + System: frame_system, + Balances: pallet_balances, + MsgQueue: mock_msg_queue, + PolkadotXcm: pallet_xcm, } ); diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs index d3f91b01317..143f8974f3e 100644 --- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs +++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs @@ -252,10 +252,10 @@ impl pallet_message_queue::Config for Runtime { construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - MessageQueue: pallet_message_queue::{Pallet, Event}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/bin/minimal/runtime/src/lib.rs b/substrate/bin/minimal/runtime/src/lib.rs index efee400c3f5..610289693d9 100644 --- a/substrate/bin/minimal/runtime/src/lib.rs +++ b/substrate/bin/minimal/runtime/src/lib.rs @@ -63,7 +63,7 @@ type SignedExtra = ( ); construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Timestamp: pallet_timestamp, diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 5f399edda98..e9ccd5697df 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -258,7 +258,7 @@ impl pallet_template::Config for Runtime { // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Timestamp: pallet_timestamp, Aura: pallet_aura, diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 1043e5017dc..d7598adb5a2 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -2083,8 +2083,7 @@ impl pallet_mixnet::Config for Runtime { } construct_runtime!( - pub struct Runtime - { + pub enum Runtime { System: frame_system, Utility: pallet_utility, Babe: pallet_babe, @@ -2099,11 +2098,11 @@ construct_runtime!( AssetConversionTxPayment: pallet_asset_conversion_tx_payment, ElectionProviderMultiPhase: pallet_election_provider_multi_phase, Staking: pallet_staking, - Beefy: pallet_beefy::{Pallet, Call, Storage, Config, ValidateUnsigned}, + Beefy: pallet_beefy, // MMR leaf construction must be before session in order to have leaf contents // refer to block consistently. see substrate issue #11797 for details. - Mmr: pallet_mmr::{Pallet, Storage}, - MmrLeaf: pallet_beefy_mmr::{Pallet, Storage}, + Mmr: pallet_mmr, + MmrLeaf: pallet_beefy_mmr, Session: pallet_session, Democracy: pallet_democracy, Council: pallet_collective::, @@ -2118,7 +2117,7 @@ construct_runtime!( ImOnline: pallet_im_online, AuthorityDiscovery: pallet_authority_discovery, Offences: pallet_offences, - Historical: pallet_session_historical::{Pallet}, + Historical: pallet_session_historical, RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip, Identity: pallet_identity, Society: pallet_society, diff --git a/substrate/frame/assets/src/mock.rs b/substrate/frame/assets/src/mock.rs index a4d85b64922..d60f5358336 100644 --- a/substrate/frame/assets/src/mock.rs +++ b/substrate/frame/assets/src/mock.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Assets: pallet_assets, } ); diff --git a/substrate/frame/atomic-swap/src/tests.rs b/substrate/frame/atomic-swap/src/tests.rs index 7e2f22b1836..58502aa4f93 100644 --- a/substrate/frame/atomic-swap/src/tests.rs +++ b/substrate/frame/atomic-swap/src/tests.rs @@ -35,9 +35,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - AtomicSwap: pallet_atomic_swap::{Pallet, Call, Event}, + System: frame_system, + Balances: pallet_balances, + AtomicSwap: pallet_atomic_swap, } ); diff --git a/substrate/frame/aura/src/mock.rs b/substrate/frame/aura/src/mock.rs index d38a8583819..d87fea8fc81 100644 --- a/substrate/frame/aura/src/mock.rs +++ b/substrate/frame/aura/src/mock.rs @@ -35,9 +35,9 @@ const SLOT_DURATION: u64 = 2; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Aura: pallet_aura::{Pallet, Storage, Config}, + System: frame_system, + Timestamp: pallet_timestamp, + Aura: pallet_aura, } ); diff --git a/substrate/frame/authority-discovery/src/lib.rs b/substrate/frame/authority-discovery/src/lib.rs index 3044b41e31d..640c0c8759e 100644 --- a/substrate/frame/authority-discovery/src/lib.rs +++ b/substrate/frame/authority-discovery/src/lib.rs @@ -187,9 +187,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config}, + System: frame_system, + Session: pallet_session, + AuthorityDiscovery: pallet_authority_discovery, } ); diff --git a/substrate/frame/authorship/src/lib.rs b/substrate/frame/authorship/src/lib.rs index 56a516894de..8b38a58d8e7 100644 --- a/substrate/frame/authorship/src/lib.rs +++ b/substrate/frame/authorship/src/lib.rs @@ -108,8 +108,8 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Authorship: pallet_authorship::{Pallet, Storage}, + System: frame_system, + Authorship: pallet_authorship, } ); diff --git a/substrate/frame/bags-list/src/mock.rs b/substrate/frame/bags-list/src/mock.rs index 9946a2198ac..4282120983b 100644 --- a/substrate/frame/bags-list/src/mock.rs +++ b/substrate/frame/bags-list/src/mock.rs @@ -68,10 +68,9 @@ impl bags_list::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Storage, Event, Config}, - BagsList: bags_list::{Pallet, Call, Storage, Event}, + pub enum Runtime { + System: frame_system, + BagsList: bags_list, } ); diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs index 8e834483cbe..708e081fe0b 100644 --- a/substrate/frame/balances/src/tests/mod.rs +++ b/substrate/frame/balances/src/tests/mod.rs @@ -75,11 +75,10 @@ impl VariantCount for TestId { } frame_support::construct_runtime!( - pub struct Test - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + pub enum Test { + System: frame_system, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, } ); diff --git a/substrate/frame/beefy-mmr/src/mock.rs b/substrate/frame/beefy-mmr/src/mock.rs index b85096813de..94149ac6776 100644 --- a/substrate/frame/beefy-mmr/src/mock.rs +++ b/substrate/frame/beefy-mmr/src/mock.rs @@ -49,11 +49,11 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Mmr: pallet_mmr::{Pallet, Storage}, - Beefy: pallet_beefy::{Pallet, Config, Storage}, - BeefyMmr: pallet_beefy_mmr::{Pallet, Storage}, + System: frame_system, + Session: pallet_session, + Mmr: pallet_mmr, + Beefy: pallet_beefy, + BeefyMmr: pallet_beefy_mmr, } ); diff --git a/substrate/frame/benchmarking/pov/src/benchmarking.rs b/substrate/frame/benchmarking/pov/src/benchmarking.rs index a24b772ade0..84d81890b17 100644 --- a/substrate/frame/benchmarking/pov/src/benchmarking.rs +++ b/substrate/frame/benchmarking/pov/src/benchmarking.rs @@ -350,8 +350,8 @@ mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Baseline: crate::{Pallet, Call, Storage, Event}, + System: frame_system, + Baseline: crate, } ); diff --git a/substrate/frame/benchmarking/pov/src/tests.rs b/substrate/frame/benchmarking/pov/src/tests.rs index dda29c071de..7fa2fb97dea 100644 --- a/substrate/frame/benchmarking/pov/src/tests.rs +++ b/substrate/frame/benchmarking/pov/src/tests.rs @@ -170,8 +170,8 @@ mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Baseline: crate::{Pallet, Call, Storage, Event}, + System: frame_system, + Baseline: crate, } ); diff --git a/substrate/frame/benchmarking/src/baseline.rs b/substrate/frame/benchmarking/src/baseline.rs index 6451284e012..2fd3b634ae7 100644 --- a/substrate/frame/benchmarking/src/baseline.rs +++ b/substrate/frame/benchmarking/src/baseline.rs @@ -121,7 +121,7 @@ pub mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system, } ); diff --git a/substrate/frame/benchmarking/src/tests.rs b/substrate/frame/benchmarking/src/tests.rs index 7d6cfaad609..f47a3d9f96a 100644 --- a/substrate/frame/benchmarking/src/tests.rs +++ b/substrate/frame/benchmarking/src/tests.rs @@ -70,8 +70,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - TestPallet: pallet_test::{Pallet, Call, Storage}, + System: frame_system, + TestPallet: pallet_test, } ); diff --git a/substrate/frame/benchmarking/src/tests_instance.rs b/substrate/frame/benchmarking/src/tests_instance.rs index 55010840896..c28aa694a13 100644 --- a/substrate/frame/benchmarking/src/tests_instance.rs +++ b/substrate/frame/benchmarking/src/tests_instance.rs @@ -80,8 +80,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - TestPallet: pallet_test::{Pallet, Call, Storage, Event}, + System: frame_system, + TestPallet: pallet_test, } ); diff --git a/substrate/frame/bounties/src/tests.rs b/substrate/frame/bounties/src/tests.rs index 22e608cce63..a7177393a44 100644 --- a/substrate/frame/bounties/src/tests.rs +++ b/substrate/frame/bounties/src/tests.rs @@ -44,12 +44,12 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, - Bounties1: pallet_bounties::::{Pallet, Call, Storage, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - Treasury1: pallet_treasury::::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Bounties: pallet_bounties, + Bounties1: pallet_bounties::, + Treasury: pallet_treasury, + Treasury1: pallet_treasury::, } ); diff --git a/substrate/frame/child-bounties/src/tests.rs b/substrate/frame/child-bounties/src/tests.rs index 7de45c73127..e57721adad0 100644 --- a/substrate/frame/child-bounties/src/tests.rs +++ b/substrate/frame/child-bounties/src/tests.rs @@ -46,11 +46,11 @@ type BountiesError = pallet_bounties::Error; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - ChildBounties: pallet_child_bounties::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Bounties: pallet_bounties, + Treasury: pallet_treasury, + ChildBounties: pallet_child_bounties, } ); diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs index 06a91cf6fe9..dbc3fbe69b3 100644 --- a/substrate/frame/collective/src/tests.rs +++ b/substrate/frame/collective/src/tests.rs @@ -38,11 +38,11 @@ pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic}, - Collective: pallet_collective::::{Pallet, Call, Event, Origin, Config}, - CollectiveMajority: pallet_collective::::{Pallet, Call, Event, Origin, Config}, - DefaultCollective: pallet_collective::{Pallet, Call, Event, Origin, Config}, - Democracy: mock_democracy::{Pallet, Call, Event}, + System: frame_system, + Collective: pallet_collective::, + CollectiveMajority: pallet_collective::, + DefaultCollective: pallet_collective, + Democracy: mock_democracy, } ); @@ -176,6 +176,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { + system: frame_system::GenesisConfig::default(), collective: pallet_collective::GenesisConfig { members: self.collective_members, phantom: Default::default(), diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs index abe907839d9..9671857fb78 100644 --- a/substrate/frame/contracts/mock-network/src/relay_chain.rs +++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs @@ -233,10 +233,10 @@ impl pallet_message_queue::Config for Runtime { construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParasOrigin: origin::{Pallet, Origin}, - XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin}, - MessageQueue: pallet_message_queue::{Pallet, Event}, + System: frame_system, + Balances: pallet_balances, + ParasOrigin: origin, + XcmPallet: pallet_xcm, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs index 28fe3c2af49..81539591019 100644 --- a/substrate/frame/contracts/src/tests.rs +++ b/substrate/frame/contracts/src/tests.rs @@ -71,13 +71,13 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Randomness: pallet_insecure_randomness_collective_flip::{Pallet, Storage}, - Utility: pallet_utility::{Pallet, Call, Storage, Event}, - Contracts: pallet_contracts::{Pallet, Call, Storage, Event, HoldReason}, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Timestamp: pallet_timestamp, + Randomness: pallet_insecure_randomness_collective_flip, + Utility: pallet_utility, + Contracts: pallet_contracts, + Proxy: pallet_proxy, Dummy: pallet_dummy } ); diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs index 371d0364384..d7bac505a54 100644 --- a/substrate/frame/conviction-voting/src/tests.rs +++ b/substrate/frame/conviction-voting/src/tests.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Voting: pallet_conviction_voting::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Voting: pallet_conviction_voting, } ); diff --git a/substrate/frame/core-fellowship/src/tests.rs b/substrate/frame/core-fellowship/src/tests.rs index c9098f2171f..838bd9bbdc8 100644 --- a/substrate/frame/core-fellowship/src/tests.rs +++ b/substrate/frame/core-fellowship/src/tests.rs @@ -41,8 +41,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - CoreFellowship: pallet_core_fellowship::{Pallet, Call, Storage, Event}, + System: frame_system, + CoreFellowship: pallet_core_fellowship, } ); diff --git a/substrate/frame/democracy/src/tests.rs b/substrate/frame/democracy/src/tests.rs index 00d8fedca0c..888d7e59614 100644 --- a/substrate/frame/democracy/src/tests.rs +++ b/substrate/frame/democracy/src/tests.rs @@ -55,11 +55,11 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, Preimage: pallet_preimage, - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, - Democracy: pallet_democracy::{Pallet, Call, Storage, Config, Event}, + Scheduler: pallet_scheduler, + Democracy: pallet_democracy, } ); diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index e7dd8acf36b..507e8f2c39b 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -54,11 +54,10 @@ pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event, Config}, - Balances: pallet_balances::{Pallet, Call, Event, Config}, - MultiPhase: multi_phase::{Pallet, Call, Event}, + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + MultiPhase: multi_phase, } ); diff --git a/substrate/frame/election-provider-support/src/onchain.rs b/substrate/frame/election-provider-support/src/onchain.rs index 412aac45475..d937f42cb40 100644 --- a/substrate/frame/election-provider-support/src/onchain.rs +++ b/substrate/frame/election-provider-support/src/onchain.rs @@ -194,9 +194,8 @@ mod tests { pub type Block = sp_runtime::generic::Block; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event}, + pub enum Runtime { + System: frame_system, } ); diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index 5e50027e344..2b599ab5292 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -1454,9 +1454,9 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Event}, - Balances: pallet_balances::{Pallet, Call, Event, Config}, - Elections: elections_phragmen::{Pallet, Call, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Elections: elections_phragmen, } ); @@ -1507,6 +1507,7 @@ mod tests { *m.borrow_mut() = self.genesis_members.iter().map(|(m, _)| *m).collect::>() }); let mut ext: sp_io::TestExternalities = RuntimeGenesisConfig { + system: frame_system::GenesisConfig::default(), balances: pallet_balances::GenesisConfig:: { balances: vec![ (1, 10 * self.balance_factor), diff --git a/substrate/frame/examples/basic/src/tests.rs b/substrate/frame/examples/basic/src/tests.rs index e00b1ac01b3..2a6fbf0f054 100644 --- a/substrate/frame/examples/basic/src/tests.rs +++ b/substrate/frame/examples/basic/src/tests.rs @@ -39,9 +39,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Example: pallet_example_basic::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Example: pallet_example_basic, } ); diff --git a/substrate/frame/examples/default-config/src/lib.rs b/substrate/frame/examples/default-config/src/lib.rs index f1611bca2ce..cd1653e6c76 100644 --- a/substrate/frame/examples/default-config/src/lib.rs +++ b/substrate/frame/examples/default-config/src/lib.rs @@ -143,7 +143,7 @@ pub mod tests { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, DefaultPallet: pallet_default_config_example, } diff --git a/substrate/frame/examples/dev-mode/src/tests.rs b/substrate/frame/examples/dev-mode/src/tests.rs index 3acedcd0fd1..c1501a5b4cf 100644 --- a/substrate/frame/examples/dev-mode/src/tests.rs +++ b/substrate/frame/examples/dev-mode/src/tests.rs @@ -33,9 +33,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Example: pallet_dev_mode::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Example: pallet_dev_mode, } ); diff --git a/substrate/frame/examples/frame-crate/src/lib.rs b/substrate/frame/examples/frame-crate/src/lib.rs index 0fea2c22cf5..7e286df1e32 100644 --- a/substrate/frame/examples/frame-crate/src/lib.rs +++ b/substrate/frame/examples/frame-crate/src/lib.rs @@ -49,7 +49,7 @@ mod tests { use frame::testing_prelude::*; construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, MyPallet: my_pallet, } diff --git a/substrate/frame/examples/offchain-worker/src/tests.rs b/substrate/frame/examples/offchain-worker/src/tests.rs index 48a8d86588c..ea37a2da493 100644 --- a/substrate/frame/examples/offchain-worker/src/tests.rs +++ b/substrate/frame/examples/offchain-worker/src/tests.rs @@ -41,8 +41,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Example: example_offchain_worker::{Pallet, Call, Storage, Event, ValidateUnsigned}, + System: frame_system, + Example: example_offchain_worker, } ); diff --git a/substrate/frame/examples/tasks/src/mock.rs b/substrate/frame/examples/tasks/src/mock.rs index e0fbec3eb76..5ad104b0dfa 100644 --- a/substrate/frame/examples/tasks/src/mock.rs +++ b/substrate/frame/examples/tasks/src/mock.rs @@ -26,7 +26,7 @@ pub type Balance = u32; type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, TasksExample: tasks_example, } diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index f2cc3b63168..cfeb585b0fd 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -897,12 +897,11 @@ mod tests { } frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, - Custom: custom::{Pallet, Call, ValidateUnsigned, Inherent}, + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + TransactionPayment: pallet_transaction_payment, + Custom: custom, } ); diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index f9326919fd3..de1772264f1 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -181,7 +181,7 @@ impl fast_unstake::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Timestamp: pallet_timestamp, Balances: pallet_balances, diff --git a/substrate/frame/glutton/src/mock.rs b/substrate/frame/glutton/src/mock.rs index 31b78efc574..26863811e29 100644 --- a/substrate/frame/glutton/src/mock.rs +++ b/substrate/frame/glutton/src/mock.rs @@ -33,8 +33,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Glutton: pallet_glutton::{Pallet, Event}, + System: frame_system, + Glutton: pallet_glutton, } ); diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs index e6107cda0f0..a2b26120254 100644 --- a/substrate/frame/identity/src/tests.rs +++ b/substrate/frame/identity/src/tests.rs @@ -47,9 +47,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Identity: pallet_identity::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Identity: pallet_identity, } ); diff --git a/substrate/frame/im-online/src/mock.rs b/substrate/frame/im-online/src/mock.rs index 2f4e3922026..9dad148b10f 100644 --- a/substrate/frame/im-online/src/mock.rs +++ b/substrate/frame/im-online/src/mock.rs @@ -42,12 +42,11 @@ use crate::Config; type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - ImOnline: imonline::{Pallet, Call, Storage, Config, Event}, - Historical: pallet_session_historical::{Pallet}, + pub enum Runtime { + System: frame_system, + Session: pallet_session, + ImOnline: imonline, + Historical: pallet_session_historical, } ); diff --git a/substrate/frame/indices/src/mock.rs b/substrate/frame/indices/src/mock.rs index 913a37fe55b..7ea524a3167 100644 --- a/substrate/frame/indices/src/mock.rs +++ b/substrate/frame/indices/src/mock.rs @@ -32,9 +32,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Indices: pallet_indices::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Indices: pallet_indices, } ); diff --git a/substrate/frame/insecure-randomness-collective-flip/src/lib.rs b/substrate/frame/insecure-randomness-collective-flip/src/lib.rs index c7ed22d1dd5..00f1055f6f2 100644 --- a/substrate/frame/insecure-randomness-collective-flip/src/lib.rs +++ b/substrate/frame/insecure-randomness-collective-flip/src/lib.rs @@ -179,8 +179,8 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - CollectiveFlip: pallet_insecure_randomness_collective_flip::{Pallet, Storage}, + System: frame_system, + CollectiveFlip: pallet_insecure_randomness_collective_flip, } ); diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs index 6e50529619b..884f003aada 100644 --- a/substrate/frame/lottery/src/mock.rs +++ b/substrate/frame/lottery/src/mock.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Lottery: pallet_lottery::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Lottery: pallet_lottery, } ); diff --git a/substrate/frame/membership/src/lib.rs b/substrate/frame/membership/src/lib.rs index 2f4bf4bc4ff..0e03c097d12 100644 --- a/substrate/frame/membership/src/lib.rs +++ b/substrate/frame/membership/src/lib.rs @@ -541,8 +541,8 @@ mod tests { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Membership: pallet_membership::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Membership: pallet_membership, } ); diff --git a/substrate/frame/merkle-mountain-range/src/mock.rs b/substrate/frame/merkle-mountain-range/src/mock.rs index d3cb4e57029..b3b5127db02 100644 --- a/substrate/frame/merkle-mountain-range/src/mock.rs +++ b/substrate/frame/merkle-mountain-range/src/mock.rs @@ -28,8 +28,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - MMR: pallet_mmr::{Pallet, Storage}, + System: frame_system, + MMR: pallet_mmr, } ); diff --git a/substrate/frame/message-queue/src/integration_test.rs b/substrate/frame/message-queue/src/integration_test.rs index fee5d242135..aa6f019d650 100644 --- a/substrate/frame/message-queue/src/integration_test.rs +++ b/substrate/frame/message-queue/src/integration_test.rs @@ -52,8 +52,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event}, + System: frame_system, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/frame/message-queue/src/mock.rs b/substrate/frame/message-queue/src/mock.rs index 89c6e862510..f1067ed961e 100644 --- a/substrate/frame/message-queue/src/mock.rs +++ b/substrate/frame/message-queue/src/mock.rs @@ -39,8 +39,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event}, + System: frame_system, + MessageQueue: pallet_message_queue, } ); diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs index 17982725529..887c7f8bebc 100644 --- a/substrate/frame/multisig/src/tests.rs +++ b/substrate/frame/multisig/src/tests.rs @@ -32,9 +32,9 @@ type Block = frame_system::mocking::MockBlockU32; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Multisig: pallet_multisig, } ); diff --git a/substrate/frame/nfts/src/mock.rs b/substrate/frame/nfts/src/mock.rs index 4363eccc7ff..95443cf41c4 100644 --- a/substrate/frame/nfts/src/mock.rs +++ b/substrate/frame/nfts/src/mock.rs @@ -36,9 +36,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Nfts: pallet_nfts::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Nfts: pallet_nfts, } ); diff --git a/substrate/frame/node-authorization/src/mock.rs b/substrate/frame/node-authorization/src/mock.rs index 3c99d41b89e..bd648de2b24 100644 --- a/substrate/frame/node-authorization/src/mock.rs +++ b/substrate/frame/node-authorization/src/mock.rs @@ -36,10 +36,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - NodeAuthorization: pallet_node_authorization::{ - Pallet, Call, Storage, Config, Event, - }, + System: frame_system, + NodeAuthorization: pallet_node_authorization, } ); diff --git a/substrate/frame/nomination-pools/benchmarking/src/mock.rs b/substrate/frame/nomination-pools/benchmarking/src/mock.rs index c58a66f6163..77124ae3888 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/mock.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/mock.rs @@ -180,14 +180,13 @@ impl crate::Config for Runtime {} type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event}, - Pools: pallet_nomination_pools::{Pallet, Call, Storage, Event, FreezeReason}, + pub enum Runtime { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + VoterList: pallet_bags_list::, + Pools: pallet_nomination_pools, } ); diff --git a/substrate/frame/nomination-pools/src/mock.rs b/substrate/frame/nomination-pools/src/mock.rs index 1bd969230da..cd91fbb33c1 100644 --- a/substrate/frame/nomination-pools/src/mock.rs +++ b/substrate/frame/nomination-pools/src/mock.rs @@ -295,11 +295,10 @@ impl pools::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Storage, Event, Config}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Pools: pools::{Pallet, Call, Storage, Event, FreezeReason}, + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + Pools: pools, } ); diff --git a/substrate/frame/nomination-pools/test-staking/src/mock.rs b/substrate/frame/nomination-pools/test-staking/src/mock.rs index 491cd619161..cbd7a4d0758 100644 --- a/substrate/frame/nomination-pools/test-staking/src/mock.rs +++ b/substrate/frame/nomination-pools/test-staking/src/mock.rs @@ -192,14 +192,13 @@ impl pallet_nomination_pools::Config for Runtime { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - VoterList: pallet_bags_list::::{Pallet, Call, Storage, Event}, - Pools: pallet_nomination_pools::{Pallet, Call, Storage, Event, FreezeReason}, + pub enum Runtime { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + VoterList: pallet_bags_list::, + Pools: pallet_nomination_pools, } ); diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index 1d642b9b498..38c6fb6ea5f 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -227,9 +227,9 @@ frame_support::construct_runtime!( pub enum Test { System: system::{Pallet, Call, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + Balances: pallet_balances, + Staking: pallet_staking, + Session: pallet_session, ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config}, Offences: pallet_offences::{Pallet, Storage, Event}, Historical: pallet_session_historical::{Pallet}, diff --git a/substrate/frame/offences/src/mock.rs b/substrate/frame/offences/src/mock.rs index 61f680f6db9..d97be99def1 100644 --- a/substrate/frame/offences/src/mock.rs +++ b/substrate/frame/offences/src/mock.rs @@ -68,10 +68,9 @@ pub fn with_on_offence_fractions) -> R>(f: F) -> type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Offences: offences::{Pallet, Storage, Event}, + pub enum Runtime { + System: frame_system, + Offences: offences, } ); diff --git a/substrate/frame/proxy/src/tests.rs b/substrate/frame/proxy/src/tests.rs index 89bd8b68f09..67a662e01b2 100644 --- a/substrate/frame/proxy/src/tests.rs +++ b/substrate/frame/proxy/src/tests.rs @@ -35,10 +35,10 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Proxy: proxy::{Pallet, Call, Storage, Event}, - Utility: pallet_utility::{Pallet, Call, Event}, + System: frame_system, + Balances: pallet_balances, + Proxy: proxy, + Utility: pallet_utility, } ); diff --git a/substrate/frame/ranked-collective/src/tests.rs b/substrate/frame/ranked-collective/src/tests.rs index 60c0da3d7ac..b3605169339 100644 --- a/substrate/frame/ranked-collective/src/tests.rs +++ b/substrate/frame/ranked-collective/src/tests.rs @@ -37,8 +37,8 @@ type Class = Rank; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Club: pallet_ranked_collective::{Pallet, Call, Storage, Event}, + System: frame_system, + Club: pallet_ranked_collective, } ); diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs index 44cbeec0986..9adb2b80931 100644 --- a/substrate/frame/recovery/src/mock.rs +++ b/substrate/frame/recovery/src/mock.rs @@ -35,9 +35,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Recovery: recovery::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Recovery: recovery, } ); diff --git a/substrate/frame/remark/src/mock.rs b/substrate/frame/remark/src/mock.rs index 0a385c30eac..5a5e6a3ccdf 100644 --- a/substrate/frame/remark/src/mock.rs +++ b/substrate/frame/remark/src/mock.rs @@ -34,8 +34,8 @@ pub type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Remark: pallet_remark::{ Pallet, Call, Event }, + System: frame_system, + Remark: pallet_remark, } ); diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs index c0c83dd08d2..583ba5b92fb 100644 --- a/substrate/frame/root-offences/src/mock.rs +++ b/substrate/frame/root-offences/src/mock.rs @@ -48,13 +48,13 @@ pub const BLOCK_TIME: u64 = 1000; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - RootOffences: root_offences::{Pallet, Call, Storage, Event}, - Historical: pallet_session::historical::{Pallet, Storage}, + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + Session: pallet_session, + RootOffences: root_offences, + Historical: pallet_session::historical, } ); diff --git a/substrate/frame/salary/src/tests.rs b/substrate/frame/salary/src/tests.rs index fbca1be1188..f25acd93452 100644 --- a/substrate/frame/salary/src/tests.rs +++ b/substrate/frame/salary/src/tests.rs @@ -40,8 +40,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Salary: pallet_salary::{Pallet, Call, Storage, Event}, + System: frame_system, + Salary: pallet_salary, } ); diff --git a/substrate/frame/scheduler/src/mock.rs b/substrate/frame/scheduler/src/mock.rs index 4edcfa0a7bf..d22b9fcf8d9 100644 --- a/substrate/frame/scheduler/src/mock.rs +++ b/substrate/frame/scheduler/src/mock.rs @@ -97,10 +97,10 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Logger: logger::{Pallet, Call, Event}, - Scheduler: scheduler::{Pallet, Call, Storage, Event}, - Preimage: pallet_preimage::{Pallet, Call, Storage, Event, HoldReason}, + System: frame_system, + Logger: logger, + Scheduler: scheduler, + Preimage: pallet_preimage, } ); diff --git a/substrate/frame/scored-pool/src/mock.rs b/substrate/frame/scored-pool/src/mock.rs index 6c032ab808c..00818f4aad0 100644 --- a/substrate/frame/scored-pool/src/mock.rs +++ b/substrate/frame/scored-pool/src/mock.rs @@ -37,9 +37,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ScoredPool: pallet_scored_pool::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + ScoredPool: pallet_scored_pool, } ); diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs index e1744fa43ab..c305641e185 100644 --- a/substrate/frame/session/benchmarking/src/mock.rs +++ b/substrate/frame/session/benchmarking/src/mock.rs @@ -38,10 +38,10 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Staking: pallet_staking, + Session: pallet_session, } ); diff --git a/substrate/frame/session/src/mock.rs b/substrate/frame/session/src/mock.rs index f3f18fde168..eb9eddfd847 100644 --- a/substrate/frame/session/src/mock.rs +++ b/substrate/frame/session/src/mock.rs @@ -82,9 +82,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, - Historical: pallet_session_historical::{Pallet}, + System: frame_system, + Session: pallet_session, + Historical: pallet_session_historical, } ); @@ -92,8 +92,8 @@ frame_support::construct_runtime!( frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Session: pallet_session::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Session: pallet_session, } ); diff --git a/substrate/frame/society/src/mock.rs b/substrate/frame/society/src/mock.rs index 3e29d01ca8e..749d196b6e1 100644 --- a/substrate/frame/society/src/mock.rs +++ b/substrate/frame/society/src/mock.rs @@ -39,9 +39,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Society: pallet_society::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Society: pallet_society, } ); diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs index ea28d712605..c71002f420c 100644 --- a/substrate/frame/state-trie-migration/src/lib.rs +++ b/substrate/frame/state-trie-migration/src/lib.rs @@ -1071,9 +1071,9 @@ mod mock { frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Config, Storage, Event}, - StateTrieMigration: pallet_state_trie_migration::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + StateTrieMigration: pallet_state_trie_migration, } ); diff --git a/substrate/frame/sudo/src/mock.rs b/substrate/frame/sudo/src/mock.rs index 878e9239080..9ad14804524 100644 --- a/substrate/frame/sudo/src/mock.rs +++ b/substrate/frame/sudo/src/mock.rs @@ -98,9 +98,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Sudo: sudo::{Pallet, Call, Config, Storage, Event}, - Logger: logger::{Pallet, Call, Storage, Event}, + System: frame_system, + Sudo: sudo, + Logger: logger, } ); diff --git a/substrate/frame/support/procedural/src/construct_runtime/mod.rs b/substrate/frame/support/procedural/src/construct_runtime/mod.rs index 7a9c4d89a74..54ed15f7b1d 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/mod.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/mod.rs @@ -21,7 +21,7 @@ //! order to get all the pallet parts for each pallet. //! //! Pallets can define their parts: -//! - Implicitely: `System: frame_system` +//! - Implicitly: `System: frame_system` //! - Explicitly: `System: frame_system::{Pallet, Call}` //! //! The `construct_runtime` transitions from the implicit definition to the explict one. @@ -172,7 +172,7 @@ //! //! This call has no implicit pallet parts, thus it will expand to the runtime construction: //! ```ignore -//! pub struct Runtime { ... } +//! pub enum Runtime { ... } //! pub struct Call { ... } //! impl Call ... //! pub enum Origin { ... } @@ -342,7 +342,7 @@ fn construct_runtime_final_expansion( syn::Error::new( pallets_token.span.join(), "`System` pallet declaration is missing. \ - Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event},`", + Please add this line: `System: frame_system,`", ) })?; if !system_pallet.cfg_pattern.is_empty() { diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index af1f99be103..95478d1a8cc 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -2291,7 +2291,7 @@ pub mod pallet_macros { /// # type Block = frame_system::mocking::MockBlock; /// # } /// construct_runtime! { - /// pub struct Runtime { + /// pub enum Runtime { /// System: frame_system, /// Custom: custom_pallet /// } diff --git a/substrate/frame/support/src/migrations.rs b/substrate/frame/support/src/migrations.rs index bfd62c8611c..d059a992a86 100644 --- a/substrate/frame/support/src/migrations.rs +++ b/substrate/frame/support/src/migrations.rs @@ -254,10 +254,10 @@ pub fn migrate_from_pallet_version_to_storage_version< /// construct_runtime! { /// pub enum Runtime /// { -/// System: frame_system::{Pallet, Call, Storage, Config, Event} = 0, +/// System: frame_system = 0, /// -/// SomePalletToRemove: pallet_something::{Pallet, Call, Storage, Event} = 1, -/// AnotherPalletToRemove: pallet_something_else::{Pallet, Call, Storage, Event} = 2, +/// SomePalletToRemove: pallet_something = 1, +/// AnotherPalletToRemove: pallet_something_else = 2, /// /// YourOtherPallets... /// } diff --git a/substrate/frame/support/test/compile_pass/src/lib.rs b/substrate/frame/support/test/compile_pass/src/lib.rs index b304dfcb282..575322df760 100644 --- a/substrate/frame/support/test/compile_pass/src/lib.rs +++ b/substrate/frame/support/test/compile_pass/src/lib.rs @@ -83,7 +83,7 @@ pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: renamed_frame_system, } ); diff --git a/substrate/frame/support/test/stg_frame_crate/src/lib.rs b/substrate/frame/support/test/stg_frame_crate/src/lib.rs index 501fcf6a70d..59a66851f23 100644 --- a/substrate/frame/support/test/stg_frame_crate/src/lib.rs +++ b/substrate/frame/support/test/stg_frame_crate/src/lib.rs @@ -68,8 +68,8 @@ mod tests { construct_runtime! { pub struct Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Pallet: pallet::{Pallet, Config}, + System: frame_system, + Pallet: pallet, } } } diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr index 11ec6f33d20..0f74553f7ec 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr @@ -1,4 +1,4 @@ -error: `System` pallet declaration is missing. Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event},` +error: `System` pallet declaration is missing. Please add this line: `System: frame_system,` --> tests/construct_runtime_ui/missing_system_module.rs:22:2 | 22 | / { diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs b/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs index ad637087476..5cde4a9beba 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs +++ b/substrate/frame/support/test/tests/construct_runtime_ui/pass/composite_enum_instance.rs @@ -64,7 +64,7 @@ pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; frame_support::construct_runtime!( - pub struct Runtime + pub enum Runtime { // Exclude part `Storage` in order not to check its metadata in tests. System: frame_system, diff --git a/substrate/frame/support/test/tests/final_keys.rs b/substrate/frame/support/test/tests/final_keys.rs index 765afaf1e66..38240830daa 100644 --- a/substrate/frame/support/test/tests/final_keys.rs +++ b/substrate/frame/support/test/tests/final_keys.rs @@ -201,7 +201,6 @@ pub type Block = generic::Block; frame_support::construct_runtime!( pub enum Runtime - { System: frame_system, FinalKeysNone: no_instance, diff --git a/substrate/frame/support/test/tests/instance.rs b/substrate/frame/support/test/tests/instance.rs index 43a93df9dea..7a888e5685d 100644 --- a/substrate/frame/support/test/tests/instance.rs +++ b/substrate/frame/support/test/tests/instance.rs @@ -278,24 +278,14 @@ pub type Block = generic::Block; frame_support::construct_runtime!( pub enum Runtime { - System: frame_system::{Pallet, Call, Event}, - Module1_1: module1::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module1_2: module1::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module2: module2::{Pallet, Call, Storage, Event, Config, Origin, Inherent}, - Module2_1: module2::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module2_2: module2::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module2_3: module2::::{ - Pallet, Call, Storage, Event, Config, Origin, Inherent - }, - Module3: module3::{Pallet, Call}, + System: frame_system, + Module1_1: module1::, + Module1_2: module1::, + Module2: module2, + Module2_1: module2::, + Module2_2: module2::, + Module2_3: module2::, + Module3: module3, } ); @@ -350,6 +340,7 @@ impl module3::Config for Runtime { fn new_test_ext() -> sp_io::TestExternalities { RuntimeGenesisConfig { + system: Default::default(), module_1_1: module1::GenesisConfig { value: 3, test: 2 }, module_1_2: module1::GenesisConfig { value: 4, test: 5 }, module_2: module2::GenesisConfig { diff --git a/substrate/frame/support/test/tests/issue2219.rs b/substrate/frame/support/test/tests/issue2219.rs index 4016707b51a..4c384f43276 100644 --- a/substrate/frame/support/test/tests/issue2219.rs +++ b/substrate/frame/support/test/tests/issue2219.rs @@ -176,7 +176,7 @@ impl frame_system::Config for Runtime { impl module::Config for Runtime {} frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, Module: module, } diff --git a/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs b/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs index de856ddcd3e..7e67193cc76 100644 --- a/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs +++ b/substrate/frame/support/test/tests/pallet_ui/pass/no_std_genesis_config.rs @@ -57,8 +57,8 @@ impl frame_system::Config for Runtime { construct_runtime! { pub struct Runtime { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Pallet: test_pallet::{Pallet, Config}, + System: frame_system, + Pallet: test_pallet, } } diff --git a/substrate/frame/support/test/tests/storage_layers.rs b/substrate/frame/support/test/tests/storage_layers.rs index a6d16e0d66d..88edd7de6ca 100644 --- a/substrate/frame/support/test/tests/storage_layers.rs +++ b/substrate/frame/support/test/tests/storage_layers.rs @@ -94,7 +94,7 @@ impl frame_system::Config for Runtime { impl Config for Runtime {} frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: frame_system, MyPallet: pallet, } diff --git a/substrate/frame/support/test/tests/versioned_migration.rs b/substrate/frame/support/test/tests/versioned_migration.rs index 03dbd948df9..dab5e06dc85 100644 --- a/substrate/frame/support/test/tests/versioned_migration.rs +++ b/substrate/frame/support/test/tests/versioned_migration.rs @@ -66,8 +66,8 @@ impl dummy_pallet::Config for Test {} construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event} = 0, - DummyPallet: dummy_pallet::{Pallet, Config, Storage} = 1, + System: frame_system = 0, + DummyPallet: dummy_pallet = 1, } ); diff --git a/substrate/frame/system/benches/bench.rs b/substrate/frame/system/benches/bench.rs index 79d5a2d8689..a0c567bf852 100644 --- a/substrate/frame/system/benches/bench.rs +++ b/substrate/frame/system/benches/bench.rs @@ -47,10 +47,9 @@ mod module { type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( - pub struct Runtime - { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Module: module::{Pallet, Event}, + pub enum Runtime { + System: frame_system, + Module: module, } ); diff --git a/substrate/frame/system/benchmarking/src/mock.rs b/substrate/frame/system/benchmarking/src/mock.rs index 9a81cddca14..edbf74a9a51 100644 --- a/substrate/frame/system/benchmarking/src/mock.rs +++ b/substrate/frame/system/benchmarking/src/mock.rs @@ -31,7 +31,7 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system, } ); diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index e33ac2f56c8..06527a9bb29 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -31,7 +31,7 @@ type Block = mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system, } ); diff --git a/substrate/frame/timestamp/src/mock.rs b/substrate/frame/timestamp/src/mock.rs index b75bcaeb0e0..5cbc5211368 100644 --- a/substrate/frame/timestamp/src/mock.rs +++ b/substrate/frame/timestamp/src/mock.rs @@ -37,8 +37,8 @@ type Moment = u64; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + System: frame_system, + Timestamp: pallet_timestamp, } ); diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs index 63ac8e37cdd..b8e528bbe7a 100644 --- a/substrate/frame/tips/src/tests.rs +++ b/substrate/frame/tips/src/tests.rs @@ -44,12 +44,12 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, - Treasury1: pallet_treasury::::{Pallet, Call, Storage, Config, Event}, - Tips: pallet_tips::{Pallet, Call, Storage, Event}, - Tips1: pallet_tips::::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Treasury: pallet_treasury, + Treasury1: pallet_treasury::, + Tips: pallet_tips, + Tips1: pallet_tips::, } ); diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs index c9b00be8e2c..03142d6ae37 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs @@ -37,7 +37,7 @@ type Balance = u64; type AccountId = u64; frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: system, Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs index 5c540c3e459..17c4c773997 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs @@ -84,7 +84,7 @@ pub mod pallet_dummy { impl pallet_dummy::Config for Runtime {} frame_support::construct_runtime!( - pub struct Runtime { + pub enum Runtime { System: system, SkipFeeless: pallet_skip_feeless_payment, DummyPallet: pallet_dummy, diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs index d6686d44c80..2f025ae81d2 100644 --- a/substrate/frame/transaction-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/src/mock.rs @@ -36,8 +36,8 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub struct Runtime { - System: system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + System: system, + Balances: pallet_balances, TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, } ); diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs index a8da19a382d..4b2fe5a2a8c 100644 --- a/substrate/frame/transaction-storage/src/mock.rs +++ b/substrate/frame/transaction-storage/src/mock.rs @@ -33,11 +33,9 @@ pub type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Config, Storage, Event}, - TransactionStorage: pallet_transaction_storage::{ - Pallet, Call, Storage, Config, Inherent, Event, HoldReason - }, + System: frame_system, + Balances: pallet_balances, + TransactionStorage: pallet_transaction_storage, } ); diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index 093757b2770..602159262e4 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -47,9 +47,9 @@ type TreasuryCall = crate::Call; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: treasury::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + Treasury: treasury, Utility: pallet_utility, } ); diff --git a/substrate/frame/uniques/src/mock.rs b/substrate/frame/uniques/src/mock.rs index 056c19ec559..9120108e0d4 100644 --- a/substrate/frame/uniques/src/mock.rs +++ b/substrate/frame/uniques/src/mock.rs @@ -35,9 +35,9 @@ type Block = frame_system::mocking::MockBlock; construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, + System: frame_system, + Balances: pallet_balances, + Uniques: pallet_uniques, } ); diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index 7b42fa511d1..cfdbd6faf0d 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -129,14 +129,14 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Call, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - RootTesting: pallet_root_testing::{Pallet, Call, Storage, Event}, + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + RootTesting: pallet_root_testing, Council: pallet_collective::, - Utility: utility::{Pallet, Call, Event}, - Example: example::{Pallet, Call}, - Democracy: mock_democracy::{Pallet, Call, Event}, + Utility: utility, + Example: example, + Democracy: mock_democracy, } ); diff --git a/substrate/frame/vesting/src/mock.rs b/substrate/frame/vesting/src/mock.rs index 3af4a9c962d..420edd5e17a 100644 --- a/substrate/frame/vesting/src/mock.rs +++ b/substrate/frame/vesting/src/mock.rs @@ -33,9 +33,9 @@ type Block = frame_system::mocking::MockBlock; frame_support::construct_runtime!( pub enum Test { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Vesting: pallet_vesting, } ); diff --git a/substrate/primitives/api/src/lib.rs b/substrate/primitives/api/src/lib.rs index 1b8b7c40ae0..0a9b334a96f 100644 --- a/substrate/primitives/api/src/lib.rs +++ b/substrate/primitives/api/src/lib.rs @@ -282,7 +282,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// # /// # /// The declaration of the `Runtime` type is done by the `construct_runtime!` macro /// # /// in a real runtime. -/// # pub struct Runtime {} +/// # pub enum Runtime {} /// # /// # sp_api::decl_runtime_apis! { /// # /// Declare the api trait. @@ -361,7 +361,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// let's say you want to implement a staging version of the runtime api and put it behind a /// feature flag. You can do it this way: /// ```ignore -/// pub struct Runtime {} +/// pub enum Runtime {} /// sp_api::decl_runtime_apis! { /// pub trait ApiWithStagingMethod { /// fn stable_one(data: u64); diff --git a/substrate/primitives/api/test/tests/decl_and_impl.rs b/substrate/primitives/api/test/tests/decl_and_impl.rs index 6e895680e41..d68470551d2 100644 --- a/substrate/primitives/api/test/tests/decl_and_impl.rs +++ b/substrate/primitives/api/test/tests/decl_and_impl.rs @@ -24,7 +24,7 @@ use substrate_test_runtime_client::runtime::{Block, Hash}; /// The declaration of the `Runtime` type is done by the `construct_runtime!` macro in a real /// runtime. -pub struct Runtime {} +pub enum Runtime {} decl_runtime_apis! { pub trait Api { diff --git a/substrate/utils/frame/rpc/support/src/lib.rs b/substrate/utils/frame/rpc/support/src/lib.rs index bb5098293c2..e3ccbd69658 100644 --- a/substrate/utils/frame/rpc/support/src/lib.rs +++ b/substrate/utils/frame/rpc/support/src/lib.rs @@ -42,8 +42,8 @@ use sp_storage::{StorageData, StorageKey}; /// # construct_runtime!( /// # pub enum TestRuntime /// # { -/// # System: frame_system::{Pallet, Call, Config, Storage, Event}, -/// # Test: pallet_test::{Pallet, Storage}, +/// # System: frame_system, +/// # Test: pallet_test, /// # } /// # ); /// # -- GitLab From e2caa813bfd2973e7a7a74aa5292433397dbc787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 22 Jan 2024 10:12:58 +0100 Subject: [PATCH 050/283] Review: Remove audit rules (#3010) Srlabs review is most of the times just blocking the merge, especially when the changes do not require any audit. This pr removes the requirement of srlabs to approve these prs. --- .github/review-bot.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/review-bot.yml b/.github/review-bot.yml index aa4ab8a69e0..ed719cefec8 100644 --- a/.github/review-bot.yml +++ b/.github/review-bot.yml @@ -20,23 +20,6 @@ rules: teams: - core-devs - - name: Audit rules - type: basic - condition: - include: - - ^polkadot/runtime/common/.* - - ^polkadot/primitives/src\/.+\.rs$ - - ^substrate/primitives/.* - - ^substrate/frame/.* - exclude: - - ^substrate\/frame\/.+\.md$ - minApprovals: 1 - allowedToSkipRule: - teams: - - core-devs - teams: - - srlabs - - name: Core developers countAuthor: true condition: -- GitLab From d53534c49e0f649e8b6b8219df5e65893ea9511d Mon Sep 17 00:00:00 2001 From: Marcin S Date: Mon, 22 Jan 2024 11:29:13 +0100 Subject: [PATCH 051/283] Enable async backing on asset-hub-rococo (#2826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The goal is to move all system chains on Rococo (+ other testnets?) to use async backing. Starting with `asset-hub-rococo` to get feedback, before I do the rest. ## Related Example: https://github.com/paritytech/polkadot-sdk/pull/1619/ Guide: https://github.com/w3f/polkadot-wiki/blob/master/docs/maintain/maintain-guides-async-backing.md --------- Co-authored-by: Branislav Kontur Co-authored-by: Dónal Murray --- Cargo.lock | 1 + cumulus/client/collator/src/lib.rs | 22 +-- .../consensus/aura/src/collators/lookahead.rs | 3 + .../assets/asset-hub-rococo/Cargo.toml | 2 + .../assets/asset-hub-rococo/src/lib.rs | 63 +++++-- .../assets/asset-hub-rococo/tests/tests.rs | 19 ++- .../assets/asset-hub-westend/src/lib.rs | 1 - .../assets/asset-hub-westend/tests/tests.rs | 19 ++- .../assets/test-utils/src/test_cases.rs | 13 +- .../test-utils/src/test_cases_over_bridge.rs | 4 +- .../bridge-hub-rococo/tests/tests.rs | 21 ++- .../bridge-hub-westend/tests/tests.rs | 19 ++- .../src/test_cases/from_grandpa_chain.rs | 6 +- .../src/test_cases/from_parachain.rs | 6 +- .../test-utils/src/test_cases/helpers.rs | 4 +- .../test-utils/src/test_cases/mod.rs | 4 +- .../parachains/runtimes/test-utils/src/lib.rs | 14 +- cumulus/polkadot-parachain/src/command.rs | 13 +- cumulus/polkadot-parachain/src/service.rs | 157 +++++++++++++++++- polkadot/node/collation-generation/src/lib.rs | 10 ++ polkadot/node/subsystem-types/src/messages.rs | 4 +- prdoc/pr_2826.prdoc | 10 ++ 22 files changed, 366 insertions(+), 49 deletions(-) create mode 100644 prdoc/pr_2826.prdoc diff --git a/Cargo.lock b/Cargo.lock index 1d404a2c231..15e3022bfb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,6 +864,7 @@ dependencies = [ "cumulus-pallet-session-benchmarking", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", + "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", "frame-benchmarking", diff --git a/cumulus/client/collator/src/lib.rs b/cumulus/client/collator/src/lib.rs index f17ae488310..83249186f62 100644 --- a/cumulus/client/collator/src/lib.rs +++ b/cumulus/client/collator/src/lib.rs @@ -242,17 +242,19 @@ pub async fn initialize_collator_subsystems( overseer_handle: &mut OverseerHandle, key: CollatorPair, para_id: ParaId, + reinitialize: bool, ) { - overseer_handle - .send_msg( - CollationGenerationMessage::Initialize(CollationGenerationConfig { - key, - para_id, - collator: None, - }), - "StartCollator", - ) - .await; + let config = CollationGenerationConfig { key, para_id, collator: None }; + + if reinitialize { + overseer_handle + .send_msg(CollationGenerationMessage::Reinitialize(config), "StartCollator") + .await; + } else { + overseer_handle + .send_msg(CollationGenerationMessage::Initialize(config), "StartCollator") + .await; + } overseer_handle .send_msg(CollatorProtocolMessage::CollateOn(para_id), "StartCollator") diff --git a/cumulus/client/consensus/aura/src/collators/lookahead.rs b/cumulus/client/consensus/aura/src/collators/lookahead.rs index 5d62094e4aa..e24b7f6f1c9 100644 --- a/cumulus/client/consensus/aura/src/collators/lookahead.rs +++ b/cumulus/client/consensus/aura/src/collators/lookahead.rs @@ -105,6 +105,8 @@ pub struct Params { pub collator_service: CS, /// The amount of time to spend authoring each block. pub authoring_duration: Duration, + /// Whether we should reinitialize the collator config (i.e. we are transitioning to aura). + pub reinitialize: bool, } /// Run async-backing-friendly Aura. @@ -149,6 +151,7 @@ where &mut params.overseer_handle, params.collator_key, params.para_id, + params.reinitialize, ) .await; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 5d0cb41395f..254aca90078 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -77,6 +77,7 @@ cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false } cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false } cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] } +cumulus-primitives-aura = { path = "../../../../primitives/aura", default-features = false } cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false } cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false } pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false } @@ -188,6 +189,7 @@ std = [ "cumulus-pallet-session-benchmarking/std", "cumulus-pallet-xcm/std", "cumulus-pallet-xcmp-queue/std", + "cumulus-primitives-aura/std", "cumulus-primitives-core/std", "cumulus-primitives-utility/std", "frame-benchmarking?/std", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index a812e747f00..983e250d0cc 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -33,7 +33,7 @@ use assets_common::{ matching::{FromNetwork, FromSiblingParachain}, AssetIdForTrustBackedAssetsConvert, }; -use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; use parachains_common::rococo::snowbridge::EthereumNetwork; use sp_api::impl_runtime_apis; @@ -62,7 +62,7 @@ use frame_support::{ ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, TransformOrigin, }, - weights::{ConstantMultiplier, Weight}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight}, BoundedVec, PalletId, }; use frame_system::{ @@ -71,14 +71,13 @@ use frame_system::{ }; use pallet_asset_conversion_tx_payment::AssetConversionAdapter; use pallet_nfts::PalletFeatures; -pub use parachains_common as common; use parachains_common::{ impls::DealWithFees, message_queue::{NarrowOriginToSibling, ParaIdToSibling}, rococo::{consensus::*, currency::*, fee::WeightToFee}, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, - MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, + NORMAL_DISPATCH_RATIO, }; use sp_runtime::{Perbill, RuntimeDebug}; use xcm_config::{ @@ -141,6 +140,28 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } +/// We allow for 2 seconds of compute with a 6 second average block. +const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), + cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, +); + +/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included +/// into the relay chain. +const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; +/// How many parachain blocks are processed by the relay chain per parent. Limits the +/// number of blocks authored per slot. +const BLOCK_PROCESSING_VELOCITY: u32 = 1; + +/// This determines the average expected block time that we are targeting. +/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. +/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked +/// up by `pallet_aura` to implement `fn slot_duration()`. +/// +/// Change this to adjust the block time. +pub const MILLISECS_PER_BLOCK: u64 = 6000; +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + parameter_types! { pub const Version: RuntimeVersion = VERSION; pub RuntimeBlockLength: BlockLength = @@ -189,6 +210,9 @@ impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; + #[cfg(feature = "experimental")] + type MinimumPeriod = ConstU64<0>; + #[cfg(not(feature = "experimental"))] type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; type WeightInfo = weights::pallet_timestamp::WeightInfo; } @@ -630,15 +654,17 @@ impl cumulus_pallet_parachain_system::Config for Runtime { type OutboundXcmpMessageSource = XcmpQueue; type XcmpMessageHandler = XcmpQueue; type ReservedXcmpWeight = ReservedXcmpWeight; - type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; - type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< - Runtime, - RELAY_CHAIN_SLOT_DURATION_MILLIS, - BLOCK_PROCESSING_VELOCITY, - UNINCLUDED_SEGMENT_CAPACITY, - >; + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; } +type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + RELAY_CHAIN_SLOT_DURATION_MILLIS, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; + parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; } @@ -722,9 +748,9 @@ impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; - type AllowMultipleBlocksPerSlot = ConstBool; + type AllowMultipleBlocksPerSlot = ConstBool; #[cfg(feature = "experimental")] - type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; + type SlotDuration = ConstU64; } parameter_types! { @@ -1067,7 +1093,7 @@ mod benches { impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) } fn authorities() -> Vec { @@ -1075,6 +1101,15 @@ impl_runtime_apis! { } } + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot, + ) -> bool { + ConsensusHook::can_build_upon(included_hash, slot) + } + } + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index cb7ea34a057..e7ac37b2d5c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -28,10 +28,11 @@ use asset_hub_rococo_runtime::{ AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, - ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, + ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, SLOT_DURATION, }; use asset_test_utils::{ - test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, + ExtBuilder, SlotDurations, }; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; @@ -46,9 +47,10 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - rococo::{currency::UNITS, fee::WeightToFee}, + rococo::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, currency::UNITS, fee::WeightToFee}, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; +use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; use xcm::latest::prelude::{Assets as XcmAssets, *}; @@ -78,6 +80,13 @@ fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::default().add(collator_session_key(ALICE)) } +fn slot_durations() -> SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() @@ -892,6 +901,7 @@ asset_test_utils::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -912,6 +922,7 @@ asset_test_utils::include_teleports_for_foreign_assets_works!( ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -1023,6 +1034,7 @@ fn limited_reserve_transfer_assets_for_native_asset_over_bridge_works( LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { @@ -1194,6 +1206,7 @@ mod asset_hub_rococo_tests { LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index b4bcc716513..e642475698e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -55,7 +55,6 @@ use frame_system::{ use pallet_asset_conversion_tx_payment::AssetConversionAdapter; use pallet_nfts::{DestroyWitness, PalletFeatures}; use pallet_xcm::EnsureXcm; -pub use parachains_common as common; use parachains_common::{ impls::DealWithFees, message_queue::*, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 3fc9f4a9658..381b2867c9c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -32,7 +32,8 @@ use asset_hub_westend_runtime::{ }; pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ - test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, + ExtBuilder, SlotDurations, }; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; @@ -47,9 +48,10 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - westend::{currency::UNITS, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + westend::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, SLOT_DURATION, }; +use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; use xcm::latest::prelude::{Assets as XcmAssets, *}; @@ -79,6 +81,13 @@ fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::default().add(collator_session_key(ALICE)) } +fn slot_durations() -> SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() @@ -895,6 +904,7 @@ asset_test_utils::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -915,6 +925,7 @@ asset_test_utils::include_teleports_for_foreign_assets_works!( ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -1041,6 +1052,7 @@ fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_rococo_works() LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { @@ -1208,6 +1220,7 @@ fn reserve_transfer_native_asset_to_non_teleport_para_works() { LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index e981fae8015..4007d926983 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -31,7 +31,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::{AccountId, Balance}; use parachains_runtimes_test_utils::{ assert_metadata, assert_total, mock_open_hrmp_channel, AccountIdOf, BalanceOf, - CollatorSessionKeys, ExtBuilder, ValidatorIdOf, XcmReceivedFrom, + CollatorSessionKeys, ExtBuilder, SlotDurations, ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{ traits::{MaybeEquivalence, StaticLookup, Zero}, @@ -57,6 +57,7 @@ pub fn teleports_for_native_asset_works< HrmpChannelOpener, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, target_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -205,6 +206,7 @@ pub fn teleports_for_native_asset_works< None, included_head.clone(), &alice, + &slot_durations, )); // check balances @@ -257,6 +259,7 @@ pub fn teleports_for_native_asset_works< Some((runtime_para_id, other_para_id)), included_head, &alice, + &slot_durations, ), Err(DispatchError::Module(sp_runtime::ModuleError { index: 31, @@ -288,6 +291,7 @@ macro_rules! include_teleports_for_native_asset_works( $weight_to_fee:path, $hrmp_channel_opener:path, $collator_session_key:expr, + $slot_durations:expr, $existential_deposit:expr, $unwrap_pallet_xcm_event:expr, $runtime_para_id:expr @@ -306,6 +310,7 @@ macro_rules! include_teleports_for_native_asset_works( $hrmp_channel_opener >( $collator_session_key, + $slot_durations, $existential_deposit, target_account, $unwrap_pallet_xcm_event, @@ -328,6 +333,7 @@ pub fn teleports_for_foreign_assets_works< ForeignAssetsPalletInstance, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, target_account: AccountIdOf, existential_deposit: BalanceOf, asset_owner: AccountIdOf, @@ -592,6 +598,7 @@ pub fn teleports_for_foreign_assets_works< Some((runtime_para_id, foreign_para_id)), included_head, &alice, + &slot_durations, )); // check balances @@ -644,6 +651,7 @@ macro_rules! include_teleports_for_foreign_assets_works( $sovereign_account_of:path, $assets_pallet_instance:path, $collator_session_key:expr, + $slot_durations:expr, $existential_deposit:expr, $unwrap_pallet_xcm_event:expr, $unwrap_xcmp_queue_event:expr @@ -666,6 +674,7 @@ macro_rules! include_teleports_for_foreign_assets_works( $assets_pallet_instance >( $collator_session_key, + $slot_durations, target_account, $existential_deposit, asset_owner, @@ -1397,6 +1406,7 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< LocationToAccountId, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, alice_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -1470,6 +1480,7 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< other_para_id.into(), included_head, &alice, + &slot_durations, ); // we calculate exact delivery fees _after_ sending the message by weighing the sent diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 878dddc9137..905703a9d16 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -27,7 +27,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::{AccountId, Balance}; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeHelper, - ValidatorIdOf, XcmReceivedFrom, + SlotDurations, ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{traits::StaticLookup, Saturating}; use sp_std::ops::Mul; @@ -52,6 +52,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< LocationToAccountId, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, alice_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -125,6 +126,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< local_bridge_hub_para_id.into(), included_head, &alice, + &slot_durations, ); // we calculate exact delivery fees _after_ sending the message by weighing the sent diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 63e64506ec7..9e46dc08654 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -24,9 +24,14 @@ use bridge_hub_rococo_runtime::{ Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic, }; +use bridge_hub_test_utils::SlotDurations; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; -use parachains_common::{rococo::fee::WeightToFee, AccountId, AuraId, Balance}; +use parachains_common::{ + rococo::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee}, + AccountId, AuraId, Balance, SLOT_DURATION, +}; +use sp_consensus_aura::SlotDuration; use sp_core::H160; use sp_keyring::AccountKeyring::Alice; use sp_runtime::{ @@ -95,6 +100,13 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -103,6 +115,7 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -264,6 +277,7 @@ mod bridge_hub_westend_tests { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -288,6 +302,7 @@ mod bridge_hub_westend_tests { // from Westend from_parachain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, BridgeHubWestendChainId::get(), @@ -304,6 +319,7 @@ mod bridge_hub_westend_tests { // for Westend from_parachain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, SIBLING_PARACHAIN_ID, @@ -459,6 +475,7 @@ mod bridge_hub_bulletin_tests { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -483,6 +500,7 @@ mod bridge_hub_bulletin_tests { // from Bulletin from_grandpa_chain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, RococoBulletinChainId::get(), SIBLING_PARACHAIN_ID, @@ -498,6 +516,7 @@ mod bridge_hub_bulletin_tests { // for Bulletin from_grandpa_chain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, RococoBulletinChainId::get(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 1237a231390..91d69b80420 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -18,7 +18,7 @@ use bp_polkadot_core::Signature; use bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; -use bridge_hub_test_utils::test_cases::from_parachain; +use bridge_hub_test_utils::{test_cases::from_parachain, SlotDurations}; use bridge_hub_westend_runtime::{ bridge_common_config, bridge_to_rococo_config, xcm_config::{RelayNetwork, WestendLocation, XcmConfig}, @@ -33,7 +33,11 @@ use bridge_to_rococo_config::{ }; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; -use parachains_common::{westend::fee::WeightToFee, AccountId, AuraId, Balance}; +use parachains_common::{ + westend::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee}, + AccountId, AuraId, Balance, SLOT_DURATION, +}; +use sp_consensus_aura::SlotDuration; use sp_keyring::AccountKeyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, @@ -111,6 +115,13 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -119,6 +130,7 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -229,6 +241,7 @@ fn message_dispatch_routing_works() { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -252,6 +265,7 @@ fn message_dispatch_routing_works() { fn relayed_incoming_message_works() { from_parachain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, BridgeHubRococoChainId::get(), @@ -267,6 +281,7 @@ fn relayed_incoming_message_works() { pub fn complex_relay_extrinsic_works() { from_parachain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index 5eca85d3112..acf0f2c7162 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -39,7 +39,7 @@ use bridge_runtime_common::{ use frame_support::traits::{Get, OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; use parachains_runtimes_test_utils::{ - AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, + AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_keyring::AccountKeyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; @@ -107,6 +107,7 @@ where /// Also verifies relayer transaction signed extensions work as intended. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_chain_id: bp_runtime::ChainId, sibling_parachain_id: u32, @@ -136,6 +137,7 @@ pub fn relayed_incoming_message_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, @@ -205,6 +207,7 @@ pub fn relayed_incoming_message_works( /// Also verifies relayer transaction signed extensions work as intended. pub fn complex_relay_extrinsic_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, bridged_chain_id: bp_runtime::ChainId, @@ -237,6 +240,7 @@ pub fn complex_relay_extrinsic_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 6e638b7b350..8a86c5bb72f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -40,7 +40,7 @@ use bridge_runtime_common::{ use frame_support::traits::{Get, OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; use parachains_runtimes_test_utils::{ - AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, + AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_keyring::AccountKeyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; @@ -112,6 +112,7 @@ where /// Also verifies relayer transaction signed extensions work as intended. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_para_id: u32, bridged_chain_id: bp_runtime::ChainId, @@ -146,6 +147,7 @@ pub fn relayed_incoming_message_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, @@ -244,6 +246,7 @@ pub fn relayed_incoming_message_works( /// Also verifies relayer transaction signed extensions work as intended. pub fn complex_relay_extrinsic_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_para_id: u32, sibling_parachain_id: u32, @@ -281,6 +284,7 @@ pub fn complex_relay_extrinsic_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index ba58aeb046e..4f634c184aa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -31,7 +31,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use pallet_bridge_grandpa::{BridgedBlockHash, BridgedHeader}; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ - mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, + mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_core::Get; use sp_keyring::AccountKeyring::*; @@ -220,6 +220,7 @@ pub fn relayer_id_at_bridged_chain, /// with proofs (finality, message) independently submitted. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, @@ -272,6 +273,7 @@ pub fn relayed_incoming_message_works( sibling_parachain_id.into(), included_head, &alice, + &slot_durations, ); // set up relayer details and proofs diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index eb7ba132168..ce939692644 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -45,7 +45,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeCallOf, - XcmReceivedFrom, + SlotDurations, XcmReceivedFrom, }; use sp_runtime::{traits::Zero, AccountId32}; use xcm::{latest::prelude::*, AlwaysLatest}; @@ -419,6 +419,7 @@ pub fn message_dispatch_routing_works< NetworkDistanceAsParentCount, >( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, unwrap_cumulus_pallet_parachain_system_event: Box< @@ -529,6 +530,7 @@ pub fn message_dispatch_routing_works< sibling_parachain_id.into(), included_head, &alice, + &slot_durations, ); let result = <>::MessageDispatch>::dispatch( diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 88e878c73a3..eb75c2f7ee0 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -29,7 +29,6 @@ use frame_support::{ weights::Weight, }; use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor}; -use parachains_common::SLOT_DURATION; use polkadot_parachain_primitives::primitives::{ HeadData, HrmpChannelId, RelayChainBlockNumber, XcmpMessageFormat, }; @@ -115,6 +114,11 @@ impl, included_head: HeaderFor, slot_digest: &[u8], + slot_durations: &SlotDurations, ) -> DispatchResult where HrmpChannelOpener: frame_support::inherent::ProvideInherent< @@ -348,6 +353,7 @@ impl< target_para_id.into(), included_head, slot_digest, + slot_durations, ); } @@ -493,12 +499,12 @@ pub fn mock_open_hrmp_channel< recipient: ParaId, included_head: HeaderFor, mut slot_digest: &[u8], + slot_durations: &SlotDurations, ) { - const RELAY_CHAIN_SLOT_DURATION: SlotDuration = SlotDuration::from_millis(6000); let slot = Slot::decode(&mut slot_digest).expect("failed to decode digest"); // Convert para slot to relay chain. - let timestamp = slot.saturating_mul(SLOT_DURATION); - let relay_slot = Slot::from_timestamp(timestamp.into(), RELAY_CHAIN_SLOT_DURATION); + let timestamp = slot.saturating_mul(slot_durations.para.as_millis()); + let relay_slot = Slot::from_timestamp(timestamp.into(), slot_durations.relay); let n = 1_u32; let mut sproof_builder = RelayStateSproofBuilder { diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 04d618f66c7..a7319b6dfbb 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -695,9 +695,7 @@ pub fn run() -> Result<()> { .map(|r| r.0) .map_err(Into::into), - AssetHubKusama | - AssetHubRococo | - AssetHubWestend => + AssetHubKusama | AssetHubWestend => crate::service::start_asset_hub_node::< RuntimeApi, AuraId, @@ -706,6 +704,15 @@ pub fn run() -> Result<()> { .map(|r| r.0) .map_err(Into::into), + AssetHubRococo => + crate::service::start_asset_hub_lookahead_node::< + RuntimeApi, + AuraId, + >(config, polkadot_config, collator_options, id, hwbench) + .await + .map(|r| r.0) + .map_err(Into::into), + CollectivesPolkadot | CollectivesWestend => crate::service::start_generic_aura_node::< RuntimeApi, diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index 81d0c9d3980..61b9cbbd80d 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -976,6 +976,7 @@ pub async fn start_rococo_parachain_node( proposer, collator_service, authoring_duration: Duration::from_millis(1500), + reinitialize: false, }; let fut = aura::run::< @@ -1291,7 +1292,7 @@ where Ok(BasicQueue::new(verifier, Box::new(block_import), None, &spawner, registry)) } -/// Start an aura powered parachain node. Asset Hub and Collectives use this. +/// Start an aura powered parachain node. Collectives uses this. pub async fn start_generic_aura_node( parachain_config: Configuration, polkadot_config: Configuration, @@ -1530,6 +1531,159 @@ where .await } +/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub +/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and +/// needs to sync and upgrade before it can run `AuraApi` functions. +/// +/// Uses the lookahead collator to support async backing. +#[sc_tracing::logging::prefix_logs_with("Parachain")] +pub async fn start_asset_hub_lookahead_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> +where + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi::Pair as Pair>::Public> + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + + frame_rpc_system::AccountNonceApi + + cumulus_primitives_aura::AuraUnincludedSegmentApi, + <::Pair as Pair>::Signature: + TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, +{ + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + |_| Ok(RpcModule::new(())), + aura_build_import_queue::<_, AuraId>, + |client, + block_import, + prometheus_registry, + telemetry, + task_manager, + relay_chain_interface, + transaction_pool, + sync_oracle, + keystore, + relay_chain_slot_duration, + para_id, + collator_key, + overseer_handle, + announce_block, + backend| { + let relay_chain_interface2 = relay_chain_interface.clone(); + + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); + + let spawner = task_manager.spawn_handle(); + + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + spawner, + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let collation_future = Box::pin(async move { + // Start collating with the `shell` runtime while waiting for an upgrade to an Aura + // compatible runtime. + let mut request_stream = cumulus_client_collator::relay_chain_driven::init( + collator_key.clone(), + para_id, + overseer_handle.clone(), + ) + .await; + while let Some(request) = request_stream.next().await { + let pvd = request.persisted_validation_data().clone(); + let last_head_hash = + match ::Header::decode(&mut &pvd.parent_head.0[..]) { + Ok(header) => header.hash(), + Err(e) => { + log::error!("Could not decode the head data: {e}"); + request.complete(None); + continue + }, + }; + + // Check if we have upgraded to an Aura compatible runtime and transition if + // necessary. + if client + .runtime_api() + .has_api::>(last_head_hash) + .unwrap_or(false) + { + // Respond to this request before transitioning to Aura. + request.complete(None); + break + } + } + + // Move to Aura consensus. + let slot_duration = match cumulus_client_consensus_aura::slot_duration(&*client) { + Ok(d) => d, + Err(e) => { + log::error!("Could not get Aura slot duration: {e}"); + return + }, + }; + + let proposer = Proposer::new(proposer_factory); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface2, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + slot_duration, + relay_chain_slot_duration, + proposer, + collator_service, + authoring_duration: Duration::from_millis(1500), + reinitialize: true, /* we need to always re-initialize for asset-hub moving + * to aura */ + }; + + aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params) + .await + }); + + let spawner = task_manager.spawn_essential_handle(); + spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); + + Ok(()) + }, + hwbench, + ) + .await +} + /// Start an aura powered parachain node which uses the lookahead collator to support async backing. /// This node is basic in the sense that its runtime api doesn't include common contents such as /// transaction payment. Used for aura glutton. @@ -1615,6 +1769,7 @@ where proposer, collator_service, authoring_duration: Duration::from_millis(1500), + reinitialize: false, }; let fut = diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs index b8c9c1a36e4..cfa75d7b441 100644 --- a/polkadot/node/collation-generation/src/lib.rs +++ b/polkadot/node/collation-generation/src/lib.rs @@ -143,6 +143,16 @@ impl CollationGenerationSubsystem { } false }, + Ok(FromOrchestra::Communication { + msg: CollationGenerationMessage::Reinitialize(config), + }) => { + if self.config.is_none() { + gum::error!(target: LOG_TARGET, "no initial initialization"); + } else { + self.config = Some(Arc::new(config)); + } + false + }, Ok(FromOrchestra::Communication { msg: CollationGenerationMessage::SubmitCollation(params), }) => { diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index c7675c84b91..1d5d82b57fd 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -830,8 +830,10 @@ pub enum ProvisionerMessage { /// Message to the Collation Generation subsystem. #[derive(Debug)] pub enum CollationGenerationMessage { - /// Initialize the collation generation subsystem + /// Initialize the collation generation subsystem. Initialize(CollationGenerationConfig), + /// Reinitialize the collation generation subsystem, overriding the existing config. + Reinitialize(CollationGenerationConfig), /// Submit a collation to the subsystem. This will package it into a signed /// [`CommittedCandidateReceipt`] and distribute along the network to validators. /// diff --git a/prdoc/pr_2826.prdoc b/prdoc/pr_2826.prdoc new file mode 100644 index 00000000000..70de795a100 --- /dev/null +++ b/prdoc/pr_2826.prdoc @@ -0,0 +1,10 @@ +title: Enable async backing on asset-hub-rococo + +doc: + - audience: Runtime User + description: | + Async backing has been enabled on Asset Hub Rococo, which now targets 6s block times. + +crates: + - name: asset-hub-rococo-runtime + - name: polkadot-parachain-bin \ No newline at end of file -- GitLab From deb72f432dd8adf25fb58db7c3a21d747274c5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 22 Jan 2024 11:31:37 +0100 Subject: [PATCH 052/283] sc-informant: Respect `--disable-log-color` (#3009) Changes `sc-informant` to respect the `--disable-log-color` CLI flag. Closes: https://github.com/paritytech/polkadot-sdk/issues/2795 --------- Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> --- prdoc/pr_3009.prdoc | 10 ++++ substrate/client/cli/src/config.rs | 6 +-- substrate/client/informant/src/display.rs | 45 ++++++------------ substrate/client/informant/src/lib.rs | 58 ++++++++++++++++++++--- substrate/client/service/src/config.rs | 8 ++-- 5 files changed, 82 insertions(+), 45 deletions(-) create mode 100644 prdoc/pr_3009.prdoc diff --git a/prdoc/pr_3009.prdoc b/prdoc/pr_3009.prdoc new file mode 100644 index 00000000000..2a55f3d7d32 --- /dev/null +++ b/prdoc/pr_3009.prdoc @@ -0,0 +1,10 @@ +title: "sc-informant: Respect `--disable-log-color`" + +doc: + - audience: Node Operator + description: | + Fixes some places that weren't respecting the `--disable-log-color` CLI flag. + +crates: + - name: "sc-informant" + - name: "sc-service" diff --git a/substrate/client/cli/src/config.rs b/substrate/client/cli/src/config.rs index b842df5a690..170173c8c28 100644 --- a/substrate/client/cli/src/config.rs +++ b/substrate/client/cli/src/config.rs @@ -27,8 +27,8 @@ use names::{Generator, Name}; use sc_service::{ config::{ BasePath, Configuration, DatabaseSource, KeystoreConfig, NetworkConfiguration, - NodeKeyConfig, OffchainWorkerConfig, PrometheusConfig, PruningMode, Role, RpcMethods, - TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, + NodeKeyConfig, OffchainWorkerConfig, OutputFormat, PrometheusConfig, PruningMode, Role, + RpcMethods, TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, }, BlocksPruning, ChainSpec, TracingReceiver, }; @@ -516,7 +516,7 @@ pub trait CliConfiguration: Sized { announce_block: self.announce_block()?, role, base_path, - informant_output_format: Default::default(), + informant_output_format: OutputFormat { enable_color: !self.disable_log_color()? }, runtime_cache_size, }) } diff --git a/substrate/client/informant/src/display.rs b/substrate/client/informant/src/display.rs index bcf3794032f..cdbb83b6596 100644 --- a/substrate/client/informant/src/display.rs +++ b/substrate/client/informant/src/display.rs @@ -142,37 +142,20 @@ impl InformantDisplay { ("⚙️ ", format!("Preparing{}", speed), format!(", target=#{target}")), }; - if self.format.enable_color { - info!( - target: "substrate", - "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", - level, - Colour::White.bold().paint(&status), - target, - Colour::White.bold().paint(format!("{}", num_connected_peers)), - Colour::White.bold().paint(format!("{}", best_number)), - best_hash, - Colour::White.bold().paint(format!("{}", finalized_number)), - info.chain.finalized_hash, - Colour::Green.paint(format!("⬇ {}", TransferRateFormat(avg_bytes_per_sec_inbound))), - Colour::Red.paint(format!("⬆ {}", TransferRateFormat(avg_bytes_per_sec_outbound))), - ) - } else { - info!( - target: "substrate", - "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", - level, - status, - target, - num_connected_peers, - best_number, - best_hash, - finalized_number, - info.chain.finalized_hash, - TransferRateFormat(avg_bytes_per_sec_inbound), - TransferRateFormat(avg_bytes_per_sec_outbound), - ) - } + info!( + target: "substrate", + "{} {}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", + level, + self.format.print_with_color(Colour::White.bold(), status), + target, + self.format.print_with_color(Colour::White.bold(), num_connected_peers), + self.format.print_with_color(Colour::White.bold(), best_number), + best_hash, + self.format.print_with_color(Colour::White.bold(), finalized_number), + info.chain.finalized_hash, + self.format.print_with_color(Colour::Green, format!("⬇ {}", TransferRateFormat(avg_bytes_per_sec_inbound))), + self.format.print_with_color(Colour::Red, format!("⬆ {}", TransferRateFormat(avg_bytes_per_sec_outbound))), + ) } } diff --git a/substrate/client/informant/src/lib.rs b/substrate/client/informant/src/lib.rs index b072f8551f9..7db80bb2d97 100644 --- a/substrate/client/informant/src/lib.rs +++ b/substrate/client/informant/src/lib.rs @@ -18,7 +18,7 @@ //! Console informant. Prints sync progress and block events. Runs on the calling thread. -use ansi_term::Colour; +use ansi_term::{Colour, Style}; use futures::prelude::*; use futures_timer::Delay; use log::{debug, info, trace}; @@ -51,6 +51,47 @@ impl Default for OutputFormat { } } +enum ColorOrStyle { + Color(Colour), + Style(Style), +} + +impl From for ColorOrStyle { + fn from(value: Colour) -> Self { + Self::Color(value) + } +} + +impl From diff --git a/docs/sdk/headers/theme.css b/docs/sdk/headers/theme.css new file mode 100644 index 00000000000..bb9254ec4a8 --- /dev/null +++ b/docs/sdk/headers/theme.css @@ -0,0 +1,16 @@ +:root { + --polkadot-pink: #E6007A ; + --polkadot-green: #56F39A ; + --polkadot-lime: #D3FF33 ; + --polkadot-cyan: #00B2FF ; + --polkadot-purple: #552BBF ; + } + +body > nav.sidebar > div.sidebar-crate > a > img { + /* logo width, given that the sidebar width is 200px; */ + width: 190px; +} + +body nav.sidebar { + flex: 0 0 250px; +} diff --git a/docs/sdk/headers/toc.html b/docs/sdk/headers/toc.html deleted file mode 100644 index a4a074cb4f3..00000000000 --- a/docs/sdk/headers/toc.html +++ /dev/null @@ -1,54 +0,0 @@ - - diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index 29cdda36ed1..20a8639b270 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -128,8 +128,8 @@ //! //! Recall that within our pallet, (almost) all blocks of code are generic over ``. And, //! because `trait Config: frame_system::Config`, we can get access to all items in `Config` (or -//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how Rust -//! traits and generics work. If unfamiliar with this pattern, read +//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how +//! Rust traits and generics work. If unfamiliar with this pattern, read //! [`crate::reference_docs::trait_based_programming`] before going further. //! //! Crucially, a typical FRAME runtime contains a `struct Runtime`. The main role of this `struct` @@ -270,7 +270,7 @@ #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", config_v2)] //! //! > These `Runtime*` types are better explained in -//! > [`crate::reference_docs::frame_composite_enums`]. +//! > [`crate::reference_docs::frame_runtime_types`]. //! //! Then, we can rewrite the `transfer` dispatchable as such: #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", transfer_v2)] @@ -285,7 +285,6 @@ //! [`crate::guides::your_first_pallet::pallet_v2::tests::runtime_v2::RuntimeEvent`]. //! //! -//! //! ## What Next? //! //! The following topics where used in this guide, but not covered in depth. It is suggested to @@ -293,7 +292,7 @@ //! //! - [`crate::reference_docs::safe_defensive_programming`]. //! - [`crate::reference_docs::frame_origin`]. -//! - [`crate::reference_docs::frame_composite_enums`]. +//! - [`crate::reference_docs::frame_runtime_types`]. //! - The pallet we wrote in this guide was using `dev_mode`, learn more in //! [`frame::pallet_macros::config`]. //! - Learn more about the individual pallet items/macros, such as event and errors and call, in diff --git a/docs/sdk/src/lib.rs b/docs/sdk/src/lib.rs index 075d9ddaffe..e211476d251 100644 --- a/docs/sdk/src/lib.rs +++ b/docs/sdk/src/lib.rs @@ -15,7 +15,7 @@ //! - Start by learning about the the [`polkadot_sdk`], its structure and context. //! - Then, head over the [`guides`]. This modules contains in-depth guides about the most important //! user-journeys of the Polkadot SDK. -//! - Whilst reading the guides, you might find back-links to [`crate::reference_docs`]. +//! - Whilst reading the guides, you might find back-links to [`reference_docs`]. //! - Finally, is the parent website of this crate that contains the //! list of further tools related to the Polkadot SDK. //! @@ -25,6 +25,11 @@ #![doc = simple_mermaid::mermaid!("../../mermaid/IA.mmd")] #![warn(rustdoc::broken_intra_doc_links)] #![warn(rustdoc::private_intra_doc_links)] +#![doc(html_favicon_url = "https://polkadot.network/favicon-32x32.png")] +#![doc( + html_logo_url = "https://europe1.discourse-cdn.com/standard21/uploads/polkadot2/original/1X/eb57081e2bb7c39e5fcb1a98b443e423fa4448ae.svg" +)] +#![doc(issue_tracker_base_url = "https://github.com/paritytech/polkadot-sdk/issues")] /// Meta information about this crate, how it is built, what principles dictates its evolution and /// how one can contribute to it. diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index 7ecf8b0adfd..fcdcea9934b 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -101,7 +101,7 @@ //! * Before even getting started, what is with all of this ``? We link to //! [`crate::reference_docs::trait_based_programming`]. //! * First, the name. Why is this called `pallet::call`? This goes back to `enum Call`, which is -//! explained in [`crate::reference_docs::frame_composite_enums`]. Build on top of this! +//! explained in [`crate::reference_docs::frame_runtime_types`]. Build on top of this! //! * Then, what is `origin`? Just an account id? [`crate::reference_docs::frame_origin`]. //! * Then, what is `DispatchResult`? Why is this called *dispatch*? Probably something that can be //! explained in the documentation of [`frame::prelude::DispatchResult`]. @@ -138,7 +138,9 @@ //! injected, run: //! //! ```sh -//! SKIP_WASM_BUILD=1 RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/toc.html" cargo doc -p polkadot-sdk-docs --no-deps --open +//! SKIP_WASM_BUILD=1 \ +//! RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css --default-theme=ayu" \ +//! cargo doc -p polkadot-sdk-docs --no-deps --open //! ``` //! //! If even faster build time for docs is needed, you can temporarily remove most of the diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index 9008f8f835f..8c8568a228f 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -127,7 +127,7 @@ //! runtimes, a call is represented as an enum of enums, where the outer enum represents the FRAME //! pallet being called, and the inner enum represents the call being made within that pallet, and //! any arguments to it. Read more about the call enum -//! [here][crate::reference_docs::frame_composite_enums]. +//! [here][crate::reference_docs::frame_runtime_types]. //! //! FRAME `Call` enums are automatically generated, and end up looking something like this: #![doc = docify::embed!("./src/reference_docs/extrinsic_encoding.rs", call_data)] diff --git a/docs/sdk/src/reference_docs/frame_composite_enums.rs b/docs/sdk/src/reference_docs/frame_composite_enums.rs deleted file mode 100644 index 6051cd53446..00000000000 --- a/docs/sdk/src/reference_docs/frame_composite_enums.rs +++ /dev/null @@ -1 +0,0 @@ -//! # FRAME Composite Enums diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index a4078377cd7..49533157b01 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -1,14 +1,260 @@ //! # FRAME Origin //! -//! Notes: -//! -//! - Def talk about account abstraction and how it is a solved issue in frame. See Gav's talk in -//! Protocol Berg 2023 -//! - system's raw origin, how it is amalgamated with other origins into one type -//! [`frame_composite_enums`] -//! - signed origin -//! - unsigned origin, link to [`fee_less_runtime`] -//! - Root origin, how no one can obtain it. -//! - Abstract origin: how FRAME allows you to express "origin is 2/3 of the this body or 1/2 of -//! that body or half of the token holders". -//! - `type CustomOrigin: EnsureOrigin<_>` in pallets. +//! Let's start by clarifying a common wrong assumption about Origin: +//! +//! **ORIGIN IS NOT AN ACCOUNT ID**. +//! +//! FRAME's origin abstractions allow you to convey meanings far beyond just an account-id being the +//! caller of an extrinsic. Nonetheless, an account-id having signed an extrinsic is one of the +//! meanings that an origin can convey. This is the commonly used [`frame_system::ensure_signed`], +//! where the return value happens to be an account-id. +//! +//! Instead, let's establish the following as the correct definition of an origin: +//! +//! > The origin type represents the privilege level of the caller of an extrinsic. +//! +//! That is, an extrinsic, through checking the origin, can *express what privilege level it wishes +//! to impose on the caller of the extrinsic*. One of those checks can be as simple as "*any account +//! that has signed a statement can pass*". +//! +//! But the origin system can also express more abstract and complicated privilege levels. For +//! example: +//! +//! * If the majority of token holders agreed upon this. This is more or less what the +//! [`pallet_democracy`] does under the hood ([reference](https://github.com/paritytech/polkadot-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633)). +//! * If a specific ratio of an instance of [`pallet_collective`]/DAO agrees upon this. +//! * If another consensus system, for example a bridged network or a parachain, agrees upon this. +//! * If the majority of validator/authority set agrees upon this[^1]. +//! * If caller holds a particular NFT. +//! +//! and many more. +//! +//! ## Context +//! +//! First, let's look at where the `origin` type is encountered in a typical pallet. The `origin: +//! OriginFor` has to be the first argument of any given callable extrinsic in FRAME: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", call_simple)] +//! +//! Typically, the code of an extrinsic starts with an origin check, such as +//! [`frame_system::ensure_signed`]. +//! +//! Note that [`OriginFor`](frame_system::pallet_prelude::OriginFor) is merely a shorthand for +//! [`frame_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that +//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite enum that is +//! amalgamated at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to +//! familiarize yourself with these types. +//! +//! To understand this better, we will next create a pallet with a custom origin, which will add a +//! new variant to `RuntimeOrigin`. +//! +//! ## Adding Custom Pallet Origin to the Runtime +//! +//! For example, given a pallet that defines the following custom origin: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin)] +//! +//! And a runtime with the following pallets: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", runtime_exp)] +//! +//! The type [`crate::reference_docs::frame_origin::runtime_for_origin::RuntimeOrigin`] is expanded. +//! This `RuntimeOrigin` contains a variant for the [`frame_system::RawOrigin`] and the custom +//! origin of the pallet. +//! +//! > Notice how the [`frame_system::ensure_signed`] is nothing more than a `match` statement. If +//! > you want to know where the actual origin of an extrinsic is set (and the signature +//! > verification happens, if any), see +//! > [`sp_runtime::generic::CheckedExtrinsic#trait-implementations`], specifically +//! > [`sp_runtime::traits::Applyable`]'s implementation. +//! +//! ## Asserting on a Custom Internal Origin +//! +//! In order to assert on a custom origin that is defined within your pallet, we need a way to first +//! convert the `::RuntimeOrigin` into the local `enum Origin` of the +//! current pallet. This is a common process that is explained in +//! [`crate::reference_docs::frame_runtime_types# +//! adding-further-constraints-to-runtime-composite-enums`]. +//! +//! We use the same process here to express that `RuntimeOrigin` has a number of additional bounds, +//! as follows. +//! +//! 1. Defining a custom `RuntimeOrigin` with further bounds in the pallet. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_bound)] +//! +//! 2. Using it in the pallet. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_usage)] +//! +//! ## Asserting on a Custom External Origin +//! +//! Very often, a pallet wants to have a parameterized origin that is **NOT** defined within the +//! pallet. In other words, a pallet wants to delegate an origin check to something that is +//! specified later at the runtime level. Like many other parameterizations in FRAME, this implies +//! adding a new associated type to `trait Config`. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_def)] +//! +//! Then, within the pallet, we can simply use this "unknown" origin check type: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_usage)] +//! +//! Finally, at the runtime, any implementation of [`frame::traits::EnsureOrigin`] can be passed. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_provide)] +//! +//! Indeed, some of these implementations of [`frame::traits::EnsureOrigin`] are similar to the ones +//! that we know about: [`frame::runtime::prelude::EnsureSigned`], +//! [`frame::runtime::prelude::EnsureSignedBy`], [`frame::runtime::prelude::EnsureRoot`], +//! [`frame::runtime::prelude::EnsureNone`], etc. But, there are also many more that are not known +//! to us, and are defined in other pallets. +//! +//! For example, [`pallet_collective`] defines [`pallet_collective::EnsureMember`] and +//! [`pallet_collective::EnsureProportionMoreThan`] and many more, which is exactly what we alluded +//! to earlier in this document. +//! +//! Make sure to check the full list of [implementors of +//! `EnsureOrigin`](frame::traits::EnsureOrigin#implementors) for more inspiration. +//! +//! ## Obtaining Abstract Origins +//! +//! So far we have learned that FRAME pallets can assert on custom and abstract origin types, +//! whether they are defined within the pallet or not. But how can we obtain these abstract origins? +//! +//! > All extrinsics that come from the outer world can generally only be obtained as either +//! > `signed` or `none` origin. +//! +//! Generally, these abstract origins are only obtained within the runtime, when a call is +//! dispatched within the runtime. +//! +//! ## Further References +//! +//! - [Gavin Wood's speech about FRAME features at Protocol Berg 2023.](https://youtu.be/j7b8Upipmeg?si=83_XUgYuJxMwWX4g&t=195) +//! - [A related StackExchange question.](https://substrate.stackexchange.com/questions/10992/how-do-you-find-the-public-key-for-the-medium-spender-track-origin) +//! +//! [^1]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`] +//! origin check, and through the virtue of being an inherent, are agreed upon by all validators. + +use frame::prelude::*; + +#[frame::pallet(dev_mode)] +pub mod pallet_for_origin { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(call_simple)] + #[pallet::call] + impl Pallet { + pub fn do_something(_origin: OriginFor) -> DispatchResult { + // ^^^^^^^^^^^^^^^^^^^^^ + todo!(); + } + } +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_custom_origin { + use super::*; + + #[docify::export(custom_origin_bound)] + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeOrigin: From<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(custom_origin)] + /// A dummy custom origin. + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub enum Origin { + /// If all holders of a particular NFT have agreed upon this. + AllNftHolders, + /// If all validators have agreed upon this. + ValidatorSet, + } + + #[docify::export(custom_origin_usage)] + #[pallet::call] + impl Pallet { + pub fn only_validators(origin: OriginFor) -> DispatchResult { + // first, we convert from `::RuntimeOrigin` to `::RuntimeOrigin` + let local_runtime_origin = <::RuntimeOrigin as From< + ::RuntimeOrigin, + >>::from(origin); + // then we convert to `origin`, if possible + let local_origin = + local_runtime_origin.into().map_err(|_| "invalid origin type provided")?; + ensure!(matches!(local_origin, Origin::ValidatorSet), "Not authorized"); + todo!(); + } + } +} + +pub mod runtime_for_origin { + use super::pallet_with_custom_origin; + use frame::{runtime::prelude::*, testing_prelude::*}; + + #[docify::export(runtime_exp)] + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithCustomOrigin: pallet_with_custom_origin, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_with_custom_origin::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + } +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_external_origin { + use super::*; + #[docify::export(external_origin_def)] + #[pallet::config] + pub trait Config: frame_system::Config { + type ExternalOrigin: EnsureOrigin; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(external_origin_usage)] + #[pallet::call] + impl Pallet { + pub fn externally_checked_ext(origin: OriginFor) -> DispatchResult { + let _ = T::ExternalOrigin::ensure_origin(origin)?; + todo!(); + } + } +} + +pub mod runtime_for_external_origin { + use super::*; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithExternalOrigin: pallet_with_external_origin, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + #[docify::export(external_origin_provide)] + impl pallet_with_external_origin::Config for Runtime { + type ExternalOrigin = EnsureSigned<::AccountId>; + } +} diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs new file mode 100644 index 00000000000..b5838b79e51 --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -0,0 +1,306 @@ +//! # FRAME Runtime Types +//! +//! This reference document briefly explores the idea around types generated at the runtime level by +//! the FRAME macros. +//! +//! > As of now, many of these important types are generated within the internals of +//! > [`construct_runtime`], and there is no easy way for you to visually know they exist. +//! > [#polkadot-sdk#1378](https://github.com/paritytech/polkadot-sdk/pull/1378) is meant to +//! > significantly improve this. Exploring the rust-docs of a runtime, such as [`runtime`] which is +//! > defined in this module is as of now the best way to learn about these types. +//! +//! ## Composite Enums +//! +//! Many types within a FRAME runtime follow the following structure: +//! +//! * Each individual pallet defines a type, for example `Foo`. +//! * At the runtime level, these types are amalgamated into a single type, for example +//! `RuntimeFoo`. +//! +//! As the names suggest, all composite enums in a FRAME runtime start their name with `Runtime`. +//! For example, `RuntimeCall` is a representation of the most high level `Call`-able type in the +//! runtime. +//! +//! Composite enums are generally convertible to their individual parts as such: +#![doc = simple_mermaid::mermaid!("../../../mermaid/outer_runtime_types.mmd")] +//! +//! In that one can always convert from the inner type into the outer type, but not vice versa. This +//! is usually expressed by implementing `From`, `TryFrom`, `From>` and similar traits. +//! +//! ### Example +//! +//! We provide the following two pallets: [`pallet_foo`] and [`pallet_bar`]. Each define a +//! dispatchable, and `Foo` also defines a custom origin. Lastly, `Bar` defines an additional +//! `GenesisConfig`. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_foo)] +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_bar)] +//! +//! Let's explore how each of these affect the [`RuntimeCall`], [`RuntimeOrigin`] and +//! [`RuntimeGenesisConfig`] generated in [`runtime`] by respectively. +//! +//! As observed, [`RuntimeCall`] has 3 variants, one for each pallet and one for `frame_system`. If +//! you explore further, you will soon realize that each variant is merely a pointer to the `Call` +//! type in each pallet, for example [`pallet_foo::Call`]. +//! +//! [`RuntimeOrigin`]'s [`OriginCaller`] has two variants, one for system, and one for `pallet_foo` +//! which utilized [`frame::pallet_macros::origin`]. +//! +//! Finally, [`RuntimeGenesisConfig`] is composed of `frame_system` and a variant for `pallet_bar`'s +//! [`pallet_bar::GenesisConfig`]. +//! +//! You can find other composite enums by scanning [`runtime`] for other types who's name starts +//! with `Runtime`. Some of the more noteworthy ones are: +//! +//! - [`RuntimeEvent`] +//! - [`RuntimeError`] +//! - [`RuntimeHoldReason`] +//! +//! ### Adding Further Constraints to Runtime Composite Enums +//! +//! This section explores a common scenario where a pallet has access to one of these runtime +//! composite enums, but it wishes to further specify it by adding more trait bounds to it. +//! +//! Let's take the example of `RuntimeCall`. This is an associated type in +//! [`frame_system::Config::RuntimeCall`], and all pallets have access to this type, because they +//! have access to [`frame_system::Config`]. Finally, this type is meant to be set to outer call of +//! the entire runtime. +//! +//! But, let's not forget that this is information that *we know*, and the Rust compiler does not. +//! All that the rust compiler knows about this type is *ONLY* what the trait bounds of +//! [`frame_system::Config::RuntimeCall`] are specifying: +#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", system_runtime_call)] +//! +//! So, when at a given pallet, one accesses `::RuntimeCall`, the type is +//! extremely opaque from the perspective of the Rust compiler. +//! +//! How can a pallet access the `RuntimeCall` type with further constraints? For example, each +//! pallet has its own `enum Call`, and knows that its local `Call` is a part of `RuntimeCall`, +//! therefore there should be a `impl From> for RuntimeCall`. +//! +//! The only way to express this using Rust's associated types is for the pallet to **define its own +//! associated type `RuntimeCall`, and further specify what it thinks `RuntimeCall` should be**. +//! +//! In this case, we will want to assert the existence of [`frame::traits::IsSubType`], which is +//! very similar to [`TryFrom`]. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call)] +//! +//! And indeed, at the runtime level, this associated type would be the same `RuntimeCall` that is +//! passed to `frame_system`. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_with_specific_runtime_call_impl)] +//! +//! > In other words, the degree of specificity that [`frame_system::Config::RuntimeCall`] has is +//! > not enough for the pallet to work with. Therefore, the pallet has to define its own associated +//! > type representing `RuntimeCall`. +//! +//! Another way to look at this is: +//! +//! `pallet_with_specific_runtime_call::Config::RuntimeCall` and `frame_system::Config::RuntimeCall` +//! are two different representations of the same concrete type that is only known when the runtime +//! is being constructed. +//! +//! Now, within this pallet, this new `RuntimeCall` can be used, and it can use its new trait +//! bounds, such as being [`frame::traits::IsSubType`]: +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call_usages)] +//! +//! ### Asserting Equality of Multiple Runtime Composite Enums +//! +//! Recall that in the above example, `::RuntimeCall` and `::RuntimeCall` are expected to be equal types, but at the compile-time we +//! have to represent them with two different associated types with different bounds. Would it not +//! be cool if we had a test to make sure they actually resolve to the same concrete type once the +//! runtime is constructed? The following snippet exactly does that: +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", assert_equality)] +//! +//! We leave it to the reader to further explore what [`frame::traits::Hooks::integrity_test`] is, +//! and what [`core::any::TypeId`] is. Another way to assert this is using +//! [`frame::traits::IsType`]. +//! +//! ## Type Aliases +//! +//! A number of type aliases are generated by the `construct_runtime` which are also noteworthy: +//! +//! * [`runtime::PalletFoo`] is an alias to [`pallet_foo::Pallet`]. Same for `PalletBar`, and +//! `System` +//! * [`runtime::AllPalletsWithSystem`] is an alias for a tuple of all of the above. This type is +//! important to FRAME internals such as `executive`, as it implements traits such as +//! [`frame::traits::Hooks`]. +//! +//! ## Further Details +//! +//! * [`crate::reference_docs::frame_origin`] explores further details about the usage of +//! `RuntimeOrigin`. +//! * [`RuntimeCall`] is a particularly interesting composite enum as it dictates the encoding of an +//! extrinsic. See [`crate::reference_docs::signed_extensions`] for more information. +//! * See the documentation of [`construct_runtime`]. +//! * See the corresponding lecture in the [pba-book](https://polkadot-blockchain-academy.github.io/pba-book/frame/outer-enum/page.html). +//! +//! +//! [`construct_runtime`]: frame::runtime::prelude::construct_runtime +//! [`runtime::PalletFoo`]: crate::reference_docs::frame_runtime_types::runtime::PalletFoo +//! [`runtime::AllPalletsWithSystem`]: crate::reference_docs::frame_runtime_types::runtime::AllPalletsWithSystem +//! [`runtime`]: crate::reference_docs::frame_runtime_types::runtime +//! [`pallet_foo`]: crate::reference_docs::frame_runtime_types::pallet_foo +//! [`pallet_foo::Call`]: crate::reference_docs::frame_runtime_types::pallet_foo::Call +//! [`pallet_foo::Pallet`]: crate::reference_docs::frame_runtime_types::pallet_foo::Pallet +//! [`pallet_bar`]: crate::reference_docs::frame_runtime_types::pallet_bar +//! [`pallet_bar::GenesisConfig`]: crate::reference_docs::frame_runtime_types::pallet_bar::GenesisConfig +//! [`RuntimeEvent`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeEvent +//! [`RuntimeGenesisConfig`]: +//! crate::reference_docs::frame_runtime_types::runtime::RuntimeGenesisConfig +//! [`RuntimeOrigin`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeOrigin +//! [`OriginCaller`]: crate::reference_docs::frame_runtime_types::runtime::OriginCaller +//! [`RuntimeError`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeError +//! [`RuntimeCall`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeCall +//! [`RuntimeHoldReason`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeHoldReason + +use frame::prelude::*; + +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet_foo { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub enum Origin { + A, + B, + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet { + pub fn foo(_origin: OriginFor) -> DispatchResult { + todo!(); + } + + pub fn other(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } +} + +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet_bar { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + pub initial_account: Option, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) {} + } + + #[pallet::call] + impl Pallet { + pub fn bar(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } +} + +pub mod runtime { + use super::{pallet_bar, pallet_foo}; + use frame::{runtime::prelude::*, testing_prelude::*}; + + #[docify::export(runtime_exp)] + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletFoo: pallet_foo, + PalletBar: pallet_bar, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_foo::Config for Runtime {} + impl pallet_bar::Config for Runtime {} +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_specific_runtime_call { + use super::*; + use frame::traits::IsSubType; + + #[docify::export(custom_runtime_call)] + /// A pallet that wants to further narrow down what `RuntimeCall` is. + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeCall: IsSubType>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + // note that this pallet needs some `call` to have a `enum Call`. + #[pallet::call] + impl Pallet { + pub fn foo(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } + + #[docify::export(custom_runtime_call_usages)] + impl Pallet { + fn _do_something_useful_with_runtime_call(call: ::RuntimeCall) { + // check if the runtime call given is of this pallet's variant. + let _maybe_my_call: Option<&Call> = call.is_sub_type(); + todo!(); + } + } + + #[docify::export(assert_equality)] + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + use core::any::TypeId; + assert_eq!( + TypeId::of::<::RuntimeCall>(), + TypeId::of::<::RuntimeCall>() + ); + } + } +} + +pub mod runtime_with_specific_runtime_call { + use super::pallet_with_specific_runtime_call; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithSpecificRuntimeCall: pallet_with_specific_runtime_call, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + #[docify::export(pallet_with_specific_runtime_call_impl)] + impl pallet_with_specific_runtime_call::Config for Runtime { + // an implementation of `IsSubType` is provided by `construct_runtime`. + type RuntimeCall = RuntimeCall; + } +} diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index c16122ee428..760bb442c16 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -43,16 +43,16 @@ pub mod extrinsic_encoding; // TODO: @jsdw https://github.com/paritytech/polkadot-sdk-docs/issues/42 pub mod signed_extensions; -/// Learn about *"Origin"* A topic in FRAME that enables complex account abstractions to be built. -// TODO: @shawntabrizi https://github.com/paritytech/polkadot-sdk-docs/issues/43 +/// Learn about *Origins*, a topic in FRAME that enables complex account abstractions to be built. pub mod frame_origin; /// Learn about how to write safe and defensive code in your FRAME runtime. // TODO: @CrackTheCode016 https://github.com/paritytech/polkadot-sdk-docs/issues/44 pub mod safe_defensive_programming; -/// Learn about composite enums in FRAME-based runtimes, such as "RuntimeEvent" and "RuntimeCall". -pub mod frame_composite_enums; +/// Learn about composite enums and other runtime level types, such as "RuntimeEvent" and +/// "RuntimeCall". +pub mod frame_runtime_types; /// Learn about how to make a pallet/runtime that is fee-less and instead uses another mechanism to /// control usage and sybil attacks. diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index a1715ba4900..a2e5d726fdd 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -163,6 +163,12 @@ pub mod runtime { ConstU32, ConstU64, ConstU8, }; + /// Primary types used to parameterize `EnsureOrigin` and `EnsureRootWithArg`. + pub use frame_system::{ + EnsureNever, EnsureNone, EnsureRoot, EnsureRootWithSuccess, EnsureSigned, + EnsureSignedBy, + }; + /// Types to define your runtime version. pub use sp_version::{create_runtime_str, runtime_version, RuntimeVersion}; diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs index b421d2aaffa..83049919d01 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs @@ -104,7 +104,7 @@ pub fn expand_outer_origin( #[doc = #doc_string] #[derive(Clone)] pub struct RuntimeOrigin { - caller: OriginCaller, + pub caller: OriginCaller, filter: #scrate::__private::sp_std::rc::Rc::RuntimeCall) -> bool>>, } diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 20b8d74310f..441b21e26ff 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -1480,22 +1480,11 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::origin]` attribute allows you to define some origin for the pallet. /// -/// Item must be either a type alias, an enum, or a struct. It needs to be public. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::origin] -/// pub struct Origin(PhantomData<(T)>); -/// ``` -/// -/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin -/// can be stored on-chain (e.g. in `pallet-scheduler`), thus any change must be done with care -/// as it might require some migration. +/// --- /// -/// NOTE: for instantiable pallets, the origin must be generic over `T` and `I`. +/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// `frame_support::pallet_macros::origin`. #[proc_macro_attribute] pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index cd12da6de54..26fc1fe42c1 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -2274,9 +2274,8 @@ pub mod pallet_macros { pub use frame_support_procedural::{ composite_enum, config, disable_frame_system_supertrait_check, error, event, extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, - import_section, inherent, no_default, no_default_bounds, origin, pallet_section, - storage_prefix, storage_version, type_value, unbounded, validate_unsigned, weight, - whitelist_storage, + import_section, inherent, no_default, no_default_bounds, pallet_section, storage_prefix, + storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; /// Allows a pallet to declare a set of functions as a *dispatchable extrinsic*. In @@ -2718,7 +2717,7 @@ pub mod pallet_macros { /// } /// ``` pub use frame_support_procedural::storage; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the conditions for a /// given work item to be valid. /// @@ -2726,21 +2725,21 @@ pub mod pallet_macros { /// should have the same signature as the function it is attached to, except that it should /// return a `bool` instead. pub use frame_support_procedural::task_condition; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the index of a given /// work item. /// /// It takes an integer literal as input, which is then used to define the index. This /// index should be unique for each function in the `impl` block. pub use frame_support_procedural::task_index; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define an iterator over the /// available work items for a task. /// /// It takes an iterator as input that yields a tuple with same types as the function /// arguments. pub use frame_support_procedural::task_list; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) define the weight of a given work /// item. /// @@ -2773,6 +2772,61 @@ pub mod pallet_macros { /// Now, this can be executed as follows: #[doc = docify::embed!("src/tests/tasks.rs", tasks_work)] pub use frame_support_procedural::tasks_experimental; + + /// Allows a pallet to declare a type as an origin. + /// + /// If defined as such, this type will be amalgamated at the runtime level into + /// `RuntimeOrigin`, very similar to [`call`], [`error`] and [`event`]. See + /// [`composite_enum`] for similar cases. + /// + /// Origin is a complex FRAME topics and is further explained in `polkadot_sdk_docs`. + /// + /// ## Syntax Variants + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # #[pallet::pallet] + /// # pub struct Pallet(_); + /// /// On the spot declaration. + /// #[pallet::origin] + /// #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + /// pub enum Origin { + /// Foo, + /// Bar, + /// } + /// } + /// ``` + /// + /// Or, more commonly used:/ + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # #[pallet::pallet] + /// # pub struct Pallet(_); + /// #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + /// pub enum RawOrigin { + /// Foo, + /// Bar, + /// } + /// + /// #[pallet::origin] + /// pub type Origin = RawOrigin; + /// } + /// ``` + /// + /// ## Warning + /// + /// Modifying any pallet's origin type will cause the runtime level origin type to also + /// change in encoding. If stored anywhere on-chain, this will require a data migration. + pub use frame_support_procedural::origin; } #[deprecated(note = "Will be removed after July 2023; Use `sp_runtime::traits` directly instead.")] diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 1405c7303f8..aa6841c008a 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -452,6 +452,7 @@ pub mod pallet { + Clone + OriginTrait; + #[docify::export(system_runtime_call)] /// The aggregated `RuntimeCall` type. #[pallet::no_default_bounds] type RuntimeCall: Parameter -- GitLab From 0cc9b9003c019400a8e26c2e1d5679ab654a63dc Mon Sep 17 00:00:00 2001 From: Petr Mensik Date: Tue, 27 Feb 2024 23:50:07 +0100 Subject: [PATCH 265/283] Add Polkadotters bootnoders per IBP application (#3423) Hey everyone, this PR will replace existing Polkadotters bootnodes for Polkadot, Kusama and Westend and add Paseo bootnode to the relay chain suite. At the same time, it will add new bootnodes for all the system parachains, including People on Westend. This PR is a part of our membership in the IBP, meaning that all the bootnodes are hosted on our hardware housed in the data center in Christchurch, New Zealand. All the bootnodes were tested with an empty chain spec file with the following command yielding 1 peer. The test commands used are as follows: ``` ./polkadot --base-path /tmp/node --reserved-only --chain paseo --reserved-nodes "/dns/paseo.bootnodes.polkadotters.com/tcp/30540/wss/p2p/12D3KooWPbbFy4TefEGTRF5eTYhq8LEzc4VAHdNUVCbY4nAnhqPP" ./polkadot --base-path /tmp/node --reserved-only --chain westend --reserved-nodes "/dns/westend.bootnodes.polkadotters.com/tcp/30310/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5" ./polkadot --base-path /tmp/node --reserved-only --chain kusama --reserved-nodes "/dns/kusama.bootnodes.polkadotters.com/tcp/30313/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG" ./polkadot --base-path /tmp/node --no-hardware-benchmarks --reserved-only --chain polkadot --reserved-nodes "/dns/polkadot.bootnodes.polkadotters.com/tcp/30316/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain asset-hub-kusama --reserved-nodes "/dns/asset-hub-kusama.bootnodes.polkadotters.com/tcp/30513/wss/p2p/12D3KooWDpk7wVH7RgjErEvbvAZ2kY5VeaAwRJP5ojmn1e8b8UbU" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain asset-hub-polkadot --reserved-nodes "/dns/asset-hub-polkadot.bootnodes.polkadotters.com/tcp/30510/wss/p2p/12D3KooWKbfY9a9oywxMJKiALmt7yhrdQkjXMtvxhhDDN23vG93R" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain asset-hub-westend --reserved-nodes "/dns/asset-hub-westend.bootnodes.polkadotters.com/tcp/30516/wss/p2p/12D3KooWNFYysCqmojxqjjaTfD2VkWBNngfyUKWjcR4WFixfHNTk" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain bridge-hub-kusama --reserved-nodes "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30522/wss/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain bridge-hub-kusama --reserved-nodes "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30522/wss/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain bridge-hub-westend --reserved-nodes "/dns/bridge-hub-westend.bootnodes.polkadotters.com/tcp/30525/wss/p2p/12D3KooWPkwgJofp4GeeRwNgXqkp2aFwdLkCWv3qodpBJLwK43Jj" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain collectives-polkadot --reserved-nodes "/dns/collectives-polkadot.bootnodes.polkadotters.com/tcp/30528/wss/p2p/12D3KooWNohUjvJtGKUa8Vhy8C1ZBB5N8JATB6e7rdLVCioeb3ff" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain collectives-westend --reserved-nodes "/dns/collectives-westend.bootnodes.polkadotters.com/tcp/30531/wss/p2p/12D3KooWAFkXNSBfyPduZVgfS7pj5NuVpbU8Ee5gHeF8wvos7Yqn" ./polkadot-parachain --base-path /tmp/node --reserved-only --chain people-westend --reserved-nodes "/dns/identity-westend.bootnodes.polkadotters.com/tcp/30534/wss/p2p/12D3KooWKr9San6KTM7REJ95cBaDoiciGcWnW8TTftEJgxGF5Ehb" ``` Best regards, Petr, Polkadotters --- cumulus/parachains/chain-specs/asset-hub-kusama.json | 4 +++- cumulus/parachains/chain-specs/asset-hub-polkadot.json | 4 +++- cumulus/parachains/chain-specs/asset-hub-westend.json | 4 +++- cumulus/parachains/chain-specs/bridge-hub-kusama.json | 4 +++- cumulus/parachains/chain-specs/bridge-hub-polkadot.json | 4 +++- cumulus/parachains/chain-specs/bridge-hub-westend.json | 4 +++- cumulus/parachains/chain-specs/collectives-polkadot.json | 4 +++- cumulus/parachains/chain-specs/collectives-westend.json | 4 +++- cumulus/parachains/chain-specs/people-westend.json | 6 ++++-- polkadot/node/service/chain-specs/kusama.json | 4 ++-- polkadot/node/service/chain-specs/paseo.json | 4 +++- polkadot/node/service/chain-specs/polkadot.json | 4 ++-- polkadot/node/service/chain-specs/westend.json | 4 ++-- 13 files changed, 37 insertions(+), 17 deletions(-) diff --git a/cumulus/parachains/chain-specs/asset-hub-kusama.json b/cumulus/parachains/chain-specs/asset-hub-kusama.json index fba74b17f96..654275eade8 100644 --- a/cumulus/parachains/chain-specs/asset-hub-kusama.json +++ b/cumulus/parachains/chain-specs/asset-hub-kusama.json @@ -25,7 +25,9 @@ "/dns/statemine-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWCKUrE5uaXQ288ko3Ex3zCyozyJLG47KEYTopinnXNtYL", "/dns/mine14.rotko.net/tcp/33524/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu", "/dns/mine14.rotko.net/tcp/34524/ws/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu", - "/dns/mine14.rotko.net/tcp/35524/wss/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu" + "/dns/mine14.rotko.net/tcp/35524/wss/p2p/12D3KooWJUFnjR2PNbsJhudwPVaWCoZy1acPGKjM2cSuGj345BBu", + "/dns/asset-hub-kusama.bootnodes.polkadotters.com/tcp/30511/p2p/12D3KooWDpk7wVH7RgjErEvbvAZ2kY5VeaAwRJP5ojmn1e8b8UbU", + "/dns/asset-hub-kusama.bootnodes.polkadotters.com/tcp/30513/wss/p2p/12D3KooWDpk7wVH7RgjErEvbvAZ2kY5VeaAwRJP5ojmn1e8b8UbU" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/asset-hub-polkadot.json b/cumulus/parachains/chain-specs/asset-hub-polkadot.json index 685a00ddc71..454060d2a87 100644 --- a/cumulus/parachains/chain-specs/asset-hub-polkadot.json +++ b/cumulus/parachains/chain-specs/asset-hub-polkadot.json @@ -25,7 +25,9 @@ "/dns/statemint-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWLKxHom7f3XawRJqrF8RwiKK5Sj3qZqz5c7hF6eJeXhTx", "/dns/mint14.rotko.net/tcp/33514/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW", "/dns/mint14.rotko.net/tcp/34514/ws/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW", - "/dns/mint14.rotko.net/tcp/35514/wss/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW" + "/dns/mint14.rotko.net/tcp/35514/wss/p2p/12D3KooWKkzLjYF6M5eEs7nYiqEtRqY8SGVouoCwo3nCWsRnThDW", + "/dns/asset-hub-polkadot.bootnodes.polkadotters.com/tcp/30508/p2p/12D3KooWKbfY9a9oywxMJKiALmt7yhrdQkjXMtvxhhDDN23vG93R", + "/dns/asset-hub-polkadot.bootnodes.polkadotters.com/tcp/30510/wss/p2p/12D3KooWKbfY9a9oywxMJKiALmt7yhrdQkjXMtvxhhDDN23vG93R" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/asset-hub-westend.json b/cumulus/parachains/chain-specs/asset-hub-westend.json index 6f42b5f7d8b..670935c9d24 100644 --- a/cumulus/parachains/chain-specs/asset-hub-westend.json +++ b/cumulus/parachains/chain-specs/asset-hub-westend.json @@ -23,7 +23,9 @@ "/dns/westmint-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWDoq4PVdWm5nzRSvEz3DSSKjVgRhWVUaKyi5JMKwJKYbk", "/dns/wmint14.rotko.net/tcp/33534/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN", "/dns/wmint14.rotko.net/tcp/34534/ws/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN", - "/dns/wmint14.rotko.net/tcp/35534/wss/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN" + "/dns/wmint14.rotko.net/tcp/35534/wss/p2p/12D3KooWE4UDXqgtTcMCyUQ8S4uvaT8VMzzTBA6NWmKuYwTacWuN", + "/dns/asset-hub-westend.bootnodes.polkadotters.com/tcp/30514/p2p/12D3KooWNFYysCqmojxqjjaTfD2VkWBNngfyUKWjcR4WFixfHNTk", + "/dns/asset-hub-westend.bootnodes.polkadotters.com/tcp/30516/wss/p2p/12D3KooWNFYysCqmojxqjjaTfD2VkWBNngfyUKWjcR4WFixfHNTk" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/bridge-hub-kusama.json b/cumulus/parachains/chain-specs/bridge-hub-kusama.json index 0ef81806cc5..90b70b05016 100644 --- a/cumulus/parachains/chain-specs/bridge-hub-kusama.json +++ b/cumulus/parachains/chain-specs/bridge-hub-kusama.json @@ -25,7 +25,9 @@ "/dns/bridgehub-kusama-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWQMWofXj8v3RroDNnrhv1iURqm8vnaG98AdGnCn2YoDcW", "/dns/kbr13.rotko.net/tcp/33553/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66", "/dns/kbr13.rotko.net/tcp/34553/ws/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66", - "/dns/kbr13.rotko.net/tcp/35553/wss/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66" + "/dns/kbr13.rotko.net/tcp/35553/wss/p2p/12D3KooWAmBp54mUEYtvsk2kxNEsDbAvdUMcaghxKXgUQxmPEQ66", + "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30520/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV", + "/dns/bridge-hub-kusama.bootnodes.polkadotters.com/tcp/30522/wss/p2p/12D3KooWH3pucezRRS5esoYyzZsUkKWcPSByQxEvmM819QL1HPLV" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/bridge-hub-polkadot.json b/cumulus/parachains/chain-specs/bridge-hub-polkadot.json index 130bdf31ef2..a9444b89e1e 100644 --- a/cumulus/parachains/chain-specs/bridge-hub-polkadot.json +++ b/cumulus/parachains/chain-specs/bridge-hub-polkadot.json @@ -21,7 +21,9 @@ "/dns/bridgehub-polkadot-bootnode.radiumblock.com/tcp/30333/p2p/12D3KooWPNZm78tWUmKbta3SXdkqTPsquRc8ekEbJjZsGGi7YiRi", "/dns/pbr13.rotko.net/tcp/33543/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw", "/dns/pbr13.rotko.net/tcp/34543/ws/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw", - "/dns/pbr13.rotko.net/tcp/35543/wss/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw" + "/dns/pbr13.rotko.net/tcp/35543/wss/p2p/12D3KooWMxZY7tDc2Rh454VaJJ7RexKAXVS6xSBEvTnXSGCnuGDw", + "/dns/bridge-hub-polkadot.bootnodes.polkadotters.com/tcp/30517/p2p/12D3KooWLUNE3LHPDa1WrrZaYT7ArK66CLM1bPv7kKz74UcLnQRB", + "/dns/bridge-hub-polkadot.bootnodes.polkadotters.com/tcp/30519/wss/p2p/12D3KooWLUNE3LHPDa1WrrZaYT7ArK66CLM1bPv7kKz74UcLnQRB" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/bridge-hub-westend.json b/cumulus/parachains/chain-specs/bridge-hub-westend.json index 018ab0ee6fd..447207a5810 100644 --- a/cumulus/parachains/chain-specs/bridge-hub-westend.json +++ b/cumulus/parachains/chain-specs/bridge-hub-westend.json @@ -19,7 +19,9 @@ "/dns/bridgehub-westend-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWBsBArCMxmQyo3feCEqMWuwyhb2LTRK8hmCCJxgrNeMke", "/dns/wbr13.rotko.net/tcp/33563/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD", "/dns/wbr13.rotko.net/tcp/34563/ws/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD", - "/dns/wbr13.rotko.net/tcp/35563/wss/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD" + "/dns/wbr13.rotko.net/tcp/35563/wss/p2p/12D3KooWJyeRHpxZZbfBCNEgeUFzmRC5AMSAs2tJhjJS1k5hULkD", + "/dns/bridge-hub-westend.bootnodes.polkadotters.com/tcp/30523/p2p/12D3KooWPkwgJofp4GeeRwNgXqkp2aFwdLkCWv3qodpBJLwK43Jj", + "/dns/bridge-hub-westend.bootnodes.polkadotters.com/tcp/30525/wss/p2p/12D3KooWPkwgJofp4GeeRwNgXqkp2aFwdLkCWv3qodpBJLwK43Jj" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/collectives-polkadot.json b/cumulus/parachains/chain-specs/collectives-polkadot.json index e9f690234e4..259669cf37a 100644 --- a/cumulus/parachains/chain-specs/collectives-polkadot.json +++ b/cumulus/parachains/chain-specs/collectives-polkadot.json @@ -25,7 +25,9 @@ "/dns/collectives-polkadot-bootnode.radiumblock.com/tcp/30336/wss/p2p/12D3KooWDumvnNwPbBg5inBEapgjKU7ECdMHHgwfYeGWUkzYUE1c", "/dns/pch13.rotko.net/tcp/33573/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH", "/dns/pch13.rotko.net/tcp/34573/ws/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH", - "/dns/pch13.rotko.net/tcp/35573/wss/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH" + "/dns/pch13.rotko.net/tcp/35573/wss/p2p/12D3KooWRXudHoazPZ9osMfdY38e8CBxQLD4RhrVeHpRSNNpcDtH", + "/dns/collectives-polkadot.bootnodes.polkadotters.com/tcp/30526/p2p/12D3KooWNohUjvJtGKUa8Vhy8C1ZBB5N8JATB6e7rdLVCioeb3ff", + "/dns/collectives-polkadot.bootnodes.polkadotters.com/tcp/30528/wss/p2p/12D3KooWNohUjvJtGKUa8Vhy8C1ZBB5N8JATB6e7rdLVCioeb3ff" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/collectives-westend.json b/cumulus/parachains/chain-specs/collectives-westend.json index ffe73b5a05a..e459c631f8b 100644 --- a/cumulus/parachains/chain-specs/collectives-westend.json +++ b/cumulus/parachains/chain-specs/collectives-westend.json @@ -25,7 +25,9 @@ "/dns/westend-collectives-boot-ng.dwellir.com/tcp/443/wss/p2p/12D3KooWPFM93jgm4pgxx8PM8WJKAJF49qia8jRB95uciUQwYh7m", "/dns/wch13.rotko.net/tcp/33593/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr", "/dns/wch13.rotko.net/tcp/34593/ws/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr", - "/dns/wch13.rotko.net/tcp/35593/wss/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr" + "/dns/wch13.rotko.net/tcp/35593/wss/p2p/12D3KooWPG85zhuSRoyptjLkFD4iJFistjiBmc15JgQ96B4fdXYr", + "/dns/collectives-westend.bootnodes.polkadotters.com/tcp/30529/p2p/12D3KooWAFkXNSBfyPduZVgfS7pj5NuVpbU8Ee5gHeF8wvos7Yqn", + "/dns/collectives-westend.bootnodes.polkadotters.com/tcp/30531/wss/p2p/12D3KooWAFkXNSBfyPduZVgfS7pj5NuVpbU8Ee5gHeF8wvos7Yqn" ], "telemetryEndpoints": null, "protocolId": null, diff --git a/cumulus/parachains/chain-specs/people-westend.json b/cumulus/parachains/chain-specs/people-westend.json index fa29853c70b..29fa0c9cde7 100644 --- a/cumulus/parachains/chain-specs/people-westend.json +++ b/cumulus/parachains/chain-specs/people-westend.json @@ -10,7 +10,9 @@ "/dns/westend-people-collator-node-2.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWGVYTVKW7tYe51JvetvGvVLDPXzqQX1mueJgz14FgkmHG", "/dns/westend-people-collator-node-2.parity-testnet.parity.io/tcp/443/wss/p2p/12D3KooWGVYTVKW7tYe51JvetvGvVLDPXzqQX1mueJgz14FgkmHG", "/dns/westend-people-collator-node-3.parity-testnet.parity.io/tcp/30333/p2p/12D3KooWCF1eA2Gap69zgXD7Df3e9DqDUsGoByocggTGejoHjK23", - "/dns/westend-people-collator-node-3.parity-testnet.parity.io/tcp/443/wss/p2p/12D3KooWCF1eA2Gap69zgXD7Df3e9DqDUsGoByocggTGejoHjK23" + "/dns/westend-people-collator-node-3.parity-testnet.parity.io/tcp/443/wss/p2p/12D3KooWCF1eA2Gap69zgXD7Df3e9DqDUsGoByocggTGejoHjK23", + "/dns/identity-westend.bootnodes.polkadotters.com/tcp/30532/p2p/12D3KooWKr9San6KTM7REJ95cBaDoiciGcWnW8TTftEJgxGF5Ehb", + "/dns/identity-westend.bootnodes.polkadotters.com/tcp/30534/wss/p2p/12D3KooWKr9San6KTM7REJ95cBaDoiciGcWnW8TTftEJgxGF5Ehb" ], "telemetryEndpoints": null, "protocolId": null, @@ -79,4 +81,4 @@ "childrenDefault": {} } } -} \ No newline at end of file +} diff --git a/polkadot/node/service/chain-specs/kusama.json b/polkadot/node/service/chain-specs/kusama.json index 979550c7570..fd60cb8b6c1 100644 --- a/polkadot/node/service/chain-specs/kusama.json +++ b/polkadot/node/service/chain-specs/kusama.json @@ -16,8 +16,8 @@ "/dns/boot-node.helikon.io/tcp/7062/wss/p2p/12D3KooWL4KPqfAsPE2aY1g5Zo1CxsDwcdJ7mmAghK7cg6M2fdbD", "/dns/kusama.bootnode.amforc.com/tcp/30333/p2p/12D3KooWLx6nsj6Fpd8biP1VDyuCUjazvRiGWyBam8PsqRJkbUb9", "/dns/kusama.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWLx6nsj6Fpd8biP1VDyuCUjazvRiGWyBam8PsqRJkbUb9", - "/dns/kusama-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", - "/dns/kusama-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", + "/dns/kusama.bootnodes.polkadotters.com/tcp/30311/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", + "/dns/kusama.bootnodes.polkadotters.com/tcp/30313/wss/p2p/12D3KooWHB5rTeNkQdXNJ9ynvGz8Lpnmsctt7Tvp7mrYv6bcwbPG", "/dns/boot-cr.gatotech.network/tcp/33200/p2p/12D3KooWRNZXf99BfzQDE1C8YhuBbuy7Sj18UEf7FNpD8egbURYD", "/dns/boot-cr.gatotech.network/tcp/35200/wss/p2p/12D3KooWRNZXf99BfzQDE1C8YhuBbuy7Sj18UEf7FNpD8egbURYD", "/dns/boot-kusama.metaspan.io/tcp/23012/p2p/12D3KooWE1tq9ZL9AAxMiUBBqy1ENmh5pwfWabnoBPMo8gFPXhn6", diff --git a/polkadot/node/service/chain-specs/paseo.json b/polkadot/node/service/chain-specs/paseo.json index c8f2b58533c..8db75ff137b 100644 --- a/polkadot/node/service/chain-specs/paseo.json +++ b/polkadot/node/service/chain-specs/paseo.json @@ -12,7 +12,9 @@ "/dns/boot-node.helikon.io/tcp/10020/p2p/12D3KooWBetfzZpf6tGihKrqCo5z854Ub4ZNAUUTRT6eYHNh7FYi", "/dns/boot-node.helikon.io/tcp/10022/wss/p2p/12D3KooWBetfzZpf6tGihKrqCo5z854Ub4ZNAUUTRT6eYHNh7FYi", "/dns/pso16.rotko.net/tcp/33246/p2p/12D3KooWRH8eBMhw8c7bucy6pJfy94q4dKpLkF3pmeGohHmemdRu", - "/dns/pso16.rotko.net/tcp/35246/wss/p2p/12D3KooWRH8eBMhw8c7bucy6pJfy94q4dKpLkF3pmeGohHmemdRu" + "/dns/pso16.rotko.net/tcp/35246/wss/p2p/12D3KooWRH8eBMhw8c7bucy6pJfy94q4dKpLkF3pmeGohHmemdRu", + "/dns/paseo.bootnodes.polkadotters.com/tcp/30538/p2p/12D3KooWPbbFy4TefEGTRF5eTYhq8LEzc4VAHdNUVCbY4nAnhqPP", + "/dns/paseo.bootnodes.polkadotters.com/tcp/30540/wss/p2p/12D3KooWPbbFy4TefEGTRF5eTYhq8LEzc4VAHdNUVCbY4nAnhqPP" ], "telemetryEndpoints": [ [ diff --git a/polkadot/node/service/chain-specs/polkadot.json b/polkadot/node/service/chain-specs/polkadot.json index 71dbb900403..c235cdd09d8 100644 --- a/polkadot/node/service/chain-specs/polkadot.json +++ b/polkadot/node/service/chain-specs/polkadot.json @@ -17,8 +17,8 @@ "/dns/boot-node.helikon.io/tcp/7072/wss/p2p/12D3KooWS9ZcvRxyzrSf6p63QfTCWs12nLoNKhGux865crgxVA4H", "/dns/polkadot.bootnode.amforc.com/tcp/30333/p2p/12D3KooWAsuCEVCzUVUrtib8W82Yne3jgVGhQZN3hizko5FTnDg3", "/dns/polkadot.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWAsuCEVCzUVUrtib8W82Yne3jgVGhQZN3hizko5FTnDg3", - "/dns/polkadot-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", - "/dns/polkadot-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", + "/dns/polkadot.bootnodes.polkadotters.com/tcp/30314/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", + "/dns/polkadot.bootnodes.polkadotters.com/tcp/30316/wss/p2p/12D3KooWPAVUgBaBk6n8SztLrMk8ESByncbAfRKUdxY1nygb9zG3", "/dns/boot-cr.gatotech.network/tcp/33100/p2p/12D3KooWK4E16jKk9nRhvC4RfrDVgcZzExg8Q3Q2G7ABUUitks1w", "/dns/boot-cr.gatotech.network/tcp/35100/wss/p2p/12D3KooWK4E16jKk9nRhvC4RfrDVgcZzExg8Q3Q2G7ABUUitks1w", "/dns/boot-polkadot.metaspan.io/tcp/13012/p2p/12D3KooWRjHFApinuqSBjoaDjQHvxwubQSpEVy5hrgC9Smvh92WF", diff --git a/polkadot/node/service/chain-specs/westend.json b/polkadot/node/service/chain-specs/westend.json index 697675871fc..775f3e72ac7 100644 --- a/polkadot/node/service/chain-specs/westend.json +++ b/polkadot/node/service/chain-specs/westend.json @@ -14,8 +14,8 @@ "/dns/boot-node.helikon.io/tcp/7082/wss/p2p/12D3KooWRFDPyT8vA8mLzh6dJoyujn4QNjeqi6Ch79eSMz9beKXC", "/dns/westend.bootnode.amforc.com/tcp/30333/p2p/12D3KooWJ5y9ZgVepBQNW4aabrxgmnrApdVnscqgKWiUu4BNJbC8", "/dns/westend.bootnode.amforc.com/tcp/30334/wss/p2p/12D3KooWJ5y9ZgVepBQNW4aabrxgmnrApdVnscqgKWiUu4BNJbC8", - "/dns/westend-bootnode.polkadotters.com/tcp/30333/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", - "/dns/westend-bootnode.polkadotters.com/tcp/30334/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", + "/dns/westend.bootnodes.polkadotters.com/tcp/30308/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", + "/dns/westend.bootnodes.polkadotters.com/tcp/30310/wss/p2p/12D3KooWHPHb64jXMtSRJDrYFATWeLnvChL8NtWVttY67DCH1eC5", "/dns/boot-cr.gatotech.network/tcp/33300/p2p/12D3KooWQGR1vUhoy6mvQorFp3bZFn6NNezhQZ6NWnVV7tpFgoPd", "/dns/boot-cr.gatotech.network/tcp/35300/wss/p2p/12D3KooWQGR1vUhoy6mvQorFp3bZFn6NNezhQZ6NWnVV7tpFgoPd", "/dns/boot-westend.metaspan.io/tcp/33012/p2p/12D3KooWNTau7iG4G9cUJSwwt2QJP1W88pUf2SgqsHjRU2RL8pfa", -- GitLab From 95da6583602691fd0c8403e9eda26db1e10dafc4 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Wed, 28 Feb 2024 13:13:09 +1100 Subject: [PATCH 266/283] Introduce storage attr macro `#[disable_try_decode_storage]` and set it on `System::Events` and `ParachainSystem::HostConfiguration` (#3454) Closes https://github.com/paritytech/polkadot-sdk/issues/2560 Allows marking storage items with `#[disable_try_decode_storage]`, and uses it with `System::Events`. Question: what's the recommended way to write a test for this? I couldn't find a test for similar existing macro `#[whitelist_storage]`. --- cumulus/pallets/parachain-system/src/lib.rs | 1 + prdoc/pr_3454.prdoc | 19 +++++++++++++++ substrate/frame/support/procedural/src/lib.rs | 19 +++++++++++++++ .../procedural/src/pallet/expand/storage.rs | 5 +++- .../procedural/src/pallet/parse/storage.rs | 24 +++++++++++++++++-- substrate/frame/support/src/lib.rs | 17 +++++++++++-- .../storage_invalid_attribute.stderr | 2 +- substrate/frame/system/src/lib.rs | 1 + 8 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 prdoc/pr_3454.prdoc diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs index d86a67e58f4..3439227bc5b 100644 --- a/cumulus/pallets/parachain-system/src/lib.rs +++ b/cumulus/pallets/parachain-system/src/lib.rs @@ -840,6 +840,7 @@ pub mod pallet { /// /// This data is also absent from the genesis. #[pallet::storage] + #[pallet::disable_try_decode_storage] #[pallet::getter(fn host_configuration)] pub(super) type HostConfiguration = StorageValue<_, AbridgedHostConfiguration>; diff --git a/prdoc/pr_3454.prdoc b/prdoc/pr_3454.prdoc new file mode 100644 index 00000000000..7f564258f23 --- /dev/null +++ b/prdoc/pr_3454.prdoc @@ -0,0 +1,19 @@ +# 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: "Introduce storage attr macro #[disable_try_decode_storage] and set it on System::Events and ParachainSystem::HostConfiguration" + +doc: + - audience: Runtime Dev + description: | + Allows marking storage items with \#[disable_try_decode_storage], which disables that storage item from being decoded + during try_decode_entire_state calls. + + Applied the attribute to System::Events to close https://github.com/paritytech/polkadot-sdk/issues/2560. + Applied the attribute to ParachainSystem::HostConfiguration to resolve periodic issues with it. + +crates: + - name: frame-support-procedural + - name: frame-system + - name: cumulus-pallet-parachain-system + diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 441b21e26ff..78729ee3dc3 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -1371,6 +1371,25 @@ pub fn whitelist_storage(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } +/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the +/// storage as whitelisted from decoding during try-runtime checks. This should only be +/// attached to transient storage which cannot be migrated during runtime upgrades. +/// +/// ### Example +/// ```ignore +/// #[pallet::storage] +/// #[pallet::disable_try_decode_storage] +/// pub(super) type Events = StorageValue<_, Vec>>, ValueQuery>; +/// ``` +/// +/// NOTE: As with all `pallet::*` attributes, this one _must_ be written as +/// `#[pallet::disable_try_decode_storage]` and can only be placed inside a `pallet` module in order +/// for it to work properly. +#[proc_macro_attribute] +pub fn disable_try_decode_storage(_: TokenStream, _: TokenStream) -> TokenStream { + pallet_macro_stub() +} + /// The `#[pallet::type_value]` attribute lets you define a struct implementing the `Get` trait /// to ease the use of storage types. This attribute is meant to be used alongside /// [`#[pallet::storage]`](`macro@storage`) to define a storage's default value. This attribute diff --git a/substrate/frame/support/procedural/src/pallet/expand/storage.rs b/substrate/frame/support/procedural/src/pallet/expand/storage.rs index 96c2c8e3120..937b068cfab 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/storage.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/storage.rs @@ -834,7 +834,10 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { .storages .iter() .filter_map(|storage| { - if storage.cfg_attrs.is_empty() { + // A little hacky; don't generate for cfg gated storages to not get compile errors + // when building "frame-feature-testing" gated storages in the "frame-support-test" + // crate. + if storage.try_decode && storage.cfg_attrs.is_empty() { let ident = &storage.ident; let gen = &def.type_use_generics(storage.attr_span); Some(quote::quote_spanned!(storage.attr_span => #ident<#gen> )) diff --git a/substrate/frame/support/procedural/src/pallet/parse/storage.rs b/substrate/frame/support/procedural/src/pallet/parse/storage.rs index d1c7ba2e5e3..9d96a18b569 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/storage.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/storage.rs @@ -29,6 +29,7 @@ mod keyword { syn::custom_keyword!(storage_prefix); syn::custom_keyword!(unbounded); syn::custom_keyword!(whitelist_storage); + syn::custom_keyword!(disable_try_decode_storage); syn::custom_keyword!(OptionQuery); syn::custom_keyword!(ResultQuery); syn::custom_keyword!(ValueQuery); @@ -39,11 +40,13 @@ mod keyword { /// * `#[pallet::storage_prefix = "CustomName"]` /// * `#[pallet::unbounded]` /// * `#[pallet::whitelist_storage] +/// * `#[pallet::disable_try_decode_storage]` pub enum PalletStorageAttr { Getter(syn::Ident, proc_macro2::Span), StorageName(syn::LitStr, proc_macro2::Span), Unbounded(proc_macro2::Span), WhitelistStorage(proc_macro2::Span), + DisableTryDecodeStorage(proc_macro2::Span), } impl PalletStorageAttr { @@ -53,6 +56,7 @@ impl PalletStorageAttr { Self::StorageName(_, span) | Self::Unbounded(span) | Self::WhitelistStorage(span) => *span, + Self::DisableTryDecodeStorage(span) => *span, } } } @@ -93,6 +97,9 @@ impl syn::parse::Parse for PalletStorageAttr { } else if lookahead.peek(keyword::whitelist_storage) { content.parse::()?; Ok(Self::WhitelistStorage(attr_span)) + } else if lookahead.peek(keyword::disable_try_decode_storage) { + content.parse::()?; + Ok(Self::DisableTryDecodeStorage(attr_span)) } else { Err(lookahead.error()) } @@ -104,6 +111,7 @@ struct PalletStorageAttrInfo { rename_as: Option, unbounded: bool, whitelisted: bool, + try_decode: bool, } impl PalletStorageAttrInfo { @@ -112,6 +120,7 @@ impl PalletStorageAttrInfo { let mut rename_as = None; let mut unbounded = false; let mut whitelisted = false; + let mut disable_try_decode_storage = false; for attr in attrs { match attr { PalletStorageAttr::Getter(ident, ..) if getter.is_none() => getter = Some(ident), @@ -119,6 +128,8 @@ impl PalletStorageAttrInfo { rename_as = Some(name), PalletStorageAttr::Unbounded(..) if !unbounded => unbounded = true, PalletStorageAttr::WhitelistStorage(..) if !whitelisted => whitelisted = true, + PalletStorageAttr::DisableTryDecodeStorage(..) if !disable_try_decode_storage => + disable_try_decode_storage = true, attr => return Err(syn::Error::new( attr.attr_span(), @@ -127,7 +138,13 @@ impl PalletStorageAttrInfo { } } - Ok(PalletStorageAttrInfo { getter, rename_as, unbounded, whitelisted }) + Ok(PalletStorageAttrInfo { + getter, + rename_as, + unbounded, + whitelisted, + try_decode: !disable_try_decode_storage, + }) } } @@ -186,6 +203,8 @@ pub struct StorageDef { pub unbounded: bool, /// Whether or not reads to this storage key will be ignored by benchmarking pub whitelisted: bool, + /// Whether or not to try to decode the storage key when running try-runtime checks. + pub try_decode: bool, /// Whether or not a default hasher is allowed to replace `_` pub use_default_hasher: bool, } @@ -775,7 +794,7 @@ impl StorageDef { }; let attrs: Vec = helper::take_item_pallet_attrs(&mut item.attrs)?; - let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted } = + let PalletStorageAttrInfo { getter, rename_as, mut unbounded, whitelisted, try_decode } = PalletStorageAttrInfo::from_attrs(attrs)?; // set all storages to be unbounded if dev_mode is enabled @@ -921,6 +940,7 @@ impl StorageDef { named_generics, unbounded, whitelisted, + try_decode, use_default_hasher, }) } diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 26fc1fe42c1..3e97a384275 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -982,6 +982,7 @@ pub mod pallet_prelude { /// * [`pallet::storage_prefix = "SomeName"`](#palletstorage_prefix--somename-optional) /// * [`pallet::unbounded`](#palletunbounded-optional) /// * [`pallet::whitelist_storage`](#palletwhitelist_storage-optional) +/// * [`pallet::disable_try_decode_storage`](#palletdisable_try_decode_storage-optional) /// * [`cfg(..)`](#cfg-for-storage) (on storage items) /// * [`pallet::type_value`](#type-value-pallettype_value-optional) /// * [`pallet::genesis_config`](#genesis-config-palletgenesis_config-optional) @@ -1498,6 +1499,15 @@ pub mod pallet_prelude { /// [`pallet::whitelist_storage`](frame_support::pallet_macros::whitelist_storage) /// for more info. /// +/// ## `#[pallet::disable_try_decode_storage]` (optional) +/// +/// The optional attribute `#[pallet::disable_try_decode_storage]` will declare the storage as +/// whitelisted state decoding during try-runtime logic. +/// +/// See +/// [`pallet::disable_try_decode_storage`](frame_support::pallet_macros::disable_try_decode_storage) +/// for more info. +/// /// ## `#[cfg(..)]` (for storage) /// The optional attributes `#[cfg(..)]` allow conditional compilation for the storage. /// @@ -2272,8 +2282,8 @@ pub use frame_support_procedural::pallet; /// Contains macro stubs for all of the pallet:: macros pub mod pallet_macros { pub use frame_support_procedural::{ - composite_enum, config, disable_frame_system_supertrait_check, error, event, - extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, + composite_enum, config, disable_frame_system_supertrait_check, disable_try_decode_storage, + error, event, extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, import_section, inherent, no_default, no_default_bounds, pallet_section, storage_prefix, storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; @@ -2698,6 +2708,8 @@ pub mod pallet_macros { /// * [`macro@getter`]: Creates a custom getter function. /// * [`macro@storage_prefix`]: Overrides the default prefix of the storage item. /// * [`macro@unbounded`]: Declares the storage item as unbounded. + /// * [`macro@disable_try_decode_storage`]: Declares that try-runtime checks should not + /// attempt to decode the storage item. /// /// #### Example /// ``` @@ -2713,6 +2725,7 @@ pub mod pallet_macros { /// #[pallet::getter(fn foo)] /// #[pallet::storage_prefix = "OtherFoo"] /// #[pallet::unbounded] + /// #[pallet::disable_try_decode_storage] /// pub type Foo = StorageValue<_, u32, ValueQuery>; /// } /// ``` diff --git a/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr b/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr index 7f125526edf..519fadaa604 100644 --- a/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr +++ b/substrate/frame/support/test/tests/pallet_ui/storage_invalid_attribute.stderr @@ -1,4 +1,4 @@ -error: expected one of: `getter`, `storage_prefix`, `unbounded`, `whitelist_storage` +error: expected one of: `getter`, `storage_prefix`, `unbounded`, `whitelist_storage`, `disable_try_decode_storage` --> tests/pallet_ui/storage_invalid_attribute.rs:33:12 | 33 | #[pallet::generate_store(pub trait Store)] diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index aa6841c008a..c527a483d88 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -894,6 +894,7 @@ pub mod pallet { /// just in case someone still reads them from within the runtime. #[pallet::storage] #[pallet::whitelist_storage] + #[pallet::disable_try_decode_storage] #[pallet::unbounded] pub(super) type Events = StorageValue<_, Vec>>, ValueQuery>; -- GitLab From 7ec0b8741b4ead5bc85411b30e53b459a03b1938 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Wed, 28 Feb 2024 05:05:54 +0100 Subject: [PATCH 267/283] Collator overseer builder unification (#3335) resolve https://github.com/paritytech/polkadot-sdk/issues/3116 a follow-up on https://github.com/paritytech/polkadot-sdk/pull/3061#pullrequestreview-1847530265: - [x] reuse collator overseer builder for polkadot-node and collator - [x] run zombienet test (0001-parachains-smoke-test.toml) - [x] make wasm build errors more user-friendly for an easier problem detection when using different toolchains in Rust --------- Co-authored-by: ordian Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> --- Cargo.lock | 1 + .../relay-chain-minimal-node/Cargo.toml | 1 + .../src/collator_overseer.rs | 144 +----------------- .../relay-chain-minimal-node/src/lib.rs | 30 ++-- .../relay-chain-minimal-node/src/network.rs | 8 +- .../src/variants/back_garbage_candidate.rs | 15 +- polkadot/node/malus/src/variants/common.rs | 4 - .../variants/dispute_finalized_candidates.rs | 17 +-- .../src/variants/dispute_valid_candidates.rs | 15 +- .../src/variants/suggest_garbage_candidate.rs | 17 +-- .../malus/src/variants/support_disabled.rs | 15 +- polkadot/node/service/src/lib.rs | 13 +- polkadot/node/service/src/overseer.rs | 76 +++------ .../subsystem-types/src/runtime_client.rs | 64 +++++++- .../utils/wasm-builder/src/prerequisites.rs | 20 ++- 15 files changed, 162 insertions(+), 278 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c52feafe7a7..27ba43780ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4166,6 +4166,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", + "polkadot-service", "sc-authority-discovery", "sc-client-api", "sc-network", diff --git a/cumulus/client/relay-chain-minimal-node/Cargo.toml b/cumulus/client/relay-chain-minimal-node/Cargo.toml index 0b1e001e007..98240c92ada 100644 --- a/cumulus/client/relay-chain-minimal-node/Cargo.toml +++ b/cumulus/client/relay-chain-minimal-node/Cargo.toml @@ -24,6 +24,7 @@ polkadot-node-collation-generation = { path = "../../../polkadot/node/collation- polkadot-node-core-runtime-api = { path = "../../../polkadot/node/core/runtime-api" } polkadot-node-core-chain-api = { path = "../../../polkadot/node/core/chain-api" } polkadot-node-core-prospective-parachains = { path = "../../../polkadot/node/core/prospective-parachains" } +polkadot-service = { path = "../../../polkadot/node/service" } # substrate deps sc-authority-discovery = { path = "../../../substrate/client/authority-discovery" } diff --git a/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs b/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs index 5f5bf338ef9..f01ef8b05ec 100644 --- a/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs +++ b/cumulus/client/relay-chain-minimal-node/src/collator_overseer.rs @@ -15,159 +15,29 @@ // along with Polkadot. If not, see . use futures::{select, StreamExt}; -use parking_lot::Mutex; -use std::{collections::HashMap, sync::Arc}; +use std::sync::Arc; -use polkadot_availability_recovery::AvailabilityRecoverySubsystem; -use polkadot_collator_protocol::{CollatorProtocolSubsystem, ProtocolSide}; -use polkadot_network_bridge::{ - Metrics as NetworkBridgeMetrics, NetworkBridgeRx as NetworkBridgeRxSubsystem, - NetworkBridgeTx as NetworkBridgeTxSubsystem, -}; -use polkadot_node_collation_generation::CollationGenerationSubsystem; -use polkadot_node_core_chain_api::ChainApiSubsystem; -use polkadot_node_core_prospective_parachains::ProspectiveParachainsSubsystem; -use polkadot_node_core_runtime_api::RuntimeApiSubsystem; -use polkadot_node_network_protocol::{ - peer_set::{PeerSet, PeerSetProtocolNames}, - request_response::{ - v1::{self, AvailableDataFetchingRequest}, - v2, IncomingRequestReceiver, ReqProtocolNames, - }, -}; -use polkadot_node_subsystem_util::metrics::{prometheus::Registry, Metrics}; use polkadot_overseer::{ - BlockInfo, DummySubsystem, Handle, Overseer, OverseerConnector, OverseerHandle, SpawnGlue, - UnpinHandle, + BlockInfo, Handle, Overseer, OverseerConnector, OverseerHandle, SpawnGlue, UnpinHandle, }; -use polkadot_primitives::CollatorPair; +use polkadot_service::overseer::{collator_overseer_builder, OverseerGenArgs}; -use sc_authority_discovery::Service as AuthorityDiscoveryService; -use sc_network::{NetworkStateInfo, NotificationService}; use sc_service::TaskManager; use sc_utils::mpsc::tracing_unbounded; -use cumulus_primitives_core::relay_chain::{Block, Hash as PHash}; use cumulus_relay_chain_interface::RelayChainError; use crate::BlockChainRpcClient; -/// Arguments passed for overseer construction. -pub(crate) struct CollatorOverseerGenArgs<'a> { - /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others. - pub runtime_client: Arc, - /// Underlying network service implementation. - pub network_service: Arc>, - /// Syncing oracle. - pub sync_oracle: Box, - /// Underlying authority discovery service. - pub authority_discovery_service: AuthorityDiscoveryService, - /// Receiver for collation request protocol v1. - pub collation_req_receiver_v1: IncomingRequestReceiver, - /// Receiver for collation request protocol v2. - pub collation_req_receiver_v2: IncomingRequestReceiver, - /// Receiver for availability request protocol - pub available_data_req_receiver: IncomingRequestReceiver, - /// Prometheus registry, commonly used for production systems, less so for test. - pub registry: Option<&'a Registry>, - /// Task spawner to be used throughout the overseer and the APIs it provides. - pub spawner: sc_service::SpawnTaskHandle, - /// Determines the behavior of the collator. - pub collator_pair: CollatorPair, - /// Request response protocols - pub req_protocol_names: ReqProtocolNames, - /// Peerset protocols name mapping - pub peer_set_protocol_names: PeerSetProtocolNames, - /// Notification services for validation/collation protocols. - pub notification_services: HashMap>, -} - fn build_overseer( connector: OverseerConnector, - CollatorOverseerGenArgs { - runtime_client, - network_service, - sync_oracle, - authority_discovery_service, - collation_req_receiver_v1, - collation_req_receiver_v2, - available_data_req_receiver, - registry, - spawner, - collator_pair, - req_protocol_names, - peer_set_protocol_names, - notification_services, - }: CollatorOverseerGenArgs<'_>, + args: OverseerGenArgs, ) -> Result< (Overseer, Arc>, OverseerHandle), RelayChainError, > { - let spawner = SpawnGlue(spawner); - let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; - let notification_sinks = Arc::new(Mutex::new(HashMap::new())); - - let builder = Overseer::builder() - .availability_distribution(DummySubsystem) - .availability_recovery(AvailabilityRecoverySubsystem::for_collator( - available_data_req_receiver, - Metrics::register(registry)?, - )) - .availability_store(DummySubsystem) - .bitfield_distribution(DummySubsystem) - .bitfield_signing(DummySubsystem) - .candidate_backing(DummySubsystem) - .candidate_validation(DummySubsystem) - .pvf_checker(DummySubsystem) - .chain_api(ChainApiSubsystem::new(runtime_client.clone(), Metrics::register(registry)?)) - .collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?)) - .collator_protocol({ - let side = ProtocolSide::Collator { - peer_id: network_service.local_peer_id(), - collator_pair, - request_receiver_v1: collation_req_receiver_v1, - request_receiver_v2: collation_req_receiver_v2, - metrics: Metrics::register(registry)?, - }; - CollatorProtocolSubsystem::new(side) - }) - .network_bridge_rx(NetworkBridgeRxSubsystem::new( - network_service.clone(), - authority_discovery_service.clone(), - sync_oracle, - network_bridge_metrics.clone(), - peer_set_protocol_names.clone(), - notification_services, - notification_sinks.clone(), - )) - .network_bridge_tx(NetworkBridgeTxSubsystem::new( - network_service, - authority_discovery_service, - network_bridge_metrics, - req_protocol_names, - peer_set_protocol_names, - notification_sinks, - )) - .provisioner(DummySubsystem) - .runtime_api(RuntimeApiSubsystem::new( - runtime_client.clone(), - Metrics::register(registry)?, - spawner.clone(), - )) - .statement_distribution(DummySubsystem) - .prospective_parachains(ProspectiveParachainsSubsystem::new(Metrics::register(registry)?)) - .approval_distribution(DummySubsystem) - .approval_voting(DummySubsystem) - .gossip_support(DummySubsystem) - .dispute_coordinator(DummySubsystem) - .dispute_distribution(DummySubsystem) - .chain_selection(DummySubsystem) - .activation_external_listeners(Default::default()) - .span_per_active_leaf(Default::default()) - .active_leaves(Default::default()) - .supports_parachains(runtime_client) - .metrics(Metrics::register(registry)?) - .spawner(spawner); + let builder = + collator_overseer_builder(args).map_err(|e| RelayChainError::Application(e.into()))?; builder .build_with_connector(connector) @@ -175,7 +45,7 @@ fn build_overseer( } pub(crate) fn spawn_overseer( - overseer_args: CollatorOverseerGenArgs, + overseer_args: OverseerGenArgs, task_manager: &TaskManager, relay_chain_rpc_client: Arc, ) -> Result { diff --git a/cumulus/client/relay-chain-minimal-node/src/lib.rs b/cumulus/client/relay-chain-minimal-node/src/lib.rs index d121d2d3356..4bccca59fe3 100644 --- a/cumulus/client/relay-chain-minimal-node/src/lib.rs +++ b/cumulus/client/relay-chain-minimal-node/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use collator_overseer::{CollatorOverseerGenArgs, NewMinimalNode}; +use collator_overseer::NewMinimalNode; use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult}; use cumulus_relay_chain_rpc_interface::{RelayChainRpcClient, RelayChainRpcInterface, Url}; @@ -29,6 +29,7 @@ use polkadot_node_network_protocol::{ use polkadot_node_subsystem_util::metrics::prometheus::Registry; use polkadot_primitives::CollatorPair; +use polkadot_service::{overseer::OverseerGenArgs, IsParachainNode}; use sc_authority_discovery::Service as AuthorityDiscoveryService; use sc_network::{config::FullNetworkConfiguration, Event, NetworkEventStream, NetworkService}; @@ -172,10 +173,10 @@ async fn new_minimal_relay_chain( } let genesis_hash = relay_chain_rpc_client.block_get_hash(Some(0)).await?.unwrap_or_default(); - let peer_set_protocol_names = + let peerset_protocol_names = PeerSetProtocolNames::new(genesis_hash, config.chain_spec.fork_id()); let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No }; - let notification_services = peer_sets_info(is_authority, &peer_set_protocol_names) + let notification_services = peer_sets_info(is_authority, &peerset_protocol_names) .into_iter() .map(|(config, (peerset, service))| { net_config.add_notification_protocol(config); @@ -184,14 +185,14 @@ async fn new_minimal_relay_chain( .collect::>>(); let request_protocol_names = ReqProtocolNames::new(genesis_hash, config.chain_spec.fork_id()); - let (collation_req_receiver_v1, collation_req_receiver_v2, available_data_req_receiver) = + let (collation_req_v1_receiver, collation_req_v2_receiver, available_data_req_receiver) = build_request_response_protocol_receivers(&request_protocol_names, &mut net_config); let best_header = relay_chain_rpc_client .chain_get_header(None) .await? .ok_or_else(|| RelayChainError::RpcCallError("Unable to fetch best header".to_string()))?; - let (network, network_starter, sync_oracle) = build_collator_network( + let (network, network_starter, sync_service) = build_collator_network( &config, net_config, task_manager.spawn_handle(), @@ -208,19 +209,20 @@ async fn new_minimal_relay_chain( prometheus_registry.cloned(), ); - let overseer_args = CollatorOverseerGenArgs { + let overseer_args = OverseerGenArgs { runtime_client: relay_chain_rpc_client.clone(), network_service: network, - sync_oracle, + sync_service, authority_discovery_service, - collation_req_receiver_v1, - collation_req_receiver_v2, + collation_req_v1_receiver, + collation_req_v2_receiver, available_data_req_receiver, registry: prometheus_registry, spawner: task_manager.spawn_handle(), - collator_pair, + is_parachain_node: IsParachainNode::Collator(collator_pair), + overseer_message_channel_capacity_override: None, req_protocol_names: request_protocol_names, - peer_set_protocol_names, + peerset_protocol_names, notification_services, }; @@ -240,10 +242,10 @@ fn build_request_response_protocol_receivers( IncomingRequestReceiver, IncomingRequestReceiver, ) { - let (collation_req_receiver_v1, cfg) = + let (collation_req_v1_receiver, cfg) = IncomingRequest::get_config_receiver(request_protocol_names); config.add_request_response_protocol(cfg); - let (collation_req_receiver_v2, cfg) = + let (collation_req_v2_receiver, cfg) = IncomingRequest::get_config_receiver(request_protocol_names); config.add_request_response_protocol(cfg); let (available_data_req_receiver, cfg) = @@ -251,5 +253,5 @@ fn build_request_response_protocol_receivers( config.add_request_response_protocol(cfg); let cfg = Protocol::ChunkFetchingV1.get_outbound_only_config(request_protocol_names); config.add_request_response_protocol(cfg); - (collation_req_receiver_v1, collation_req_receiver_v2, available_data_req_receiver) + (collation_req_v1_receiver, collation_req_v2_receiver, available_data_req_receiver) } diff --git a/cumulus/client/relay-chain-minimal-node/src/network.rs b/cumulus/client/relay-chain-minimal-node/src/network.rs index 95785063c1a..7286fab7907 100644 --- a/cumulus/client/relay-chain-minimal-node/src/network.rs +++ b/cumulus/client/relay-chain-minimal-node/src/network.rs @@ -40,7 +40,11 @@ pub(crate) fn build_collator_network( genesis_hash: Hash, best_header: Header, ) -> Result< - (Arc>, NetworkStarter, Box), + ( + Arc>, + NetworkStarter, + Arc, + ), Error, > { let protocol_id = config.protocol_id(); @@ -112,7 +116,7 @@ pub(crate) fn build_collator_network( let network_starter = NetworkStarter::new(network_start_tx); - Ok((network_service, network_starter, Box::new(SyncOracle {}))) + Ok((network_service, network_starter, Arc::new(SyncOracle {}))) } fn adjust_network_config_light_in_peers(config: &mut NetworkConfiguration) { diff --git a/polkadot/node/malus/src/variants/back_garbage_candidate.rs b/polkadot/node/malus/src/variants/back_garbage_candidate.rs index 82475d29142..b939a2151e2 100644 --- a/polkadot/node/malus/src/variants/back_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/back_garbage_candidate.rs @@ -20,14 +20,13 @@ use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use sp_core::traits::SpawnNamed; use crate::{ @@ -63,13 +62,9 @@ impl OverseerGen for BackGarbageCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { let spawner = args.spawner.clone(); diff --git a/polkadot/node/malus/src/variants/common.rs b/polkadot/node/malus/src/variants/common.rs index 011fcc80e37..eb6988f8181 100644 --- a/polkadot/node/malus/src/variants/common.rs +++ b/polkadot/node/malus/src/variants/common.rs @@ -23,10 +23,6 @@ use crate::{ use polkadot_node_core_candidate_validation::find_validation_data; use polkadot_node_primitives::{InvalidCandidate, ValidationResult}; -use polkadot_node_subsystem::{ - messages::{CandidateValidationMessage, ValidationFailed}, - overseer, -}; use polkadot_primitives::{ CandidateCommitments, CandidateDescriptor, CandidateReceipt, PersistedValidationData, diff --git a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs index b3555ba2f5b..7a95bdaead2 100644 --- a/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_finalized_candidates.rs @@ -34,14 +34,13 @@ use futures::channel::oneshot; use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; -use polkadot_node_subsystem::{messages::ApprovalVotingMessage, SpawnGlue}; -use polkadot_node_subsystem_types::{DefaultSubsystemClient, OverseerSignal}; +use polkadot_node_subsystem::SpawnGlue; +use polkadot_node_subsystem_types::{ChainApiBackend, OverseerSignal, RuntimeApiSubsystemClient}; use polkadot_node_subsystem_util::request_candidate_events; use polkadot_primitives::CandidateEvent; use sp_core::traits::SpawnNamed; @@ -237,13 +236,9 @@ impl OverseerGen for DisputeFinalizedCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { gum::info!( diff --git a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs index b9812cbb501..a50fdce16e4 100644 --- a/polkadot/node/malus/src/variants/dispute_valid_candidates.rs +++ b/polkadot/node/malus/src/variants/dispute_valid_candidates.rs @@ -24,14 +24,13 @@ use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use sp_core::traits::SpawnNamed; // Filter wrapping related types. @@ -80,13 +79,9 @@ impl OverseerGen for DisputeValidCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { let spawner = args.spawner.clone(); diff --git a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs index 22b44ddd1dc..739ed40db36 100644 --- a/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs +++ b/polkadot/node/malus/src/variants/suggest_garbage_candidate.rs @@ -25,14 +25,13 @@ use futures::channel::oneshot; use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_primitives::{AvailableData, BlockData, PoV}; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use polkadot_primitives::{CandidateDescriptor, CandidateReceipt}; use polkadot_node_subsystem_util::request_validators; @@ -52,7 +51,7 @@ use crate::{ // Import extra types relevant to the particular // subsystem. -use polkadot_node_subsystem::{messages::CandidateBackingMessage, SpawnGlue}; +use polkadot_node_subsystem::SpawnGlue; use std::sync::Arc; @@ -296,13 +295,9 @@ impl OverseerGen for SuggestGarbageCandidates { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { gum::info!( diff --git a/polkadot/node/malus/src/variants/support_disabled.rs b/polkadot/node/malus/src/variants/support_disabled.rs index e25df56fd64..169c442db25 100644 --- a/polkadot/node/malus/src/variants/support_disabled.rs +++ b/polkadot/node/malus/src/variants/support_disabled.rs @@ -19,14 +19,13 @@ use polkadot_cli::{ service::{ - AuthorityDiscoveryApi, AuxStore, BabeApi, Block, Error, ExtendedOverseerGenArgs, - HeaderBackend, Overseer, OverseerConnector, OverseerGen, OverseerGenArgs, OverseerHandle, - ParachainHost, ProvideRuntimeApi, + AuxStore, Error, ExtendedOverseerGenArgs, Overseer, OverseerConnector, OverseerGen, + OverseerGenArgs, OverseerHandle, }, validator_overseer_builder, Cli, }; use polkadot_node_subsystem::SpawnGlue; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use sp_core::traits::SpawnNamed; use crate::interceptor::*; @@ -50,13 +49,9 @@ impl OverseerGen for SupportDisabled { connector: OverseerConnector, args: OverseerGenArgs<'_, Spawner, RuntimeClient>, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { validator_overseer_builder( diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index 6dcdec07ca8..83a0afc077e 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -92,6 +92,7 @@ pub use chain_spec::{GenericChainSpec, RococoChainSpec, WestendChainSpec}; pub use consensus_common::{Proposal, SelectChain}; use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; use mmr_gadget::MmrGadget; +use polkadot_node_subsystem_types::DefaultSubsystemClient; pub use polkadot_primitives::{Block, BlockId, BlockNumber, CollatorPair, Hash, Id as ParaId}; pub use sc_client_api::{Backend, CallExecutor}; pub use sc_consensus::{BlockImport, LongestChain}; @@ -1081,12 +1082,17 @@ pub fn new_full( None }; + let runtime_client = Arc::new(DefaultSubsystemClient::new( + overseer_client.clone(), + OffchainTransactionPoolFactory::new(transaction_pool.clone()), + )); + let overseer_handle = if let Some(authority_discovery_service) = authority_discovery_service { let (overseer, overseer_handle) = overseer_gen - .generate::( + .generate::>( overseer_connector, OverseerGenArgs { - runtime_client: overseer_client.clone(), + runtime_client, network_service: network.clone(), sync_service: sync_service.clone(), authority_discovery_service, @@ -1099,9 +1105,6 @@ pub fn new_full( overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, - offchain_transaction_pool_factory: OffchainTransactionPoolFactory::new( - transaction_pool.clone(), - ), notification_services, }, ext_overseer_args, diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs index b2b0786bfc2..a8167370464 100644 --- a/polkadot/node/service/src/overseer.rs +++ b/polkadot/node/service/src/overseer.rs @@ -14,10 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use super::{AuthorityDiscoveryApi, Block, Error, Hash, IsParachainNode, Registry}; -use polkadot_node_subsystem_types::DefaultSubsystemClient; +use super::{Block, Error, Hash, IsParachainNode, Registry}; +use polkadot_node_subsystem_types::{ChainApiBackend, RuntimeApiSubsystemClient}; use polkadot_overseer::{DummySubsystem, InitializedOverseerBuilder, SubsystemError}; -use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_core::traits::SpawnNamed; use polkadot_availability_distribution::IncomingRequestReceivers; @@ -40,14 +39,10 @@ use polkadot_overseer::{ }; use parking_lot::Mutex; -use polkadot_primitives::runtime_api::ParachainHost; use sc_authority_discovery::Service as AuthorityDiscoveryService; use sc_client_api::AuxStore; use sc_keystore::LocalKeystore; use sc_network::{NetworkStateInfo, NotificationService}; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; -use sp_consensus_babe::BabeApi; use std::{collections::HashMap, sync::Arc}; pub use polkadot_approval_distribution::ApprovalDistribution as ApprovalDistributionSubsystem; @@ -80,8 +75,6 @@ pub use polkadot_statement_distribution::StatementDistributionSubsystem; /// Arguments passed for overseer construction. pub struct OverseerGenArgs<'a, Spawner, RuntimeClient> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, { /// Runtime client generic, providing the `ProvieRuntimeApi` trait besides others. @@ -89,7 +82,7 @@ where /// Underlying network service implementation. pub network_service: Arc>, /// Underlying syncing service implementation. - pub sync_service: Arc>, + pub sync_service: Arc, /// Underlying authority discovery service. pub authority_discovery_service: AuthorityDiscoveryService, /// Collations request receiver for network protocol v1. @@ -111,8 +104,6 @@ where pub req_protocol_names: ReqProtocolNames, /// `PeerSet` protocol names to protocols mapping. pub peerset_protocol_names: PeerSetProtocolNames, - /// The offchain transaction pool factory. - pub offchain_transaction_pool_factory: OffchainTransactionPoolFactory, /// Notification services for validation/collation protocols. pub notification_services: HashMap>, } @@ -160,7 +151,6 @@ pub fn validator_overseer_builder( overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, - offchain_transaction_pool_factory, notification_services, }: OverseerGenArgs, ExtendedOverseerGenArgs { @@ -180,7 +170,7 @@ pub fn validator_overseer_builder( ) -> Result< InitializedOverseerBuilder< SpawnGlue, - Arc>, + Arc, CandidateValidationSubsystem, PvfCheckerSubsystem, CandidateBackingSubsystem, @@ -190,7 +180,7 @@ pub fn validator_overseer_builder( BitfieldSigningSubsystem, BitfieldDistributionSubsystem, ProvisionerSubsystem, - RuntimeApiSubsystem>, + RuntimeApiSubsystem, AvailabilityStoreSubsystem, NetworkBridgeRxSubsystem< Arc>, @@ -214,8 +204,7 @@ pub fn validator_overseer_builder( Error, > where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { use polkadot_node_subsystem_util::metrics::Metrics; @@ -227,11 +216,6 @@ where let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; - let runtime_api_client = Arc::new(DefaultSubsystemClient::new( - runtime_client.clone(), - offchain_transaction_pool_factory, - )); - let builder = Overseer::builder() .network_bridge_tx(NetworkBridgeTxSubsystem::new( network_service.clone(), @@ -298,7 +282,7 @@ where }) .provisioner(ProvisionerSubsystem::new(Metrics::register(registry)?)) .runtime_api(RuntimeApiSubsystem::new( - runtime_api_client.clone(), + runtime_client.clone(), Metrics::register(registry)?, spawner.clone(), )) @@ -339,7 +323,7 @@ where .activation_external_listeners(Default::default()) .span_per_active_leaf(Default::default()) .active_leaves(Default::default()) - .supports_parachains(runtime_api_client) + .supports_parachains(runtime_client) .metrics(metrics) .spawner(spawner); @@ -367,13 +351,12 @@ pub fn collator_overseer_builder( overseer_message_channel_capacity_override, req_protocol_names, peerset_protocol_names, - offchain_transaction_pool_factory, notification_services, }: OverseerGenArgs, ) -> Result< InitializedOverseerBuilder< SpawnGlue, - Arc>, + Arc, DummySubsystem, DummySubsystem, DummySubsystem, @@ -383,7 +366,7 @@ pub fn collator_overseer_builder( DummySubsystem, DummySubsystem, DummySubsystem, - RuntimeApiSubsystem>, + RuntimeApiSubsystem, DummySubsystem, NetworkBridgeRxSubsystem< Arc>, @@ -407,24 +390,17 @@ pub fn collator_overseer_builder( Error, > where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, Spawner: 'static + SpawnNamed + Clone + Unpin, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, { use polkadot_node_subsystem_util::metrics::Metrics; - let metrics = ::register(registry)?; let notification_sinks = Arc::new(Mutex::new(HashMap::new())); let spawner = SpawnGlue(spawner); let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; - let runtime_api_client = Arc::new(DefaultSubsystemClient::new( - runtime_client.clone(), - offchain_transaction_pool_factory, - )); - let builder = Overseer::builder() .network_bridge_tx(NetworkBridgeTxSubsystem::new( network_service.clone(), @@ -475,7 +451,7 @@ where }) .provisioner(DummySubsystem) .runtime_api(RuntimeApiSubsystem::new( - runtime_api_client.clone(), + runtime_client.clone(), Metrics::register(registry)?, spawner.clone(), )) @@ -490,8 +466,8 @@ where .activation_external_listeners(Default::default()) .span_per_active_leaf(Default::default()) .active_leaves(Default::default()) - .supports_parachains(runtime_api_client) - .metrics(metrics) + .supports_parachains(runtime_client) + .metrics(Metrics::register(registry)?) .spawner(spawner); let builder = if let Some(capacity) = overseer_message_channel_capacity_override { @@ -510,13 +486,9 @@ pub trait OverseerGen { connector: OverseerConnector, args: OverseerGenArgs, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin; // It would be nice to make `create_subsystems` part of this trait, @@ -533,13 +505,9 @@ impl OverseerGen for ValidatorOverseerGen { connector: OverseerConnector, args: OverseerGenArgs, ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { let ext_args = ext_args.ok_or(Error::Overseer(SubsystemError::Context( @@ -561,13 +529,9 @@ impl OverseerGen for CollatorOverseerGen { connector: OverseerConnector, args: OverseerGenArgs, _ext_args: Option, - ) -> Result< - (Overseer, Arc>>, OverseerHandle), - Error, - > + ) -> Result<(Overseer, Arc>, OverseerHandle), Error> where - RuntimeClient: 'static + ProvideRuntimeApi + HeaderBackend + AuxStore, - RuntimeClient::Api: ParachainHost + BabeApi + AuthorityDiscoveryApi, + RuntimeClient: RuntimeApiSubsystemClient + ChainApiBackend + AuxStore + 'static, Spawner: 'static + SpawnNamed + Clone + Unpin, { collator_overseer_builder(args)? diff --git a/polkadot/node/subsystem-types/src/runtime_client.rs b/polkadot/node/subsystem-types/src/runtime_client.rs index 7f618307610..4039fc9127d 100644 --- a/polkadot/node/subsystem-types/src/runtime_client.rs +++ b/polkadot/node/subsystem-types/src/runtime_client.rs @@ -26,13 +26,13 @@ use polkadot_primitives::{ PersistedValidationData, PvfCheckStatement, ScrapedOnChainVotes, SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature, }; -use sc_client_api::HeaderBackend; +use sc_client_api::{AuxStore, HeaderBackend}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_api::{ApiError, ApiExt, ProvideRuntimeApi}; use sp_authority_discovery::AuthorityDiscoveryApi; -use sp_blockchain::Info; +use sp_blockchain::{BlockStatus, Info}; use sp_consensus_babe::{BabeApi, Epoch}; -use sp_runtime::traits::{Header as HeaderT, NumberFor}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::{collections::BTreeMap, sync::Arc}; /// Offers header utilities. @@ -595,3 +595,61 @@ where self.client.runtime_api().approval_voting_params(at) } } + +impl HeaderBackend for DefaultSubsystemClient +where + Client: HeaderBackend, + Block: sp_runtime::traits::Block, +{ + fn header( + &self, + hash: Block::Hash, + ) -> sc_client_api::blockchain::Result> { + self.client.header(hash) + } + + fn info(&self) -> Info { + self.client.info() + } + + fn status(&self, hash: Block::Hash) -> sc_client_api::blockchain::Result { + self.client.status(hash) + } + + fn number( + &self, + hash: Block::Hash, + ) -> sc_client_api::blockchain::Result::Header as HeaderT>::Number>> { + self.client.number(hash) + } + + fn hash( + &self, + number: NumberFor, + ) -> sc_client_api::blockchain::Result> { + self.client.hash(number) + } +} + +impl AuxStore for DefaultSubsystemClient +where + Client: AuxStore, +{ + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >( + &self, + insert: I, + delete: D, + ) -> sp_blockchain::Result<()> { + self.client.insert_aux(insert, delete) + } + + fn get_aux(&self, key: &[u8]) -> sp_blockchain::Result>> { + self.client.get_aux(key) + } +} diff --git a/substrate/utils/wasm-builder/src/prerequisites.rs b/substrate/utils/wasm-builder/src/prerequisites.rs index a601e3210dd..22caf895063 100644 --- a/substrate/utils/wasm-builder/src/prerequisites.rs +++ b/substrate/utils/wasm-builder/src/prerequisites.rs @@ -149,6 +149,14 @@ impl<'a> DummyCrate<'a> { sysroot_cmd.output().ok().and_then(|o| String::from_utf8(o.stdout).ok()) } + fn get_toolchain(&self) -> Option { + let sysroot = self.get_sysroot()?; + Path::new(sysroot.trim()) + .file_name() + .and_then(|s| s.to_str()) + .map(|s| s.to_string()) + } + fn try_build(&self) -> Result<(), Option> { let Ok(result) = self.prepare_command("build").output() else { return Err(None) }; if !result.status.success() { @@ -164,14 +172,15 @@ fn check_wasm_toolchain_installed( let dummy_crate = DummyCrate::new(&cargo_command, RuntimeTarget::Wasm); if let Err(error) = dummy_crate.try_build() { + let toolchain = dummy_crate.get_toolchain().unwrap_or("".to_string()); let basic_error_message = colorize_error_message( - "Rust WASM toolchain is not properly installed; please install it!", + &format!("Rust WASM target for toolchain {toolchain} is not properly installed; please install it!") ); return match error { None => Err(basic_error_message), Some(error) if error.contains("the `wasm32-unknown-unknown` target may not be installed") => { - Err(colorize_error_message("Cannot compile the WASM runtime: the `wasm32-unknown-unknown` target is not installed!\n\ - You can install it with `rustup target add wasm32-unknown-unknown` if you're using `rustup`.")) + Err(colorize_error_message(&format!("Cannot compile the WASM runtime: the `wasm32-unknown-unknown` target is not installed!\n\ + You can install it with `rustup target add wasm32-unknown-unknown --toolchain {toolchain}` if you're using `rustup`."))) }, // Apparently this can happen when we're running on a non Tier 1 platform. Some(ref error) if error.contains("linker `rust-lld` not found") => @@ -193,9 +202,10 @@ fn check_wasm_toolchain_installed( let src_path = Path::new(sysroot.trim()).join("lib").join("rustlib").join("src").join("rust"); if !src_path.exists() { + let toolchain = dummy_crate.get_toolchain().unwrap_or("".to_string()); return Err(colorize_error_message( - "Cannot compile the WASM runtime: no standard library sources found!\n\ - You can install them with `rustup component add rust-src` if you're using `rustup`.", + &format!("Cannot compile the WASM runtime: no standard library sources found at {}!\n\ + You can install them with `rustup component add rust-src --toolchain {toolchain}` if you're using `rustup`.", src_path.display()), )) } } -- GitLab From 12ce4f7d049b70918cadb658de4bbe8eb6ffc670 Mon Sep 17 00:00:00 2001 From: Liam Aharon Date: Wed, 28 Feb 2024 18:32:02 +1100 Subject: [PATCH 268/283] Runtime Upgrade ref docs and Single Block Migration example pallet (#1554) Closes https://github.com/paritytech/polkadot-sdk-docs/issues/55 - Changes 'current storage version' terminology to less ambiguous 'in-code storage version' (suggestion by @ggwpez) - Adds a new example pallet `pallet-example-single-block-migrations` - Adds a new reference doc to replace https://docs.substrate.io/maintain/runtime-upgrades/ (temporarily living in the pallet while we wait for developer hub PR to merge) - Adds documentation for the `storage_alias` macro - Improves `trait Hooks` docs - Improves `trait GetStorageVersion` docs - Update the suggested patterns for using `VersionedMigration`, so that version unchecked migrations are never exported - Prevents accidental usage of version unchecked migrations in runtimes https://github.com/paritytech/substrate/pull/14421#discussion_r1255467895 - Unversioned migration code is kept inside `mod version_unchecked`, versioned code is kept in `pub mod versioned` - It is necessary to use modules to limit visibility because the inner migration must be `pub`. See https://github.com/rust-lang/rust/issues/30905 and https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40 for more. ### todo - [x] move to reference docs to proper place within sdk-docs (now that https://github.com/paritytech/polkadot-sdk/pull/2102 is merged) - [x] prdoc --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Juan Co-authored-by: Oliver Tale-Yazdi Co-authored-by: command-bot <> Co-authored-by: gupnik --- Cargo.lock | 26 ++ Cargo.toml | 1 + cumulus/pallets/collator-selection/src/lib.rs | 2 +- .../collator-selection/src/migration.rs | 10 +- .../pallets/parachain-system/src/migration.rs | 2 +- cumulus/pallets/xcmp-queue/src/migration.rs | 2 +- .../pallets/collective-content/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/lib.rs | 14 +- .../assets/asset-hub-westend/src/lib.rs | 6 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 4 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 +- docs/sdk/Cargo.toml | 7 +- .../reference_docs/frame_runtime_migration.rs | 9 - .../frame_runtime_upgrades_and_migrations.rs | 138 +++++++++++ docs/sdk/src/reference_docs/mod.rs | 5 +- .../node/service/src/parachains_db/upgrade.rs | 2 +- .../common/src/assigned_slots/migration.rs | 12 +- .../runtime/common/src/assigned_slots/mod.rs | 2 +- .../runtime/common/src/crowdloan/migration.rs | 4 +- polkadot/runtime/common/src/crowdloan/mod.rs | 2 +- .../runtime/common/src/paras_registrar/mod.rs | 2 +- .../runtime/parachains/src/configuration.rs | 2 +- polkadot/runtime/parachains/src/disputes.rs | 2 +- .../parachains/src/session_info/migration.rs | 2 +- prdoc/pr_1554.prdoc | 14 ++ substrate/client/executor/src/executor.rs | 14 +- substrate/frame/alliance/src/migration.rs | 8 +- substrate/frame/assets/src/lib.rs | 2 +- substrate/frame/assets/src/migration.rs | 20 +- substrate/frame/balances/src/lib.rs | 2 +- substrate/frame/balances/src/migration.rs | 8 +- substrate/frame/collective/src/lib.rs | 2 +- substrate/frame/contracts/src/lib.rs | 2 +- substrate/frame/contracts/src/migration.rs | 20 +- .../frame/contracts/src/migration/v09.rs | 14 +- .../frame/contracts/src/migration/v10.rs | 24 +- .../frame/contracts/src/migration/v11.rs | 12 +- .../frame/contracts/src/migration/v12.rs | 40 ++-- .../frame/contracts/src/migration/v13.rs | 10 +- .../frame/contracts/src/migration/v14.rs | 20 +- .../frame/contracts/src/migration/v15.rs | 16 +- substrate/frame/democracy/src/lib.rs | 2 +- .../election-provider-multi-phase/src/lib.rs | 2 +- .../src/migrations.rs | 4 +- substrate/frame/elections-phragmen/src/lib.rs | 2 +- substrate/frame/examples/Cargo.toml | 3 + .../single-block-migrations/Cargo.toml | 61 +++++ .../single-block-migrations/src/lib.rs | 213 +++++++++++++++++ .../src/migrations/mod.rs | 20 ++ .../src/migrations/v1.rs | 222 ++++++++++++++++++ .../single-block-migrations/src/mock.rs | 69 ++++++ substrate/frame/examples/src/lib.rs | 3 + .../frame/fast-unstake/src/migrations.rs | 4 +- substrate/frame/grandpa/src/lib.rs | 2 +- substrate/frame/im-online/src/lib.rs | 2 +- substrate/frame/im-online/src/migration.rs | 2 +- substrate/frame/membership/src/lib.rs | 2 +- substrate/frame/multisig/src/lib.rs | 2 +- substrate/frame/multisig/src/migrations.rs | 2 +- substrate/frame/nfts/src/lib.rs | 2 +- substrate/frame/nfts/src/migration.rs | 16 +- substrate/frame/nomination-pools/src/lib.rs | 2 +- .../frame/nomination-pools/src/migration.rs | 28 +-- substrate/frame/preimage/src/lib.rs | 2 +- substrate/frame/referenda/src/lib.rs | 2 +- substrate/frame/referenda/src/migration.rs | 16 +- substrate/frame/scheduler/src/lib.rs | 2 +- substrate/frame/session/src/historical/mod.rs | 2 +- substrate/frame/session/src/lib.rs | 2 +- substrate/frame/society/src/migrations.rs | 54 ++--- substrate/frame/society/src/tests.rs | 44 ++-- substrate/frame/staking/src/migrations.rs | 12 +- substrate/frame/staking/src/pallet/mod.rs | 2 +- substrate/frame/support/procedural/src/lib.rs | 38 ++- .../procedural/src/pallet/expand/hooks.rs | 22 +- .../src/pallet/expand/pallet_struct.rs | 6 +- .../src/pallet/parse/pallet_struct.rs | 2 +- substrate/frame/support/src/lib.rs | 4 +- substrate/frame/support/src/migrations.rs | 55 +++-- substrate/frame/support/src/traits/hooks.rs | 70 +++--- .../frame/support/src/traits/metadata.rs | 71 ++++-- .../support/test/tests/construct_runtime.rs | 2 +- substrate/frame/support/test/tests/pallet.rs | 22 +- .../compare_unset_storage_version.rs | 2 +- .../compare_unset_storage_version.stderr | 2 +- substrate/frame/system/src/lib.rs | 2 +- substrate/frame/tips/src/lib.rs | 2 +- 87 files changed, 1223 insertions(+), 370 deletions(-) delete mode 100644 docs/sdk/src/reference_docs/frame_runtime_migration.rs create mode 100644 docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs create mode 100644 prdoc/pr_1554.prdoc create mode 100644 substrate/frame/examples/single-block-migrations/Cargo.toml create mode 100644 substrate/frame/examples/single-block-migrations/src/lib.rs create mode 100644 substrate/frame/examples/single-block-migrations/src/migrations/mod.rs create mode 100644 substrate/frame/examples/single-block-migrations/src/migrations/v1.rs create mode 100644 substrate/frame/examples/single-block-migrations/src/mock.rs diff --git a/Cargo.lock b/Cargo.lock index 27ba43780ed..026786378d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9965,6 +9965,26 @@ dependencies = [ "sp-std 14.0.0", ] +[[package]] +name = "pallet-example-single-block-migrations" +version = "0.0.1" +dependencies = [ + "docify", + "frame-executive", + "frame-support", + "frame-system", + "frame-try-runtime", + "log", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 14.0.0", + "sp-version", +] + [[package]] name = "pallet-example-split" version = "10.0.0" @@ -10006,6 +10026,7 @@ dependencies = [ "pallet-example-frame-crate", "pallet-example-kitchensink", "pallet-example-offchain-worker", + "pallet-example-single-block-migrations", "pallet-example-split", "pallet-example-tasks", ] @@ -13385,6 +13406,8 @@ dependencies = [ "cumulus-pallet-parachain-system", "docify", "frame", + "frame-executive", + "frame-support", "frame-system", "kitchensink-runtime", "pallet-aura", @@ -13393,9 +13416,11 @@ dependencies = [ "pallet-collective", "pallet-default-config-example", "pallet-democracy", + "pallet-example-single-block-migrations", "pallet-examples", "pallet-multisig", "pallet-proxy", + "pallet-scheduler", "pallet-timestamp", "pallet-transaction-payment", "pallet-utility", @@ -13418,6 +13443,7 @@ dependencies = [ "sp-io", "sp-keyring", "sp-runtime", + "sp-version", "staging-chain-spec-builder", "staging-node-cli", "staging-parachain-info", diff --git a/Cargo.toml b/Cargo.toml index 1d27cfe9539..654367cc1e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -337,6 +337,7 @@ members = [ "substrate/frame/examples/frame-crate", "substrate/frame/examples/kitchensink", "substrate/frame/examples/offchain-worker", + "substrate/frame/examples/single-block-migrations", "substrate/frame/examples/split", "substrate/frame/examples/tasks", "substrate/frame/executive", diff --git a/cumulus/pallets/collator-selection/src/lib.rs b/cumulus/pallets/collator-selection/src/lib.rs index 7449f4d68c7..fb4c4a445df 100644 --- a/cumulus/pallets/collator-selection/src/lib.rs +++ b/cumulus/pallets/collator-selection/src/lib.rs @@ -118,7 +118,7 @@ pub mod pallet { use sp_staking::SessionIndex; use sp_std::vec::Vec; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); type BalanceOf = diff --git a/cumulus/pallets/collator-selection/src/migration.rs b/cumulus/pallets/collator-selection/src/migration.rs index 58b4cc5b06a..f384981dbae 100644 --- a/cumulus/pallets/collator-selection/src/migration.rs +++ b/cumulus/pallets/collator-selection/src/migration.rs @@ -31,8 +31,8 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 0 { + let on_chain_version = Pallet::::on_chain_storage_version(); + if on_chain_version == 0 { let invulnerables_len = Invulnerables::::get().to_vec().len(); >::mutate(|invulnerables| { invulnerables.sort(); @@ -45,7 +45,7 @@ pub mod v1 { invulnerables_len, ); // Similar complexity to `set_invulnerables` (put storage value) - // Plus 1 read for length, 1 read for `onchain_version`, 1 write to put version + // Plus 1 read for length, 1 read for `on_chain_version`, 1 write to put version T::WeightInfo::set_invulnerables(invulnerables_len as u32) .saturating_add(T::DbWeight::get().reads_writes(2, 1)) } else { @@ -83,8 +83,8 @@ pub mod v1 { "after migration, there should be the same number of invulnerables" ); - let onchain_version = Pallet::::on_chain_storage_version(); - frame_support::ensure!(onchain_version >= 1, "must_upgrade"); + let on_chain_version = Pallet::::on_chain_storage_version(); + frame_support::ensure!(on_chain_version >= 1, "must_upgrade"); Ok(()) } diff --git a/cumulus/pallets/parachain-system/src/migration.rs b/cumulus/pallets/parachain-system/src/migration.rs index a92f85b9cd4..30106aceab5 100644 --- a/cumulus/pallets/parachain-system/src/migration.rs +++ b/cumulus/pallets/parachain-system/src/migration.rs @@ -21,7 +21,7 @@ use frame_support::{ weights::Weight, }; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); /// Migrates the pallet storage to the most recent version. diff --git a/cumulus/pallets/xcmp-queue/src/migration.rs b/cumulus/pallets/xcmp-queue/src/migration.rs index 6c86c3011d2..c7fa61a3e3f 100644 --- a/cumulus/pallets/xcmp-queue/src/migration.rs +++ b/cumulus/pallets/xcmp-queue/src/migration.rs @@ -24,7 +24,7 @@ use frame_support::{ weights::{constants::WEIGHT_REF_TIME_PER_MILLIS, Weight}, }; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); pub const LOG: &str = "runtime::xcmp-queue-migration"; diff --git a/cumulus/parachains/pallets/collective-content/src/lib.rs b/cumulus/parachains/pallets/collective-content/src/lib.rs index 7a685858acc..b1c960ad6a0 100644 --- a/cumulus/parachains/pallets/collective-content/src/lib.rs +++ b/cumulus/parachains/pallets/collective-content/src/lib.rs @@ -59,7 +59,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; use sp_runtime::{traits::BadOrigin, Saturating}; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); #[pallet::pallet] diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 81bb66a56a2..6791dc4064e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -986,37 +986,37 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if Multisig::on_chain_storage_version() == StorageVersion::new(0) { - Multisig::current_storage_version().put::(); + Multisig::in_code_storage_version().put::(); writes.saturating_inc(); } if Assets::on_chain_storage_version() == StorageVersion::new(0) { - Assets::current_storage_version().put::(); + Assets::in_code_storage_version().put::(); writes.saturating_inc(); } if Uniques::on_chain_storage_version() == StorageVersion::new(0) { - Uniques::current_storage_version().put::(); + Uniques::in_code_storage_version().put::(); writes.saturating_inc(); } if Nfts::on_chain_storage_version() == StorageVersion::new(0) { - Nfts::current_storage_version().put::(); + Nfts::in_code_storage_version().put::(); writes.saturating_inc(); } if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) { - ForeignAssets::current_storage_version().put::(); + ForeignAssets::in_code_storage_version().put::(); writes.saturating_inc(); } if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) { - PoolAssets::current_storage_version().put::(); + PoolAssets::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 3f58c679eee..5352eeb1a1b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1037,17 +1037,17 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if ForeignAssets::on_chain_storage_version() == StorageVersion::new(0) { - ForeignAssets::current_storage_version().put::(); + ForeignAssets::in_code_storage_version().put::(); writes.saturating_inc(); } if PoolAssets::on_chain_storage_version() == StorageVersion::new(0) { - PoolAssets::current_storage_version().put::(); + PoolAssets::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index f576776696c..db1dfbd45d6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -168,12 +168,12 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if Balances::on_chain_storage_version() == StorageVersion::new(0) { - Balances::current_storage_version().put::(); + Balances::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index bd42a33370d..1c8c9aa2075 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -142,12 +142,12 @@ impl frame_support::traits::OnRuntimeUpgrade for InitStorageVersions { let mut writes = 0; if PolkadotXcm::on_chain_storage_version() == StorageVersion::new(0) { - PolkadotXcm::current_storage_version().put::(); + PolkadotXcm::in_code_storage_version().put::(); writes.saturating_inc(); } if Balances::on_chain_storage_version() == StorageVersion::new(0) { - Balances::current_storage_version().put::(); + Balances::in_code_storage_version().put::(); writes.saturating_inc(); } diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index 576a81834f8..b1b60a2d77d 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -33,6 +33,10 @@ node-cli = { package = "staging-node-cli", path = "../../substrate/bin/node/cli" kitchensink-runtime = { path = "../../substrate/bin/node/runtime" } chain-spec-builder = { package = "staging-chain-spec-builder", path = "../../substrate/bin/utils/chain-spec-builder" } subkey = { path = "../../substrate/bin/utils/subkey" } +frame-system = { path = "../../substrate/frame/system", default-features = false } +frame-support = { path = "../../substrate/frame/support", default-features = false } +frame-executive = { path = "../../substrate/frame/executive", default-features = false } +pallet-example-single-block-migrations = { path = "../../substrate/frame/examples/single-block-migrations" } # Substrate sc-network = { path = "../../substrate/client/network" } @@ -66,7 +70,7 @@ pallet-proxy = { path = "../../substrate/frame/proxy" } pallet-authorship = { path = "../../substrate/frame/authorship" } pallet-collective = { path = "../../substrate/frame/collective" } pallet-democracy = { path = "../../substrate/frame/democracy" } -frame-system = { path = "../../substrate/frame/system" } +pallet-scheduler = { path = "../../substrate/frame/scheduler" } # Primitives sp-io = { path = "../../substrate/primitives/io" } @@ -74,6 +78,7 @@ sp-api = { path = "../../substrate/primitives/api" } sp-core = { path = "../../substrate/primitives/core" } sp-keyring = { path = "../../substrate/primitives/keyring" } sp-runtime = { path = "../../substrate/primitives/runtime" } +sp-version = { path = "../../substrate/primitives/version" } # XCM xcm = { package = "staging-xcm", path = "../../polkadot/xcm" } diff --git a/docs/sdk/src/reference_docs/frame_runtime_migration.rs b/docs/sdk/src/reference_docs/frame_runtime_migration.rs deleted file mode 100644 index 0616ccbb6f5..00000000000 --- a/docs/sdk/src/reference_docs/frame_runtime_migration.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! # Runtime Runtime Upgrade and Testing -//! -//! -//! Notes: -//! -//! - Flow of things, when does `on_runtime_upgrade` get called. Link to to `Hooks` and its diagram -//! as source of truth. -//! - Data migration and when it is needed. -//! - Look into the pba-lecture. diff --git a/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs b/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs new file mode 100644 index 00000000000..7d870b43221 --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_runtime_upgrades_and_migrations.rs @@ -0,0 +1,138 @@ +//! # Runtime Upgrades +//! +//! At their core, blockchain logic consists of +//! +//! 1. on-chain state and +//! 2. a state transition function +//! +//! In Substrate-based blockchains, state transition functions are referred to as +//! [runtimes](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/blockchain_state_machines/index.html). +//! +//! Traditionally, before Substrate, upgrading state transition functions required node +//! operators to download new software and restart their nodes in a process called +//! [forking](https://en.wikipedia.org/wiki/Fork_(blockchain)). +//! +//! Substrate-based blockchains do not require forking, and instead upgrade runtimes +//! in a process called "Runtime Upgrades". +//! +//! Forkless runtime upgrades are a defining feature of the Substrate framework. Updating the +//! runtime logic without forking the code base enables your blockchain to seemlessly evolve +//! over time in a deterministic, rules-based manner. It also removes ambiguity for node operators +//! and other participants in the network about what is the canonical runtime. +//! +//! This capability is possible due to the runtime of a blockchain existing in on-chain storage. +//! +//! ## Performing a Runtime Upgrade +//! +//! To upgrade a runtime, an [`Origin`](frame_system::RawOrigin) with the necesarry permissions +//! (usually via governance) changes the `:code` storage. Usually, this is performed via a call to +//! [`set_code`] (or [`set_code_without_checks`]) with the desired new runtime blob, scheduled +//! using [`pallet_scheduler`]. +//! +//! Prior to building the new runtime, don't forget to update the +//! [`RuntimeVersion`](sp_version::RuntimeVersion). +//! +//! # Migrations +//! +//! It is often desirable to define logic to execute immediately after runtime upgrades (see +//! [this diagram](frame::traits::Hooks)). +//! +//! Self-contained pieces of logic that execute after a runtime upgrade are called "Migrations". +//! +//! The typical use case of a migration is to 'migrate' pallet storage from one layout to another, +//! for example when the encoding of a storage item is changed. However, they can also execute +//! arbitary logic such as: +//! +//! - Calling arbitrary pallet methods +//! - Mutating arbitrary on-chain state +//! - Cleaning up some old storage items that are no longer needed +//! +//! ## Single Block Migrations +//! +//! - Execute immediately and entirely at the beginning of the block following +//! a runtime upgrade. +//! - Are suitable for migrations which are guaranteed to not exceed the block weight. +//! - Are simply implementations of [`OnRuntimeUpgrade`]. +//! +//! To learn best practices for writing single block pallet storage migrations, see the +//! [Single Block Migration Example Pallet](pallet_example_single_block_migrations). +//! +//! ### Scheduling the Single Block Migrations to Run Next Runtime Upgrade +//! +//! Schedule migrations to run next runtime upgrade passing them as a generic parameter to your +//! [`Executive`](frame_executive) pallet: +//! +//! ```ignore +//! /// Tuple of migrations (structs that implement `OnRuntimeUpgrade`) +//! type Migrations = ( +//! pallet_example_storage_migration::migrations::v1::versioned::MigrateV0ToV1, +//! MyCustomMigration, +//! // ...more migrations here +//! ); +//! pub type Executive = frame_executive::Executive< +//! Runtime, +//! Block, +//! frame_system::ChainContext, +//! Runtime, +//! AllPalletsWithSystem, +//! Migrations, // <-- pass your migrations to Executive here +//! >; +//! ``` +//! +//! ### Ensuring Single Block Migration Safety +//! +//! "My migration unit tests pass, so it should be safe to deploy right?" +//! +//! No! Unit tests execute the migration in a very simple test environment, and cannot account +//! for the complexities of a real runtime or real on-chain state. +//! +//! Prior to deploying migrations, it is critical to perform additional checks to ensure that when +//! run in our real runtime they will not brick the chain due to: +//! - Panicing +//! - Touching too many storage keys and resulting in an excessively large PoV +//! - Taking too long to execute +//! +//! [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) has a sub-command +//! [`on-runtime-upgrade`](https://paritytech.github.io/try-runtime-cli/try_runtime_core/commands/enum.Action.html#variant.OnRuntimeUpgrade) +//! which is designed to help with exactly this. +//! +//! Developers MUST run this command before deploying migrations to ensure they will not +//! inadvertently result in a bricked chain. +//! +//! It is recommended to run as part of your CI pipeline. See the +//! [polkadot-sdk check-runtime-migration job](https://github.com/paritytech/polkadot-sdk/blob/4a293bc5a25be637c06ce950a34490706597615b/.gitlab/pipeline/check.yml#L103-L124) +//! for an example of how to configure this. +//! +//! ### Note on the Manipulability of PoV Size and Execution Time +//! +//! While [`try-runtime-cli`](https://github.com/paritytech/try-runtime-cli) can help ensure with +//! very high certainty that a migration will succeed given **existing** on-chain state, it cannot +//! prevent a malicious actor from manipulating state in a way that will cause the migration to take +//! longer or produce a PoV much larger than previously measured. +//! +//! Therefore, it is important to write migrations in such a way that the execution time or PoV size +//! it adds to the block cannot be easily manipulated. e.g., do not iterate over storage that can +//! quickly or cheaply be bloated. +//! +//! If writing your migration in such a way is not possible, a multi block migration should be used +//! instead. +//! +//! ### Other useful tools +//! +//! [`Chopsticks`](https://github.com/AcalaNetwork/chopsticks) is another tool in the Substrate +//! ecosystem which developers may find useful to use in addition to `try-runtime-cli` when testing +//! their single block migrations. +//! +//! ## Multi Block Migrations +//! +//! Safely and easily execute long-running migrations across multiple blocks. +//! +//! Suitable for migrations which could use arbitrary amounts of block weight. +//! +//! TODO: Link to multi block migration example/s once PR is merged (). +//! +//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion +//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade +//! [`StorageVersion`]: frame_support::traits::StorageVersion +//! [`set_code`]: frame_system::Call::set_code +//! [`set_code_without_checks`]: frame_system::Call::set_code_without_checks diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index 760bb442c16..b2c751420ce 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -92,9 +92,8 @@ pub mod cli; // TODO: @JoshOrndorff @kianenigma https://github.com/paritytech/polkadot-sdk-docs/issues/54 pub mod consensus_swapping; -/// Learn about all the advance ways to test your coordinate a rutnime upgrade and data migration. -// TODO: @liamaharon https://github.com/paritytech/polkadot-sdk-docs/issues/55 -pub mod frame_runtime_migration; +/// Learn about Runtime Upgrades and best practices for writing Migrations. +pub mod frame_runtime_upgrades_and_migrations; /// Learn about light nodes, how they function, and how Substrate-based chains come /// light-node-first out of the box. diff --git a/polkadot/node/service/src/parachains_db/upgrade.rs b/polkadot/node/service/src/parachains_db/upgrade.rs index d22eebb5c8d..2eceb391b15 100644 --- a/polkadot/node/service/src/parachains_db/upgrade.rs +++ b/polkadot/node/service/src/parachains_db/upgrade.rs @@ -93,7 +93,7 @@ pub(crate) fn try_upgrade_db( } /// Try upgrading parachain's database to the next version. -/// If successfull, it returns the current version. +/// If successful, it returns the current version. pub(crate) fn try_upgrade_db_to_next_version( db_path: &Path, db_kind: DatabaseKind, diff --git a/polkadot/runtime/common/src/assigned_slots/migration.rs b/polkadot/runtime/common/src/assigned_slots/migration.rs index ba3108c0aa3..def6bad692a 100644 --- a/polkadot/runtime/common/src/assigned_slots/migration.rs +++ b/polkadot/runtime/common/src/assigned_slots/migration.rs @@ -29,14 +29,14 @@ pub mod v1 { impl OnRuntimeUpgrade for VersionUncheckedMigrateToV1 { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - let onchain_version = Pallet::::on_chain_storage_version(); - ensure!(onchain_version < 1, "assigned_slots::MigrateToV1 migration can be deleted"); + let on_chain_version = Pallet::::on_chain_storage_version(); + ensure!(on_chain_version < 1, "assigned_slots::MigrateToV1 migration can be deleted"); Ok(Default::default()) } fn on_runtime_upgrade() -> frame_support::weights::Weight { - let onchain_version = Pallet::::on_chain_storage_version(); - if onchain_version < 1 { + let on_chain_version = Pallet::::on_chain_storage_version(); + if on_chain_version < 1 { const MAX_PERMANENT_SLOTS: u32 = 100; const MAX_TEMPORARY_SLOTS: u32 = 100; @@ -52,8 +52,8 @@ pub mod v1 { #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { - let onchain_version = Pallet::::on_chain_storage_version(); - ensure!(onchain_version == 1, "assigned_slots::MigrateToV1 needs to be run"); + let on_chain_version = Pallet::::on_chain_storage_version(); + ensure!(on_chain_version == 1, "assigned_slots::MigrateToV1 needs to be run"); assert_eq!(>::get(), 100); assert_eq!(>::get(), 100); Ok(()) diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs index 3419e3497f7..4f032f4dfa3 100644 --- a/polkadot/runtime/common/src/assigned_slots/mod.rs +++ b/polkadot/runtime/common/src/assigned_slots/mod.rs @@ -107,7 +107,7 @@ type LeasePeriodOf = <::Leaser as Leaser>>::Le pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/polkadot/runtime/common/src/crowdloan/migration.rs b/polkadot/runtime/common/src/crowdloan/migration.rs index 5133c14ada9..3afd6b3fbc9 100644 --- a/polkadot/runtime/common/src/crowdloan/migration.rs +++ b/polkadot/runtime/common/src/crowdloan/migration.rs @@ -24,9 +24,9 @@ use frame_support::{ pub struct MigrateToTrackInactiveV2(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToTrackInactiveV2 { fn on_runtime_upgrade() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 1 { + if on_chain_version == 1 { let mut translated = 0u64; for item in Funds::::iter_values() { let b = diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs index 7d1b892dfa7..35d075f2ff6 100644 --- a/polkadot/runtime/common/src/crowdloan/mod.rs +++ b/polkadot/runtime/common/src/crowdloan/mod.rs @@ -180,7 +180,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::{ensure_root, ensure_signed, pallet_prelude::*}; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); #[pallet::pallet] diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs index 5450c4309e4..4541b88ec6f 100644 --- a/polkadot/runtime/common/src/paras_registrar/mod.rs +++ b/polkadot/runtime/common/src/paras_registrar/mod.rs @@ -106,7 +106,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index 7cc5b31fc8f..b0e9d03df88 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -505,7 +505,7 @@ impl WeightInfo for TestWeightInfo { pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. /// /// v0-v1: /// v1-v2: diff --git a/polkadot/runtime/parachains/src/disputes.rs b/polkadot/runtime/parachains/src/disputes.rs index c2383dad305..da95b060c14 100644 --- a/polkadot/runtime/parachains/src/disputes.rs +++ b/polkadot/runtime/parachains/src/disputes.rs @@ -379,7 +379,7 @@ pub mod pallet { type WeightInfo: WeightInfo; } - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/polkadot/runtime/parachains/src/session_info/migration.rs b/polkadot/runtime/parachains/src/session_info/migration.rs index 228c1e3bb25..ea6f81834b5 100644 --- a/polkadot/runtime/parachains/src/session_info/migration.rs +++ b/polkadot/runtime/parachains/src/session_info/migration.rs @@ -18,5 +18,5 @@ use frame_support::traits::StorageVersion; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); diff --git a/prdoc/pr_1554.prdoc b/prdoc/pr_1554.prdoc new file mode 100644 index 00000000000..bfce7c5edaf --- /dev/null +++ b/prdoc/pr_1554.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: Runtime Upgrade ref docs and Single Block Migration example pallet + +doc: + - audience: Runtime Dev + description: | + `frame_support::traits::GetStorageVersion::current_storage_version` has been renamed `frame_support::traits::GetStorageVersion::in_code_storage_version`. + A simple find-replace is sufficient to handle this change. + +crates: + - name: "frame-support" + diff --git a/substrate/client/executor/src/executor.rs b/substrate/client/executor/src/executor.rs index 499bb704b16..d56a3b389ef 100644 --- a/substrate/client/executor/src/executor.rs +++ b/substrate/client/executor/src/executor.rs @@ -518,7 +518,7 @@ where runtime_code, ext, heap_alloc_strategy, - |_, mut instance, _onchain_version, mut ext| { + |_, mut instance, _on_chain_version, mut ext| { with_externalities_safe(&mut **ext, move || instance.call_export(method, data)) }, ); @@ -682,18 +682,18 @@ impl CodeExecutor for NativeElseWasmExecut runtime_code, ext, heap_alloc_strategy, - |_, mut instance, onchain_version, mut ext| { - let onchain_version = - onchain_version.ok_or_else(|| Error::ApiError("Unknown version".into()))?; + |_, mut instance, on_chain_version, mut ext| { + let on_chain_version = + on_chain_version.ok_or_else(|| Error::ApiError("Unknown version".into()))?; let can_call_with = - onchain_version.can_call_with(&self.native_version.runtime_version); + on_chain_version.can_call_with(&self.native_version.runtime_version); if use_native && can_call_with { tracing::trace!( target: "executor", native = %self.native_version.runtime_version, - chain = %onchain_version, + chain = %on_chain_version, "Request for native execution succeeded", ); @@ -705,7 +705,7 @@ impl CodeExecutor for NativeElseWasmExecut tracing::trace!( target: "executor", native = %self.native_version.runtime_version, - chain = %onchain_version, + chain = %on_chain_version, "Request for native execution failed", ); } diff --git a/substrate/frame/alliance/src/migration.rs b/substrate/frame/alliance/src/migration.rs index e3a44a7887e..432f09a16f4 100644 --- a/substrate/frame/alliance/src/migration.rs +++ b/substrate/frame/alliance/src/migration.rs @@ -19,19 +19,19 @@ use crate::{Config, Pallet, Weight, LOG_TARGET}; use frame_support::{pallet_prelude::*, storage::migration, traits::OnRuntimeUpgrade}; use log; -/// The current storage version. +/// The in-code storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); /// Wrapper for all migrations of this pallet. pub fn migrate, I: 'static>() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); let mut weight: Weight = Weight::zero(); - if onchain_version < 1 { + if on_chain_version < 1 { weight = weight.saturating_add(v0_to_v1::migrate::()); } - if onchain_version < 2 { + if on_chain_version < 2 { weight = weight.saturating_add(v1_to_v2::migrate::()); } diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs index cafe7bb1a3b..60316f8cdcf 100644 --- a/substrate/frame/assets/src/lib.rs +++ b/substrate/frame/assets/src/lib.rs @@ -208,7 +208,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/assets/src/migration.rs b/substrate/frame/assets/src/migration.rs index ff0ffbff0d3..dd7c12293e8 100644 --- a/substrate/frame/assets/src/migration.rs +++ b/substrate/frame/assets/src/migration.rs @@ -67,9 +67,9 @@ pub mod v1 { pub struct MigrateToV1(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 0 && current_version == 1 { + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); + if on_chain_version == 0 && in_code_version == 1 { let mut translated = 0u64; Asset::::translate::< OldAssetDetails>, @@ -78,12 +78,12 @@ pub mod v1 { translated.saturating_inc(); Some(old_value.migrate_to_v1()) }); - current_version.put::>(); + in_code_version.put::>(); log::info!( target: LOG_TARGET, "Upgraded {} pools, storage to version {:?}", translated, - current_version + in_code_version ); T::DbWeight::get().reads_writes(translated + 1, translated + 1) } else { @@ -116,13 +116,13 @@ pub mod v1 { "the asset count before and after the migration should be the same" ); - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - frame_support::ensure!(current_version == 1, "must_upgrade"); + frame_support::ensure!(in_code_version == 1, "must_upgrade"); ensure!( - current_version == onchain_version, - "after migration, the current_version and onchain_version should be the same" + in_code_version == on_chain_version, + "after migration, the in_code_version and on_chain_version should be the same" ); Asset::::iter().try_for_each(|(_id, asset)| -> Result<(), TryRuntimeError> { diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs index 7dd087eabd6..e87aa6f9311 100644 --- a/substrate/frame/balances/src/lib.rs +++ b/substrate/frame/balances/src/lib.rs @@ -320,7 +320,7 @@ pub mod pallet { type MaxFreezes: Get; } - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: frame_support::traits::StorageVersion = frame_support::traits::StorageVersion::new(1); diff --git a/substrate/frame/balances/src/migration.rs b/substrate/frame/balances/src/migration.rs index ba6819ec6e8..38d9c07ff7e 100644 --- a/substrate/frame/balances/src/migration.rs +++ b/substrate/frame/balances/src/migration.rs @@ -22,9 +22,9 @@ use frame_support::{ }; fn migrate_v0_to_v1, I: 'static>(accounts: &[T::AccountId]) -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 0 { + if on_chain_version == 0 { let total = accounts .iter() .map(|a| Pallet::::total_balance(a)) @@ -76,9 +76,9 @@ impl, A: Get>, I: 'static> OnRuntimeUpgrade pub struct ResetInactive(PhantomData<(T, I)>); impl, I: 'static> OnRuntimeUpgrade for ResetInactive { fn on_runtime_upgrade() -> Weight { - let onchain_version = Pallet::::on_chain_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); - if onchain_version == 1 { + if on_chain_version == 1 { // Remove the old `StorageVersion` type. frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix( Pallet::::name().as_bytes(), diff --git a/substrate/frame/collective/src/lib.rs b/substrate/frame/collective/src/lib.rs index c084784e0a9..dd481b53681 100644 --- a/substrate/frame/collective/src/lib.rs +++ b/substrate/frame/collective/src/lib.rs @@ -176,7 +176,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs index d8939ee88ba..32d789a458f 100644 --- a/substrate/frame/contracts/src/lib.rs +++ b/substrate/frame/contracts/src/lib.rs @@ -234,7 +234,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; use sp_runtime::Perbill; - /// The current storage version. + /// The in-code storage version. pub(crate) const STORAGE_VERSION: StorageVersion = StorageVersion::new(15); #[pallet::pallet] diff --git a/substrate/frame/contracts/src/migration.rs b/substrate/frame/contracts/src/migration.rs index 6d61cb6b1e1..f30ae1ebfad 100644 --- a/substrate/frame/contracts/src/migration.rs +++ b/substrate/frame/contracts/src/migration.rs @@ -263,10 +263,10 @@ impl Migration { impl OnRuntimeUpgrade for Migration { fn on_runtime_upgrade() -> Weight { let name = >::name(); - let current_version = >::current_storage_version(); + let in_code_version = >::in_code_storage_version(); let on_chain_version = >::on_chain_storage_version(); - if on_chain_version == current_version { + if on_chain_version == in_code_version { log::warn!( target: LOG_TARGET, "{name}: No Migration performed storage_version = latest_version = {:?}", @@ -289,7 +289,7 @@ impl OnRuntimeUpgrade for Migration OnRuntimeUpgrade for Migration>::on_chain_storage_version(); - let current_version = >::current_storage_version(); + let in_code_version = >::in_code_storage_version(); - if on_chain_version == current_version { + if on_chain_version == in_code_version { return Ok(Default::default()) } log::debug!( target: LOG_TARGET, - "Requested migration of {} from {:?}(on-chain storage version) to {:?}(current storage version)", - >::name(), on_chain_version, current_version + "Requested migration of {} from {:?}(on-chain storage version) to {:?}(in-code storage version)", + >::name(), on_chain_version, in_code_version ); ensure!( - T::Migrations::is_upgrade_supported(on_chain_version, current_version), - "Unsupported upgrade: VERSION_RANGE should be (on-chain storage version + 1, current storage version)" + T::Migrations::is_upgrade_supported(on_chain_version, in_code_version), + "Unsupported upgrade: VERSION_RANGE should be (on-chain storage version + 1, in-code storage version)" ); Ok(Default::default()) @@ -421,7 +421,7 @@ impl Migration { }, StepResult::Completed { steps_done } => { in_progress_version.put::>(); - if >::current_storage_version() != in_progress_version { + if >::in_code_storage_version() != in_progress_version { log::info!( target: LOG_TARGET, "{name}: Next migration is {:?},", diff --git a/substrate/frame/contracts/src/migration/v09.rs b/substrate/frame/contracts/src/migration/v09.rs index 98fcccc2c0b..f19bff9d674 100644 --- a/substrate/frame/contracts/src/migration/v09.rs +++ b/substrate/frame/contracts/src/migration/v09.rs @@ -28,7 +28,7 @@ use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound, Identity}; use sp_runtime::TryRuntimeError; use sp_std::prelude::*; -mod old { +mod v8 { use super::*; #[derive(Encode, Decode)] @@ -50,14 +50,14 @@ mod old { #[cfg(feature = "runtime-benchmarks")] pub fn store_old_dummy_code(len: usize) { use sp_runtime::traits::Hash; - let module = old::PrefabWasmModule { + let module = v8::PrefabWasmModule { instruction_weights_version: 0, initial: 0, maximum: 0, code: vec![42u8; len], }; let hash = T::Hashing::hash(&module.code); - old::CodeStorage::::insert(hash, module); + v8::CodeStorage::::insert(hash, module); } #[derive(Encode, Decode)] @@ -89,9 +89,9 @@ impl MigrationStep for Migration { fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_key) = self.last_code_hash.take() { - old::CodeStorage::::iter_from(old::CodeStorage::::hashed_key_for(last_key)) + v8::CodeStorage::::iter_from(v8::CodeStorage::::hashed_key_for(last_key)) } else { - old::CodeStorage::::iter() + v8::CodeStorage::::iter() }; if let Some((key, old)) = iter.next() { @@ -115,7 +115,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let sample: Vec<_> = old::CodeStorage::::iter().take(100).collect(); + let sample: Vec<_> = v8::CodeStorage::::iter().take(100).collect(); log::debug!(target: LOG_TARGET, "Taking sample of {} contract codes", sample.len()); Ok(sample.encode()) @@ -123,7 +123,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { - let sample = , old::PrefabWasmModule)> as Decode>::decode(&mut &state[..]) + let sample = , v8::PrefabWasmModule)> as Decode>::decode(&mut &state[..]) .expect("pre_upgrade_step provides a valid state; qed"); log::debug!(target: LOG_TARGET, "Validating sample of {} contract codes", sample.len()); diff --git a/substrate/frame/contracts/src/migration/v10.rs b/substrate/frame/contracts/src/migration/v10.rs index d64673aac7d..1bee86e6a77 100644 --- a/substrate/frame/contracts/src/migration/v10.rs +++ b/substrate/frame/contracts/src/migration/v10.rs @@ -47,7 +47,7 @@ use sp_runtime::{ }; use sp_std::prelude::*; -mod old { +mod v9 { use super::*; pub type BalanceOf = ( ) where OldCurrency: ReservableCurrency<::AccountId> + 'static, { - let info = old::ContractInfo { + let info = v9::ContractInfo { trie_id: info.trie_id, code_hash: info.code_hash, storage_bytes: Default::default(), @@ -94,7 +94,7 @@ pub fn store_old_contract_info( storage_item_deposit: Default::default(), storage_base_deposit: Default::default(), }; - old::ContractInfoOf::::insert(account, info); + v9::ContractInfoOf::::insert(account, info); } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen)] @@ -120,9 +120,9 @@ where pub code_hash: CodeHash, storage_bytes: u32, storage_items: u32, - pub storage_byte_deposit: old::BalanceOf, - storage_item_deposit: old::BalanceOf, - storage_base_deposit: old::BalanceOf, + pub storage_byte_deposit: v9::BalanceOf, + storage_item_deposit: v9::BalanceOf, + storage_base_deposit: v9::BalanceOf, } #[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)] @@ -152,7 +152,7 @@ fn deposit_address( impl MigrationStep for Migration where OldCurrency: ReservableCurrency<::AccountId> - + Inspect<::AccountId, Balance = old::BalanceOf>, + + Inspect<::AccountId, Balance = v9::BalanceOf>, { const VERSION: u16 = 10; @@ -162,11 +162,11 @@ where fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_account) = self.last_account.take() { - old::ContractInfoOf::::iter_from( - old::ContractInfoOf::::hashed_key_for(last_account), + v9::ContractInfoOf::::iter_from( + v9::ContractInfoOf::::hashed_key_for(last_account), ) } else { - old::ContractInfoOf::::iter() + v9::ContractInfoOf::::iter() }; if let Some((account, contract)) = iter.next() { @@ -276,7 +276,7 @@ where #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let sample: Vec<_> = old::ContractInfoOf::::iter().take(10).collect(); + let sample: Vec<_> = v9::ContractInfoOf::::iter().take(10).collect(); log::debug!(target: LOG_TARGET, "Taking sample of {} contracts", sample.len()); Ok(sample.encode()) @@ -284,7 +284,7 @@ where #[cfg(feature = "try-runtime")] fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { - let sample = )> as Decode>::decode( + let sample = )> as Decode>::decode( &mut &state[..], ) .expect("pre_upgrade_step provides a valid state; qed"); diff --git a/substrate/frame/contracts/src/migration/v11.rs b/substrate/frame/contracts/src/migration/v11.rs index a5b11f6e089..9bfbb25edfb 100644 --- a/substrate/frame/contracts/src/migration/v11.rs +++ b/substrate/frame/contracts/src/migration/v11.rs @@ -29,7 +29,7 @@ use sp_runtime::TryRuntimeError; use codec::{Decode, Encode}; use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound}; use sp_std::{marker::PhantomData, prelude::*}; -mod old { +mod v10 { use super::*; #[derive(Encode, Decode, TypeInfo, MaxEncodedLen)] @@ -51,11 +51,11 @@ pub struct DeletionQueueManager { #[cfg(any(feature = "runtime-benchmarks", feature = "try-runtime"))] pub fn fill_old_queue(len: usize) { - let queue: Vec = - core::iter::repeat_with(|| old::DeletedContract { trie_id: Default::default() }) + let queue: Vec = + core::iter::repeat_with(|| v10::DeletedContract { trie_id: Default::default() }) .take(len) .collect(); - old::DeletionQueue::::set(Some(queue)); + v10::DeletionQueue::::set(Some(queue)); } #[storage_alias] @@ -80,7 +80,7 @@ impl MigrationStep for Migration { } fn step(&mut self) -> (IsFinished, Weight) { - let Some(old_queue) = old::DeletionQueue::::take() else { + let Some(old_queue) = v10::DeletionQueue::::take() else { return (IsFinished::Yes, Weight::zero()) }; let len = old_queue.len(); @@ -106,7 +106,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let old_queue = old::DeletionQueue::::take().unwrap_or_default(); + let old_queue = v10::DeletionQueue::::take().unwrap_or_default(); if old_queue.is_empty() { let len = 10u32; diff --git a/substrate/frame/contracts/src/migration/v12.rs b/substrate/frame/contracts/src/migration/v12.rs index 7dee3150310..d9128286df3 100644 --- a/substrate/frame/contracts/src/migration/v12.rs +++ b/substrate/frame/contracts/src/migration/v12.rs @@ -34,7 +34,7 @@ use sp_runtime::TryRuntimeError; use sp_runtime::{traits::Zero, FixedPointNumber, FixedU128, Saturating}; use sp_std::prelude::*; -mod old { +mod v11 { use super::*; pub type BalanceOf = , #[codec(compact)] - deposit: old::BalanceOf, + deposit: v11::BalanceOf, #[codec(compact)] refcount: u64, determinism: Determinism, @@ -112,17 +112,17 @@ where let hash = T::Hashing::hash(&code); PristineCode::::insert(hash, code.clone()); - let module = old::PrefabWasmModule { + let module = v11::PrefabWasmModule { instruction_weights_version: Default::default(), initial: Default::default(), maximum: Default::default(), code, determinism: Determinism::Enforced, }; - old::CodeStorage::::insert(hash, module); + v11::CodeStorage::::insert(hash, module); - let info = old::OwnerInfo { owner: account, deposit: u32::MAX.into(), refcount: u64::MAX }; - old::OwnerInfoOf::::insert(hash, info); + let info = v11::OwnerInfo { owner: account, deposit: u32::MAX.into(), refcount: u64::MAX }; + v11::OwnerInfoOf::::insert(hash, info); } #[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)] @@ -148,16 +148,16 @@ where fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_key) = self.last_code_hash.take() { - old::OwnerInfoOf::::iter_from( - old::OwnerInfoOf::::hashed_key_for(last_key), + v11::OwnerInfoOf::::iter_from( + v11::OwnerInfoOf::::hashed_key_for(last_key), ) } else { - old::OwnerInfoOf::::iter() + v11::OwnerInfoOf::::iter() }; if let Some((hash, old_info)) = iter.next() { log::debug!(target: LOG_TARGET, "Migrating OwnerInfo for code_hash {:?}", hash); - let module = old::CodeStorage::::take(hash) + let module = v11::CodeStorage::::take(hash) .expect(format!("No PrefabWasmModule found for code_hash: {:?}", hash).as_str()); let code_len = module.code.len(); @@ -184,7 +184,7 @@ where let bytes_before = module .encoded_size() .saturating_add(code_len) - .saturating_add(old::OwnerInfo::::max_encoded_len()) + .saturating_add(v11::OwnerInfo::::max_encoded_len()) as u32; let items_before = 3u32; let deposit_expected_before = price_per_byte @@ -241,10 +241,10 @@ where fn pre_upgrade_step() -> Result, TryRuntimeError> { let len = 100; log::debug!(target: LOG_TARGET, "Taking sample of {} OwnerInfo(s)", len); - let sample: Vec<_> = old::OwnerInfoOf::::iter() + let sample: Vec<_> = v11::OwnerInfoOf::::iter() .take(len) .map(|(k, v)| { - let module = old::CodeStorage::::get(k) + let module = v11::CodeStorage::::get(k) .expect("No PrefabWasmModule found for code_hash: {:?}"); let info: CodeInfo = CodeInfo { determinism: module.determinism, @@ -258,9 +258,9 @@ where .collect(); let storage: u32 = - old::CodeStorage::::iter().map(|(_k, v)| v.encoded_size() as u32).sum(); - let mut deposit: old::BalanceOf = Default::default(); - old::OwnerInfoOf::::iter().for_each(|(_k, v)| deposit += v.deposit); + v11::CodeStorage::::iter().map(|(_k, v)| v.encoded_size() as u32).sum(); + let mut deposit: v11::BalanceOf = Default::default(); + v11::OwnerInfoOf::::iter().for_each(|(_k, v)| deposit += v.deposit); Ok((sample, deposit, storage).encode()) } @@ -269,7 +269,7 @@ where fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { let state = <( Vec<(CodeHash, CodeInfo)>, - old::BalanceOf, + v11::BalanceOf, u32, ) as Decode>::decode(&mut &state[..]) .unwrap(); @@ -283,7 +283,7 @@ where ensure!(info.refcount == old.refcount, "invalid refcount"); } - if let Some((k, _)) = old::CodeStorage::::iter().next() { + if let Some((k, _)) = v11::CodeStorage::::iter().next() { log::warn!( target: LOG_TARGET, "CodeStorage is still NOT empty, found code_hash: {:?}", @@ -292,7 +292,7 @@ where } else { log::debug!(target: LOG_TARGET, "CodeStorage is empty."); } - if let Some((k, _)) = old::OwnerInfoOf::::iter().next() { + if let Some((k, _)) = v11::OwnerInfoOf::::iter().next() { log::warn!( target: LOG_TARGET, "OwnerInfoOf is still NOT empty, found code_hash: {:?}", @@ -302,7 +302,7 @@ where log::debug!(target: LOG_TARGET, "OwnerInfoOf is empty."); } - let mut deposit: old::BalanceOf = Default::default(); + let mut deposit: v11::BalanceOf = Default::default(); let mut items = 0u32; let mut storage_info = 0u32; CodeInfoOf::::iter().for_each(|(_k, v)| { diff --git a/substrate/frame/contracts/src/migration/v13.rs b/substrate/frame/contracts/src/migration/v13.rs index dd2eb12eb62..498c44d53ab 100644 --- a/substrate/frame/contracts/src/migration/v13.rs +++ b/substrate/frame/contracts/src/migration/v13.rs @@ -28,7 +28,7 @@ use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound}; use sp_runtime::BoundedBTreeMap; use sp_std::prelude::*; -mod old { +mod v12 { use super::*; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -59,7 +59,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co let entropy = (b"contract_depo_v1", account.clone()).using_encoded(T::Hashing::hash); let deposit_account = Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) .expect("infinite length input; no invalid inputs for type; qed"); - let info = old::ContractInfo { + let info = v12::ContractInfo { trie_id: info.trie_id.clone(), deposit_account, code_hash: info.code_hash, @@ -69,7 +69,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co storage_item_deposit: Default::default(), storage_base_deposit: Default::default(), }; - old::ContractInfoOf::::insert(account, info); + v12::ContractInfoOf::::insert(account, info); } #[storage_alias] @@ -104,11 +104,11 @@ impl MigrationStep for Migration { fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_account) = self.last_account.take() { - old::ContractInfoOf::::iter_from(old::ContractInfoOf::::hashed_key_for( + v12::ContractInfoOf::::iter_from(v12::ContractInfoOf::::hashed_key_for( last_account, )) } else { - old::ContractInfoOf::::iter() + v12::ContractInfoOf::::iter() }; if let Some((key, old)) = iter.next() { diff --git a/substrate/frame/contracts/src/migration/v14.rs b/substrate/frame/contracts/src/migration/v14.rs index 94534d05fdf..09da09e5bcf 100644 --- a/substrate/frame/contracts/src/migration/v14.rs +++ b/substrate/frame/contracts/src/migration/v14.rs @@ -44,7 +44,7 @@ use sp_runtime::{traits::Zero, Saturating}; #[cfg(feature = "try-runtime")] use sp_std::collections::btree_map::BTreeMap; -mod old { +mod v13 { use super::*; pub type BalanceOf = , #[codec(compact)] - pub deposit: old::BalanceOf, + pub deposit: v13::BalanceOf, #[codec(compact)] pub refcount: u64, pub determinism: Determinism, @@ -86,14 +86,14 @@ where let code = vec![42u8; len as usize]; let hash = T::Hashing::hash(&code); - let info = old::CodeInfo { + let info = v13::CodeInfo { owner: account, deposit: 10_000u32.into(), refcount: u64::MAX, determinism: Determinism::Enforced, code_len: len, }; - old::CodeInfoOf::::insert(hash, info); + v13::CodeInfoOf::::insert(hash, info); } #[cfg(feature = "try-runtime")] @@ -105,9 +105,9 @@ where OldCurrency: ReservableCurrency<::AccountId>, { /// Total reserved balance as code upload deposit for the owner. - reserved: old::BalanceOf, + reserved: v13::BalanceOf, /// Total balance of the owner. - total: old::BalanceOf, + total: v13::BalanceOf, } #[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)] @@ -134,11 +134,11 @@ where fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_hash) = self.last_code_hash.take() { - old::CodeInfoOf::::iter_from( - old::CodeInfoOf::::hashed_key_for(last_hash), + v13::CodeInfoOf::::iter_from( + v13::CodeInfoOf::::hashed_key_for(last_hash), ) } else { - old::CodeInfoOf::::iter() + v13::CodeInfoOf::::iter() }; if let Some((hash, code_info)) = iter.next() { @@ -194,7 +194,7 @@ where #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let info: Vec<_> = old::CodeInfoOf::::iter().collect(); + let info: Vec<_> = v13::CodeInfoOf::::iter().collect(); let mut owner_balance_allocation = BTreeMap::, BalanceAllocation>::new(); diff --git a/substrate/frame/contracts/src/migration/v15.rs b/substrate/frame/contracts/src/migration/v15.rs index 180fe855ca6..c77198d6fea 100644 --- a/substrate/frame/contracts/src/migration/v15.rs +++ b/substrate/frame/contracts/src/migration/v15.rs @@ -46,7 +46,7 @@ use sp_runtime::{traits::Zero, Saturating}; #[cfg(feature = "try-runtime")] use sp_std::vec::Vec; -mod old { +mod v14 { use super::*; #[derive( @@ -81,7 +81,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co let entropy = (b"contract_depo_v1", account.clone()).using_encoded(T::Hashing::hash); let deposit_account = Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) .expect("infinite length input; no invalid inputs for type; qed"); - let info = old::ContractInfo { + let info = v14::ContractInfo { trie_id: info.trie_id.clone(), deposit_account, code_hash: info.code_hash, @@ -92,7 +92,7 @@ pub fn store_old_contract_info(account: T::AccountId, info: crate::Co storage_base_deposit: info.storage_base_deposit(), delegate_dependencies: info.delegate_dependencies().clone(), }; - old::ContractInfoOf::::insert(account, info); + v14::ContractInfoOf::::insert(account, info); } #[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -127,11 +127,11 @@ impl MigrationStep for Migration { fn step(&mut self) -> (IsFinished, Weight) { let mut iter = if let Some(last_account) = self.last_account.take() { - old::ContractInfoOf::::iter_from(old::ContractInfoOf::::hashed_key_for( + v14::ContractInfoOf::::iter_from(v14::ContractInfoOf::::hashed_key_for( last_account, )) } else { - old::ContractInfoOf::::iter() + v14::ContractInfoOf::::iter() }; if let Some((account, old_contract)) = iter.next() { @@ -243,11 +243,11 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn pre_upgrade_step() -> Result, TryRuntimeError> { - let sample: Vec<_> = old::ContractInfoOf::::iter().take(100).collect(); + let sample: Vec<_> = v14::ContractInfoOf::::iter().take(100).collect(); log::debug!(target: LOG_TARGET, "Taking sample of {} contracts", sample.len()); - let state: Vec<(T::AccountId, old::ContractInfo, BalanceOf, BalanceOf)> = sample + let state: Vec<(T::AccountId, v14::ContractInfo, BalanceOf, BalanceOf)> = sample .iter() .map(|(account, contract)| { ( @@ -265,7 +265,7 @@ impl MigrationStep for Migration { #[cfg(feature = "try-runtime")] fn post_upgrade_step(state: Vec) -> Result<(), TryRuntimeError> { let sample = - , BalanceOf, BalanceOf)> as Decode>::decode( + , BalanceOf, BalanceOf)> as Decode>::decode( &mut &state[..], ) .expect("pre_upgrade_step provides a valid state; qed"); diff --git a/substrate/frame/democracy/src/lib.rs b/substrate/frame/democracy/src/lib.rs index 089556191cd..08e2a7599f5 100644 --- a/substrate/frame/democracy/src/lib.rs +++ b/substrate/frame/democracy/src/lib.rs @@ -211,7 +211,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index 4f43f89abed..6bf4dfe4f1e 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -1343,7 +1343,7 @@ pub mod pallet { #[pallet::getter(fn minimum_untrusted_score)] pub type MinimumUntrustedScore = StorageValue<_, ElectionScore>; - /// The current storage version. + /// The in-code storage version. /// /// v1: https://github.com/paritytech/substrate/pull/12237/ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); diff --git a/substrate/frame/election-provider-multi-phase/src/migrations.rs b/substrate/frame/election-provider-multi-phase/src/migrations.rs index 50b821e6db6..156f1c02e27 100644 --- a/substrate/frame/election-provider-multi-phase/src/migrations.rs +++ b/substrate/frame/election-provider-multi-phase/src/migrations.rs @@ -27,12 +27,12 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs index a078361a5f7..308f2cdc1aa 100644 --- a/substrate/frame/elections-phragmen/src/lib.rs +++ b/substrate/frame/elections-phragmen/src/lib.rs @@ -188,7 +188,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/examples/Cargo.toml b/substrate/frame/examples/Cargo.toml index eb6355edd31..45c7440eb89 100644 --- a/substrate/frame/examples/Cargo.toml +++ b/substrate/frame/examples/Cargo.toml @@ -23,6 +23,7 @@ pallet-example-frame-crate = { path = "frame-crate", default-features = false } pallet-example-kitchensink = { path = "kitchensink", default-features = false } pallet-example-offchain-worker = { path = "offchain-worker", default-features = false } pallet-example-split = { path = "split", default-features = false } +pallet-example-single-block-migrations = { path = "single-block-migrations", default-features = false } pallet-example-tasks = { path = "tasks", default-features = false } [features] @@ -34,6 +35,7 @@ std = [ "pallet-example-frame-crate/std", "pallet-example-kitchensink/std", "pallet-example-offchain-worker/std", + "pallet-example-single-block-migrations/std", "pallet-example-split/std", "pallet-example-tasks/std", ] @@ -43,6 +45,7 @@ try-runtime = [ "pallet-example-basic/try-runtime", "pallet-example-kitchensink/try-runtime", "pallet-example-offchain-worker/try-runtime", + "pallet-example-single-block-migrations/try-runtime", "pallet-example-split/try-runtime", "pallet-example-tasks/try-runtime", ] diff --git a/substrate/frame/examples/single-block-migrations/Cargo.toml b/substrate/frame/examples/single-block-migrations/Cargo.toml new file mode 100644 index 00000000000..5059b2433c7 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "pallet-example-single-block-migrations" +version = "0.0.1" +authors.workspace = true +edition.workspace = true +license = "MIT-0" +homepage = "https://substrate.io" +repository.workspace = true +description = "FRAME example pallet demonstrating best-practices for writing storage migrations." +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +docify = { version = "0.2.3", default-features = false } +log = { version = "0.4.20", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +frame-support = { path = "../../support", default-features = false } +frame-executive = { path = "../../executive", default-features = false } +frame-system = { path = "../../system", default-features = false } +frame-try-runtime = { path = "../../try-runtime", default-features = false, optional = true } +pallet-balances = { path = "../../balances", default-features = false } +sp-std = { path = "../../../primitives/std", default-features = false } +sp-runtime = { path = "../../../primitives/runtime", default-features = false } +sp-core = { path = "../../../primitives/core", default-features = false } +sp-io = { path = "../../../primitives/io", default-features = false } +sp-version = { path = "../../../primitives/version", default-features = false } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-executive/std", + "frame-support/std", + "frame-system/std", + "frame-try-runtime/std", + "log/std", + "pallet-balances/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "sp-version/std", +] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime/try-runtime", + "pallet-balances/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/substrate/frame/examples/single-block-migrations/src/lib.rs b/substrate/frame/examples/single-block-migrations/src/lib.rs new file mode 100644 index 00000000000..86a9e5d6e95 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/lib.rs @@ -0,0 +1,213 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # Single Block Migration Example Pallet +//! +//! An example pallet demonstrating best-practices for writing single-block migrations in the +//! context of upgrading pallet storage. +//! +//! ## Forwarning +//! +//! Single block migrations **MUST** execute in a single block, therefore when executed on a +//! parachain are only appropriate when guaranteed to not exceed block weight limits. If a +//! parachain submits a block that exceeds the block weight limit it will **brick the chain**! +//! +//! If weight is a concern or you are not sure which type of migration to use, you should probably +//! use a multi-block migration. +//! +//! TODO: Link above to multi-block migration example. +//! +//! ## Pallet Overview +//! +//! This example pallet contains a single storage item [`Value`](pallet::Value), which may be set by +//! any signed origin by calling the [`set_value`](crate::Call::set_value) extrinsic. +//! +//! For the purposes of this exercise, we imagine that in [`StorageVersion`] V0 of this pallet +//! [`Value`](pallet::Value) is a `u32`, and this what is currently stored on-chain. +//! +//! ```ignore +//! // (Old) Storage Version V0 representation of `Value` +//! #[pallet::storage] +//! pub type Value = StorageValue<_, u32>; +//! ``` +//! +//! In [`StorageVersion`] V1 of the pallet a new struct [`CurrentAndPreviousValue`] is introduced: +#![doc = docify::embed!("src/lib.rs", CurrentAndPreviousValue)] +//! and [`Value`](pallet::Value) is updated to store this new struct instead of a `u32`: +#![doc = docify::embed!("src/lib.rs", Value)] +//! +//! In StorageVersion V1 of the pallet when [`set_value`](crate::Call::set_value) is called, the +//! new value is stored in the `current` field of [`CurrentAndPreviousValue`], and the previous +//! value (if it exists) is stored in the `previous` field. +#![doc = docify::embed!("src/lib.rs", pallet_calls)] +//! +//! ## Why a migration is necessary +//! +//! Without a migration, there will be a discrepancy between the on-chain storage for [`Value`] (in +//! V0 it is a `u32`) and the current storage for [`Value`] (in V1 it was changed to a +//! [`CurrentAndPreviousValue`] struct). +//! +//! The on-chain storage for [`Value`] would be a `u32` but the runtime would try to read it as a +//! [`CurrentAndPreviousValue`]. This would result in unacceptable undefined behavior. +//! +//! ## Adding a migration module +//! +//! Writing a pallets migrations in a seperate module is strongly recommended. +//! +//! Here's how the migration module is defined for this pallet: +//! +//! ```text +//! substrate/frame/examples/single-block-migrations/src/ +//! ├── lib.rs <-- pallet definition +//! ├── Cargo.toml <-- pallet manifest +//! └── migrations/ +//! ├── mod.rs <-- migrations module definition +//! └── v1.rs <-- migration logic for the V0 to V1 transition +//! ``` +//! +//! This structure allows keeping migration logic separate from the pallet logic and +//! easily adding new migrations in the future. +//! +//! ## Writing the Migration +//! +//! All code related to the migration can be found under +//! [`v1.rs`](migrations::v1). +//! +//! See the migration source code for detailed comments. +//! +//! To keep the migration logic organised, it is split across additional modules: +//! +//! ### `mod v0` +//! +//! Here we define a [`storage_alias`](frame_support::storage_alias) for the old v0 [`Value`] +//! format. +//! +//! This allows reading the old v0 value from storage during the migration. +//! +//! ### `mod version_unchecked` +//! +//! Here we define our raw migration logic, +//! `version_unchecked::MigrateV0ToV1` which implements the [`OnRuntimeUpgrade`] trait. +//! +//! Importantly, it is kept in a private module so that it cannot be accidentally used in a runtime. +//! +//! Private modules cannot be referenced in docs, so please read the code directly. +//! +//! #### Standalone Struct or Pallet Hook? +//! +//! Note that the storage migration logic is attached to a standalone struct implementing +//! [`OnRuntimeUpgrade`], rather than implementing the +//! [`Hooks::on_runtime_upgrade`](frame_support::traits::Hooks::on_runtime_upgrade) hook directly on +//! the pallet. The pallet hook is better suited for special types of logic that need to execute on +//! every runtime upgrade, but not so much for one-off storage migrations. +//! +//! ### `pub mod versioned` +//! +//! Here, `version_unchecked::MigrateV0ToV1` is wrapped in a +//! [`VersionedMigration`] to define +//! [`versioned::MigrateV0ToV1`](crate::migrations::v1::versioned::MigrateV0ToV1), which may be used +//! in runtimes. +//! +//! Using [`VersionedMigration`] ensures that +//! - The migration only runs once when the on-chain storage version is `0` +//! - The on-chain storage version is updated to `1` after the migration executes +//! - Reads and writes from checking and setting the on-chain storage version are accounted for in +//! the final [`Weight`](frame_support::weights::Weight) +//! +//! This is the only public module exported from `v1`. +//! +//! ### `mod test` +//! +//! Here basic unit tests are defined for the migration. +//! +//! When writing migration tests, don't forget to check: +//! - `on_runtime_upgrade` returns the expected weight +//! - `post_upgrade` succeeds when given the bytes returned by `pre_upgrade` +//! - Pallet storage is in the expected state after the migration +//! +//! [`VersionedMigration`]: frame_support::migrations::VersionedMigration +//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion +//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade +//! [`MigrateV0ToV1`]: crate::migrations::v1::versioned::MigrationV0ToV1 + +// We make sure this pallet uses `no_std` for compiling to Wasm. +#![cfg_attr(not(feature = "std"), no_std)] +// allow non-camel-case names for storage version V0 value +#![allow(non_camel_case_types)] + +// Re-export pallet items so that they can be accessed from the crate namespace. +pub use pallet::*; + +// Export migrations so they may be used in the runtime. +pub mod migrations; +#[doc(hidden)] +mod mock; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::StorageVersion; +use sp_runtime::RuntimeDebug; + +/// Example struct holding the most recently set [`u32`] and the +/// second most recently set [`u32`] (if one existed). +#[docify::export] +#[derive( + Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen, +)] +pub struct CurrentAndPreviousValue { + /// The most recently set value. + pub current: u32, + /// The previous value, if one existed. + pub previous: Option, +} + +// Pallet for demonstrating storage migrations. +#[frame_support::pallet(dev_mode)] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + /// Define the current [`StorageVersion`] of the pallet. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + /// [`StorageVersion`] V1 of [`Value`]. + /// + /// Currently used. + #[docify::export] + #[pallet::storage] + pub type Value = StorageValue<_, CurrentAndPreviousValue>; + + #[docify::export(pallet_calls)] + #[pallet::call] + impl Pallet { + pub fn set_value(origin: OriginFor, value: u32) -> DispatchResult { + ensure_signed(origin)?; + + let previous = Value::::get().map(|v| v.current); + let new_struct = CurrentAndPreviousValue { current: value, previous }; + >::put(new_struct); + + Ok(()) + } + } +} diff --git a/substrate/frame/examples/single-block-migrations/src/migrations/mod.rs b/substrate/frame/examples/single-block-migrations/src/migrations/mod.rs new file mode 100644 index 00000000000..80a33f69941 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/migrations/mod.rs @@ -0,0 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Module containing all logic associated with the example migration from +/// [`StorageVersion`](frame_support::traits::StorageVersion) V0 to V1. +pub mod v1; diff --git a/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs b/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs new file mode 100644 index 00000000000..b46640a3202 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/migrations/v1.rs @@ -0,0 +1,222 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use frame_support::{ + storage_alias, + traits::{Get, OnRuntimeUpgrade}, +}; + +#[cfg(feature = "try-runtime")] +use sp_std::vec::Vec; + +/// Collection of storage item formats from the previous storage version. +/// +/// Required so we can read values in the v0 storage format during the migration. +mod v0 { + use super::*; + + /// V0 type for [`crate::Value`]. + #[storage_alias] + pub type Value = StorageValue, u32>; +} + +/// Private module containing *version unchecked* migration logic. +/// +/// Should only be used by the [`VersionedMigration`](frame_support::migrations::VersionedMigration) +/// type in this module to create something to export. +/// +/// The unversioned migration should be kept private so the unversioned migration cannot +/// accidentally be used in any runtimes. +/// +/// For more about this pattern of keeping items private, see +/// - +/// - +mod version_unchecked { + use super::*; + + /// Implements [`OnRuntimeUpgrade`], migrating the state of this pallet from V0 to V1. + /// + /// In V0 of the template [`crate::Value`] is just a `u32`. In V1, it has been upgraded to + /// contain the struct [`crate::CurrentAndPreviousValue`]. + /// + /// In this migration, update the on-chain storage for the pallet to reflect the new storage + /// layout. + pub struct MigrateV0ToV1(sp_std::marker::PhantomData); + + impl OnRuntimeUpgrade for MigrateV0ToV1 { + /// Return the existing [`crate::Value`] so we can check that it was correctly set in + /// `version_unchecked::MigrateV0ToV1::post_upgrade`. + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + use codec::Encode; + + // Access the old value using the `storage_alias` type + let old_value = v0::Value::::get(); + // Return it as an encoded `Vec` + Ok(old_value.encode()) + } + + /// Migrate the storage from V0 to V1. + /// + /// - If the value doesn't exist, there is nothing to do. + /// - If the value exists, it is read and then written back to storage inside a + /// [`crate::CurrentAndPreviousValue`]. + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // Read the old value from storage + if let Some(old_value) = v0::Value::::take() { + // Write the new value to storage + let new = crate::CurrentAndPreviousValue { current: old_value, previous: None }; + crate::Value::::put(new); + // One read for the old value, one write for the new value + T::DbWeight::get().reads_writes(1, 1) + } else { + // One read for trying to access the old value + T::DbWeight::get().reads(1) + } + } + + /// Verifies the storage was migrated correctly. + /// + /// - If there was no old value, the new value should not be set. + /// - If there was an old value, the new value should be a + /// [`crate::CurrentAndPreviousValue`]. + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + use codec::Decode; + use frame_support::ensure; + + let maybe_old_value = Option::::decode(&mut &state[..]).map_err(|_| { + sp_runtime::TryRuntimeError::Other("Failed to decode old value from storage") + })?; + + match maybe_old_value { + Some(old_value) => { + let expected_new_value = + crate::CurrentAndPreviousValue { current: old_value, previous: None }; + let actual_new_value = crate::Value::::get(); + + ensure!(actual_new_value.is_some(), "New value not set"); + ensure!( + actual_new_value == Some(expected_new_value), + "New value not set correctly" + ); + }, + None => { + ensure!(crate::Value::::get().is_none(), "New value unexpectedly set"); + }, + }; + Ok(()) + } + } +} + +/// Public module containing *version checked* migration logic. +/// +/// This is the only module that should be exported from this module. +/// +/// See [`VersionedMigration`](frame_support::migrations::VersionedMigration) docs for more about +/// how it works. +pub mod versioned { + use super::*; + + /// `version_unchecked::MigrateV0ToV1` wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), which ensures that: + /// - The migration only runs once when the on-chain storage version is 0 + /// - The on-chain storage version is updated to `1` after the migration executes + /// - Reads/Writes from checking/settings the on-chain storage version are accounted for + pub type MigrateV0ToV1 = frame_support::migrations::VersionedMigration< + 0, // The migration will only execute when the on-chain storage version is 0 + 1, // The on-chain storage version will be set to 1 after the migration is complete + version_unchecked::MigrateV0ToV1, + crate::pallet::Pallet, + ::DbWeight, + >; +} + +/// Tests for our migration. +/// +/// When writing migration tests, it is important to check: +/// 1. `on_runtime_upgrade` returns the expected weight +/// 2. `post_upgrade` succeeds when given the bytes returned by `pre_upgrade` +/// 3. The storage is in the expected state after the migration +#[cfg(any(all(feature = "try-runtime", test), doc))] +mod test { + use super::*; + use crate::mock::{new_test_ext, MockRuntime}; + use frame_support::assert_ok; + use version_unchecked::MigrateV0ToV1; + + #[test] + fn handles_no_existing_value() { + new_test_ext().execute_with(|| { + // By default, no value should be set. Verify this assumption. + assert!(crate::Value::::get().is_none()); + assert!(v0::Value::::get().is_none()); + + // Get the pre_upgrade bytes + let bytes = match MigrateV0ToV1::::pre_upgrade() { + Ok(bytes) => bytes, + Err(e) => panic!("pre_upgrade failed: {:?}", e), + }; + + // Execute the migration + let weight = MigrateV0ToV1::::on_runtime_upgrade(); + + // Verify post_upgrade succeeds + assert_ok!(MigrateV0ToV1::::post_upgrade(bytes)); + + // The weight should be just 1 read for trying to access the old value. + assert_eq!(weight, ::DbWeight::get().reads(1)); + + // After the migration, no value should have been set. + assert!(crate::Value::::get().is_none()); + }) + } + + #[test] + fn handles_existing_value() { + new_test_ext().execute_with(|| { + // Set up an initial value + let initial_value = 42; + v0::Value::::put(initial_value); + + // Get the pre_upgrade bytes + let bytes = match MigrateV0ToV1::::pre_upgrade() { + Ok(bytes) => bytes, + Err(e) => panic!("pre_upgrade failed: {:?}", e), + }; + + // Execute the migration + let weight = MigrateV0ToV1::::on_runtime_upgrade(); + + // Verify post_upgrade succeeds + assert_ok!(MigrateV0ToV1::::post_upgrade(bytes)); + + // The weight used should be 1 read for the old value, and 1 write for the new + // value. + assert_eq!( + weight, + ::DbWeight::get().reads_writes(1, 1) + ); + + // After the migration, the new value should be set as the `current` value. + let expected_new_value = + crate::CurrentAndPreviousValue { current: initial_value, previous: None }; + assert_eq!(crate::Value::::get(), Some(expected_new_value)); + }) + } +} diff --git a/substrate/frame/examples/single-block-migrations/src/mock.rs b/substrate/frame/examples/single-block-migrations/src/mock.rs new file mode 100644 index 00000000000..02f72e01836 --- /dev/null +++ b/substrate/frame/examples/single-block-migrations/src/mock.rs @@ -0,0 +1,69 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(any(all(feature = "try-runtime", test), doc))] + +use crate::*; +use frame_support::{derive_impl, traits::ConstU64, weights::constants::ParityDbWeight}; + +// Re-export crate as its pallet name for construct_runtime. +use crate as pallet_example_storage_migration; + +type Block = frame_system::mocking::MockBlock; + +// For testing the pallet, we construct a mock runtime. +frame_support::construct_runtime!( + pub struct MockRuntime { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Example: pallet_example_storage_migration::{Pallet, Call, Storage}, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for MockRuntime { + type Block = Block; + type AccountData = pallet_balances::AccountData; + type DbWeight = ParityDbWeight; +} + +impl pallet_balances::Config for MockRuntime { + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = RuntimeFreezeReason; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU64<1>; + type AccountStore = System; + type WeightInfo = (); + type FreezeIdentifier = (); + type MaxFreezes = (); +} + +impl Config for MockRuntime {} + +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + + let t = RuntimeGenesisConfig { system: Default::default(), balances: Default::default() } + .build_storage() + .unwrap(); + t.into() +} diff --git a/substrate/frame/examples/src/lib.rs b/substrate/frame/examples/src/lib.rs index f38bbe52dc1..dee23a41379 100644 --- a/substrate/frame/examples/src/lib.rs +++ b/substrate/frame/examples/src/lib.rs @@ -43,6 +43,9 @@ //! - [`pallet_example_frame_crate`]: Example pallet showcasing how one can be //! built using only the `frame` umbrella crate. //! +//! - [`pallet_example_single_block_migrations`]: An example pallet demonstrating best-practices for +//! writing storage migrations. +//! //! - [`pallet_example_tasks`]: This pallet demonstrates the use of `Tasks` to execute service work. //! //! **Tip**: Use `cargo doc --package --open` to view each pallet's documentation. diff --git a/substrate/frame/fast-unstake/src/migrations.rs b/substrate/frame/fast-unstake/src/migrations.rs index 56438840704..97ad86bfff4 100644 --- a/substrate/frame/fast-unstake/src/migrations.rs +++ b/substrate/frame/fast-unstake/src/migrations.rs @@ -33,12 +33,12 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); diff --git a/substrate/frame/grandpa/src/lib.rs b/substrate/frame/grandpa/src/lib.rs index 0b9f2b35827..90bcd8721df 100644 --- a/substrate/frame/grandpa/src/lib.rs +++ b/substrate/frame/grandpa/src/lib.rs @@ -73,7 +73,7 @@ pub mod pallet { use frame_support::{dispatch::DispatchResult, pallet_prelude::*}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(5); #[pallet::pallet] diff --git a/substrate/frame/im-online/src/lib.rs b/substrate/frame/im-online/src/lib.rs index 1de89dd00c8..f14093aa09a 100644 --- a/substrate/frame/im-online/src/lib.rs +++ b/substrate/frame/im-online/src/lib.rs @@ -251,7 +251,7 @@ type OffchainResult = Result>>; pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/im-online/src/migration.rs b/substrate/frame/im-online/src/migration.rs index 0d2c0a055b6..754a2e672e6 100644 --- a/substrate/frame/im-online/src/migration.rs +++ b/substrate/frame/im-online/src/migration.rs @@ -72,7 +72,7 @@ pub mod v1 { if StorageVersion::get::>() != 0 { log::warn!( target: TARGET, - "Skipping migration because current storage version is not 0" + "Skipping migration because in-code storage version is not 0" ); return weight } diff --git a/substrate/frame/membership/src/lib.rs b/substrate/frame/membership/src/lib.rs index f3226397003..f4ac697130d 100644 --- a/substrate/frame/membership/src/lib.rs +++ b/substrate/frame/membership/src/lib.rs @@ -46,7 +46,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/multisig/src/lib.rs b/substrate/frame/multisig/src/lib.rs index e4426c64b41..a83b78e316f 100644 --- a/substrate/frame/multisig/src/lib.rs +++ b/substrate/frame/multisig/src/lib.rs @@ -168,7 +168,7 @@ pub mod pallet { type WeightInfo: WeightInfo; } - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/multisig/src/migrations.rs b/substrate/frame/multisig/src/migrations.rs index d03e42a66a5..e6402600d0d 100644 --- a/substrate/frame/multisig/src/migrations.rs +++ b/substrate/frame/multisig/src/migrations.rs @@ -51,7 +51,7 @@ pub mod v1 { fn on_runtime_upgrade() -> Weight { use sp_runtime::Saturating; - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); if onchain > 0 { diff --git a/substrate/frame/nfts/src/lib.rs b/substrate/frame/nfts/src/lib.rs index a7d505e2e39..7cf7cdc61a7 100644 --- a/substrate/frame/nfts/src/lib.rs +++ b/substrate/frame/nfts/src/lib.rs @@ -76,7 +76,7 @@ pub mod pallet { use frame_support::{pallet_prelude::*, traits::ExistenceRequirement}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/nfts/src/migration.rs b/substrate/frame/nfts/src/migration.rs index d4cdf7e820d..8f82e092262 100644 --- a/substrate/frame/nfts/src/migration.rs +++ b/substrate/frame/nfts/src/migration.rs @@ -54,17 +54,17 @@ pub mod v1 { pub struct MigrateToV1(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); log::info!( target: LOG_TARGET, - "Running migration with current storage version {:?} / onchain {:?}", - current_version, - onchain_version + "Running migration with in-code storage version {:?} / onchain {:?}", + in_code_version, + on_chain_version ); - if onchain_version == 0 && current_version == 1 { + if on_chain_version == 0 && in_code_version == 1 { let mut translated = 0u64; let mut configs_iterated = 0u64; Collection::::translate::< @@ -77,13 +77,13 @@ pub mod v1 { Some(old_value.migrate_to_v1(item_configs)) }); - current_version.put::>(); + in_code_version.put::>(); log::info!( target: LOG_TARGET, "Upgraded {} records, storage to version {:?}", translated, - current_version + in_code_version ); T::DbWeight::get().reads_writes(translated + configs_iterated + 1, translated + 1) } else { diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 074d59931ad..c64db9ed692 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -1576,7 +1576,7 @@ pub mod pallet { use frame_system::{ensure_signed, pallet_prelude::*}; use sp_runtime::Perbill; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(8); #[pallet::pallet] diff --git a/substrate/frame/nomination-pools/src/migration.rs b/substrate/frame/nomination-pools/src/migration.rs index 6887fcfa7ec..14410339f59 100644 --- a/substrate/frame/nomination-pools/src/migration.rs +++ b/substrate/frame/nomination-pools/src/migration.rs @@ -342,25 +342,25 @@ pub mod v5 { pub struct MigrateToV5(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV5 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let in_code = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", - current, + "Running migration with in-code storage version {:?} / onchain {:?}", + in_code, onchain ); - if current == 5 && onchain == 4 { + if in_code == 5 && onchain == 4 { let mut translated = 0u64; RewardPools::::translate::, _>(|_id, old_value| { translated.saturating_inc(); Some(old_value.migrate_to_v5()) }); - current.put::>(); - log!(info, "Upgraded {} pools, storage to version {:?}", translated, current); + in_code.put::>(); + log!(info, "Upgraded {} pools, storage to version {:?}", translated, in_code); // reads: translated + onchain version. // writes: translated + current.put. @@ -498,12 +498,12 @@ pub mod v4 { #[allow(deprecated)] impl> OnRuntimeUpgrade for MigrateToV4 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); @@ -579,13 +579,13 @@ pub mod v3 { pub struct MigrateToV3(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV3 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); if onchain == 2 { log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); @@ -859,12 +859,12 @@ pub mod v2 { impl OnRuntimeUpgrade for MigrateToV2 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); @@ -976,12 +976,12 @@ pub mod v1 { pub struct MigrateToV1(sp_std::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV1 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let current = Pallet::::in_code_storage_version(); let onchain = Pallet::::on_chain_storage_version(); log!( info, - "Running migration with current storage version {:?} / onchain {:?}", + "Running migration with in-code storage version {:?} / onchain {:?}", current, onchain ); diff --git a/substrate/frame/preimage/src/lib.rs b/substrate/frame/preimage/src/lib.rs index e344bdfe2d8..4e474685166 100644 --- a/substrate/frame/preimage/src/lib.rs +++ b/substrate/frame/preimage/src/lib.rs @@ -102,7 +102,7 @@ pub const MAX_HASH_UPGRADE_BULK_COUNT: u32 = 1024; pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::config] diff --git a/substrate/frame/referenda/src/lib.rs b/substrate/frame/referenda/src/lib.rs index c5bf2266e67..e616056c302 100644 --- a/substrate/frame/referenda/src/lib.rs +++ b/substrate/frame/referenda/src/lib.rs @@ -143,7 +143,7 @@ pub mod pallet { use frame_support::{pallet_prelude::*, traits::EnsureOriginWithArg}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/referenda/src/migration.rs b/substrate/frame/referenda/src/migration.rs index a80897242ee..631eb7340e5 100644 --- a/substrate/frame/referenda/src/migration.rs +++ b/substrate/frame/referenda/src/migration.rs @@ -109,16 +109,16 @@ pub mod v1 { } fn on_runtime_upgrade() -> Weight { - let current_version = Pallet::::current_storage_version(); - let onchain_version = Pallet::::on_chain_storage_version(); + let in_code_version = Pallet::::in_code_storage_version(); + let on_chain_version = Pallet::::on_chain_storage_version(); let mut weight = T::DbWeight::get().reads(1); log::info!( target: TARGET, - "running migration with current storage version {:?} / onchain {:?}.", - current_version, - onchain_version + "running migration with in-code storage version {:?} / onchain {:?}.", + in_code_version, + on_chain_version ); - if onchain_version != 0 { + if on_chain_version != 0 { log::warn!(target: TARGET, "skipping migration from v0 to v1."); return weight } @@ -149,8 +149,8 @@ pub mod v1 { #[cfg(feature = "try-runtime")] fn post_upgrade(state: Vec) -> Result<(), TryRuntimeError> { - let onchain_version = Pallet::::on_chain_storage_version(); - ensure!(onchain_version == 1, "must upgrade from version 0 to 1."); + let on_chain_version = Pallet::::on_chain_storage_version(); + ensure!(on_chain_version == 1, "must upgrade from version 0 to 1."); let pre_referendum_count: u32 = Decode::decode(&mut &state[..]) .expect("failed to decode the state from pre-upgrade."); let post_referendum_count = ReferendumInfoFor::::iter().count() as u32; diff --git a/substrate/frame/scheduler/src/lib.rs b/substrate/frame/scheduler/src/lib.rs index daebebdee99..af3abd8ac4f 100644 --- a/substrate/frame/scheduler/src/lib.rs +++ b/substrate/frame/scheduler/src/lib.rs @@ -229,7 +229,7 @@ pub mod pallet { use frame_support::{dispatch::PostDispatchInfo, pallet_prelude::*}; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] diff --git a/substrate/frame/session/src/historical/mod.rs b/substrate/frame/session/src/historical/mod.rs index d74e9dd0b7c..b9cecea1a7f 100644 --- a/substrate/frame/session/src/historical/mod.rs +++ b/substrate/frame/session/src/historical/mod.rs @@ -58,7 +58,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); #[pallet::pallet] diff --git a/substrate/frame/session/src/lib.rs b/substrate/frame/session/src/lib.rs index fc35cd6ddd8..7d8128dbc1f 100644 --- a/substrate/frame/session/src/lib.rs +++ b/substrate/frame/session/src/lib.rs @@ -368,7 +368,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); #[pallet::pallet] diff --git a/substrate/frame/society/src/migrations.rs b/substrate/frame/society/src/migrations.rs index dafb1e0b9e5..6a102911451 100644 --- a/substrate/frame/society/src/migrations.rs +++ b/substrate/frame/society/src/migrations.rs @@ -40,11 +40,11 @@ impl< { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, TryRuntimeError> { - let current = Pallet::::current_storage_version(); - let onchain = Pallet::::on_chain_storage_version(); - ensure!(onchain == 0 && current == 2, "pallet_society: invalid version"); + let in_code = Pallet::::in_code_storage_version(); + let on_chain = Pallet::::on_chain_storage_version(); + ensure!(on_chain == 0 && in_code == 2, "pallet_society: invalid version"); - Ok((old::Candidates::::get(), old::Members::::get()).encode()) + Ok((v0::Candidates::::get(), v0::Members::::get()).encode()) } fn on_runtime_upgrade() -> Weight { @@ -103,7 +103,7 @@ pub type MigrateToV2 = frame_support::migrations::VersionedMi ::DbWeight, >; -pub(crate) mod old { +pub(crate) mod v0 { use super::*; use frame_support::storage_alias; @@ -230,37 +230,37 @@ pub fn assert_internal_consistency, I: Instance + 'static>() { } // We don't use these - make sure they don't exist. - assert_eq!(old::SuspendedCandidates::::iter().count(), 0); - assert_eq!(old::Strikes::::iter().count(), 0); - assert_eq!(old::Vouching::::iter().count(), 0); - assert!(!old::Defender::::exists()); - assert!(!old::Members::::exists()); + assert_eq!(v0::SuspendedCandidates::::iter().count(), 0); + assert_eq!(v0::Strikes::::iter().count(), 0); + assert_eq!(v0::Vouching::::iter().count(), 0); + assert!(!v0::Defender::::exists()); + assert!(!v0::Members::::exists()); } pub fn from_original, I: Instance + 'static>( past_payouts: &mut [(::AccountId, BalanceOf)], ) -> Result { // Migrate Bids from old::Bids (just a trunctation). - Bids::::put(BoundedVec::<_, T::MaxBids>::truncate_from(old::Bids::::take())); + Bids::::put(BoundedVec::<_, T::MaxBids>::truncate_from(v0::Bids::::take())); // Initialise round counter. RoundCount::::put(0); // Migrate Candidates from old::Candidates - for Bid { who: candidate, kind, value } in old::Candidates::::take().into_iter() { + for Bid { who: candidate, kind, value } in v0::Candidates::::take().into_iter() { let mut tally = Tally::default(); // Migrate Votes from old::Votes // No need to drain, since we're overwriting values. - for (voter, vote) in old::Votes::::iter_prefix(&candidate) { + for (voter, vote) in v0::Votes::::iter_prefix(&candidate) { Votes::::insert( &candidate, &voter, - Vote { approve: vote == old::Vote::Approve, weight: 1 }, + Vote { approve: vote == v0::Vote::Approve, weight: 1 }, ); match vote { - old::Vote::Approve => tally.approvals.saturating_inc(), - old::Vote::Reject => tally.rejections.saturating_inc(), - old::Vote::Skeptic => Skeptic::::put(&voter), + v0::Vote::Approve => tally.approvals.saturating_inc(), + v0::Vote::Reject => tally.rejections.saturating_inc(), + v0::Vote::Skeptic => Skeptic::::put(&voter), } } Candidates::::insert( @@ -271,9 +271,9 @@ pub fn from_original, I: Instance + 'static>( // Migrate Members from old::Members old::Strikes old::Vouching let mut member_count = 0; - for member in old::Members::::take() { - let strikes = old::Strikes::::take(&member); - let vouching = old::Vouching::::take(&member); + for member in v0::Members::::take() { + let strikes = v0::Strikes::::take(&member); + let vouching = v0::Vouching::::take(&member); let record = MemberRecord { index: member_count, rank: 0, strikes, vouching }; Members::::insert(&member, record); MemberByIndex::::insert(member_count, &member); @@ -314,7 +314,7 @@ pub fn from_original, I: Instance + 'static>( // Migrate Payouts from: old::Payouts and raw info (needed since we can't query old chain // state). past_payouts.sort(); - for (who, mut payouts) in old::Payouts::::iter() { + for (who, mut payouts) in v0::Payouts::::iter() { payouts.truncate(T::MaxPayouts::get() as usize); // ^^ Safe since we already truncated. let paid = past_payouts @@ -329,19 +329,19 @@ pub fn from_original, I: Instance + 'static>( } // Migrate SuspendedMembers from old::SuspendedMembers old::Strikes old::Vouching. - for who in old::SuspendedMembers::::iter_keys() { - let strikes = old::Strikes::::take(&who); - let vouching = old::Vouching::::take(&who); + for who in v0::SuspendedMembers::::iter_keys() { + let strikes = v0::Strikes::::take(&who); + let vouching = v0::Vouching::::take(&who); let record = MemberRecord { index: 0, rank: 0, strikes, vouching }; SuspendedMembers::::insert(&who, record); } // Any suspended candidates remaining are rejected. - let _ = old::SuspendedCandidates::::clear(u32::MAX, None); + let _ = v0::SuspendedCandidates::::clear(u32::MAX, None); // We give the current defender the benefit of the doubt. - old::Defender::::kill(); - let _ = old::DefenderVotes::::clear(u32::MAX, None); + v0::Defender::::kill(); + let _ = v0::DefenderVotes::::clear(u32::MAX, None); Ok(T::BlockWeights::get().max_block) } diff --git a/substrate/frame/society/src/tests.rs b/substrate/frame/society/src/tests.rs index 940643168fb..411567e1ded 100644 --- a/substrate/frame/society/src/tests.rs +++ b/substrate/frame/society/src/tests.rs @@ -18,7 +18,7 @@ //! Tests for the module. use super::*; -use migrations::old; +use migrations::v0; use mock::*; use frame_support::{assert_noop, assert_ok}; @@ -32,41 +32,41 @@ use RuntimeOrigin as Origin; #[test] fn migration_works() { EnvBuilder::new().founded(false).execute(|| { - use old::Vote::*; + use v0::Vote::*; // Initialise the old storage items. Founder::::put(10); Head::::put(30); - old::Members::::put(vec![10, 20, 30]); - old::Vouching::::insert(30, Vouching); - old::Vouching::::insert(40, Banned); - old::Strikes::::insert(20, 1); - old::Strikes::::insert(30, 2); - old::Strikes::::insert(40, 5); - old::Payouts::::insert(20, vec![(1, 1)]); - old::Payouts::::insert( + v0::Members::::put(vec![10, 20, 30]); + v0::Vouching::::insert(30, Vouching); + v0::Vouching::::insert(40, Banned); + v0::Strikes::::insert(20, 1); + v0::Strikes::::insert(30, 2); + v0::Strikes::::insert(40, 5); + v0::Payouts::::insert(20, vec![(1, 1)]); + v0::Payouts::::insert( 30, (0..=::MaxPayouts::get()) .map(|i| (i as u64, i as u64)) .collect::>(), ); - old::SuspendedMembers::::insert(40, true); + v0::SuspendedMembers::::insert(40, true); - old::Defender::::put(20); - old::DefenderVotes::::insert(10, Approve); - old::DefenderVotes::::insert(20, Approve); - old::DefenderVotes::::insert(30, Reject); + v0::Defender::::put(20); + v0::DefenderVotes::::insert(10, Approve); + v0::DefenderVotes::::insert(20, Approve); + v0::DefenderVotes::::insert(30, Reject); - old::SuspendedCandidates::::insert(50, (10, Deposit(100))); + v0::SuspendedCandidates::::insert(50, (10, Deposit(100))); - old::Candidates::::put(vec![ + v0::Candidates::::put(vec![ Bid { who: 60, kind: Deposit(100), value: 200 }, Bid { who: 70, kind: Vouch(30, 30), value: 100 }, ]); - old::Votes::::insert(60, 10, Approve); - old::Votes::::insert(70, 10, Reject); - old::Votes::::insert(70, 20, Approve); - old::Votes::::insert(70, 30, Approve); + v0::Votes::::insert(60, 10, Approve); + v0::Votes::::insert(70, 10, Reject); + v0::Votes::::insert(70, 20, Approve); + v0::Votes::::insert(70, 30, Approve); let bids = (0..=::MaxBids::get()) .map(|i| Bid { @@ -75,7 +75,7 @@ fn migration_works() { value: 10u64 + i as u64, }) .collect::>(); - old::Bids::::put(bids); + v0::Bids::::put(bids); migrations::from_original::(&mut [][..]).expect("migration failed"); migrations::assert_internal_consistency::(); diff --git a/substrate/frame/staking/src/migrations.rs b/substrate/frame/staking/src/migrations.rs index 98984be9920..3e3b1113a81 100644 --- a/substrate/frame/staking/src/migrations.rs +++ b/substrate/frame/staking/src/migrations.rs @@ -67,11 +67,11 @@ pub mod v14 { pub struct MigrateToV14(core::marker::PhantomData); impl OnRuntimeUpgrade for MigrateToV14 { fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let in_code = Pallet::::in_code_storage_version(); let on_chain = Pallet::::on_chain_storage_version(); - if current == 14 && on_chain == 13 { - current.put::>(); + if in_code == 14 && on_chain == 13 { + in_code.put::>(); log!(info, "v14 applied successfully."); T::DbWeight::get().reads_writes(1, 1) @@ -108,12 +108,12 @@ pub mod v13 { } fn on_runtime_upgrade() -> Weight { - let current = Pallet::::current_storage_version(); + let in_code = Pallet::::in_code_storage_version(); let onchain = StorageVersion::::get(); - if current == 13 && onchain == ObsoleteReleases::V12_0_0 { + if in_code == 13 && onchain == ObsoleteReleases::V12_0_0 { StorageVersion::::kill(); - current.put::>(); + in_code.put::>(); log!(info, "v13 applied successfully"); T::DbWeight::get().reads_writes(1, 2) diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index e0213efd507..992a7fe2c9c 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -66,7 +66,7 @@ pub mod pallet { use super::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(14); #[pallet::pallet] diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 78729ee3dc3..5840377d722 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -555,6 +555,42 @@ pub fn __create_tt_macro(input: TokenStream) -> TokenStream { tt_macro::create_tt_return_macro(input) } +/// Allows accessing on-chain pallet storage that is no longer accessible via the pallet. +/// +/// This is especially useful when writing storage migrations, when types of storage items are +/// modified or outright removed, but the previous definition is required to perform the migration. +/// +/// ## Example +/// +/// Imagine a pallet with the following storage definition: +/// ```ignore +/// #[pallet::storage] +/// pub type Value = StorageValue<_, u32>; +/// ``` +/// `Value` can be accessed by calling `Value::::get()`. +/// +/// Now imagine the definition of `Value` is updated to a `(u32, u32)`: +/// ```ignore +/// #[pallet::storage] +/// pub type Value = StorageValue<_, (u32, u32)>; +/// ``` +/// The on-chain value of `Value` is `u32`, but `Value::::get()` expects it to be `(u32, u32)`. +/// +/// In this instance the developer must write a storage migration to reading the old value of +/// `Value` and writing it back to storage in the new format, so that the on-chain storage layout is +/// consistent with what is defined in the pallet. +/// +/// We can read the old v0 value of `Value` in the migration by creating a `storage_alias`: +/// ```ignore +/// pub(crate) mod v0 { +/// use super::*; +/// +/// #[storage_alias] +/// pub type Value = StorageValue, u32>; +/// } +/// ``` +/// +/// The developer can now access the old value of `Value` by calling `v0::Value::::get()`. #[proc_macro_attribute] pub fn storage_alias(attributes: TokenStream, input: TokenStream) -> TokenStream { storage_alias::storage_alias(attributes.into(), input.into()) @@ -1058,7 +1094,7 @@ pub fn generate_store(_: TokenStream, _: TokenStream) -> TokenStream { /// pub struct Pallet(_); /// ``` /// -/// If not present, the current storage version is set to the default value. +/// If not present, the in-code storage version is set to the default value. #[proc_macro_attribute] pub fn storage_version(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() diff --git a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs index 5044d4285bb..6b25ddcba1a 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs @@ -42,7 +42,7 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { >::name::().unwrap_or("") }; - let initialize_on_chain_storage_version = if let Some(current_version) = + let initialize_on_chain_storage_version = if let Some(in_code_version) = &def.pallet_struct.storage_version { quote::quote! { @@ -50,9 +50,9 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { target: #frame_support::LOG_TARGET, "🐥 New pallet {:?} detected in the runtime. Initializing the on-chain storage version to match the storage version defined in the pallet: {:?}", #pallet_name, - #current_version + #in_code_version ); - #current_version.put::(); + #in_code_version.put::(); } } else { quote::quote! { @@ -73,10 +73,10 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { #frame_support::__private::log::info!( target: #frame_support::LOG_TARGET, "⚠️ {} declares internal migrations (which *might* execute). \ - On-chain `{:?}` vs current storage version `{:?}`", + On-chain `{:?}` vs in-code storage version `{:?}`", #pallet_name, ::on_chain_storage_version(), - ::current_storage_version(), + ::in_code_storage_version(), ); } } else { @@ -102,23 +102,23 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { }; // If a storage version is set, we should ensure that the storage version on chain matches the - // current storage version. This assumes that `Executive` is running custom migrations before + // in-code storage version. This assumes that `Executive` is running custom migrations before // the pallets are called. let post_storage_version_check = if def.pallet_struct.storage_version.is_some() { quote::quote! { let on_chain_version = ::on_chain_storage_version(); - let current_version = ::current_storage_version(); + let in_code_version = ::in_code_storage_version(); - if on_chain_version != current_version { + if on_chain_version != in_code_version { #frame_support::__private::log::error!( target: #frame_support::LOG_TARGET, - "{}: On chain storage version {:?} doesn't match current storage version {:?}.", + "{}: On chain storage version {:?} doesn't match in-code storage version {:?}.", #pallet_name, on_chain_version, - current_version, + in_code_version, ); - return Err("On chain and current storage version do not match. Missing runtime upgrade?".into()); + return Err("On chain and in-code storage version do not match. Missing runtime upgrade?".into()); } } } else { diff --git a/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs index c2102f0284d..7cdf6bde9de 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -160,7 +160,7 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { } ); - let (storage_version, current_storage_version_ty) = + let (storage_version, in_code_storage_version_ty) = if let Some(v) = def.pallet_struct.storage_version.as_ref() { (quote::quote! { #v }, quote::quote! { #frame_support::traits::StorageVersion }) } else { @@ -203,9 +203,9 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { for #pallet_ident<#type_use_gen> #config_where_clause { - type CurrentStorageVersion = #current_storage_version_ty; + type InCodeStorageVersion = #in_code_storage_version_ty; - fn current_storage_version() -> Self::CurrentStorageVersion { + fn in_code_storage_version() -> Self::InCodeStorageVersion { #storage_version } diff --git a/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs index f4af86aa3e9..c2855ae38ef 100644 --- a/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs +++ b/substrate/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -44,7 +44,7 @@ pub struct PalletStructDef { /// Whether to specify the storages max encoded len when implementing `StorageInfoTrait`. /// Contains the span of the attribute. pub without_storage_info: Option, - /// The current storage version of the pallet. + /// The in-code storage version of the pallet. pub storage_version: Option, } diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 3e97a384275..d2d9a33053f 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -1178,7 +1178,7 @@ pub mod pallet_prelude { /// # `pallet::storage_version` /// /// Because the [`pallet::pallet`](#pallet-struct-placeholder-palletpallet-mandatory) macro -/// implements [`traits::GetStorageVersion`], the current storage version needs to be +/// implements [`traits::GetStorageVersion`], the in-code storage version needs to be /// communicated to the macro. This can be done by using the `pallet::storage_version` /// attribute: /// @@ -1190,7 +1190,7 @@ pub mod pallet_prelude { /// pub struct Pallet(_); /// ``` /// -/// If not present, the current storage version is set to the default value. +/// If not present, the in-code storage version is set to the default value. /// /// Also see [`pallet::storage_version`](`frame_support::pallet_macros::storage_version`) /// diff --git a/substrate/frame/support/src/migrations.rs b/substrate/frame/support/src/migrations.rs index d059a992a86..f7541059023 100644 --- a/substrate/frame/support/src/migrations.rs +++ b/substrate/frame/support/src/migrations.rs @@ -43,12 +43,30 @@ use sp_std::marker::PhantomData; /// Otherwise, a warning is logged notifying the developer that the upgrade was a noop and should /// probably be removed. /// +/// It is STRONGLY RECOMMENDED to write the unversioned migration logic in a private module and +/// only export the versioned migration logic to prevent accidentally using the unversioned +/// migration in any runtimes. +/// /// ### Examples /// ```ignore /// // In file defining migrations -/// pub struct VersionUncheckedMigrateV5ToV6(sp_std::marker::PhantomData); -/// impl OnRuntimeUpgrade for VersionUncheckedMigrateV5ToV6 { -/// // OnRuntimeUpgrade implementation... +/// +/// /// Private module containing *version unchecked* migration logic. +/// /// +/// /// Should only be used by the [`VersionedMigration`] type in this module to create something to +/// /// export. +/// /// +/// /// We keep this private so the unversioned migration cannot accidentally be used in any runtimes. +/// /// +/// /// For more about this pattern of keeping items private, see +/// /// - https://github.com/rust-lang/rust/issues/30905 +/// /// - https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504/40 +/// mod version_unchecked { +/// use super::*; +/// pub struct MigrateV5ToV6(sp_std::marker::PhantomData); +/// impl OnRuntimeUpgrade for VersionUncheckedMigrateV5ToV6 { +/// // OnRuntimeUpgrade implementation... +/// } /// } /// /// pub type MigrateV5ToV6 = @@ -91,7 +109,7 @@ impl< const FROM: u16, const TO: u16, Inner: crate::traits::OnRuntimeUpgrade, - Pallet: GetStorageVersion + PalletInfoAccess, + Pallet: GetStorageVersion + PalletInfoAccess, DbWeight: Get, > crate::traits::OnRuntimeUpgrade for VersionedMigration { @@ -163,25 +181,25 @@ impl< } } -/// Can store the current pallet version in storage. -pub trait StoreCurrentStorageVersion { - /// Write the current storage version to the storage. - fn store_current_storage_version(); +/// Can store the in-code pallet version on-chain. +pub trait StoreInCodeStorageVersion { + /// Write the in-code storage version on-chain. + fn store_in_code_storage_version(); } -impl + PalletInfoAccess> - StoreCurrentStorageVersion for StorageVersion +impl + PalletInfoAccess> + StoreInCodeStorageVersion for StorageVersion { - fn store_current_storage_version() { - let version = ::current_storage_version(); + fn store_in_code_storage_version() { + let version = ::in_code_storage_version(); version.put::(); } } -impl + PalletInfoAccess> - StoreCurrentStorageVersion for NoStorageVersionSet +impl + PalletInfoAccess> + StoreInCodeStorageVersion for NoStorageVersionSet { - fn store_current_storage_version() { + fn store_in_code_storage_version() { StorageVersion::default().put::(); } } @@ -193,7 +211,7 @@ pub trait PalletVersionToStorageVersionHelper { impl PalletVersionToStorageVersionHelper for T where - T::CurrentStorageVersion: StoreCurrentStorageVersion, + T::InCodeStorageVersion: StoreInCodeStorageVersion, { fn migrate(db_weight: &RuntimeDbWeight) -> Weight { const PALLET_VERSION_STORAGE_KEY_POSTFIX: &[u8] = b":__PALLET_VERSION__:"; @@ -204,8 +222,7 @@ where sp_io::storage::clear(&pallet_version_key(::name())); - >::store_current_storage_version( - ); + >::store_in_code_storage_version(); db_weight.writes(2) } @@ -226,7 +243,7 @@ impl PalletVersionToStorageVersionHelper for T { /// Migrate from the `PalletVersion` struct to the new [`StorageVersion`] struct. /// -/// This will remove all `PalletVersion's` from the state and insert the current storage version. +/// This will remove all `PalletVersion's` from the state and insert the in-code storage version. pub fn migrate_from_pallet_version_to_storage_version< Pallets: PalletVersionToStorageVersionHelper, >( diff --git a/substrate/frame/support/src/traits/hooks.rs b/substrate/frame/support/src/traits/hooks.rs index 20788ce932d..72f047c3a73 100644 --- a/substrate/frame/support/src/traits/hooks.rs +++ b/substrate/frame/support/src/traits/hooks.rs @@ -90,7 +90,7 @@ impl OnIdle for Tuple { /// /// Implementing this trait for a pallet let's you express operations that should /// happen at genesis. It will be called in an externalities provided environment and -/// will see the genesis state after all pallets have written their genesis state. +/// will set the genesis state after all pallets have written their genesis state. #[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] #[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] #[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] @@ -306,19 +306,23 @@ pub trait IntegrityTest { /// end /// ``` /// -/// * `OnRuntimeUpgrade` is only executed before everything else if a code -/// * `OnRuntimeUpgrade` is mandatorily at the beginning of the block body (extrinsics) being -/// processed. change is detected. -/// * Extrinsics start with inherents, and continue with other signed or unsigned extrinsics. -/// * `OnIdle` optionally comes after extrinsics. -/// `OnFinalize` mandatorily comes after `OnIdle`. +/// * [`OnRuntimeUpgrade`](Hooks::OnRuntimeUpgrade) hooks are only executed when a code change is +/// detected. +/// * [`OnRuntimeUpgrade`](Hooks::OnRuntimeUpgrade) hooks are mandatorily executed at the very +/// beginning of the block body, before any extrinsics are processed. +/// * [`Inherents`](sp_inherents) are always executed before any other other signed or unsigned +/// extrinsics. +/// * [`OnIdle`](Hooks::OnIdle) hooks are executed after extrinsics if there is weight remaining in +/// the block. +/// * [`OnFinalize`](Hooks::OnFinalize) hooks are mandatorily executed after +/// [`OnIdle`](Hooks::OnIdle). /// -/// > `OffchainWorker` is not part of this flow, as it is not really part of the consensus/main -/// > block import path, and is called optionally, and in other circumstances. See -/// > [`crate::traits::misc::OffchainWorker`] for more information. +/// > [`OffchainWorker`](crate::traits::misc::OffchainWorker) hooks are not part of this flow, +/// > because they are not part of the consensus/main block building logic. See +/// > [`OffchainWorker`](crate::traits::misc::OffchainWorker) for more information. /// -/// To learn more about the execution of hooks see `frame-executive` as this component is is charge -/// of dispatching extrinsics and placing the hooks in the correct order. +/// To learn more about the execution of hooks see the FRAME `Executive` pallet which is in charge +/// of dispatching extrinsics and calling hooks in the correct order. pub trait Hooks { /// Block initialization hook. This is called at the very beginning of block execution. /// @@ -370,30 +374,38 @@ pub trait Hooks { Weight::zero() } - /// Hook executed when a code change (aka. a "runtime upgrade") is detected by FRAME. + /// Hook executed when a code change (aka. a "runtime upgrade") is detected by the FRAME + /// `Executive` pallet. /// /// Be aware that this is called before [`Hooks::on_initialize`] of any pallet; therefore, a lot /// of the critical storage items such as `block_number` in system pallet might have not been - /// set. + /// set yet. /// - /// Vert similar to [`Hooks::on_initialize`], any code in this block is mandatory and MUST - /// execute. Use with care. + /// Similar to [`Hooks::on_initialize`], any code in this block is mandatory and MUST execute. + /// It is strongly recommended to dry-run the execution of these hooks using + /// [try-runtime-cli](https://github.com/paritytech/try-runtime-cli) to ensure they will not + /// produce and overweight block which can brick your chain. Use with care! /// - /// ## Implementation Note: Versioning + /// ## Implementation Note: Standalone Migrations /// - /// 1. An implementation of this should typically follow a pattern where the version of the - /// pallet is checked against the onchain version, and a decision is made about what needs to be - /// done. This is helpful to prevent accidental repetitive execution of this hook, which can be - /// catastrophic. + /// Additional migrations can be created by directly implementing [`OnRuntimeUpgrade`] on + /// structs and passing them to `Executive`. /// - /// Alternatively, [`frame_support::migrations::VersionedMigration`] can be used to assist with - /// this. + /// ## Implementation Note: Pallet Versioning /// - /// ## Implementation Note: Runtime Level Migration + /// Implementations of this hook are typically wrapped in + /// [`crate::migrations::VersionedMigration`] to ensure the migration is executed exactly + /// once and only when it is supposed to. /// - /// Additional "upgrade hooks" can be created by pallets by a manual implementation of - /// [`Hooks::on_runtime_upgrade`] which can be passed on to `Executive` at the top level - /// runtime. + /// Alternatively, developers can manually implement version checks. + /// + /// Failure to adequately check storage versions can result in accidental repetitive execution + /// of the hook, which can be catastrophic. + /// + /// ## Implementation Note: Weight + /// + /// Typically, implementations of this method are simple enough that weights can be calculated + /// manually. However, if required, a benchmark can also be used. fn on_runtime_upgrade() -> Weight { Weight::zero() } @@ -403,7 +415,7 @@ pub trait Hooks { /// It should focus on certain checks to ensure that the state is sensible. This is never /// executed in a consensus code-path, therefore it can consume as much weight as it needs. /// - /// This hook should not alter any storage. + /// This hook must not alter any storage. #[cfg(feature = "try-runtime")] fn try_state(_n: BlockNumber) -> Result<(), TryRuntimeError> { Ok(()) @@ -415,7 +427,7 @@ pub trait Hooks { /// which will be passed to `post_upgrade` after upgrading for post-check. An empty vector /// should be returned if there is no such need. /// - /// This hook is never meant to be executed on-chain but is meant to be used by testing tools. + /// This hook is never executed on-chain but instead used by testing tools. #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, TryRuntimeError> { Ok(Vec::new()) diff --git a/substrate/frame/support/src/traits/metadata.rs b/substrate/frame/support/src/traits/metadata.rs index 586af20511a..8bda4186bc9 100644 --- a/substrate/frame/support/src/traits/metadata.rs +++ b/substrate/frame/support/src/traits/metadata.rs @@ -261,41 +261,64 @@ impl Add for StorageVersion { } } -/// Special marker struct if no storage version is set for a pallet. +/// Special marker struct used when [`storage_version`](crate::pallet_macros::storage_version) is +/// not defined for a pallet. /// /// If you (the reader) end up here, it probably means that you tried to compare /// [`GetStorageVersion::on_chain_storage_version`] against -/// [`GetStorageVersion::current_storage_version`]. This basically means that the -/// [`storage_version`](crate::pallet_macros::storage_version) is missing in the pallet where the -/// mentioned functions are being called. +/// [`GetStorageVersion::in_code_storage_version`]. This basically means that the +/// [`storage_version`](crate::pallet_macros::storage_version) is missing from the pallet where the +/// mentioned functions are being called, and needs to be defined. #[derive(Debug, Default)] pub struct NoStorageVersionSet; -/// Provides information about the storage version of a pallet. +/// Provides information about a pallet's storage versions. /// -/// It differentiates between current and on-chain storage version. Both should be only out of sync -/// when a new runtime upgrade was applied and the runtime migrations did not yet executed. -/// Otherwise it means that the pallet works with an unsupported storage version and unforeseen -/// stuff can happen. +/// Every pallet has two storage versions: +/// 1. An in-code storage version +/// 2. An on-chain storage version /// -/// The current storage version is the version of the pallet as supported at runtime. The active -/// storage version is the version of the pallet in the storage. +/// The in-code storage version is the version of the pallet as defined in the runtime blob, and the +/// on-chain storage version is the version of the pallet stored on-chain. /// -/// It is required to update the on-chain storage version manually when a migration was applied. +/// Storage versions should be only ever be out of sync when a pallet has been updated to a new +/// version and the in-code version is incremented, but the migration has not yet been executed +/// on-chain as part of a runtime upgrade. +/// +/// It is the responsibility of the developer to ensure that the on-chain storage version is set +/// correctly during a migration so that it matches the in-code storage version. pub trait GetStorageVersion { - /// This will be filled out by the [`pallet`](crate::pallet) macro. + /// This type is generated by the [`pallet`](crate::pallet) macro. + /// + /// If the [`storage_version`](crate::pallet_macros::storage_version) attribute isn't specified, + /// this is set to [`NoStorageVersionSet`] to signify that it is missing. + /// + /// If the [`storage_version`](crate::pallet_macros::storage_version) attribute is specified, + /// this is be set to a [`StorageVersion`] corresponding to the attribute. /// - /// If the [`storage_version`](crate::pallet_macros::storage_version) attribute isn't given - /// this is set to [`NoStorageVersionSet`] to inform the user that the attribute is missing. - /// This should prevent that the user forgets to set a storage version when required. However, - /// this will only work when the user actually tries to call [`Self::current_storage_version`] - /// to compare it against the [`Self::on_chain_storage_version`]. If the attribute is given, - /// this will be set to [`StorageVersion`]. - type CurrentStorageVersion; - - /// Returns the current storage version as supported by the pallet. - fn current_storage_version() -> Self::CurrentStorageVersion; - /// Returns the on-chain storage version of the pallet as stored in the storage. + /// The intention of using [`NoStorageVersionSet`] instead of defaulting to a [`StorageVersion`] + /// of zero is to prevent developers from forgetting to set + /// [`storage_version`](crate::pallet_macros::storage_version) when it is required, like in the + /// case that they wish to compare the in-code storage version to the on-chain storage version. + type InCodeStorageVersion; + + #[deprecated( + note = "This method has been renamed to `in_code_storage_version` and will be removed after March 2024." + )] + /// DEPRECATED: Use [`Self::current_storage_version`] instead. + /// + /// Returns the in-code storage version as specified in the + /// [`storage_version`](crate::pallet_macros::storage_version) attribute, or + /// [`NoStorageVersionSet`] if the attribute is missing. + fn current_storage_version() -> Self::InCodeStorageVersion { + Self::in_code_storage_version() + } + + /// Returns the in-code storage version as specified in the + /// [`storage_version`](crate::pallet_macros::storage_version) attribute, or + /// [`NoStorageVersionSet`] if the attribute is missing. + fn in_code_storage_version() -> Self::InCodeStorageVersion; + /// Returns the storage version of the pallet as last set in the actual on-chain storage. fn on_chain_storage_version() -> StorageVersion; } diff --git a/substrate/frame/support/test/tests/construct_runtime.rs b/substrate/frame/support/test/tests/construct_runtime.rs index b8341b25cb0..b7698681886 100644 --- a/substrate/frame/support/test/tests/construct_runtime.rs +++ b/substrate/frame/support/test/tests/construct_runtime.rs @@ -683,7 +683,7 @@ fn test_metadata() { name: "Version", ty: meta_type::(), value: RuntimeVersion::default().encode(), - docs: maybe_docs(vec![ " Get the chain's current version."]), + docs: maybe_docs(vec![ " Get the chain's in-code version."]), }, PalletConstantMetadata { name: "SS58Prefix", diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs index 9b4381c2f82..7bee4b7c820 100644 --- a/substrate/frame/support/test/tests/pallet.rs +++ b/substrate/frame/support/test/tests/pallet.rs @@ -590,7 +590,7 @@ pub mod pallet2 { Self::deposit_event(Event::Something(31)); if UpdateStorageVersion::get() { - Self::current_storage_version().put::(); + Self::in_code_storage_version().put::(); } Weight::zero() @@ -1310,7 +1310,7 @@ fn pallet_on_genesis() { assert_eq!(pallet::Pallet::::on_chain_storage_version(), StorageVersion::new(0)); pallet::Pallet::::on_genesis(); assert_eq!( - pallet::Pallet::::current_storage_version(), + pallet::Pallet::::in_code_storage_version(), pallet::Pallet::::on_chain_storage_version(), ); }) @@ -2257,10 +2257,10 @@ fn pallet_on_chain_storage_version_initializes_correctly() { AllPalletsWithSystem, >; - // Simple example of a pallet with current version 10 being added to the runtime for the first + // Simple example of a pallet with in-code version 10 being added to the runtime for the first // time. TestExternalities::default().execute_with(|| { - let current_version = Example::current_storage_version(); + let in_code_version = Example::in_code_storage_version(); // Check the pallet has no storage items set. let pallet_hashed_prefix = twox_128(Example::name().as_bytes()); @@ -2271,14 +2271,14 @@ fn pallet_on_chain_storage_version_initializes_correctly() { // version. Executive::execute_on_runtime_upgrade(); - // Check that the storage version was initialized to the current version + // Check that the storage version was initialized to the in-code version let on_chain_version_after = StorageVersion::get::(); - assert_eq!(on_chain_version_after, current_version); + assert_eq!(on_chain_version_after, in_code_version); }); - // Pallet with no current storage version should have the on-chain version initialized to 0. + // Pallet with no in-code storage version should have the on-chain version initialized to 0. TestExternalities::default().execute_with(|| { - // Example4 current_storage_version is NoStorageVersionSet. + // Example4 in_code_storage_version is NoStorageVersionSet. // Check the pallet has no storage items set. let pallet_hashed_prefix = twox_128(Example4::name().as_bytes()); @@ -2308,7 +2308,7 @@ fn post_runtime_upgrade_detects_storage_version_issues() { impl OnRuntimeUpgrade for CustomUpgrade { fn on_runtime_upgrade() -> Weight { - Example2::current_storage_version().put::(); + Example2::in_code_storage_version().put::(); Default::default() } @@ -2351,14 +2351,14 @@ fn post_runtime_upgrade_detects_storage_version_issues() { >; TestExternalities::default().execute_with(|| { - // Set the on-chain version to one less than the current version for `Example`, simulating a + // Set the on-chain version to one less than the in-code version for `Example`, simulating a // forgotten migration StorageVersion::new(9).put::(); // The version isn't changed, we should detect it. assert!( Executive::try_runtime_upgrade(UpgradeCheckSelect::PreAndPost).unwrap_err() == - "On chain and current storage version do not match. Missing runtime upgrade?" + "On chain and in-code storage version do not match. Missing runtime upgrade?" .into() ); }); diff --git a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs index 840a6dee20c..d2ca9fc8099 100644 --- a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs +++ b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.rs @@ -29,7 +29,7 @@ mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { - if Self::current_storage_version() != Self::on_chain_storage_version() { + if Self::in_code_storage_version() != Self::on_chain_storage_version() { } diff --git a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr index 1b48197cc9e..3256e69528a 100644 --- a/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr +++ b/substrate/frame/support/test/tests/pallet_ui/compare_unset_storage_version.stderr @@ -1,7 +1,7 @@ error[E0369]: binary operation `!=` cannot be applied to type `NoStorageVersionSet` --> tests/pallet_ui/compare_unset_storage_version.rs:32:39 | -32 | if Self::current_storage_version() != Self::on_chain_storage_version() { +32 | if Self::in_code_storage_version() != Self::on_chain_storage_version() { | ------------------------------- ^^ -------------------------------- StorageVersion | | | NoStorageVersionSet diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index c527a483d88..01df09106d9 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -525,7 +525,7 @@ pub mod pallet { #[pallet::constant] type DbWeight: Get; - /// Get the chain's current version. + /// Get the chain's in-code version. #[pallet::constant] type Version: Get; diff --git a/substrate/frame/tips/src/lib.rs b/substrate/frame/tips/src/lib.rs index 4c7cfc3028a..8c360fb57d7 100644 --- a/substrate/frame/tips/src/lib.rs +++ b/substrate/frame/tips/src/lib.rs @@ -122,7 +122,7 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - /// The current storage version. + /// The in-code storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(4); #[pallet::pallet] -- GitLab From f1b2189e8312821a9f8a79dc4f0183d314273faa Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:43:58 +0200 Subject: [PATCH 269/283] rpc-v2/tx/tests: Add transaction broadcast tests and check propagated tx status (#3193) This PR adds tests for the `transaction_broadcast` method. The testing needs to coordinate the following components: - The `TestApi` marks transactions as invalid and implements `ChainApi::validate_transaction` - this is what dictates if a transaction is valid or not and is called from within the `BasicPool` - The `BasicPool` which maintains the transactions and implements `submit_and_watch` needed by the tx broadcast to submit the transaction - The status of the transaction pool is exposed by mocking the BasicPool - The `ChainHeadMockClient` which mocks the `BlockchainEvents::import_notification_stream` needed by the tx broadcast to know to which blocks the transaction is submitted The following changes have been added to the substrate testing to accommodate this: - `TestApi` gets ` remove_invalid`, counterpart to `add_invalid` to ensure an invalid transaction can become valid again; as well as a priority setter for extrinsics - `BasicPool` test constructor is extended with options for the `PoolRotator` - this mechanism is needed because transactions are banned for 30mins (default) after they are declared invalid - testing bypasses this by providing a `Duration::ZERO` ### Testing Scenarios - Capture the status of the transaction as it is normally broadcasted - `transaction_stop` is valid while the transaction is in progress - A future transaction is handled when the dependencies are completed - Try to resubmit the transaction at a later block (currently invalid) - An invalid transaction status is propagated; the transaction is marked as temporarily banned; then the ban expires and transaction is resubmitted This builds on top of: https://github.com/paritytech/polkadot-sdk/pull/3079 Part of: https://github.com/paritytech/polkadot-sdk/issues/3084 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile Co-authored-by: James Wilson --- .../rpc-spec-v2/src/chain_head/test_utils.rs | 4 +- .../rpc-spec-v2/src/transaction/tests.rs | 238 -------- .../src/transaction/tests/executor.rs | 100 ++++ .../src/transaction/tests/middleware_pool.rs | 187 +++++++ .../rpc-spec-v2/src/transaction/tests/mod.rs | 24 + .../src/transaction/tests/setup.rs | 120 ++++ .../tests/transaction_broadcast_tests.rs | 523 ++++++++++++++++++ substrate/client/transaction-pool/src/lib.rs | 3 +- .../client/transaction-pool/tests/pool.rs | 3 +- .../runtime/transaction-pool/src/lib.rs | 27 +- 10 files changed, 985 insertions(+), 244 deletions(-) delete mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs create mode 100644 substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs diff --git a/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs b/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs index d63a98a5cb0..e81bd4bfa0b 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs @@ -63,7 +63,7 @@ impl ChainHeadMockClient { BlockImportNotification::new(header.hash(), BlockOrigin::Own, header, true, None, sink); for sink in self.import_sinks.lock().iter_mut() { - sink.unbounded_send(notification.clone()).unwrap(); + let _ = sink.unbounded_send(notification.clone()); } } @@ -83,7 +83,7 @@ impl ChainHeadMockClient { let notification = FinalityNotification::from_summary(summary, sink); for sink in self.finality_sinks.lock().iter_mut() { - sink.unbounded_send(notification.clone()).unwrap(); + let _ = sink.unbounded_send(notification.clone()); } } } diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests.rs b/substrate/client/rpc-spec-v2/src/transaction/tests.rs deleted file mode 100644 index 382f5adeae1..00000000000 --- a/substrate/client/rpc-spec-v2/src/transaction/tests.rs +++ /dev/null @@ -1,238 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 - -// This program 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. - -// This program 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 this program. If not, see . - -use super::*; -use crate::{ - chain_head::test_utils::ChainHeadMockClient, hex_string, - transaction::TransactionBroadcast as RpcTransactionBroadcast, -}; -use assert_matches::assert_matches; -use codec::Encode; -use futures::Future; -use jsonrpsee::{rpc_params, MethodsError as Error, RpcModule}; -use sc_transaction_pool::*; -use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool}; -use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; -use std::{pin::Pin, sync::Arc, time::Duration}; -use substrate_test_runtime_client::{prelude::*, AccountKeyring::*, Client}; -use substrate_test_runtime_transaction_pool::{uxt, TestApi}; -use tokio::sync::mpsc; - -type Block = substrate_test_runtime_client::runtime::Block; - -/// Wrap the `TaskExecutor` to know when the broadcast future is dropped. -#[derive(Clone)] -struct TaskExecutorBroadcast { - executor: TaskExecutor, - sender: mpsc::UnboundedSender<()>, -} - -/// The channel that receives events when the broadcast futures are dropped. -type TaskExecutorRecv = mpsc::UnboundedReceiver<()>; - -impl TaskExecutorBroadcast { - /// Construct a new `TaskExecutorBroadcast` and a receiver to know when the broadcast futures - /// are dropped. - fn new() -> (Self, TaskExecutorRecv) { - let (sender, recv) = mpsc::unbounded_channel(); - - (Self { executor: TaskExecutor::new(), sender }, recv) - } -} - -impl SpawnNamed for TaskExecutorBroadcast { - fn spawn( - &self, - name: &'static str, - group: Option<&'static str>, - future: futures::future::BoxFuture<'static, ()>, - ) { - let sender = self.sender.clone(); - let future = Box::pin(async move { - future.await; - let _ = sender.send(()); - }); - - self.executor.spawn(name, group, future) - } - - fn spawn_blocking( - &self, - name: &'static str, - group: Option<&'static str>, - future: futures::future::BoxFuture<'static, ()>, - ) { - let sender = self.sender.clone(); - let future = Box::pin(async move { - future.await; - let _ = sender.send(()); - }); - - self.executor.spawn_blocking(name, group, future) - } -} - -/// Initial Alice account nonce. -const ALICE_NONCE: u64 = 209; - -fn create_basic_pool_with_genesis( - test_api: Arc, -) -> (BasicPool, Pin + Send>>) { - let genesis_hash = { - test_api - .chain() - .read() - .block_by_number - .get(&0) - .map(|blocks| blocks[0].0.header.hash()) - .expect("there is block 0. qed") - }; - BasicPool::new_test(test_api, genesis_hash, genesis_hash) -} - -fn maintained_pool() -> (BasicPool, Arc, futures::executor::ThreadPool) { - let api = Arc::new(TestApi::with_alice_nonce(ALICE_NONCE)); - let (pool, background_task) = create_basic_pool_with_genesis(api.clone()); - - let thread_pool = futures::executor::ThreadPool::new().unwrap(); - thread_pool.spawn_ok(background_task); - (pool, api, thread_pool) -} - -fn setup_api() -> ( - Arc, - Arc>, - Arc>>, - RpcModule< - TransactionBroadcast, ChainHeadMockClient>>, - >, - TaskExecutorRecv, -) { - let (pool, api, _) = maintained_pool(); - let pool = Arc::new(pool); - - let builder = TestClientBuilder::new(); - let client = Arc::new(builder.build()); - let client_mock = Arc::new(ChainHeadMockClient::new(client.clone())); - - let (task_executor, executor_recv) = TaskExecutorBroadcast::new(); - - let tx_api = - RpcTransactionBroadcast::new(client_mock.clone(), pool.clone(), Arc::new(task_executor)) - .into_rpc(); - - (api, pool, client_mock, tx_api, executor_recv) -} - -#[tokio::test] -async fn tx_broadcast_enters_pool() { - let (api, pool, client_mock, tx_api, _) = setup_api(); - - // Start at block 1. - let block_1_header = api.push_block(1, vec![], true); - - let uxt = uxt(Alice, ALICE_NONCE); - let xt = hex_string(&uxt.encode()); - - let operation_id: String = - tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); - - // Announce block 1 to `transaction_unstable_broadcast`. - client_mock.trigger_import_stream(block_1_header).await; - - // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. - - // TODO: Improve testability by extending the `transaction_unstable_broadcast` with - // a middleware trait that intercepts the transaction status for testing. - let mut num_retries = 12; - while num_retries > 0 && pool.status().ready != 1 { - tokio::time::sleep(Duration::from_secs(5)).await; - num_retries -= 1; - } - assert_eq!(1, pool.status().ready); - assert_eq!(uxt.encode().len(), pool.status().ready_bytes); - - // Import block 2 with the transaction included. - let block_2_header = api.push_block(2, vec![uxt.clone()], true); - let block_2 = block_2_header.hash(); - - // Announce block 2 to the pool. - let event = ChainEvent::NewBestBlock { hash: block_2, tree_route: None }; - pool.maintain(event).await; - - assert_eq!(0, pool.status().ready); - - // Stop call can still be made. - let _: () = tx_api - .call("transaction_unstable_stop", rpc_params![&operation_id]) - .await - .unwrap(); -} - -#[tokio::test] -async fn tx_broadcast_invalid_tx() { - let (_, pool, _, tx_api, mut exec_recv) = setup_api(); - - // Invalid parameters. - let err = tx_api - .call::<_, serde_json::Value>("transaction_unstable_broadcast", [1u8]) - .await - .unwrap_err(); - assert_matches!(err, - Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid params" - ); - - assert_eq!(0, pool.status().ready); - - // Invalid transaction that cannot be decoded. The broadcast silently exits. - let xt = "0xdeadbeef"; - let operation_id: String = - tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); - - assert_eq!(0, pool.status().ready); - - // Await the broadcast future to exit. - // Without this we'd be subject to races, where we try to call the stop before the tx is - // dropped. - exec_recv.recv().await.unwrap(); - - // The broadcast future was dropped, and the operation is no longer active. - // When the operation is not active, either from the tx being finalized or a - // terminal error; the stop method should return an error. - let err = tx_api - .call::<_, serde_json::Value>("transaction_unstable_stop", rpc_params![&operation_id]) - .await - .unwrap_err(); - assert_matches!(err, - Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" - ); -} - -#[tokio::test] -async fn tx_invalid_stop() { - let (_, _, _, tx_api, _) = setup_api(); - - // Make an invalid stop call. - let err = tx_api - .call::<_, serde_json::Value>("transaction_unstable_stop", ["invalid_operation_id"]) - .await - .unwrap_err(); - assert_matches!(err, - Error::JsonRpc(err) if err.code() == super::error::json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" - ); -} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs new file mode 100644 index 00000000000..ff9aca79887 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/executor.rs @@ -0,0 +1,100 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use sp_core::{testing::TaskExecutor, traits::SpawnNamed}; +use std::sync::{atomic::AtomicUsize, Arc}; +use tokio::sync::mpsc; + +/// Wrap the `TaskExecutor` to know when the broadcast future is dropped. +#[derive(Clone)] +pub struct TaskExecutorBroadcast { + executor: TaskExecutor, + sender: mpsc::UnboundedSender<()>, + num_tasks: Arc, +} + +/// The channel that receives events when the broadcast futures are dropped. +pub type TaskExecutorRecv = mpsc::UnboundedReceiver<()>; + +/// The state of the `TaskExecutorBroadcast`. +pub struct TaskExecutorState { + pub recv: TaskExecutorRecv, + pub num_tasks: Arc, +} + +impl TaskExecutorState { + pub fn num_tasks(&self) -> usize { + self.num_tasks.load(std::sync::atomic::Ordering::Acquire) + } +} + +impl TaskExecutorBroadcast { + /// Construct a new `TaskExecutorBroadcast` and a receiver to know when the broadcast futures + /// are dropped. + pub fn new() -> (Self, TaskExecutorState) { + let (sender, recv) = mpsc::unbounded_channel(); + let num_tasks = Arc::new(AtomicUsize::new(0)); + + ( + Self { executor: TaskExecutor::new(), sender, num_tasks: num_tasks.clone() }, + TaskExecutorState { recv, num_tasks }, + ) + } +} + +impl SpawnNamed for TaskExecutorBroadcast { + fn spawn( + &self, + name: &'static str, + group: Option<&'static str>, + future: futures::future::BoxFuture<'static, ()>, + ) { + let sender = self.sender.clone(); + let num_tasks = self.num_tasks.clone(); + + let future = Box::pin(async move { + num_tasks.fetch_add(1, std::sync::atomic::Ordering::AcqRel); + future.await; + num_tasks.fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + + let _ = sender.send(()); + }); + + self.executor.spawn(name, group, future) + } + + fn spawn_blocking( + &self, + name: &'static str, + group: Option<&'static str>, + future: futures::future::BoxFuture<'static, ()>, + ) { + let sender = self.sender.clone(); + let num_tasks = self.num_tasks.clone(); + + let future = Box::pin(async move { + num_tasks.fetch_add(1, std::sync::atomic::Ordering::AcqRel); + future.await; + num_tasks.fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + + let _ = sender.send(()); + }); + + self.executor.spawn_blocking(name, group, future) + } +} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs new file mode 100644 index 00000000000..aa8ac572dec --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/middleware_pool.rs @@ -0,0 +1,187 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use codec::Encode; +use futures::Future; +use sc_transaction_pool::BasicPool; +use sc_transaction_pool_api::{ + ImportNotificationStream, PoolFuture, PoolStatus, ReadyTransactions, TransactionFor, + TransactionPool, TransactionSource, TransactionStatusStreamFor, TxHash, +}; + +use crate::hex_string; +use futures::{FutureExt, StreamExt}; + +use sp_runtime::traits::{Block as BlockT, NumberFor}; +use std::{collections::HashMap, pin::Pin, sync::Arc}; +use substrate_test_runtime_transaction_pool::TestApi; +use tokio::sync::mpsc; + +pub type Block = substrate_test_runtime_client::runtime::Block; + +pub type TxTestPool = MiddlewarePool; +pub type TxStatusType = sc_transaction_pool_api::TransactionStatus< + sc_transaction_pool_api::TxHash, + sc_transaction_pool_api::BlockHash, +>; +pub type TxStatusTypeTest = TxStatusType; + +/// The type of the event that the middleware captures. +#[derive(Debug, PartialEq)] +pub enum MiddlewarePoolEvent { + TransactionStatus { + transaction: String, + status: sc_transaction_pool_api::TransactionStatus< + ::Hash, + ::Hash, + >, + }, + PoolError { + transaction: String, + err: String, + }, +} + +/// The channel that receives events when the broadcast futures are dropped. +pub type MiddlewarePoolRecv = mpsc::UnboundedReceiver; + +/// Add a middleware to the transaction pool. +/// +/// This wraps the `submit_and_watch` to gain access to the events. +pub struct MiddlewarePool { + pub inner_pool: Arc>, + /// Send the middleware events to the test. + sender: mpsc::UnboundedSender, +} + +impl MiddlewarePool { + /// Construct a new [`MiddlewarePool`]. + pub fn new(pool: Arc>) -> (Self, MiddlewarePoolRecv) { + let (sender, recv) = mpsc::unbounded_channel(); + (MiddlewarePool { inner_pool: pool, sender }, recv) + } +} + +impl TransactionPool for MiddlewarePool { + type Block = as TransactionPool>::Block; + type Hash = as TransactionPool>::Hash; + type InPoolTransaction = as TransactionPool>::InPoolTransaction; + type Error = as TransactionPool>::Error; + + fn submit_at( + &self, + at: ::Hash, + source: TransactionSource, + xts: Vec>, + ) -> PoolFuture, Self::Error>>, Self::Error> { + self.inner_pool.submit_at(at, source, xts) + } + + fn submit_one( + &self, + at: ::Hash, + source: TransactionSource, + xt: TransactionFor, + ) -> PoolFuture, Self::Error> { + self.inner_pool.submit_one(at, source, xt) + } + + fn submit_and_watch( + &self, + at: ::Hash, + source: TransactionSource, + xt: TransactionFor, + ) -> PoolFuture>>, Self::Error> { + let pool = self.inner_pool.clone(); + let sender = self.sender.clone(); + let transaction = hex_string(&xt.encode()); + + async move { + let watcher = match pool.submit_and_watch(at, source, xt).await { + Ok(watcher) => watcher, + Err(err) => { + let _ = sender.send(MiddlewarePoolEvent::PoolError { + transaction: transaction.clone(), + err: err.to_string(), + }); + return Err(err); + }, + }; + + let watcher = watcher.map(move |status| { + let sender = sender.clone(); + let transaction = transaction.clone(); + + let _ = sender.send(MiddlewarePoolEvent::TransactionStatus { + transaction, + status: status.clone(), + }); + + status + }); + + Ok(watcher.boxed()) + } + .boxed() + } + + fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { + self.inner_pool.remove_invalid(hashes) + } + + fn status(&self) -> PoolStatus { + self.inner_pool.status() + } + + fn import_notification_stream(&self) -> ImportNotificationStream> { + self.inner_pool.import_notification_stream() + } + + fn hash_of(&self, xt: &TransactionFor) -> TxHash { + self.inner_pool.hash_of(xt) + } + + fn on_broadcasted(&self, propagations: HashMap, Vec>) { + self.inner_pool.on_broadcasted(propagations) + } + + fn ready_transaction(&self, hash: &TxHash) -> Option> { + self.inner_pool.ready_transaction(hash) + } + + fn ready_at( + &self, + at: NumberFor, + ) -> Pin< + Box< + dyn Future< + Output = Box> + Send>, + > + Send, + >, + > { + self.inner_pool.ready_at(at) + } + + fn ready(&self) -> Box> + Send> { + self.inner_pool.ready() + } + + fn futures(&self) -> Vec { + self.inner_pool.futures() + } +} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs new file mode 100644 index 00000000000..ab0caaf906f --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/mod.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +mod executor; +mod middleware_pool; +#[macro_use] +mod setup; + +mod transaction_broadcast_tests; diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs new file mode 100644 index 00000000000..04ee7b9b4c9 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/setup.rs @@ -0,0 +1,120 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use crate::{ + chain_head::test_utils::ChainHeadMockClient, + transaction::{ + api::TransactionBroadcastApiServer, + tests::executor::{TaskExecutorBroadcast, TaskExecutorState}, + TransactionBroadcast as RpcTransactionBroadcast, + }, +}; +use futures::Future; +use jsonrpsee::RpcModule; +use sc_transaction_pool::*; +use std::{pin::Pin, sync::Arc}; +use substrate_test_runtime_client::{prelude::*, Client}; +use substrate_test_runtime_transaction_pool::TestApi; + +use crate::transaction::tests::middleware_pool::{MiddlewarePool, MiddlewarePoolRecv}; + +pub type Block = substrate_test_runtime_client::runtime::Block; + +/// Initial Alice account nonce. +pub const ALICE_NONCE: u64 = 209; + +fn create_basic_pool_with_genesis( + test_api: Arc, + options: Options, +) -> (BasicPool, Pin + Send>>) { + let genesis_hash = { + test_api + .chain() + .read() + .block_by_number + .get(&0) + .map(|blocks| blocks[0].0.header.hash()) + .expect("there is block 0. qed") + }; + BasicPool::new_test(test_api, genesis_hash, genesis_hash, options) +} + +fn maintained_pool( + options: Options, +) -> (BasicPool, Arc, futures::executor::ThreadPool) { + let api = Arc::new(TestApi::with_alice_nonce(ALICE_NONCE)); + let (pool, background_task) = create_basic_pool_with_genesis(api.clone(), options); + + let thread_pool = futures::executor::ThreadPool::new().unwrap(); + thread_pool.spawn_ok(background_task); + (pool, api, thread_pool) +} + +pub fn setup_api( + options: Options, +) -> ( + Arc, + Arc, + Arc>>, + RpcModule>>>, + TaskExecutorState, + MiddlewarePoolRecv, +) { + let (pool, api, _) = maintained_pool(options); + let (pool, pool_state) = MiddlewarePool::new(Arc::new(pool).clone()); + let pool = Arc::new(pool); + + let builder = TestClientBuilder::new(); + let client = Arc::new(builder.build()); + let client_mock = Arc::new(ChainHeadMockClient::new(client.clone())); + + let (task_executor, executor_recv) = TaskExecutorBroadcast::new(); + + let tx_api = + RpcTransactionBroadcast::new(client_mock.clone(), pool.clone(), Arc::new(task_executor)) + .into_rpc(); + + (api, pool, client_mock, tx_api, executor_recv, pool_state) +} + +/// Get the next event from the provided middleware in at most 5 seconds. +macro_rules! get_next_event { + ($middleware:expr) => { + tokio::time::timeout(std::time::Duration::from_secs(5), $middleware.recv()) + .await + .unwrap() + .unwrap() + }; +} + +/// Collect the next number of transaction events from the provided middleware. +macro_rules! get_next_tx_events { + ($middleware:expr, $num:expr) => {{ + let mut events = std::collections::HashMap::new(); + for _ in 0..$num { + let event = get_next_event!($middleware); + match event { + crate::transaction::tests::middleware_pool::MiddlewarePoolEvent::TransactionStatus { transaction, status } => { + events.entry(transaction).or_insert_with(|| vec![]).push(status); + }, + other => panic!("Expected TransactionStatus, received {:?}", other), + }; + } + events + }}; +} diff --git a/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs new file mode 100644 index 00000000000..690a1a64d74 --- /dev/null +++ b/substrate/client/rpc-spec-v2/src/transaction/tests/transaction_broadcast_tests.rs @@ -0,0 +1,523 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +use crate::{hex_string, transaction::error::json_rpc_spec}; +use assert_matches::assert_matches; +use codec::Encode; +use jsonrpsee::{rpc_params, MethodsError as Error}; +use sc_transaction_pool::{Options, PoolLimit}; +use sc_transaction_pool_api::{ChainEvent, MaintainedTransactionPool, TransactionPool}; +use std::sync::Arc; +use substrate_test_runtime_client::AccountKeyring::*; +use substrate_test_runtime_transaction_pool::uxt; + +// Test helpers. +use crate::transaction::tests::{ + middleware_pool::{MiddlewarePoolEvent, TxStatusTypeTest}, + setup::{setup_api, ALICE_NONCE}, +}; + +#[tokio::test] +async fn tx_broadcast_enters_pool() { + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(Default::default()); + + // Start at block 1. + let block_1_header = api.push_block(1, vec![], true); + + let uxt = uxt(Alice, ALICE_NONCE); + let xt = hex_string(&uxt.encode()); + + let operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready + } + ); + + assert_eq!(1, pool.inner_pool.status().ready); + assert_eq!(uxt.encode().len(), pool.inner_pool.status().ready_bytes); + + // Import block 2 with the transaction included. + let block_2_header = api.push_block(2, vec![uxt.clone()], true); + let block_2 = block_2_header.hash(); + + // Announce block 2 to the pool. + let event = ChainEvent::NewBestBlock { hash: block_2, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::InBlock((block_2, 0)) + } + ); + + // The future broadcast awaits for the finalized status to be reached. + // Force the future to exit by calling stop. + let _: () = tx_api + .call("transaction_unstable_stop", rpc_params![&operation_id]) + .await + .unwrap(); + + // Ensure the broadcast future finishes. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); +} + +#[tokio::test] +async fn tx_broadcast_invalid_tx() { + let (_, pool, _, tx_api, mut exec_middleware, _) = setup_api(Default::default()); + + // Invalid parameters. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_broadcast", [1u8]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid params" + ); + + assert_eq!(0, pool.status().ready); + + // Invalid transaction that cannot be decoded. The broadcast silently exits. + let xt = "0xdeadbeef"; + let operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + assert_eq!(0, pool.status().ready); + + // Await the broadcast future to exit. + // Without this we'd be subject to races, where we try to call the stop before the tx is + // dropped. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); + + // The broadcast future was dropped, and the operation is no longer active. + // When the operation is not active, either from the tx being finalized or a + // terminal error; the stop method should return an error. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_stop", rpc_params![&operation_id]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" + ); +} + +#[tokio::test] +async fn tx_stop_with_invalid_operation_id() { + let (_, _, _, tx_api, _, _) = setup_api(Default::default()); + + // Make an invalid stop call. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_stop", ["invalid_operation_id"]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" + ); +} + +#[tokio::test] +async fn tx_broadcast_resubmits_future_nonce_tx() { + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(Default::default()); + + // Start at block 1. + let block_1_header = api.push_block(1, vec![], true); + let block_1 = block_1_header.hash(); + + let current_uxt = uxt(Alice, ALICE_NONCE); + let current_xt = hex_string(¤t_uxt.encode()); + // This lives in the future. + let future_uxt = uxt(Alice, ALICE_NONCE + 1); + let future_xt = hex_string(&future_uxt.encode()); + + let future_operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![&future_xt]) + .await + .unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: future_xt.clone(), + status: TxStatusTypeTest::Future + } + ); + + let event = ChainEvent::NewBestBlock { hash: block_1, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + // Ensure the tx is in the future. + assert_eq!(1, pool.inner_pool.status().future); + + let block_2_header = api.push_block(2, vec![], true); + let block_2 = block_2_header.hash(); + + let operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![¤t_xt]) + .await + .unwrap(); + assert_ne!(future_operation_id, operation_id); + + // Announce block 2 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_2_header).await; + + // Collect the events of both transactions. + let events = get_next_tx_events!(&mut pool_middleware, 2); + // Transactions entered the ready queue. + assert_eq!(events.get(¤t_xt).unwrap(), &vec![TxStatusTypeTest::Ready]); + assert_eq!(events.get(&future_xt).unwrap(), &vec![TxStatusTypeTest::Ready]); + + let event = ChainEvent::NewBestBlock { hash: block_2, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(2, pool.inner_pool.status().ready); + assert_eq!(0, pool.inner_pool.status().future); + + // Finalize transactions. + let block_3_header = api.push_block(3, vec![current_uxt, future_uxt], true); + let block_3 = block_3_header.hash(); + client_mock.trigger_import_stream(block_3_header).await; + + let event = ChainEvent::Finalized { hash: block_3, tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + assert_eq!(0, pool.inner_pool.status().future); + + let events = get_next_tx_events!(&mut pool_middleware, 4); + assert_eq!( + events.get(¤t_xt).unwrap(), + &vec![TxStatusTypeTest::InBlock((block_3, 0)), TxStatusTypeTest::Finalized((block_3, 0))] + ); + assert_eq!( + events.get(&future_xt).unwrap(), + &vec![TxStatusTypeTest::InBlock((block_3, 1)), TxStatusTypeTest::Finalized((block_3, 1))] + ); + + // Both broadcast futures must exit. + let _ = get_next_event!(&mut exec_middleware.recv); + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); +} + +/// This test is similar to `tx_broadcast_enters_pool` +/// However the last block is announced as finalized to force the +/// broadcast future to exit before the `stop` is called. +#[tokio::test] +async fn tx_broadcast_stop_after_broadcast_finishes() { + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(Default::default()); + + // Start at block 1. + let block_1_header = api.push_block(1, vec![], true); + + let uxt = uxt(Alice, ALICE_NONCE); + let xt = hex_string(&uxt.encode()); + + let operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction + // pool.inner_pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready + } + ); + + assert_eq!(1, pool.inner_pool.status().ready); + assert_eq!(uxt.encode().len(), pool.inner_pool.status().ready_bytes); + + // Import block 2 with the transaction included. + let block_2_header = api.push_block(2, vec![uxt.clone()], true); + let block_2 = block_2_header.hash(); + + // Announce block 2 to the pool.inner_pool. + let event = ChainEvent::Finalized { hash: block_2, tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + + assert_eq!(0, pool.inner_pool.status().ready); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::InBlock((block_2, 0)) + } + ); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Finalized((block_2, 0)) + } + ); + + // Ensure the broadcast future terminated properly. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); + + // The operation ID is no longer valid, check that the broadcast future + // cleared out the inner state of the operation. + let err = tx_api + .call::<_, serde_json::Value>("transaction_unstable_stop", rpc_params![&operation_id]) + .await + .unwrap_err(); + assert_matches!(err, + Error::JsonRpc(err) if err.code() == json_rpc_spec::INVALID_PARAM_ERROR && err.message() == "Invalid operation id" + ); +} + +#[tokio::test] +async fn tx_broadcast_resubmits_invalid_tx() { + let limits = PoolLimit { count: 8192, total_bytes: 20 * 1024 * 1024 }; + let options = Options { + ready: limits.clone(), + future: limits, + reject_future_transactions: false, + // This ensures that a transaction is not banned. + ban_time: std::time::Duration::ZERO, + }; + + let (api, pool, client_mock, tx_api, mut exec_middleware, mut pool_middleware) = + setup_api(options); + + let uxt = uxt(Alice, ALICE_NONCE); + let xt = hex_string(&uxt.encode()); + let _operation_id: String = + tx_api.call("transaction_unstable_broadcast", rpc_params![&xt]).await.unwrap(); + + let block_1_header = api.push_block(1, vec![], true); + let block_1 = block_1_header.hash(); + // Announce block 1 to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_1_header).await; + + // Ensure the tx propagated from `transaction_unstable_broadcast` to the transaction pool. + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready, + } + ); + assert_eq!(1, pool.inner_pool.status().ready); + assert_eq!(uxt.encode().len(), pool.inner_pool.status().ready_bytes); + + // Mark the transaction as invalid from the API, causing a temporary ban. + api.add_invalid(&uxt); + + // Push an event to the pool to ensure the transaction is excluded. + let event = ChainEvent::NewBestBlock { hash: block_1, tree_route: None }; + pool.inner_pool.maintain(event).await; + assert_eq!(1, pool.inner_pool.status().ready); + + // Ensure the `transaction_unstable_broadcast` is aware of the invalid transaction. + let event = get_next_event!(&mut pool_middleware); + // Because we have received an `Invalid` status, we try to broadcast the transaction with the + // next announced block. + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Invalid + } + ); + + // Import block 2. + let block_2_header = api.push_block(2, vec![], true); + client_mock.trigger_import_stream(block_2_header).await; + + // Ensure we propagate the temporary ban error to `submit_and_watch`. + // This ensures we'll loop again with the next annmounced block and try to resubmit the + // transaction. The transaction remains temporarily banned until the pool is maintained. + let event = get_next_event!(&mut pool_middleware); + assert_matches!(event, MiddlewarePoolEvent::PoolError { transaction, err } if transaction == xt && err.contains("Transaction temporarily Banned")); + + // Import block 3. + let block_3_header = api.push_block(3, vec![], true); + let block_3 = block_3_header.hash(); + // Remove the invalid transaction from the pool to allow it to pass through. + api.remove_invalid(&uxt); + let event = ChainEvent::NewBestBlock { hash: block_3, tree_route: None }; + // We have to maintain the pool to ensure the transaction is no longer invalid. + // This clears out the banned transactions. + pool.inner_pool.maintain(event).await; + assert_eq!(0, pool.inner_pool.status().ready); + + // Announce block to `transaction_unstable_broadcast`. + client_mock.trigger_import_stream(block_3_header).await; + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Ready, + } + ); + assert_eq!(1, pool.inner_pool.status().ready); + + let block_4_header = api.push_block(4, vec![uxt], true); + let block_4 = block_4_header.hash(); + let event = ChainEvent::Finalized { hash: block_4, tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::InBlock((block_4, 0)), + } + ); + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: xt.clone(), + status: TxStatusTypeTest::Finalized((block_4, 0)), + } + ); + + // Ensure the broadcast future terminated properly. + let _ = get_next_event!(&mut exec_middleware.recv); + assert_eq!(0, exec_middleware.num_tasks()); +} + +/// This is similar to `tx_broadcast_resubmits_invalid_tx`. +/// However, it forces the tx to be resubmited because of the pool +/// limits. Which is a different code path than the invalid tx. +#[tokio::test] +async fn tx_broadcast_resubmits_dropped_tx() { + let limits = PoolLimit { count: 1, total_bytes: 1000 }; + let options = Options { + ready: limits.clone(), + future: limits, + reject_future_transactions: false, + // This ensures that a transaction is not banned. + ban_time: std::time::Duration::ZERO, + }; + + let (api, pool, client_mock, tx_api, _, mut pool_middleware) = setup_api(options); + + let current_uxt = uxt(Alice, ALICE_NONCE); + let current_xt = hex_string(¤t_uxt.encode()); + // This lives in the future. + let future_uxt = uxt(Alice, ALICE_NONCE + 1); + let future_xt = hex_string(&future_uxt.encode()); + + // By default the `validate_transaction` mock uses priority 1 for + // transactions. Bump the priority to ensure other transactions + // are immediately dropped. + api.set_priority(¤t_uxt, 10); + + let current_operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![¤t_xt]) + .await + .unwrap(); + + // Announce block 1 to `transaction_unstable_broadcast`. + let block_1_header = api.push_block(1, vec![], true); + let event = + ChainEvent::Finalized { hash: block_1_header.hash(), tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + client_mock.trigger_import_stream(block_1_header).await; + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::TransactionStatus { + transaction: current_xt.clone(), + status: TxStatusTypeTest::Ready, + } + ); + assert_eq!(1, pool.inner_pool.status().ready); + + // The future tx has priority 2, smaller than the current 10. + api.set_priority(&future_uxt, 2); + let future_operation_id: String = tx_api + .call("transaction_unstable_broadcast", rpc_params![&future_xt]) + .await + .unwrap(); + assert_ne!(current_operation_id, future_operation_id); + + let block_2_header = api.push_block(2, vec![], true); + let event = + ChainEvent::Finalized { hash: block_2_header.hash(), tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + client_mock.trigger_import_stream(block_2_header).await; + + // We must have at most 1 transaction in the pool, as per limits above. + assert_eq!(1, pool.inner_pool.status().ready); + + let event = get_next_event!(&mut pool_middleware); + assert_eq!( + event, + MiddlewarePoolEvent::PoolError { + transaction: future_xt.clone(), + err: "Transaction couldn't enter the pool because of the limit".into() + } + ); + + let block_3_header = api.push_block(3, vec![current_uxt], true); + let event = + ChainEvent::Finalized { hash: block_3_header.hash(), tree_route: Arc::from(vec![]) }; + pool.inner_pool.maintain(event).await; + client_mock.trigger_import_stream(block_3_header.clone()).await; + + // The first tx is in a finalzied block; the future tx must enter the pool. + let events = get_next_tx_events!(&mut pool_middleware, 3); + assert_eq!( + events.get(¤t_xt).unwrap(), + &vec![ + TxStatusTypeTest::InBlock((block_3_header.hash(), 0)), + TxStatusTypeTest::Finalized((block_3_header.hash(), 0)) + ] + ); + // The dropped transaction was resubmitted. + assert_eq!(events.get(&future_xt).unwrap(), &vec![TxStatusTypeTest::Ready]); +} diff --git a/substrate/client/transaction-pool/src/lib.rs b/substrate/client/transaction-pool/src/lib.rs index faa3f455a58..64b301e6bf3 100644 --- a/substrate/client/transaction-pool/src/lib.rs +++ b/substrate/client/transaction-pool/src/lib.rs @@ -164,8 +164,9 @@ where pool_api: Arc, best_block_hash: Block::Hash, finalized_hash: Block::Hash, + options: graph::Options, ) -> (Self, Pin + Send>>) { - let pool = Arc::new(graph::Pool::new(Default::default(), true.into(), pool_api.clone())); + let pool = Arc::new(graph::Pool::new(options, true.into(), pool_api.clone())); let (revalidation_queue, background_task) = revalidation::RevalidationQueue::new_background( pool_api.clone(), pool.clone(), diff --git a/substrate/client/transaction-pool/tests/pool.rs b/substrate/client/transaction-pool/tests/pool.rs index 6b1a197440c..461b9860d41 100644 --- a/substrate/client/transaction-pool/tests/pool.rs +++ b/substrate/client/transaction-pool/tests/pool.rs @@ -73,7 +73,7 @@ fn create_basic_pool_with_genesis( .map(|blocks| blocks[0].0.header.hash()) .expect("there is block 0. qed") }; - BasicPool::new_test(test_api, genesis_hash, genesis_hash) + BasicPool::new_test(test_api, genesis_hash, genesis_hash, Default::default()) } fn create_basic_pool(test_api: TestApi) -> BasicPool { @@ -994,6 +994,7 @@ fn import_notification_to_pool_maintain_works() { )), best_hash, finalized_hash, + Default::default(), ) .0, ); diff --git a/substrate/test-utils/runtime/transaction-pool/src/lib.rs b/substrate/test-utils/runtime/transaction-pool/src/lib.rs index 8c8345b06bd..5202e6e6515 100644 --- a/substrate/test-utils/runtime/transaction-pool/src/lib.rs +++ b/substrate/test-utils/runtime/transaction-pool/src/lib.rs @@ -81,6 +81,7 @@ pub struct ChainState { pub block_by_hash: HashMap, pub nonces: HashMap, pub invalid_hashes: HashSet, + pub priorities: HashMap, } /// Test Api for transaction pool. @@ -214,6 +215,22 @@ impl TestApi { self.chain.write().invalid_hashes.insert(Self::hash_and_length_inner(xts).0); } + /// Remove a transaction that was previously declared as invalid via `[Self::add_invalid]`. + /// + /// Next time transaction pool will try to validate this + /// extrinsic, api will succeed. + pub fn remove_invalid(&self, xts: &Extrinsic) { + self.chain.write().invalid_hashes.remove(&Self::hash_and_length_inner(xts).0); + } + + /// Set a transaction priority. + pub fn set_priority(&self, xts: &Extrinsic, priority: u64) { + self.chain + .write() + .priorities + .insert(Self::hash_and_length_inner(xts).0, priority); + } + /// Query validation requests received. pub fn validation_requests(&self) -> Vec { self.validation_requests.read().clone() @@ -300,8 +317,14 @@ impl ChainApi for TestApi { return ready(Ok(Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))))) } - let mut validity = - ValidTransaction { priority: 1, requires, provides, longevity: 64, propagate: true }; + let priority = self.chain.read().priorities.get(&self.hash_and_length(&uxt).0).cloned(); + let mut validity = ValidTransaction { + priority: priority.unwrap_or(1), + requires, + provides, + longevity: 64, + propagate: true, + }; (self.valid_modifier.read())(&mut validity); -- GitLab From f4eedcebafa4d2addb8b71ba31ab1bc579ba3c4a Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 28 Feb 2024 13:13:27 +0100 Subject: [PATCH 270/283] [prdoc] Optional SemVer bumps and Docs (#3441) Changes: - Add an optional `bump` field to the crates in a prdoc. - Explain the cargo semver interpretation for <1 versions in the release doc. --------- Signed-off-by: Oliver Tale-Yazdi --- docs/RELEASE.md | 12 +++++++++--- prdoc/schema_user.json | 33 +++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 6d681d78f36..e73be2779a9 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -18,10 +18,16 @@ Rococo. To easily refer to a release, it shall be named by its date in the form ## Crate -We try to follow [SemVer 2.0.0](https://semver.org/) as best as possible for versioning our crates. SemVer requires a -piece of software to first declare a public API. The public API of the Polkadot SDK is hereby declared as the sum of all -crates' public APIs. +We try to follow [SemVer 2.0.0](https://semver.org/) as best as possible for versioning our crates. The definitions of +`major`, `minor` and `patch` version for Rust crates are slightly altered from their standard for pre `1.0.0` versions. +Quoting [rust-lang.org](https://doc.rust-lang.org/cargo/reference/semver.html): +>Initial development releases starting with “0.y.z” can treat changes in “y” as a major release, and “z” as a minor +release. “0.0.z” releases are always major changes. This is because Cargo uses the convention that only changes in the +left-most non-zero component are considered incompatible. + +SemVer requires a piece of software to first declare a public API. The public API of the Polkadot SDK +is hereby declared as the sum of all crates' public APIs. Inductively, the public API of our library crates is declared as all public items that are neither: - Inside a `__private` module diff --git a/prdoc/schema_user.json b/prdoc/schema_user.json index 82215d51866..1bd0b3b93ee 100644 --- a/prdoc/schema_user.json +++ b/prdoc/schema_user.json @@ -3,9 +3,8 @@ "$id": "https://raw.githubusercontent.com/paritytech/prdoc/master/prdoc_schema_user.json", "version": { "major": 1, - "minor": 0, - "patch": 0, - "timestamp": 20230817152351 + "minor": 1, + "patch": 0 }, "title": "Polkadot SDK PRDoc Schema", "description": "JSON Schema definition for the Polkadot SDK PR documentation", @@ -125,10 +124,16 @@ "name": { "type": "string" }, + "bump": { + "$ref": "#/$defs/semver_bump" + }, "note": { "type": "string" } - } + }, + "required": [ + "name" + ] }, "migration_db": { "type": "object", @@ -165,6 +170,26 @@ "description" ] }, + "semver_bump": { + "description": "The type of bump to apply to the crate version according to Cargo SemVer: https://doc.rust-lang.org/cargo/reference/semver.html. Please check docs/RELEASE.md for more information.", + "oneOf": [ + { + "const": "major", + "title": "Major", + "description": "A bump to the leftmost non-zero digit of the version number." + }, + { + "const": "minor", + "title": "Minor", + "description": "A bump to the second leftmost non-zero digit of the version number." + }, + { + "const": "patch", + "title": "Patch", + "description": "A bump to the third leftmost non-zero digit of the version number." + } + ] + }, "doc": { "type": "object", "description": "You have the the option to provide different description of your PR for different audiences.", -- GitLab From 14530269b7a76f50dc939bf57b1e3d38270b662b Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:07:14 +0000 Subject: [PATCH 271/283] Add documentation around FRAME Offchain workers (#3463) - deprecation companion: https://github.com/substrate-developer-hub/substrate-docs/pull/2136 - inspired by https://substrate.stackexchange.com/questions/11058/how-can-i-create-ocw-that-wont-activates-every-block-but-will-activates-only-w/11060#11060 --------- Co-authored-by: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> --- Cargo.lock | 2 + docs/sdk/Cargo.toml | 5 +- .../reference_docs/frame_offchain_workers.rs | 115 ++++++++++++++++++ docs/sdk/src/reference_docs/mod.rs | 4 + substrate/frame/support/src/traits/hooks.rs | 2 +- 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 docs/sdk/src/reference_docs/frame_offchain_workers.rs diff --git a/Cargo.lock b/Cargo.lock index 026786378d5..ef510986257 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13416,6 +13416,7 @@ dependencies = [ "pallet-collective", "pallet-default-config-example", "pallet-democracy", + "pallet-example-offchain-worker", "pallet-example-single-block-migrations", "pallet-examples", "pallet-multisig", @@ -13442,6 +13443,7 @@ dependencies = [ "sp-core", "sp-io", "sp-keyring", + "sp-offchain", "sp-runtime", "sp-version", "staging-chain-spec-builder", diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index b1b60a2d77d..735b3d7df61 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -23,6 +23,7 @@ frame = { path = "../../substrate/frame", features = [ ] } pallet-examples = { path = "../../substrate/frame/examples" } pallet-default-config-example = { path = "../../substrate/frame/examples/default-config" } +pallet-example-offchain-worker = { path = "../../substrate/frame/examples/offchain-worker" } # How we build docs in rust-docs simple-mermaid = "0.1.1" @@ -38,7 +39,7 @@ frame-support = { path = "../../substrate/frame/support", default-features = fal frame-executive = { path = "../../substrate/frame/executive", default-features = false } pallet-example-single-block-migrations = { path = "../../substrate/frame/examples/single-block-migrations" } -# Substrate +# Substrate Client sc-network = { path = "../../substrate/client/network" } sc-rpc-api = { path = "../../substrate/client/rpc-api" } sc-rpc = { path = "../../substrate/client/rpc" } @@ -50,6 +51,7 @@ sc-consensus-grandpa = { path = "../../substrate/client/consensus/grandpa" } sc-consensus-beefy = { path = "../../substrate/client/consensus/beefy" } sc-consensus-manual-seal = { path = "../../substrate/client/consensus/manual-seal" } sc-consensus-pow = { path = "../../substrate/client/consensus/pow" } + substrate-wasm-builder = { path = "../../substrate/utils/wasm-builder" } # Cumulus @@ -78,6 +80,7 @@ sp-api = { path = "../../substrate/primitives/api" } sp-core = { path = "../../substrate/primitives/core" } sp-keyring = { path = "../../substrate/primitives/keyring" } sp-runtime = { path = "../../substrate/primitives/runtime" } +sp-offchain = { path = "../../substrate/primitives/offchain" } sp-version = { path = "../../substrate/primitives/version" } # XCM diff --git a/docs/sdk/src/reference_docs/frame_offchain_workers.rs b/docs/sdk/src/reference_docs/frame_offchain_workers.rs new file mode 100644 index 00000000000..7999707e5ee --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_offchain_workers.rs @@ -0,0 +1,115 @@ +//! # Offchain Workers +//! +//! This reference document explains how offchain workers work in Substrate and FRAME. The main +//! focus is upon FRAME's implementation of this functionality. Nonetheless, offchain workers are a +//! Substrate-provided feature and can be used with possible alternatives to [`frame`] as well. +//! +//! Offchain workers are a commonly misunderstood topic, therefore we explain them bottom-up, +//! starting at the fundamentals and then describing the developer interface. +//! +//! ## Context +//! +//! Recall from [`crate::reference_docs::wasm_meta_protocol`] that the node and the runtime +//! communicate with one another via host functions and runtime APIs. Many of these interactions +//! contribute to the actual state transition of the blockchain. For example [`sp_api::Core`] is the +//! main runtime API that is called to execute new blocks. +//! +//! Offchain workers are in principle not different in any way: It is a runtime API exposed by the +//! wasm blob ([`sp_offchain::OffchainWorkerApi`]), and the node software calls into it when it +//! deems fit. But, crucially, this API call is different in that: +//! +//! 1. It can have no impact on the state ie. it is _OFF (the) CHAIN_. If any state is altered +//! during the execution of this API call, it is discarded. +//! 2. It has access to an extended set of host functions that allow the wasm blob to do more. For +//! example, call into HTTP requests. +//! +//! > The main way through which an offchain worker can interact with the state is by submitting an +//! > extrinsic to the chain. This is the ONLY way to alter the state from an offchain worker. +//! > [`pallet_example_offchain_worker`] provides an example of this. +//! +//! +//! Given the "Off Chain" nature of this API, it is important to remember that calling this API is +//! entirely optional. Some nodes might call into it, some might not, and it would have no impact on +//! the execution of your blockchain because no state is altered no matter the execution of the +//! offchain worker API. +//! +//! Substrate's CLI allows some degree of configuration about this, allowing node operators to +//! specify when they want to run the offchain worker API. See +//! [`sc_cli::RunCmd::offchain_worker_params`]. +//! +//! ## Nondeterministic Execution +//! +//! Needless to say, given the above description, the code in your offchain worker API can be +//! nondeterministic, as it is not part of the blockchain's STF, so it can be executed at unknown +//! times, by unknown nodes, and has no impact on the state. This is why an HTTP +//! ([`sp_runtime::offchain::http`]) API is readily provided to the offchain worker APIs. Because +//! there is no need for determinism in this context. +//! +//! > A common mistake here is for novice developers to see this HTTP API, and imagine that +//! > `polkadot-sdk` somehow magically solved the determinism in blockchains, and now a blockchain +//! > can make HTTP calls and it will all work. This is absolutely NOT the case. An HTTP call made +//! > by the offchain worker is non-deterministic by design. Blockchains can't and always won't be +//! > able to perform non-deterministic operations such as making HTTP calls to a foreign server. +//! +//! ## FRAME's API +//! +//! [`frame`] provides a simple API through which pallets can define offchain worker functions. This +//! is part of [`frame::traits::Hooks`], which is implemented as a part of +//! [`frame::pallet_macros::hooks`]. +//! +//! ``` +//! +//! #[frame::pallet] +//! pub mod pallet { +//! use frame::prelude::*; +//! +//! #[pallet::config] +//! pub trait Config: frame_system::Config {} +//! +//! #[pallet::pallet] +//! pub struct Pallet(_); +//! +//! #[pallet::hooks] +//! impl Hooks> for Pallet { +//! fn offchain_worker(block_number: BlockNumberFor) { +//! // ... +//! } +//! } +//! } +//! ``` +//! +//! Additionally, [`sp_runtime::offchain`] provides a set of utilities that can be used to moderate +//! the execution of offchain workers. +//! +//! ## Think Twice: Why Use Substrate's Offchain Workers? +//! +//! Consider the fact that in principle, an offchain worker code written using the above API is no +//! different than an equivalent written with an _actual offchain interaction library_, such as +//! [Polkadot-JS](https://polkadot.js.org/docs/), or any of the other ones listed [here](https://github.com/substrate-developer-hub/awesome-substrate?tab=readme-ov-file#client-libraries). +//! +//! They can both read from the state, and have no means of updating the state, other than the route +//! of submitting an extrinsic to the chain. Therefore, it is worth thinking twice before embedding +//! a logic as a part of Substrate's offchain worker API. Does it have to be there? can it not be a +//! simple, actual offchain application that lives outside of the chain's WASM blob? +//! +//! Some of the reasons why you might want to do the opposite, and actually embed an offchain worker +//! API into the WASM blob are: +//! +//! * Accessing the state is easier within the `offchain_worker` function, as it is already a part +//! of the runtime, and [`frame::pallet_macros::storage`] provides all the tools needed to read +//! the state. Other client libraries might provide varying degrees of capability here. +//! * It will be updated in synchrony with the runtime. A Substrate's offchain application is part +//! of the same WASM blob, and is therefore guaranteed to be up to date. +//! +//! For example, imagine you have modified a storage item to have a new type. This will possibly +//! require a [`crate::reference_docs::frame_runtime_upgrades_and_migrations`], and any offchain +//! code, such as a Polkadot-JS application, will have to be updated to reflect this change. Whereas +//! the WASM offchain worker code is guaranteed to already be updated, or else the runtime code will +//! not even compile. +//! +//! +//! ## Further References +//! +//! - +//! - +//! - [Offchain worker example](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/examples/offchain-worker) diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index b2c751420ce..0bd204e4b6a 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -99,3 +99,7 @@ pub mod frame_runtime_upgrades_and_migrations; /// light-node-first out of the box. // TODO: @jsdw @josepot https://github.com/paritytech/polkadot-sdk-docs/issues/68 pub mod light_nodes; + +/// Learn about the offchain workers, how they function, and how to use them, as provided by the +/// [`frame`] APIs. +pub mod frame_offchain_workers; diff --git a/substrate/frame/support/src/traits/hooks.rs b/substrate/frame/support/src/traits/hooks.rs index 72f047c3a73..c37fb0f54bc 100644 --- a/substrate/frame/support/src/traits/hooks.rs +++ b/substrate/frame/support/src/traits/hooks.rs @@ -446,7 +446,7 @@ pub trait Hooks { } /// Implementing this function on a pallet allows you to perform long-running tasks that are - /// dispatched as separate threads, and entirely independent of the main wasm runtime. + /// dispatched as separate threads, and entirely independent of the main blockchain execution. /// /// This function can freely read from the state, but any change it makes to the state is /// meaningless. Writes can be pushed back to the chain by submitting extrinsics from the -- GitLab From 426136671a42ff759127b4a7a71eac6335744675 Mon Sep 17 00:00:00 2001 From: maksimryndin Date: Wed, 28 Feb 2024 17:29:27 +0100 Subject: [PATCH 272/283] PVF: re-preparing artifact on failed runtime construction (#3187) resolve https://github.com/paritytech/polkadot-sdk/issues/3139 - [x] use a distinguishable error for `execute_artifact` - [x] remove artifact in case of a `RuntimeConstruction` error during the execution - [x] augment the `validate_candidate_with_retry` of `ValidationBackend` with the case of retriable `RuntimeConstruction` error during the execution - [x] update the book (https://paritytech.github.io/polkadot-sdk/book/node/utility/pvf-host-and-workers.html#retrying-execution-requests) - [x] add a test - [x] run zombienet tests --------- Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> --- .../node/core/candidate-validation/src/lib.rs | 53 +++++++----- polkadot/node/core/pvf/common/src/error.rs | 1 + polkadot/node/core/pvf/common/src/execute.rs | 15 ++++ .../core/pvf/common/src/executor_interface.rs | 4 +- .../node/core/pvf/execute-worker/src/lib.rs | 10 ++- polkadot/node/core/pvf/src/artifacts.rs | 8 ++ polkadot/node/core/pvf/src/error.rs | 4 + polkadot/node/core/pvf/src/execute/mod.rs | 2 +- polkadot/node/core/pvf/src/execute/queue.rs | 68 ++++++++++++--- .../core/pvf/src/execute/worker_interface.rs | 8 ++ polkadot/node/core/pvf/src/host.rs | 53 +++++++++++- polkadot/node/core/pvf/tests/it/main.rs | 83 +++++++++++++++++-- polkadot/primitives/src/v6/executor_params.rs | 10 +-- .../src/node/utility/pvf-host-and-workers.md | 8 ++ prdoc/pr_3187.prdoc | 16 ++++ 15 files changed, 294 insertions(+), 49 deletions(-) create mode 100644 prdoc/pr_3187.prdoc diff --git a/polkadot/node/core/candidate-validation/src/lib.rs b/polkadot/node/core/candidate-validation/src/lib.rs index bf6e09fd1b6..8237137fdca 100644 --- a/polkadot/node/core/candidate-validation/src/lib.rs +++ b/polkadot/node/core/candidate-validation/src/lib.rs @@ -695,6 +695,8 @@ async fn validate_candidate_exhaustive( ))), Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))) => Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))), + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction(err))) => + Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))), Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousJobDeath(err))) => Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(format!( @@ -780,40 +782,50 @@ trait ValidationBackend { return validation_result } + macro_rules! break_if_no_retries_left { + ($counter:ident) => { + if $counter > 0 { + $counter -= 1; + } else { + break + } + }; + } + // Allow limited retries for each kind of error. let mut num_death_retries_left = 1; let mut num_job_error_retries_left = 1; let mut num_internal_retries_left = 1; + let mut num_runtime_construction_retries_left = 1; loop { // Stop retrying if we exceeded the timeout. if total_time_start.elapsed() + retry_delay > exec_timeout { break } - + let mut retry_immediately = false; match validation_result { Err(ValidationError::PossiblyInvalid( PossiblyInvalidError::AmbiguousWorkerDeath | PossiblyInvalidError::AmbiguousJobDeath(_), - )) => - if num_death_retries_left > 0 { - num_death_retries_left -= 1; - } else { - break - }, + )) => break_if_no_retries_left!(num_death_retries_left), Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(_))) => - if num_job_error_retries_left > 0 { - num_job_error_retries_left -= 1; - } else { - break - }, + break_if_no_retries_left!(num_job_error_retries_left), Err(ValidationError::Internal(_)) => - if num_internal_retries_left > 0 { - num_internal_retries_left -= 1; - } else { - break - }, + break_if_no_retries_left!(num_internal_retries_left), + + Err(ValidationError::PossiblyInvalid( + PossiblyInvalidError::RuntimeConstruction(_), + )) => { + break_if_no_retries_left!(num_runtime_construction_retries_left); + self.precheck_pvf(pvf.clone()).await?; + // In this case the error is deterministic + // And a retry forces the ValidationBackend + // to re-prepare the artifact so + // there is no need to wait before the retry + retry_immediately = true; + }, Ok(_) | Err(ValidationError::Invalid(_) | ValidationError::Preparation(_)) => break, } @@ -821,8 +833,11 @@ trait ValidationBackend { // If we got a possibly transient error, retry once after a brief delay, on the // assumption that the conditions that caused this error may have resolved on their own. { - // Wait a brief delay before retrying. - futures_timer::Delay::new(retry_delay).await; + // In case of many transient errors it is necessary to wait a little bit + // for the error to be probably resolved + if !retry_immediately { + futures_timer::Delay::new(retry_delay).await; + } let new_timeout = exec_timeout.saturating_sub(total_time_start.elapsed()); diff --git a/polkadot/node/core/pvf/common/src/error.rs b/polkadot/node/core/pvf/common/src/error.rs index f8faefc24e6..cf274044456 100644 --- a/polkadot/node/core/pvf/common/src/error.rs +++ b/polkadot/node/core/pvf/common/src/error.rs @@ -16,6 +16,7 @@ use crate::prepare::{PrepareSuccess, PrepareWorkerSuccess}; use parity_scale_codec::{Decode, Encode}; +pub use sc_executor_common::error::Error as ExecuteError; /// Result of PVF preparation from a worker, with checksum of the compiled PVF and stats of the /// preparation if successful. diff --git a/polkadot/node/core/pvf/common/src/execute.rs b/polkadot/node/core/pvf/common/src/execute.rs index 6b3becf524d..18c97b03cbc 100644 --- a/polkadot/node/core/pvf/common/src/execute.rs +++ b/polkadot/node/core/pvf/common/src/execute.rs @@ -40,6 +40,9 @@ pub enum WorkerResponse { }, /// The candidate is invalid. InvalidCandidate(String), + /// Instantiation of the WASM module instance failed during an execution. + /// Possibly related to local issues or dirty node update. May be retried with re-preparation. + RuntimeConstruction(String), /// The job timed out. JobTimedOut, /// The job process has died. We must kill the worker just in case. @@ -68,6 +71,9 @@ pub enum JobResponse { /// The result of parachain validation. result_descriptor: ValidationResult, }, + /// A possibly transient runtime instantiation error happened during the execution; may be + /// retried with re-preparation + RuntimeConstruction(String), /// The candidate is invalid. InvalidCandidate(String), } @@ -81,6 +87,15 @@ impl JobResponse { Self::InvalidCandidate(format!("{}: {}", ctx, msg)) } } + + /// Creates a may retry response from a context `ctx` and a message `msg` (which can be empty). + pub fn runtime_construction(ctx: &'static str, msg: &str) -> Self { + if msg.is_empty() { + Self::RuntimeConstruction(ctx.to_string()) + } else { + Self::RuntimeConstruction(format!("{}: {}", ctx, msg)) + } + } } /// An unexpected error occurred in the execution job process. Because this comes from the job, diff --git a/polkadot/node/core/pvf/common/src/executor_interface.rs b/polkadot/node/core/pvf/common/src/executor_interface.rs index 4cd2f5c85ee..b69a87890f6 100644 --- a/polkadot/node/core/pvf/common/src/executor_interface.rs +++ b/polkadot/node/core/pvf/common/src/executor_interface.rs @@ -16,6 +16,7 @@ //! Interface to the Substrate Executor +use crate::error::ExecuteError; use polkadot_primitives::{ executor_params::{DEFAULT_LOGICAL_STACK_MAX, DEFAULT_NATIVE_STACK_MAX}, ExecutorParam, ExecutorParams, @@ -109,7 +110,7 @@ pub unsafe fn execute_artifact( compiled_artifact_blob: &[u8], executor_params: &ExecutorParams, params: &[u8], -) -> Result, String> { +) -> Result, ExecuteError> { let mut extensions = sp_externalities::Extensions::new(); extensions.register(sp_core::traits::ReadRuntimeVersionExt::new(ReadRuntimeVersion)); @@ -123,7 +124,6 @@ pub unsafe fn execute_artifact( Ok(Ok(ok)) => Ok(ok), Ok(Err(err)) | Err(err) => Err(err), } - .map_err(|err| format!("execute error: {:?}", err)) } /// Constructs the runtime for the given PVF, given the artifact bytes. diff --git a/polkadot/node/core/pvf/execute-worker/src/lib.rs b/polkadot/node/core/pvf/execute-worker/src/lib.rs index 0cfa5a78694..bd7e76010a6 100644 --- a/polkadot/node/core/pvf/execute-worker/src/lib.rs +++ b/polkadot/node/core/pvf/execute-worker/src/lib.rs @@ -16,7 +16,9 @@ //! Contains the logic for executing PVFs. Used by the polkadot-execute-worker binary. -pub use polkadot_node_core_pvf_common::executor_interface::execute_artifact; +pub use polkadot_node_core_pvf_common::{ + error::ExecuteError, executor_interface::execute_artifact, +}; // NOTE: Initializing logging in e.g. tests will not have an effect in the workers, as they are // separate spawned processes. Run with e.g. `RUST_LOG=parachain::pvf-execute-worker=trace`. @@ -237,7 +239,9 @@ fn validate_using_artifact( // [`executor_interface::prepare`]. execute_artifact(compiled_artifact_blob, executor_params, params) } { - Err(err) => return JobResponse::format_invalid("execute", &err), + Err(ExecuteError::RuntimeConstruction(wasmerr)) => + return JobResponse::runtime_construction("execute", &wasmerr.to_string()), + Err(err) => return JobResponse::format_invalid("execute", &err.to_string()), Ok(d) => d, }; @@ -550,6 +554,8 @@ fn handle_parent_process( Ok(WorkerResponse::Ok { result_descriptor, duration: cpu_tv }) }, Ok(JobResponse::InvalidCandidate(err)) => Ok(WorkerResponse::InvalidCandidate(err)), + Ok(JobResponse::RuntimeConstruction(err)) => + Ok(WorkerResponse::RuntimeConstruction(err)), Err(job_error) => { gum::warn!( target: LOG_TARGET, diff --git a/polkadot/node/core/pvf/src/artifacts.rs b/polkadot/node/core/pvf/src/artifacts.rs index 78dfe71adad..6288755526d 100644 --- a/polkadot/node/core/pvf/src/artifacts.rs +++ b/polkadot/node/core/pvf/src/artifacts.rs @@ -238,6 +238,14 @@ impl Artifacts { .is_none()); } + /// Remove artifact by its id. + pub fn remove(&mut self, artifact_id: ArtifactId) -> Option<(ArtifactId, PathBuf)> { + self.inner.remove(&artifact_id).and_then(|state| match state { + ArtifactState::Prepared { path, .. } => Some((artifact_id, path)), + _ => None, + }) + } + /// Remove artifacts older than the given TTL and return id and path of the removed ones. pub fn prune(&mut self, artifact_ttl: Duration) -> Vec<(ArtifactId, PathBuf)> { let now = SystemTime::now(); diff --git a/polkadot/node/core/pvf/src/error.rs b/polkadot/node/core/pvf/src/error.rs index 80d41d5c64b..8dc96305ead 100644 --- a/polkadot/node/core/pvf/src/error.rs +++ b/polkadot/node/core/pvf/src/error.rs @@ -86,6 +86,10 @@ pub enum PossiblyInvalidError { /// vote invalid. #[error("possibly invalid: job error: {0}")] JobError(String), + /// Instantiation of the WASM module instance failed during an execution. + /// Possibly related to local issues or dirty node update. May be retried with re-preparation. + #[error("possibly invalid: runtime construction: {0}")] + RuntimeConstruction(String), } impl From for ValidationError { diff --git a/polkadot/node/core/pvf/src/execute/mod.rs b/polkadot/node/core/pvf/src/execute/mod.rs index c6d9cf90fa2..365e98196ca 100644 --- a/polkadot/node/core/pvf/src/execute/mod.rs +++ b/polkadot/node/core/pvf/src/execute/mod.rs @@ -23,4 +23,4 @@ mod queue; mod worker_interface; -pub use queue::{start, PendingExecutionRequest, ToQueue}; +pub use queue::{start, FromQueue, PendingExecutionRequest, ToQueue}; diff --git a/polkadot/node/core/pvf/src/execute/queue.rs b/polkadot/node/core/pvf/src/execute/queue.rs index aa91d11781f..bdc3c7327b0 100644 --- a/polkadot/node/core/pvf/src/execute/queue.rs +++ b/polkadot/node/core/pvf/src/execute/queue.rs @@ -25,7 +25,7 @@ use crate::{ InvalidCandidate, PossiblyInvalidError, ValidationError, LOG_TARGET, }; use futures::{ - channel::mpsc, + channel::{mpsc, oneshot}, future::BoxFuture, stream::{FuturesUnordered, StreamExt as _}, Future, FutureExt, @@ -54,6 +54,12 @@ pub enum ToQueue { Enqueue { artifact: ArtifactPathId, pending_execution_request: PendingExecutionRequest }, } +/// A response from queue. +#[derive(Debug)] +pub enum FromQueue { + RemoveArtifact { artifact: ArtifactId, reply_to: oneshot::Sender<()> }, +} + /// An execution request that should execute the PVF (known in the context) and send the results /// to the given result sender. #[derive(Debug)] @@ -137,6 +143,8 @@ struct Queue { /// The receiver that receives messages to the pool. to_queue_rx: mpsc::Receiver, + /// The sender to send messages back to validation host. + from_queue_tx: mpsc::UnboundedSender, // Some variables related to the current session. program_path: PathBuf, @@ -161,6 +169,7 @@ impl Queue { node_version: Option, security_status: SecurityStatus, to_queue_rx: mpsc::Receiver, + from_queue_tx: mpsc::UnboundedSender, ) -> Self { Self { metrics, @@ -170,6 +179,7 @@ impl Queue { node_version, security_status, to_queue_rx, + from_queue_tx, queue: VecDeque::new(), mux: Mux::new(), workers: Workers { @@ -301,7 +311,7 @@ async fn handle_mux(queue: &mut Queue, event: QueueEvent) { handle_worker_spawned(queue, idle, handle, job); }, QueueEvent::StartWork(worker, outcome, artifact_id, result_tx) => { - handle_job_finish(queue, worker, outcome, artifact_id, result_tx); + handle_job_finish(queue, worker, outcome, artifact_id, result_tx).await; }, } } @@ -327,42 +337,69 @@ fn handle_worker_spawned( /// If there are pending jobs in the queue, schedules the next of them onto the just freed up /// worker. Otherwise, puts back into the available workers list. -fn handle_job_finish( +async fn handle_job_finish( queue: &mut Queue, worker: Worker, outcome: Outcome, artifact_id: ArtifactId, result_tx: ResultSender, ) { - let (idle_worker, result, duration) = match outcome { + let (idle_worker, result, duration, sync_channel) = match outcome { Outcome::Ok { result_descriptor, duration, idle_worker } => { // TODO: propagate the soft timeout - (Some(idle_worker), Ok(result_descriptor), Some(duration)) + (Some(idle_worker), Ok(result_descriptor), Some(duration), None) }, Outcome::InvalidCandidate { err, idle_worker } => ( Some(idle_worker), Err(ValidationError::Invalid(InvalidCandidate::WorkerReportedInvalid(err))), None, + None, ), - Outcome::InternalError { err } => (None, Err(ValidationError::Internal(err)), None), + Outcome::RuntimeConstruction { err, idle_worker } => { + // The task for artifact removal is executed concurrently with + // the message to the host on the execution result. + let (result_tx, result_rx) = oneshot::channel(); + queue + .from_queue_tx + .unbounded_send(FromQueue::RemoveArtifact { + artifact: artifact_id.clone(), + reply_to: result_tx, + }) + .expect("from execute queue receiver is listened by the host; qed"); + ( + Some(idle_worker), + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction( + err, + ))), + None, + Some(result_rx), + ) + }, + Outcome::InternalError { err } => (None, Err(ValidationError::Internal(err)), None, None), // Either the worker or the job timed out. Kill the worker in either case. Treated as // definitely-invalid, because if we timed out, there's no time left for a retry. Outcome::HardTimeout => - (None, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)), None), + (None, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)), None, None), // "Maybe invalid" errors (will retry). Outcome::WorkerIntfErr => ( None, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousWorkerDeath)), None, + None, ), Outcome::JobDied { err } => ( None, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousJobDeath(err))), None, + None, + ), + Outcome::JobError { err } => ( + None, + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))), + None, + None, ), - Outcome::JobError { err } => - (None, Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))), None), }; queue.metrics.execute_finished(); @@ -386,6 +423,12 @@ fn handle_job_finish( ); } + if let Some(sync_channel) = sync_channel { + // err means the sender is dropped (the artifact is already removed from the cache) + // so that's legitimate to ignore the result + let _ = sync_channel.await; + } + // First we send the result. It may fail due to the other end of the channel being dropped, // that's legitimate and we don't treat that as an error. let _ = result_tx.send(result); @@ -521,8 +564,10 @@ pub fn start( spawn_timeout: Duration, node_version: Option, security_status: SecurityStatus, -) -> (mpsc::Sender, impl Future) { +) -> (mpsc::Sender, mpsc::UnboundedReceiver, impl Future) { let (to_queue_tx, to_queue_rx) = mpsc::channel(20); + let (from_queue_tx, from_queue_rx) = mpsc::unbounded(); + let run = Queue::new( metrics, program_path, @@ -532,7 +577,8 @@ pub fn start( node_version, security_status, to_queue_rx, + from_queue_tx, ) .run(); - (to_queue_tx, run) + (to_queue_tx, from_queue_rx, run) } diff --git a/polkadot/node/core/pvf/src/execute/worker_interface.rs b/polkadot/node/core/pvf/src/execute/worker_interface.rs index 9f7738f00e6..db81da118d7 100644 --- a/polkadot/node/core/pvf/src/execute/worker_interface.rs +++ b/polkadot/node/core/pvf/src/execute/worker_interface.rs @@ -87,6 +87,10 @@ pub enum Outcome { /// a trap. Errors related to the preparation process are not expected to be encountered by the /// execution workers. InvalidCandidate { err: String, idle_worker: IdleWorker }, + /// The error is probably transient. It may be for example + /// because the artifact was prepared with a Wasmtime version different from the version + /// in the current execution environment. + RuntimeConstruction { err: String, idle_worker: IdleWorker }, /// The execution time exceeded the hard limit. The worker is terminated. HardTimeout, /// An I/O error happened during communication with the worker. This may mean that the worker @@ -193,6 +197,10 @@ pub async fn start_work( err, idle_worker: IdleWorker { stream, pid, worker_dir }, }, + WorkerResponse::RuntimeConstruction(err) => Outcome::RuntimeConstruction { + err, + idle_worker: IdleWorker { stream, pid, worker_dir }, + }, WorkerResponse::JobTimedOut => Outcome::HardTimeout, WorkerResponse::JobDied { err, job_pid: _ } => Outcome::JobDied { err }, WorkerResponse::JobError(err) => Outcome::JobError { err }, diff --git a/polkadot/node/core/pvf/src/host.rs b/polkadot/node/core/pvf/src/host.rs index ae9fdc7d2de..8ec46f4b08f 100644 --- a/polkadot/node/core/pvf/src/host.rs +++ b/polkadot/node/core/pvf/src/host.rs @@ -274,7 +274,7 @@ pub async fn start( from_prepare_pool, ); - let (to_execute_queue_tx, run_execute_queue) = execute::start( + let (to_execute_queue_tx, from_execute_queue_rx, run_execute_queue) = execute::start( metrics, config.execute_worker_program_path.to_owned(), config.cache_path.clone(), @@ -296,6 +296,7 @@ pub async fn start( to_prepare_queue_tx, from_prepare_queue_rx, to_execute_queue_tx, + from_execute_queue_rx, to_sweeper_tx, awaiting_prepare: AwaitingPrepare::default(), }) @@ -342,6 +343,8 @@ struct Inner { from_prepare_queue_rx: mpsc::UnboundedReceiver, to_execute_queue_tx: mpsc::Sender, + from_execute_queue_rx: mpsc::UnboundedReceiver, + to_sweeper_tx: mpsc::Sender, awaiting_prepare: AwaitingPrepare, @@ -358,6 +361,7 @@ async fn run( to_host_rx, from_prepare_queue_rx, mut to_prepare_queue_tx, + from_execute_queue_rx, mut to_execute_queue_tx, mut to_sweeper_tx, mut awaiting_prepare, @@ -384,10 +388,21 @@ async fn run( let mut to_host_rx = to_host_rx.fuse(); let mut from_prepare_queue_rx = from_prepare_queue_rx.fuse(); + let mut from_execute_queue_rx = from_execute_queue_rx.fuse(); loop { // biased to make it behave deterministically for tests. futures::select_biased! { + from_execute_queue_rx = from_execute_queue_rx.next() => { + let from_queue = break_if_fatal!(from_execute_queue_rx.ok_or(Fatal)); + let execute::FromQueue::RemoveArtifact { artifact, reply_to } = from_queue; + break_if_fatal!(handle_artifact_removal( + &mut to_sweeper_tx, + &mut artifacts, + artifact, + reply_to, + ).await); + }, () = cleanup_pulse.select_next_some() => { // `select_next_some` because we don't expect this to fail, but if it does, we // still don't fail. The trade-off is that the compiled cache will start growing @@ -861,6 +876,37 @@ async fn handle_cleanup_pulse( Ok(()) } +async fn handle_artifact_removal( + sweeper_tx: &mut mpsc::Sender, + artifacts: &mut Artifacts, + artifact_id: ArtifactId, + reply_to: oneshot::Sender<()>, +) -> Result<(), Fatal> { + let (artifact_id, path) = if let Some(artifact) = artifacts.remove(artifact_id) { + artifact + } else { + // if we haven't found the artifact by its id, + // it has been probably removed + // anyway with the randomness of the artifact name + // it is safe to ignore + return Ok(()); + }; + reply_to + .send(()) + .expect("the execute queue waits for the artifact remove confirmation; qed"); + // Thanks to the randomness of the artifact name (see + // `artifacts::generate_artifact_path`) there is no issue with any name conflict on + // future repreparation. + // So we can confirm the artifact removal already + gum::debug!( + target: LOG_TARGET, + validation_code_hash = ?artifact_id.code_hash, + "PVF pruning: pruning artifact by request from the execute queue", + ); + sweeper_tx.send(path).await.map_err(|_| Fatal)?; + Ok(()) +} + /// A simple task which sole purpose is to delete files thrown at it. async fn sweeper_task(mut sweeper_rx: mpsc::Receiver) { loop { @@ -968,6 +1014,8 @@ pub(crate) mod tests { to_prepare_queue_rx: mpsc::Receiver, from_prepare_queue_tx: mpsc::UnboundedSender, to_execute_queue_rx: mpsc::Receiver, + #[allow(unused)] + from_execute_queue_tx: mpsc::UnboundedSender, to_sweeper_rx: mpsc::Receiver, run: BoxFuture<'static, ()>, @@ -979,6 +1027,7 @@ pub(crate) mod tests { let (to_prepare_queue_tx, to_prepare_queue_rx) = mpsc::channel(10); let (from_prepare_queue_tx, from_prepare_queue_rx) = mpsc::unbounded(); let (to_execute_queue_tx, to_execute_queue_rx) = mpsc::channel(10); + let (from_execute_queue_tx, from_execute_queue_rx) = mpsc::unbounded(); let (to_sweeper_tx, to_sweeper_rx) = mpsc::channel(10); let run = run(Inner { @@ -989,6 +1038,7 @@ pub(crate) mod tests { to_prepare_queue_tx, from_prepare_queue_rx, to_execute_queue_tx, + from_execute_queue_rx, to_sweeper_tx, awaiting_prepare: AwaitingPrepare::default(), }) @@ -999,6 +1049,7 @@ pub(crate) mod tests { to_prepare_queue_rx, from_prepare_queue_tx, to_execute_queue_rx, + from_execute_queue_tx, to_sweeper_rx, run, } diff --git a/polkadot/node/core/pvf/tests/it/main.rs b/polkadot/node/core/pvf/tests/it/main.rs index bcc10749e74..cdfbcd8e578 100644 --- a/polkadot/node/core/pvf/tests/it/main.rs +++ b/polkadot/node/core/pvf/tests/it/main.rs @@ -21,13 +21,14 @@ use parity_scale_codec::Encode as _; #[cfg(all(feature = "ci-only-tests", target_os = "linux"))] use polkadot_node_core_pvf::SecurityStatus; use polkadot_node_core_pvf::{ - start, testing::build_workers_and_get_paths, Config, InvalidCandidate, Metrics, PrepareError, - PrepareJobKind, PvfPrepData, ValidationError, ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR, + start, testing::build_workers_and_get_paths, Config, InvalidCandidate, Metrics, + PossiblyInvalidError, PrepareError, PrepareJobKind, PvfPrepData, ValidationError, + ValidationHost, JOB_TIMEOUT_WALL_CLOCK_FACTOR, }; use polkadot_parachain_primitives::primitives::{BlockData, ValidationParams, ValidationResult}; use polkadot_primitives::{ExecutorParam, ExecutorParams}; -use std::time::Duration; +use std::{io::Write, time::Duration}; use tokio::sync::Mutex; mod adder; @@ -352,10 +353,80 @@ async fn deleting_prepared_artifact_does_not_dispute() { ) .await; - match result { - Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)) => {}, - r => panic!("{:?}", r), + assert_matches!(result, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout))); +} + +// Test that corruption of a prepared artifact does not lead to a dispute when we try to execute it. +#[tokio::test] +async fn corrupted_prepared_artifact_does_not_dispute() { + let host = TestHost::new().await; + let cache_dir = host.cache_dir.path(); + + let _stats = host.precheck_pvf(halt::wasm_binary_unwrap(), Default::default()).await.unwrap(); + + // Manually corrupting the prepared artifact from disk. The in-memory artifacts table won't + // change. + let artifact_path = { + // Get the artifact path (asserting it exists). + let mut cache_dir: Vec<_> = std::fs::read_dir(cache_dir).unwrap().collect(); + // Should contain the artifact and the worker dir. + assert_eq!(cache_dir.len(), 2); + let mut artifact_path = cache_dir.pop().unwrap().unwrap(); + if artifact_path.path().is_dir() { + artifact_path = cache_dir.pop().unwrap().unwrap(); + } + + // Corrupt the artifact. + let mut f = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(artifact_path.path()) + .unwrap(); + f.write_all(b"corrupted wasm").unwrap(); + f.flush().unwrap(); + artifact_path + }; + + assert!(artifact_path.path().exists()); + + // Try to validate, artifact should get removed because of the corruption. + let result = host + .validate_candidate( + halt::wasm_binary_unwrap(), + ValidationParams { + block_data: BlockData(Vec::new()), + parent_head: Default::default(), + relay_parent_number: 1, + relay_parent_storage_root: Default::default(), + }, + Default::default(), + ) + .await; + + assert_matches!( + result, + Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction(_))) + ); + + // because of RuntimeConstruction we may retry + host.precheck_pvf(halt::wasm_binary_unwrap(), Default::default()).await.unwrap(); + + // The actual artifact removal is done concurrently + // with sending of the result of the execution + // it is not a problem for further re-preparation as + // artifact filenames are random + for _ in 1..5 { + if !artifact_path.path().exists() { + break; + } + tokio::time::sleep(Duration::from_secs(1)).await; } + + assert!( + !artifact_path.path().exists(), + "the corrupted artifact ({}) should be deleted by the host", + artifact_path.path().display() + ); } #[tokio::test] diff --git a/polkadot/primitives/src/v6/executor_params.rs b/polkadot/primitives/src/v6/executor_params.rs index 112a529f62b..1e19f3b23fe 100644 --- a/polkadot/primitives/src/v6/executor_params.rs +++ b/polkadot/primitives/src/v6/executor_params.rs @@ -159,7 +159,9 @@ impl sp_std::fmt::LowerHex for ExecutorParamsHash { // into individual fields of the structure. Thus, complex migrations shall be avoided when adding // new entries and removing old ones. At the moment, there's no mandatory parameters defined. If // they show up, they must be clearly documented as mandatory ones. -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, Serialize, Deserialize)] +#[derive( + Clone, Debug, Default, Encode, Decode, PartialEq, Eq, TypeInfo, Serialize, Deserialize, +)] pub struct ExecutorParams(Vec); impl ExecutorParams { @@ -334,9 +336,3 @@ impl From<&[ExecutorParam]> for ExecutorParams { ExecutorParams(arr.to_vec()) } } - -impl Default for ExecutorParams { - fn default() -> Self { - ExecutorParams(vec![]) - } -} diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md index e0984bd58d1..39a317a07c8 100644 --- a/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md +++ b/polkadot/roadmap/implementers-guide/src/node/utility/pvf-host-and-workers.md @@ -125,6 +125,14 @@ execution request: reason, which may or may not be independent of the candidate or PVF. 5. **Internal errors:** See "Internal Errors" section. In this case, after the retry we abstain from voting. +6. **RuntimeConstruction** error. The precheck handles a general case of a wrong + artifact but doesn't guarantee its consistency between the preparation and + the execution. If something happened with the artifact between + the preparation of the artifact and its execution (e.g. the artifact was + corrupted on disk or a dirty node upgrade happened when the prepare worker + has a wasmtime version different from the execute worker's wasmtime version). + We treat such an error as possibly transient due to local issues and retry + one time. ### Preparation timeouts diff --git a/prdoc/pr_3187.prdoc b/prdoc/pr_3187.prdoc new file mode 100644 index 00000000000..bda41142d86 --- /dev/null +++ b/prdoc/pr_3187.prdoc @@ -0,0 +1,16 @@ +# 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: Retrying an execution on failed runtime construction + +doc: + - audience: Node Dev + description: | + If a runtime construction error happened during the execution request, then the artifact is re-prepared + and the execution request is retried at most once. See also the related issue. + +crates: + - name: polkadot-node-core-candidate-validation + - name: polkadot-node-core-pvf + - name: polkadot-node-core-pvf-execute-worker + - name: polkadot-node-core-pvf-common -- GitLab From 576681b867a234b42aac282940455f9be71d108b Mon Sep 17 00:00:00 2001 From: Clara van Staden Date: Wed, 28 Feb 2024 21:42:35 +0200 Subject: [PATCH 273/283] Snowbridge - Extract Ethereum Chain ID (#3501) While adding runtime tests to https://github.com/polkadot-fellows/runtimes/pull/130, I noticed the Ethereum chain ID was hardcoded. For Kusama + Polkadot, the Ethereum chain ID should 1 (Mainnet), whereas on Rococo it is 11155111 (Sepolia). This PR also updates the Snowbridge crates versions to the current versions on crates.io. --------- Co-authored-by: claravanstaden --- Cargo.lock | 28 +++++++++---------- .../pallets/ethereum-client/Cargo.toml | 2 +- .../pallets/inbound-queue/Cargo.toml | 2 +- .../pallets/inbound-queue/fixtures/Cargo.toml | 2 +- .../pallets/outbound-queue/Cargo.toml | 2 +- .../outbound-queue/merkle-tree/Cargo.toml | 2 +- .../outbound-queue/runtime-api/Cargo.toml | 2 +- bridges/snowbridge/pallets/system/Cargo.toml | 2 +- .../pallets/system/runtime-api/Cargo.toml | 2 +- .../snowbridge/primitives/beacon/Cargo.toml | 2 +- bridges/snowbridge/primitives/core/Cargo.toml | 2 +- .../snowbridge/primitives/ethereum/Cargo.toml | 2 +- .../snowbridge/primitives/router/Cargo.toml | 2 +- .../runtime/runtime-common/Cargo.toml | 2 +- .../snowbridge/runtime/test-common/Cargo.toml | 2 +- .../snowbridge/runtime/test-common/src/lib.rs | 12 ++++++-- .../snowbridge/scripts/contribute-upstream.sh | 2 ++ .../bridge-hub-rococo/tests/snowbridge.rs | 5 ++++ 18 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef510986257..197d05e2633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17856,7 +17856,7 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.0.0" +version = "0.2.0" dependencies = [ "byte-slice-cast", "frame-support", @@ -17880,7 +17880,7 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.0.0" +version = "0.2.0" dependencies = [ "ethabi-decode", "frame-support", @@ -17903,7 +17903,7 @@ dependencies = [ [[package]] name = "snowbridge-ethereum" -version = "0.1.0" +version = "0.3.0" dependencies = [ "ethabi-decode", "ethbloom", @@ -17942,7 +17942,7 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-merkle-tree" -version = "0.1.1" +version = "0.3.0" dependencies = [ "array-bytes 4.2.0", "env_logger 0.9.3", @@ -17957,7 +17957,7 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-runtime-api" -version = "0.0.0" +version = "0.2.0" dependencies = [ "frame-support", "parity-scale-codec", @@ -17971,7 +17971,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-ethereum-client" -version = "0.0.0" +version = "0.2.0" dependencies = [ "bp-runtime", "byte-slice-cast", @@ -18017,7 +18017,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-inbound-queue" -version = "0.0.0" +version = "0.2.0" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -18050,7 +18050,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-inbound-queue-fixtures" -version = "0.9.0" +version = "0.10.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -18064,7 +18064,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-outbound-queue" -version = "0.0.0" +version = "0.2.0" dependencies = [ "bridge-hub-common", "ethabi-decode", @@ -18089,7 +18089,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-system" -version = "0.0.0" +version = "0.2.0" dependencies = [ "ethabi-decode", "frame-benchmarking", @@ -18117,7 +18117,7 @@ dependencies = [ [[package]] name = "snowbridge-router-primitives" -version = "0.0.0" +version = "0.9.0" dependencies = [ "ethabi-decode", "frame-support", @@ -18140,7 +18140,7 @@ dependencies = [ [[package]] name = "snowbridge-runtime-common" -version = "0.0.0" +version = "0.2.0" dependencies = [ "frame-support", "frame-system", @@ -18156,7 +18156,7 @@ dependencies = [ [[package]] name = "snowbridge-runtime-test-common" -version = "0.0.0" +version = "0.2.0" dependencies = [ "assets-common", "bridge-hub-test-utils", @@ -18233,7 +18233,7 @@ dependencies = [ [[package]] name = "snowbridge-system-runtime-api" -version = "0.0.0" +version = "0.2.0" dependencies = [ "parity-scale-codec", "snowbridge-core", diff --git a/bridges/snowbridge/pallets/ethereum-client/Cargo.toml b/bridges/snowbridge/pallets/ethereum-client/Cargo.toml index 99b42905311..c8999633c97 100644 --- a/bridges/snowbridge/pallets/ethereum-client/Cargo.toml +++ b/bridges/snowbridge/pallets/ethereum-client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-ethereum-client" description = "Snowbridge Ethereum Client Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml index c26ef90a22d..b850496cd4e 100644 --- a/bridges/snowbridge/pallets/inbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-inbound-queue" description = "Snowbridge Inbound Queue Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml index 61f1421e056..64605a42f0d 100644 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml +++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-inbound-queue-fixtures" description = "Snowbridge Inbound Queue Test Fixtures" -version = "0.9.0" +version = "0.10.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/outbound-queue/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/Cargo.toml index 40e57db4bbd..f16a28cb1e4 100644 --- a/bridges/snowbridge/pallets/outbound-queue/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-outbound-queue" description = "Snowbridge Outbound Queue Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml index c185d5af706..0606e9de330 100644 --- a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-outbound-queue-merkle-tree" description = "Snowbridge Outbound Queue Merkle Tree" -version = "0.1.1" +version = "0.3.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml index 347b3bae493..cb68fd0a250 100644 --- a/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml +++ b/bridges/snowbridge/pallets/outbound-queue/runtime-api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-outbound-queue-runtime-api" description = "Snowbridge Outbound Queue Runtime API" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/system/Cargo.toml b/bridges/snowbridge/pallets/system/Cargo.toml index f6c642e7376..5ad04290de0 100644 --- a/bridges/snowbridge/pallets/system/Cargo.toml +++ b/bridges/snowbridge/pallets/system/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-pallet-system" description = "Snowbridge System Pallet" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml b/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml index 355d2d29147..eb02ae1db52 100644 --- a/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml +++ b/bridges/snowbridge/pallets/system/runtime-api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-system-runtime-api" description = "Snowbridge System Runtime API" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/beacon/Cargo.toml b/bridges/snowbridge/primitives/beacon/Cargo.toml index e021bb01071..d181fa1d394 100644 --- a/bridges/snowbridge/primitives/beacon/Cargo.toml +++ b/bridges/snowbridge/primitives/beacon/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-beacon-primitives" description = "Snowbridge Beacon Primitives" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/core/Cargo.toml b/bridges/snowbridge/primitives/core/Cargo.toml index 090c48c403f..9a299ad0ae9 100644 --- a/bridges/snowbridge/primitives/core/Cargo.toml +++ b/bridges/snowbridge/primitives/core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-core" description = "Snowbridge Core" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/ethereum/Cargo.toml b/bridges/snowbridge/primitives/ethereum/Cargo.toml index 399139cef38..9fa725a6c05 100644 --- a/bridges/snowbridge/primitives/ethereum/Cargo.toml +++ b/bridges/snowbridge/primitives/ethereum/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-ethereum" description = "Snowbridge Ethereum" -version = "0.1.0" +version = "0.3.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/primitives/router/Cargo.toml b/bridges/snowbridge/primitives/router/Cargo.toml index 750a2a73e63..ded773e0d38 100644 --- a/bridges/snowbridge/primitives/router/Cargo.toml +++ b/bridges/snowbridge/primitives/router/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-router-primitives" description = "Snowbridge Router Primitives" -version = "0.0.0" +version = "0.9.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/runtime/runtime-common/Cargo.toml b/bridges/snowbridge/runtime/runtime-common/Cargo.toml index d4c86f8aa75..bf5e9a8832d 100644 --- a/bridges/snowbridge/runtime/runtime-common/Cargo.toml +++ b/bridges/snowbridge/runtime/runtime-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-runtime-common" description = "Snowbridge Runtime Common" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition.workspace = true repository.workspace = true diff --git a/bridges/snowbridge/runtime/test-common/Cargo.toml b/bridges/snowbridge/runtime/test-common/Cargo.toml index ec4466b3426..4e8b311cb97 100644 --- a/bridges/snowbridge/runtime/test-common/Cargo.toml +++ b/bridges/snowbridge/runtime/test-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "snowbridge-runtime-test-common" description = "Snowbridge Runtime Tests" -version = "0.0.0" +version = "0.2.0" authors = ["Snowfork "] edition = "2021" license = "Apache-2.0" diff --git a/bridges/snowbridge/runtime/test-common/src/lib.rs b/bridges/snowbridge/runtime/test-common/src/lib.rs index 29b0e738c18..7455adf7617 100644 --- a/bridges/snowbridge/runtime/test-common/src/lib.rs +++ b/bridges/snowbridge/runtime/test-common/src/lib.rs @@ -40,6 +40,7 @@ where } pub fn send_transfer_token_message( + ethereum_chain_id: u64, assethub_parachain_id: u32, weth_contract_address: H160, destination_address: H160, @@ -89,7 +90,7 @@ where WithdrawAsset(Assets::from(vec![fee.clone()])), BuyExecution { fees: fee, weight_limit: Unlimited }, ExportMessage { - network: Ethereum { chain_id: 11155111 }, + network: Ethereum { chain_id: ethereum_chain_id }, destination: Here, xcm: inner_xcm, }, @@ -107,6 +108,7 @@ where } pub fn send_transfer_token_message_success( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -149,6 +151,7 @@ pub fn send_transfer_token_message_success( initial_fund::(assethub_parachain_id, 5_000_000_000_000); let outcome = send_transfer_token_message::( + ethereum_chain_id, assethub_parachain_id, weth_contract_address, destination_address, @@ -205,6 +208,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works< XcmConfig, AllPalletsWithoutSystem, >( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -249,6 +253,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works< initial_fund::(assethub_parachain_id, 5_000_000_000_000); let outcome = send_transfer_token_message::( + ethereum_chain_id, assethub_parachain_id, weth_contract_address, destination_address, @@ -290,6 +295,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works< } pub fn send_unpaid_transfer_token_message( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -353,7 +359,7 @@ pub fn send_unpaid_transfer_token_message( let xcm = Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, ExportMessage { - network: Ethereum { chain_id: 11155111 }, + network: Ethereum { chain_id: ethereum_chain_id }, destination: Here, xcm: inner_xcm, }, @@ -375,6 +381,7 @@ pub fn send_unpaid_transfer_token_message( #[allow(clippy::too_many_arguments)] pub fn send_transfer_token_message_failure( + ethereum_chain_id: u64, collator_session_key: CollatorSessionKeys, runtime_para_id: u32, assethub_parachain_id: u32, @@ -414,6 +421,7 @@ pub fn send_transfer_token_message_failure( initial_fund::(assethub_parachain_id, initial_amount); let outcome = send_transfer_token_message::( + ethereum_chain_id, assethub_parachain_id, weth_contract_address, destination_address, diff --git a/bridges/snowbridge/scripts/contribute-upstream.sh b/bridges/snowbridge/scripts/contribute-upstream.sh index 8aa2d2a7035..32005b770ec 100755 --- a/bridges/snowbridge/scripts/contribute-upstream.sh +++ b/bridges/snowbridge/scripts/contribute-upstream.sh @@ -40,10 +40,12 @@ git checkout "$branch_name" # remove everything we think is not required for our needs rm -rf rust-toolchain.toml +rm -rf codecov.yml rm -rf $SNOWBRIDGE_FOLDER/.cargo rm -rf $SNOWBRIDGE_FOLDER/.github rm -rf $SNOWBRIDGE_FOLDER/SECURITY.md rm -rf $SNOWBRIDGE_FOLDER/.gitignore +rm -rf $SNOWBRIDGE_FOLDER/rustfmt.toml rm -rf $SNOWBRIDGE_FOLDER/templates rm -rf $SNOWBRIDGE_FOLDER/pallets/ethereum-client/fuzz diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index b9f43624b65..239bd946e75 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -51,6 +51,7 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys( + 11155111, collator_session_keys(), 1013, 1000, @@ -69,6 +70,7 @@ pub fn transfer_token_to_ethereum_works() { #[test] pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { snowbridge_runtime_test_common::send_unpaid_transfer_token_message::( + 11155111, collator_session_keys(), 1013, 1000, @@ -80,6 +82,7 @@ pub fn unpaid_transfer_token_to_ethereum_fails_with_barrier() { #[test] pub fn transfer_token_to_ethereum_fee_not_enough() { snowbridge_runtime_test_common::send_transfer_token_message_failure::( + 11155111, collator_session_keys(), 1013, 1000, @@ -95,6 +98,7 @@ pub fn transfer_token_to_ethereum_fee_not_enough() { #[test] pub fn transfer_token_to_ethereum_insufficient_fund() { snowbridge_runtime_test_common::send_transfer_token_message_failure::( + 11155111, collator_session_keys(), 1013, 1000, @@ -146,6 +150,7 @@ pub fn ethereum_outbound_queue_processes_messages_before_message_queue_works() { XcmConfig, AllPalletsWithoutSystem, >( + 11155111, collator_session_keys(), 1013, 1000, -- GitLab From eefd5fe4499515da66d088505093f75b5aa22550 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Wed, 28 Feb 2024 20:49:00 +0100 Subject: [PATCH 274/283] Multi-Block-Migrations, `poll` hook and new System callbacks (#1781) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This MR is the merge of https://github.com/paritytech/substrate/pull/14414 and https://github.com/paritytech/substrate/pull/14275. It implements [RFC#13](https://github.com/polkadot-fellows/RFCs/pull/13), closes https://github.com/paritytech/polkadot-sdk/issues/198. ----- This Merge request introduces three major topicals: 1. Multi-Block-Migrations 1. New pallet `poll` hook for periodic service work 1. Replacement hooks for `on_initialize` and `on_finalize` in cases where `poll` cannot be used and some more general changes to FRAME. The changes for each topical span over multiple crates. They are listed in topical order below. # 1.) Multi-Block-Migrations Multi-Block-Migrations are facilitated by creating `pallet_migrations` and configuring `System::Config::MultiBlockMigrator` to point to it. Executive picks this up and triggers one step of the migrations pallet per block. The chain is in lockdown mode for as long as an MBM is ongoing. Executive does this by polling `MultiBlockMigrator::ongoing` and not allowing any transaction in a block, if true. A MBM is defined through trait `SteppedMigration`. A condensed version looks like this: ```rust /// A migration that can proceed in multiple steps. pub trait SteppedMigration { type Cursor: FullCodec + MaxEncodedLen; type Identifier: FullCodec + MaxEncodedLen; fn id() -> Self::Identifier; fn max_steps() -> Option; fn step( cursor: Option, meter: &mut WeightMeter, ) -> Result, SteppedMigrationError>; } ``` `pallet_migrations` can be configured with an aggregated tuple of these migrations. It then starts to migrate them one-by-one on the next runtime upgrade. Two things are important here: - 1. Doing another runtime upgrade while MBMs are ongoing is not a good idea and can lead to messed up state. - 2. **Pallet Migrations MUST BE CONFIGURED IN `System::Config`, otherwise it is not used.** The pallet supports an `UpgradeStatusHandler` that can be used to notify external logic of upgrade start/finish (for example to pause XCM dispatch). Error recovery is very limited in the case that a migration errors or times out (exceeds its `max_steps`). Currently the runtime dev can decide in `FailedMigrationHandler::failed` how to handle this. One follow-up would be to pair this with the `SafeMode` pallet and enact safe mode when an upgrade fails, to allow governance to rescue the chain. This is currently not possible, since governance is not `Mandatory`. ## Runtime API - `Core`: `initialize_block` now returns `ExtrinsicInclusionMode` to inform the Block Author whether they can push transactions. ### Integration Add it to your runtime implementation of `Core` and `BlockBuilder`: ```patch diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs @@ impl_runtime_apis! { impl sp_block_builder::Core for Runtime { - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> RuntimeExecutiveMode { Executive::initialize_block(header) } ... } ``` # 2.) `poll` hook A new pallet hook is introduced: `poll`. `Poll` is intended to replace mostly all usage of `on_initialize`. The reason for this is that any code that can be called from `on_initialize` cannot be migrated through an MBM. Currently there is no way to statically check this; the implication is to use `on_initialize` as rarely as possible. Failing to do so can result in broken storage invariants. The implementation of the poll hook depends on the `Runtime API` changes that are explained above. # 3.) Hard-Deadline callbacks Three new callbacks are introduced and configured on `System::Config`: `PreInherents`, `PostInherents` and `PostTransactions`. These hooks are meant as replacement for `on_initialize` and `on_finalize` in cases where the code that runs cannot be moved to `poll`. The reason for this is to make the usage of HD-code (hard deadline) more explicit - again to prevent broken invariants by MBMs. # 4.) FRAME (general changes) ## `frame_system` pallet A new memorize storage item `InherentsApplied` is added. It is used by executive to track whether inherents have already been applied. Executive and can then execute the MBMs directly between inherents and transactions. The `Config` gets five new items: - `SingleBlockMigrations` this is the new way of configuring migrations that run in a single block. Previously they were defined as last generic argument of `Executive`. This shift is brings all central configuration about migrations closer into view of the developer (migrations that are configured in `Executive` will still work for now but is deprecated). - `MultiBlockMigrator` this can be configured to an engine that drives MBMs. One example would be the `pallet_migrations`. Note that this is only the engine; the exact MBMs are injected into the engine. - `PreInherents` a callback that executes after `on_initialize` but before inherents. - `PostInherents` a callback that executes after all inherents ran (including MBMs and `poll`). - `PostTransactions` in symmetry to `PreInherents`, this one is called before `on_finalize` but after all transactions. A sane default is to set all of these to `()`. Example diff suitable for any chain: ```patch @@ impl frame_system::Config for Test { type MaxConsumers = ConstU32<16>; + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); } ``` An overview of how the block execution now looks like is here. The same graph is also in the rust doc.
Block Execution Flow

![Screenshot 2023-12-04 at 19 11 29](https://github.com/paritytech/polkadot-sdk/assets/10380170/e88a80c4-ef11-4faa-8df5-8b33a724c054)

## Inherent Order Moved to https://github.com/paritytech/polkadot-sdk/pull/2154 --------------- ## TODO - [ ] Check that `try-runtime` still works - [ ] Ensure backwards compatibility with old Runtime APIs - [x] Consume weight correctly - [x] Cleanup --------- Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Liam Aharon Co-authored-by: Juan Girini Co-authored-by: command-bot <> Co-authored-by: Francisco Aguirre Co-authored-by: Gavin Wood Co-authored-by: Bastian Köcher --- Cargo.lock | 110 +- Cargo.toml | 1 + .../pallets/inbound-queue/src/mock.rs | 13 +- .../pallets/outbound-queue/src/mock.rs | 14 +- bridges/snowbridge/pallets/system/src/mock.rs | 15 +- .../ethereum-beacon-client/src/mock.rs | 259 +++ cumulus/parachain-template/runtime/src/lib.rs | 2 +- .../assets/asset-hub-rococo/src/lib.rs | 2 +- .../assets/asset-hub-westend/src/lib.rs | 2 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 2 +- .../collectives-westend/src/lib.rs | 2 +- .../contracts/contracts-rococo/src/lib.rs | 2 +- .../coretime/coretime-rococo/src/lib.rs | 2 +- .../coretime/coretime-westend/src/lib.rs | 2 +- .../glutton/glutton-westend/src/lib.rs | 2 +- .../runtimes/people/people-rococo/src/lib.rs | 2 +- .../runtimes/people/people-westend/src/lib.rs | 2 +- .../runtimes/starters/seedling/src/lib.rs | 2 +- .../runtimes/starters/shell/src/lib.rs | 2 +- .../runtimes/testing/penpal/src/lib.rs | 2 +- .../testing/rococo-parachain/src/lib.rs | 2 +- .../asset_hub_polkadot_aura.rs | 2 +- .../src/fake_runtime_api/aura.rs | 2 +- cumulus/test/runtime/src/lib.rs | 2 +- polkadot/node/service/src/fake_runtime_api.rs | 2 +- polkadot/runtime/common/src/claims.rs | 29 +- polkadot/runtime/rococo/src/lib.rs | 2 +- polkadot/runtime/test-runtime/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- prdoc/pr_1781.prdoc | 45 + substrate/bin/minimal/runtime/src/lib.rs | 5 +- .../bin/node-template/runtime/src/lib.rs | 2 +- substrate/bin/node/runtime/Cargo.toml | 4 + substrate/bin/node/runtime/src/lib.rs | 24 +- .../basic-authorship/src/basic_authorship.rs | 13 +- substrate/client/block-builder/src/lib.rs | 26 +- substrate/client/proposer-metrics/src/lib.rs | 4 + .../rpc-spec-v2/src/chain_head/tests.rs | 6 +- substrate/client/rpc/src/state/tests.rs | 2 +- substrate/frame/executive/Cargo.toml | 2 + substrate/frame/executive/src/lib.rs | 1194 +++----------- substrate/frame/executive/src/tests.rs | 1389 +++++++++++++++++ substrate/frame/migrations/Cargo.toml | 64 + .../frame/migrations/src/benchmarking.rs | 222 +++ substrate/frame/migrations/src/lib.rs | 746 +++++++++ substrate/frame/migrations/src/mock.rs | 163 ++ .../frame/migrations/src/mock_helpers.rs | 142 ++ substrate/frame/migrations/src/tests.rs | 335 ++++ substrate/frame/migrations/src/weights.rs | 358 +++++ substrate/frame/src/lib.rs | 2 +- .../src/construct_runtime/expand/inherent.rs | 63 +- .../procedural/src/pallet/expand/hooks.rs | 16 + substrate/frame/support/src/migrations.rs | 636 +++++++- .../support/src/storage/transactional.rs | 16 + substrate/frame/support/src/traits.rs | 11 +- substrate/frame/support/src/traits/hooks.rs | 70 + substrate/frame/support/src/traits/misc.rs | 17 +- .../undefined_inherent_part.stderr | 23 +- .../test/tests/pallet_outer_enums_explicit.rs | 1 + .../test/tests/pallet_outer_enums_implicit.rs | 1 + .../support/test/tests/runtime_metadata.rs | 6 +- substrate/frame/system/src/lib.rs | 74 +- substrate/frame/system/src/mock.rs | 16 + substrate/frame/system/src/tests.rs | 22 + .../api/proc-macro/src/decl_runtime_apis.rs | 1 + .../proc-macro/src/mock_impl_runtime_apis.rs | 2 +- substrate/primitives/api/src/lib.rs | 18 +- .../api/test/tests/decl_and_impl.rs | 2 +- .../ui/impl_incorrect_method_signature.rs | 2 +- .../api/test/tests/ui/impl_missing_version.rs | 2 +- .../test/tests/ui/missing_versioned_method.rs | 2 +- .../missing_versioned_method_multiple_vers.rs | 2 +- .../ui/positive_cases/custom_where_bound.rs | 2 +- .../tests/ui/positive_cases/default_impls.rs | 2 +- ...ype_reference_in_impl_runtime_apis_call.rs | 2 +- substrate/primitives/runtime/src/lib.rs | 10 + substrate/test-utils/runtime/src/lib.rs | 6 +- 78 files changed, 5072 insertions(+), 1188 deletions(-) create mode 100644 bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs create mode 100644 prdoc/pr_1781.prdoc create mode 100644 substrate/frame/executive/src/tests.rs create mode 100644 substrate/frame/migrations/Cargo.toml create mode 100644 substrate/frame/migrations/src/benchmarking.rs create mode 100644 substrate/frame/migrations/src/lib.rs create mode 100644 substrate/frame/migrations/src/mock.rs create mode 100644 substrate/frame/migrations/src/mock_helpers.rs create mode 100644 substrate/frame/migrations/src/tests.rs create mode 100644 substrate/frame/migrations/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 197d05e2633..3838ed0e94a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,6 +322,20 @@ dependencies = [ "num-traits", ] +[[package]] +name = "aquamarine" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da02abba9f9063d786eab1509833ebb2fac0f966862ca59439c76b9c566760" +dependencies = [ + "include_dir", + "itertools 0.10.5", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "aquamarine" version = "0.5.0" @@ -4055,7 +4069,7 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-proof-size-hostfunction", "cumulus-test-runtime", - "docify", + "docify 0.2.7", "frame-support", "frame-system", "log", @@ -4736,13 +4750,39 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "docify" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1b04e6ef3d21119d3eb7b032bca17f99fe041e9c072f30f32cc0e1a2b1f3c4" +dependencies = [ + "docify_macros 0.1.16", +] + [[package]] name = "docify" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cc4fd38aaa9fb98ac70794c82a00360d1e165a87fbf96a8a91f9dfc602aaee2" dependencies = [ - "docify_macros", + "docify_macros 0.2.7", +] + +[[package]] +name = "docify_macros" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b5610df7f2acf89a1bb5d1a66ae56b1c7fcdcfe3948856fb3ace3f644d70eb7" +dependencies = [ + "common-path", + "derive-syn-parse", + "lazy_static", + "proc-macro2", + "quote", + "regex", + "syn 2.0.50", + "termcolor", + "walkdir", ] [[package]] @@ -5451,7 +5491,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" name = "frame" version = "0.0.1-dev" dependencies = [ - "docify", + "docify 0.2.7", "frame-executive", "frame-support", "frame-system", @@ -5619,6 +5659,7 @@ dependencies = [ name = "frame-executive" version = "28.0.0" dependencies = [ + "aquamarine 0.3.3", "array-bytes 6.1.0", "frame-support", "frame-system", @@ -5675,11 +5716,11 @@ dependencies = [ name = "frame-support" version = "28.0.0" dependencies = [ - "aquamarine", + "aquamarine 0.5.0", "array-bytes 6.1.0", "assert_matches", "bitflags 1.3.2", - "docify", + "docify 0.2.7", "environmental", "frame-metadata", "frame-support-procedural", @@ -5822,7 +5863,7 @@ version = "28.0.0" dependencies = [ "cfg-if", "criterion 0.4.0", - "docify", + "docify 0.2.7", "frame-support", "log", "parity-scale-codec", @@ -7081,6 +7122,7 @@ dependencies = [ "pallet-lottery", "pallet-membership", "pallet-message-queue", + "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", @@ -9301,8 +9343,8 @@ dependencies = [ name = "pallet-bags-list" version = "27.0.0" dependencies = [ - "aquamarine", - "docify", + "aquamarine 0.5.0", + "docify 0.2.7", "frame-benchmarking", "frame-election-provider-support", "frame-support", @@ -9350,7 +9392,7 @@ dependencies = [ name = "pallet-balances" version = "28.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -9969,7 +10011,7 @@ dependencies = [ name = "pallet-example-single-block-migrations" version = "0.0.1" dependencies = [ - "docify", + "docify 0.2.7", "frame-executive", "frame-support", "frame-system", @@ -10035,7 +10077,7 @@ dependencies = [ name = "pallet-fast-unstake" version = "27.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-election-provider-support", "frame-support", @@ -10232,6 +10274,30 @@ dependencies = [ "sp-weights", ] +[[package]] +name = "pallet-migrations" +version = "1.0.0" +dependencies = [ + "docify 0.1.16", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "pretty_assertions", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 14.0.0", + "sp-tracing 16.0.0", + "sp-version", +] + [[package]] name = "pallet-mixnet" version = "0.4.0" @@ -10507,7 +10573,7 @@ dependencies = [ name = "pallet-paged-list" version = "0.6.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10550,7 +10616,7 @@ dependencies = [ name = "pallet-parameters" version = "0.0.1" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10711,7 +10777,7 @@ dependencies = [ name = "pallet-safe-mode" version = "9.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10768,7 +10834,7 @@ dependencies = [ name = "pallet-scheduler" version = "29.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -10981,7 +11047,7 @@ dependencies = [ name = "pallet-sudo" version = "28.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -11012,7 +11078,7 @@ dependencies = [ name = "pallet-timestamp" version = "27.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -11116,7 +11182,7 @@ dependencies = [ name = "pallet-treasury" version = "27.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -11136,7 +11202,7 @@ dependencies = [ name = "pallet-tx-pause" version = "9.0.0" dependencies = [ - "docify", + "docify 0.2.7", "frame-benchmarking", "frame-support", "frame-system", @@ -13404,7 +13470,7 @@ version = "0.0.1" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", - "docify", + "docify 0.2.7", "frame", "frame-executive", "frame-support", @@ -15665,7 +15731,7 @@ name = "sc-chain-spec" version = "27.0.0" dependencies = [ "array-bytes 6.1.0", - "docify", + "docify 0.2.7", "log", "memmap2 0.9.3", "parity-scale-codec", @@ -18931,7 +18997,7 @@ dependencies = [ name = "sp-runtime" version = "31.0.1" dependencies = [ - "docify", + "docify 0.2.7", "either", "hash256-std-hasher", "impl-trait-for-tuples", diff --git a/Cargo.toml b/Cargo.toml index 654367cc1e2..48aa25f5c5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -352,6 +352,7 @@ members = [ "substrate/frame/membership", "substrate/frame/merkle-mountain-range", "substrate/frame/message-queue", + "substrate/frame/migrations", "substrate/frame/mixnet", "substrate/frame/multisig", "substrate/frame/nft-fractionalization", diff --git a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs index 110f611c676..749fb0367f3 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{ConstU128, ConstU32, Everything}, weights::IdentityFee, }; @@ -47,10 +47,9 @@ parameter_types! { type Balance = u128; +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = Everything; - type BlockWeights = (); - type BlockLength = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type RuntimeTask = RuntimeTask; @@ -60,16 +59,8 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; - type DbWeight = (); - type Version = (); type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; } diff --git a/bridges/snowbridge/pallets/outbound-queue/src/mock.rs b/bridges/snowbridge/pallets/outbound-queue/src/mock.rs index dd8fee4e2ed..6e78fb44672 100644 --- a/bridges/snowbridge/pallets/outbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/outbound-queue/src/mock.rs @@ -3,7 +3,7 @@ use super::*; use frame_support::{ - parameter_types, + derive_impl, parameter_types, traits::{Everything, Hooks}, weights::IdentityFee, }; @@ -37,10 +37,9 @@ parameter_types! { pub const BlockHashCount: u64 = 250; } +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = Everything; - type BlockWeights = (); - type BlockLength = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type RuntimeTask = RuntimeTask; @@ -50,16 +49,7 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; - type DbWeight = (); - type Version = (); type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; } diff --git a/bridges/snowbridge/pallets/system/src/mock.rs b/bridges/snowbridge/pallets/system/src/mock.rs index edc3f141b07..de2970dd550 100644 --- a/bridges/snowbridge/pallets/system/src/mock.rs +++ b/bridges/snowbridge/pallets/system/src/mock.rs @@ -2,8 +2,8 @@ // SPDX-FileCopyrightText: 2023 Snowfork use crate as snowbridge_system; use frame_support::{ - parameter_types, - traits::{tokens::fungible::Mutate, ConstU128, ConstU16, ConstU64, ConstU8}, + derive_impl, parameter_types, + traits::{tokens::fungible::Mutate, ConstU128, ConstU64, ConstU8}, weights::IdentityFee, PalletId, }; @@ -95,11 +95,9 @@ frame_support::construct_runtime!( } ); +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; type RuntimeTask = RuntimeTask; @@ -109,15 +107,8 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; - type Version = (); type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; type Nonce = u64; type Block = Block; } diff --git a/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs new file mode 100644 index 00000000000..77b5c1aa631 --- /dev/null +++ b/bridges/snowbridge/parachain/pallets/ethereum-beacon-client/src/mock.rs @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +use crate as ethereum_beacon_client; +use frame_support::parameter_types; +use pallet_timestamp; +use primitives::{Fork, ForkVersions}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; + +#[cfg(not(feature = "beacon-spec-mainnet"))] +pub mod minimal { + use super::*; + + use crate::config; + use frame_support::derive_impl; + use hex_literal::hex; + use primitives::CompactExecutionHeader; + use snowbridge_core::inbound::{Log, Proof}; + use sp_runtime::BuildStorage; + use std::{fs::File, path::PathBuf}; + + type Block = frame_system::mocking::MockBlock; + + frame_support::construct_runtime!( + pub enum Test { + System: frame_system::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; + } + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type PalletInfo = PalletInfo; + type SS58Prefix = SS58Prefix; + type Nonce = u64; + type Block = Block; + } + + impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = (); + type WeightInfo = (); + } + + parameter_types! { + pub const ExecutionHeadersPruneThreshold: u32 = 10; + pub const ChainForkVersions: ForkVersions = ForkVersions{ + genesis: Fork { + version: [0, 0, 0, 1], // 0x00000001 + epoch: 0, + }, + altair: Fork { + version: [1, 0, 0, 1], // 0x01000001 + epoch: 0, + }, + bellatrix: Fork { + version: [2, 0, 0, 1], // 0x02000001 + epoch: 0, + }, + capella: Fork { + version: [3, 0, 0, 1], // 0x03000001 + epoch: 0, + }, + }; + } + + impl ethereum_beacon_client::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ForkVersions = ChainForkVersions; + type MaxExecutionHeadersToKeep = ExecutionHeadersPruneThreshold; + type WeightInfo = (); + } + + // Build genesis storage according to the mock runtime. + pub fn new_tester() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + let _ = ext.execute_with(|| Timestamp::set(RuntimeOrigin::signed(1), 30_000)); + ext + } + + fn load_fixture(basename: &str) -> Result + where + T: for<'de> serde::Deserialize<'de>, + { + let filepath: PathBuf = + [env!("CARGO_MANIFEST_DIR"), "tests", "fixtures", basename].iter().collect(); + serde_json::from_reader(File::open(filepath).unwrap()) + } + + pub fn load_execution_header_update_fixture() -> primitives::ExecutionHeaderUpdate { + load_fixture("execution-header-update.minimal.json").unwrap() + } + + pub fn load_checkpoint_update_fixture( + ) -> primitives::CheckpointUpdate<{ config::SYNC_COMMITTEE_SIZE }> { + load_fixture("initial-checkpoint.minimal.json").unwrap() + } + + pub fn load_sync_committee_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("sync-committee-update.minimal.json").unwrap() + } + + pub fn load_finalized_header_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("finalized-header-update.minimal.json").unwrap() + } + + pub fn load_next_sync_committee_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("next-sync-committee-update.minimal.json").unwrap() + } + + pub fn load_next_finalized_header_update_fixture( + ) -> primitives::Update<{ config::SYNC_COMMITTEE_SIZE }, { config::SYNC_COMMITTEE_BITS_SIZE }> { + load_fixture("next-finalized-header-update.minimal.json").unwrap() + } + + pub fn get_message_verification_payload() -> (Log, Proof) { + ( + Log { + address: hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into(), + topics: vec![ + hex!("1b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ad").into(), + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + hex!("0000000000000000000000000000000000000000000000000000000000000001").into(), + ], + data: hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").into(), + }, + Proof { + block_hash: hex!("05aaa60b0f27cce9e71909508527264b77ee14da7b5bf915fcc4e32715333213").into(), + tx_index: 0, + data: (vec![ + hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb").to_vec(), + hex!("d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c185510").to_vec(), + hex!("b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646").to_vec(), + ], vec![ + hex!("f90131a0b601337b3aa10a671caa724eba641e759399979856141d3aea6b6b4ac59b889ba00c7d5dd48be9060221a02fb8fa213860b4c50d47046c8fa65ffaba5737d569e0a094601b62a1086cd9c9cb71a7ebff9e718f3217fd6e837efe4246733c0a196f63a06a4b0dd0aefc37b3c77828c8f07d1b7a2455ceb5dbfd3c77d7d6aeeddc2f7e8ca0d6e8e23142cdd8ec219e1f5d8b56aa18e456702b195deeaa210327284d42ade4a08a313d4c87023005d1ab631bbfe3f5de1e405d0e66d0bef3e033f1e5711b5521a0bf09a5d9a48b10ade82b8d6a5362a15921c8b5228a3487479b467db97411d82fa0f95cccae2a7c572ef3c566503e30bac2b2feb2d2f26eebf6d870dcf7f8cf59cea0d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c1855108080808080808080").to_vec(), + hex!("f851a0b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646a060a634b9280e3a23fb63375e7bbdd9ab07fd379ab6a67e2312bbc112195fa358808080808080808080808080808080").to_vec(), + hex!("f9030820b9030402f90300018301d6e2b9010000000000000800000000000020040008000000000000000000000000400000008000000000000000000000000000000000000000000000000000000000042010000000001000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000002000000000000000000000000200000000000000200000000000100000000040000001000200008000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000f901f5f87a942ffa5ecdbe006d30397c7636d3e015eee251369ff842a0c965575a00553e094ca7c5d14f02e107c258dda06867cbf9e0e69f80e71bbcc1a000000000000000000000000000000000000000000000000000000000000003e8a000000000000000000000000000000000000000000000000000000000000003e8f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000f858948cf6147918a5cbb672703f879f385036f8793a24e1a01449abf21e49fd025f33495e77f7b1461caefdd3d4bb646424a3f445c4576a5ba0000000000000000000000000440edffa1352b13227e8ee646f3ea37456dec701").to_vec(), + ]), + } + ) + } + + pub fn get_message_verification_header() -> CompactExecutionHeader { + CompactExecutionHeader { + parent_hash: hex!("04a7f6ab8282203562c62f38b0ab41d32aaebe2c7ea687702b463148a6429e04") + .into(), + block_number: 55, + state_root: hex!("894d968712976d613519f973a317cb0781c7b039c89f27ea2b7ca193f7befdb3") + .into(), + receipts_root: hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb") + .into(), + } + } +} + +#[cfg(feature = "beacon-spec-mainnet")] +pub mod mainnet { + use super::*; + use frame_support::derive_impl; + + type Block = frame_system::mocking::MockBlock; + use sp_runtime::BuildStorage; + + frame_support::construct_runtime!( + pub enum Test { + System: frame_system::{Pallet, Call, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Storage, Event}, + } + ); + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; + } + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type PalletInfo = PalletInfo; + type SS58Prefix = SS58Prefix; + type Nonce = u64; + type Block = Block; + } + + impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = (); + type WeightInfo = (); + } + + parameter_types! { + pub const ChainForkVersions: ForkVersions = ForkVersions{ + genesis: Fork { + version: [0, 0, 16, 32], // 0x00001020 + epoch: 0, + }, + altair: Fork { + version: [1, 0, 16, 32], // 0x01001020 + epoch: 36660, + }, + bellatrix: Fork { + version: [2, 0, 16, 32], // 0x02001020 + epoch: 112260, + }, + capella: Fork { + version: [3, 0, 16, 32], // 0x03001020 + epoch: 162304, + }, + }; + pub const ExecutionHeadersPruneThreshold: u32 = 10; + } + + impl ethereum_beacon_client::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ForkVersions = ChainForkVersions; + type MaxExecutionHeadersToKeep = ExecutionHeadersPruneThreshold; + type WeightInfo = (); + } + + // Build genesis storage according to the mock runtime. + pub fn new_tester() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + let _ = ext.execute_with(|| Timestamp::set(RuntimeOrigin::signed(1), 30_000)); + ext + } +} diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs index cee9b33bf37..004a5d70ebc 100644 --- a/cumulus/parachain-template/runtime/src/lib.rs +++ b/cumulus/parachain-template/runtime/src/lib.rs @@ -560,7 +560,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 6791dc4064e..1c4f49fea0e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1093,7 +1093,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5352eeb1a1b..e015c7bfca3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1124,7 +1124,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index db1dfbd45d6..0f6af1b51f1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -816,7 +816,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 1c8c9aa2075..206743ba6ac 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -566,7 +566,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 36eb0e07f87..3ed9d6e8e16 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -803,7 +803,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 541978098ca..c4df5b9a565 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -466,7 +466,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index fcd7576b1e1..0cdfebce742 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -521,7 +521,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 80eb7863803..7797329b526 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -512,7 +512,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 10408aaf39a..e09ad42ea9f 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -332,7 +332,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 90c39891769..616da5519a5 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -495,7 +495,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index a904f7c3521..9f572330cac 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -495,7 +495,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs index ba077ef8879..4cc0a81ef49 100644 --- a/cumulus/parachains/runtimes/starters/seedling/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/seedling/src/lib.rs @@ -300,7 +300,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/starters/shell/src/lib.rs b/cumulus/parachains/runtimes/starters/shell/src/lib.rs index 457394760d9..829754731a4 100644 --- a/cumulus/parachains/runtimes/starters/shell/src/lib.rs +++ b/cumulus/parachains/runtimes/starters/shell/src/lib.rs @@ -357,7 +357,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index bf8dcbc24c8..0030287edb3 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -699,7 +699,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index 57969d9a4f1..b69c2341d6b 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -689,7 +689,7 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs b/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs index 76dd7347ccb..7778d1bf7d2 100644 --- a/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs +++ b/cumulus/polkadot-parachain/src/fake_runtime_api/asset_hub_polkadot_aura.rs @@ -39,7 +39,7 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs b/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs index 0f01b85ebcf..880f5d760c7 100644 --- a/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs +++ b/cumulus/polkadot-parachain/src/fake_runtime_api/aura.rs @@ -39,7 +39,7 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs index 5fb31410984..5ccec8983e9 100644 --- a/cumulus/test/runtime/src/lib.rs +++ b/cumulus/test/runtime/src/lib.rs @@ -377,7 +377,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs index ccc3da22400..085ea93fdc7 100644 --- a/polkadot/node/service/src/fake_runtime_api.rs +++ b/polkadot/node/service/src/fake_runtime_api.rs @@ -60,7 +60,7 @@ sp_api::impl_runtime_apis! { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs index 86550ea8b4e..68f42914e44 100644 --- a/polkadot/runtime/common/src/claims.rs +++ b/polkadot/runtime/common/src/claims.rs @@ -702,7 +702,6 @@ mod tests { use secp_utils::*; use parity_scale_codec::Encode; - use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use crate::claims; @@ -715,11 +714,8 @@ mod tests { }; use pallet_balances; use sp_runtime::{ - traits::{BlakeTwo256, Identity, IdentityLookup}, - transaction_validity::TransactionLongevity, - BuildStorage, - DispatchError::BadOrigin, - TokenError, + traits::Identity, transaction_validity::TransactionLongevity, BuildStorage, + DispatchError::BadOrigin, TokenError, }; type Block = frame_system::mocking::MockBlock; @@ -734,34 +730,13 @@ mod tests { } ); - parameter_types! { - pub const BlockHashCount: u32 = 250; - } - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type Nonce = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; type Block = Block; type RuntimeEvent = RuntimeEvent; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index bbc79a13d37..173301e1ad9 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1768,7 +1768,7 @@ sp_api::impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index b74def5de8a..6c899c52701 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -767,7 +767,7 @@ sp_api::impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 574710b3110..91047d953f5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1793,7 +1793,7 @@ sp_api::impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/prdoc/pr_1781.prdoc b/prdoc/pr_1781.prdoc new file mode 100644 index 00000000000..e3560842d15 --- /dev/null +++ b/prdoc/pr_1781.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: "Multi-Block-Migrations, `poll` hook and new System Callbacks" + +doc: + - audience: Runtime Dev + description: | + The major things that this MR touches are: + + **Multi-Block-Migrations**: `pallet-migrations` is introduced that can be configured in the + `System` of a runtime to act as multi-block migrator. The `migrations` pallet then in turn + receives the list of MBMs as config parameter. The list of migrations can be an aggregated + tuple of `SteppedMigration` trait implementation. + It is paramount that the `migrations` pallet is configured in `System` once it is deployed. A + test is in place to double check this. + + To integrate this into your runtime, it is only necessary to change the return type of + `initialize_block` to `RuntimeExecutiveMode`. For extended info please see + https://github.com/paritytech/polkadot-sdk/pull/1781. + + **poll**: a new pallet hook named `poll` is added. This can be used for places where the code + that should be executed is not deadline critical. Runtime devs are advised to skim their usage + of `on_initialize` and `on_finalize` to see whether they can be replace with `poll`. `poll` is + not guaranteed to be called each block. In fact it will not be called when MBMs are ongoing. + + **System Callbacks**: The `system` pallet gets five new config items - all of which can be + safely set to `()` as default. They are: + - `SingleBlockMigrations`: replaces the `Executive` now for configuring migrations. + - `MultiBlockMigrator`: the `pallet-migrations` would be set here, if deployed. + - `PreInherents`: a hook that runs before any inherent. + - `PostInherents`: a hook to run between inherents and `poll`/MBM logic. + - `PostTransactions`: a hook to run after all transactions but before `on_idle`. + +crates: + - name: frame-executive + - name: frame-system + - name: frame-support + - name: frame-support-procedural + - name: pallet-migrations + - name: sc-basic-authorship + - name: sc-block-builder + - name: sp-api + - name: sp-api-proc-macro + - name: sp-runtime diff --git a/substrate/bin/minimal/runtime/src/lib.rs b/substrate/bin/minimal/runtime/src/lib.rs index 610289693d9..fb996aef46b 100644 --- a/substrate/bin/minimal/runtime/src/lib.rs +++ b/substrate/bin/minimal/runtime/src/lib.rs @@ -26,7 +26,8 @@ use frame::{ prelude::*, runtime::{ apis::{ - self, impl_runtime_apis, ApplyExtrinsicResult, CheckInherentsResult, OpaqueMetadata, + self, impl_runtime_apis, ApplyExtrinsicResult, CheckInherentsResult, + ExtrinsicInclusionMode, OpaqueMetadata, }, prelude::*, }, @@ -121,7 +122,7 @@ impl_runtime_apis! { RuntimeExecutive::execute_block(block) } - fn initialize_block(header: &Header) { + fn initialize_block(header: &Header) -> ExtrinsicInclusionMode { RuntimeExecutive::initialize_block(header) } } diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 3b6a74be251..159697f427f 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -331,7 +331,7 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index aa13c3d292b..9607d05daf0 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -88,6 +88,7 @@ pallet-election-provider-support-benchmarking = { path = "../../../frame/electio pallet-elections-phragmen = { path = "../../../frame/elections-phragmen", default-features = false } pallet-example-tasks = { path = "../../../frame/examples/tasks", default-features = false } pallet-fast-unstake = { path = "../../../frame/fast-unstake", default-features = false } +pallet-migrations = { path = "../../../frame/migrations", default-features = false } pallet-nis = { path = "../../../frame/nis", default-features = false } pallet-grandpa = { path = "../../../frame/grandpa", default-features = false } pallet-im-online = { path = "../../../frame/im-online", default-features = false } @@ -198,6 +199,7 @@ std = [ "pallet-lottery/std", "pallet-membership/std", "pallet-message-queue/std", + "pallet-migrations/std", "pallet-mixnet/std", "pallet-mmr/std", "pallet-multisig/std", @@ -302,6 +304,7 @@ runtime-benchmarks = [ "pallet-lottery/runtime-benchmarks", "pallet-membership/runtime-benchmarks", "pallet-message-queue/runtime-benchmarks", + "pallet-migrations/runtime-benchmarks", "pallet-mixnet/runtime-benchmarks", "pallet-mmr/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", @@ -381,6 +384,7 @@ try-runtime = [ "pallet-lottery/try-runtime", "pallet-membership/try-runtime", "pallet-message-queue/try-runtime", + "pallet-migrations/try-runtime", "pallet-mixnet/try-runtime", "pallet-mmr/try-runtime", "pallet-multisig/try-runtime", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index b34d8c89e56..5431628c747 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -310,6 +310,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = frame_system::weights::SubstrateWeight; type SS58Prefix = ConstU16<42>; type MaxConsumers = ConstU32<16>; + type MultiBlockMigrator = MultiBlockMigrations; } impl pallet_insecure_randomness_collective_flip::Config for Runtime {} @@ -2007,6 +2008,25 @@ impl pallet_statement::Config for Runtime { type MaxAllowedBytes = MaxAllowedBytes; } +parameter_types! { + pub MbmServiceWeight: Weight = Perbill::from_percent(80) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_migrations::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations = (); + // Benchmarks need mocked migrations to guarantee that they succeed. + #[cfg(feature = "runtime-benchmarks")] + type Migrations = pallet_migrations::mock_helpers::MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = (); + type FailedMigrationHandler = frame_support::migrations::FreezeChainOnFailedMigration; + type MaxServiceWeight = MbmServiceWeight; + type WeightInfo = pallet_migrations::weights::SubstrateWeight; +} + parameter_types! { pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); } @@ -2241,6 +2261,7 @@ construct_runtime!( TxPause: pallet_tx_pause, SafeMode: pallet_safe_mode, Statement: pallet_statement, + MultiBlockMigrations: pallet_migrations, Broker: pallet_broker, TasksExample: pallet_example_tasks, Mixnet: pallet_mixnet, @@ -2372,6 +2393,7 @@ mod benches { [pallet_lottery, Lottery] [pallet_membership, TechnicalMembership] [pallet_message_queue, MessageQueue] + [pallet_migrations, MultiBlockMigrations] [pallet_mmr, Mmr] [pallet_multisig, Multisig] [pallet_nomination_pools, NominationPoolsBench::] @@ -2417,7 +2439,7 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { Executive::initialize_block(header) } } diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs index fdc3d4918de..932287ac865 100644 --- a/substrate/client/basic-authorship/src/basic_authorship.rs +++ b/substrate/client/basic-authorship/src/basic_authorship.rs @@ -38,7 +38,7 @@ use sp_core::traits::SpawnNamed; use sp_inherents::InherentData; use sp_runtime::{ traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as HeaderT}, - Digest, Percent, SaturatedConversion, + Digest, ExtrinsicInclusionMode, Percent, SaturatedConversion, }; use std::{marker::PhantomData, pin::Pin, sync::Arc, time}; @@ -335,11 +335,12 @@ where self.apply_inherents(&mut block_builder, inherent_data)?; - // TODO call `after_inherents` and check if we should apply extrinsincs here - // - - let end_reason = - self.apply_extrinsics(&mut block_builder, deadline, block_size_limit).await?; + let mode = block_builder.extrinsic_inclusion_mode(); + let end_reason = match mode { + ExtrinsicInclusionMode::AllExtrinsics => + self.apply_extrinsics(&mut block_builder, deadline, block_size_limit).await?, + ExtrinsicInclusionMode::OnlyInherents => EndProposingReason::TransactionForbidden, + }; let (block, storage_changes, proof) = block_builder.build()?.into_inner(); let block_took = block_timer.elapsed(); diff --git a/substrate/client/block-builder/src/lib.rs b/substrate/client/block-builder/src/lib.rs index 258e39d962b..2f22cd42591 100644 --- a/substrate/client/block-builder/src/lib.rs +++ b/substrate/client/block-builder/src/lib.rs @@ -37,7 +37,7 @@ use sp_core::traits::CallContext; use sp_runtime::{ legacy, traits::{Block as BlockT, Hash, HashingFor, Header as HeaderT, NumberFor, One}, - Digest, + Digest, ExtrinsicInclusionMode, }; use std::marker::PhantomData; @@ -198,10 +198,12 @@ pub struct BlockBuilder<'a, Block: BlockT, C: ProvideRuntimeApi + 'a> { extrinsics: Vec, api: ApiRef<'a, C::Api>, call_api_at: &'a C, + /// Version of the [`BlockBuilderApi`] runtime API. version: u32, parent_hash: Block::Hash, /// The estimated size of the block header. estimated_header_size: usize, + extrinsic_inclusion_mode: ExtrinsicInclusionMode, } impl<'a, Block, C> BlockBuilder<'a, Block, C> @@ -244,9 +246,19 @@ where api.set_call_context(CallContext::Onchain); - api.initialize_block(parent_hash, &header)?; + let core_version = api + .api_version::>(parent_hash)? + .ok_or_else(|| Error::VersionInvalid("Core".to_string()))?; - let version = api + let extrinsic_inclusion_mode = if core_version >= 5 { + api.initialize_block(parent_hash, &header)? + } else { + #[allow(deprecated)] + api.initialize_block_before_version_5(parent_hash, &header)?; + ExtrinsicInclusionMode::AllExtrinsics + }; + + let bb_version = api .api_version::>(parent_hash)? .ok_or_else(|| Error::VersionInvalid("BlockBuilderApi".to_string()))?; @@ -254,12 +266,18 @@ where parent_hash, extrinsics: Vec::new(), api, - version, + version: bb_version, estimated_header_size, call_api_at, + extrinsic_inclusion_mode, }) } + /// The extrinsic inclusion mode of the runtime for this block. + pub fn extrinsic_inclusion_mode(&self) -> ExtrinsicInclusionMode { + self.extrinsic_inclusion_mode + } + /// Push onto the block's list of extrinsics. /// /// This will ensure the extrinsic can be validly executed (by executing it). diff --git a/substrate/client/proposer-metrics/src/lib.rs b/substrate/client/proposer-metrics/src/lib.rs index 012e8ca769a..2856300cf80 100644 --- a/substrate/client/proposer-metrics/src/lib.rs +++ b/substrate/client/proposer-metrics/src/lib.rs @@ -44,11 +44,14 @@ impl MetricsLink { } /// The reason why proposing a block ended. +#[derive(Clone, Copy, PartialEq, Eq)] pub enum EndProposingReason { NoMoreTransactions, HitDeadline, HitBlockSizeLimit, HitBlockWeightLimit, + /// No transactions are allowed in the block. + TransactionForbidden, } /// Authorship metrics. @@ -112,6 +115,7 @@ impl Metrics { EndProposingReason::NoMoreTransactions => "no_more_transactions", EndProposingReason::HitBlockSizeLimit => "hit_block_size_limit", EndProposingReason::HitBlockWeightLimit => "hit_block_weight_limit", + EndProposingReason::TransactionForbidden => "transactions_forbidden", }; self.end_proposing_reason.with_label_values(&[reason]).inc(); diff --git a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs index 9544736d84c..89d8c4ce271 100644 --- a/substrate/client/rpc-spec-v2/src/chain_head/tests.rs +++ b/substrate/client/rpc-spec-v2/src/chain_head/tests.rs @@ -242,12 +242,12 @@ async fn follow_with_runtime() { let event: FollowEvent = get_next_event(&mut sub).await; // it is basically json-encoded substrate_test_runtime_client::runtime::VERSION - let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":0,\ - \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\ + let runtime_str = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ + \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",5],\ [\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ [\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\ [\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\ - [\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":0}"; + [\"0xed99c5acb25eedf5\",3],[\"0xfbc577b9d747efd6\",1]],\"transactionVersion\":1,\"stateVersion\":1}"; let runtime: RuntimeVersion = serde_json::from_str(runtime_str).unwrap(); diff --git a/substrate/client/rpc/src/state/tests.rs b/substrate/client/rpc/src/state/tests.rs index 96f4c1be960..dd866e671c5 100644 --- a/substrate/client/rpc/src/state/tests.rs +++ b/substrate/client/rpc/src/state/tests.rs @@ -475,7 +475,7 @@ async fn should_return_runtime_version() { // it is basically json-encoded substrate_test_runtime_client::runtime::VERSION let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ - \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",4],\ + \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",5],\ [\"0x37e397fc7c91f5e4\",2],[\"0xd2bc9897eed08f15\",3],[\"0x40fe3ad401f8959a\",6],\ [\"0xbc9d89904f5b923f\",1],[\"0xc6e9a76309f39b09\",2],[\"0xdd718d5cc53262d4\",1],\ [\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\ diff --git a/substrate/frame/executive/Cargo.toml b/substrate/frame/executive/Cargo.toml index a4ca265f617..63285e4cb49 100644 --- a/substrate/frame/executive/Cargo.toml +++ b/substrate/frame/executive/Cargo.toml @@ -16,6 +16,7 @@ workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] +aquamarine = "0.3.2" codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ "derive", ] } @@ -44,6 +45,7 @@ default = ["std"] with-tracing = ["sp-tracing/with-tracing"] std = [ "codec/std", + "frame-support/experimental", "frame-support/std", "frame-system/std", "frame-try-runtime/std", diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index 48ff675f808..3028eaf318e 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![cfg_attr(not(feature = "std"), no_std)] + //! # Executive Module //! //! The Executive module acts as the orchestration layer for the runtime. It dispatches incoming @@ -35,6 +37,8 @@ //! - Finalize a block. //! - Start an off-chain worker. //! +//! The flow of their application in a block is explained in the [block flowchart](block_flowchart). +//! //! ### Implementations //! //! The Executive module provides the following implementations: @@ -114,17 +118,51 @@ //! pub type Executive = executive::Executive; //! ``` -#![cfg_attr(not(feature = "std"), no_std)] +#[cfg(doc)] +#[cfg_attr(doc, aquamarine::aquamarine)] +/// # Block Execution +/// +/// These are the steps of block execution as done by [`Executive::execute_block`]. A block is +/// invalid if any of them fail. +/// +/// ```mermaid +/// flowchart TD +/// Executive::execute_block --> on_runtime_upgrade +/// on_runtime_upgrade --> System::initialize +/// Executive::initialize_block --> System::initialize +/// System::initialize --> on_initialize +/// on_initialize --> PreInherents[System::PreInherents] +/// PreInherents --> Inherents[Apply Inherents] +/// Inherents --> PostInherents[System::PostInherents] +/// PostInherents --> Check{MBM ongoing?} +/// Check -->|No| poll +/// Check -->|Yes| post_transactions_2[System::PostTransaction] +/// post_transactions_2 --> Step[MBMs::step] +/// Step --> on_finalize +/// poll --> transactions[Apply Transactions] +/// transactions --> post_transactions_1[System::PostTransaction] +/// post_transactions_1 --> CheckIdle{Weight remaining?} +/// CheckIdle -->|Yes| on_idle +/// CheckIdle -->|No| on_finalize +/// on_idle --> on_finalize +/// ``` +pub mod block_flowchart {} + +#[cfg(test)] +mod tests; use codec::{Codec, Encode}; use frame_support::{ + defensive_assert, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo}, + migrations::MultiStepMigrator, pallet_prelude::InvalidTransaction, traits::{ BeforeAllRuntimeMigrations, EnsureInherentsAreFirst, ExecuteBlock, OffchainWorker, - OnFinalize, OnIdle, OnInitialize, OnRuntimeUpgrade, + OnFinalize, OnIdle, OnInitialize, OnPoll, OnRuntimeUpgrade, PostInherents, + PostTransactions, PreInherents, }, - weights::Weight, + weights::{Weight, WeightMeter}, }; use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::{ @@ -134,7 +172,7 @@ use sp_runtime::{ ValidateUnsigned, Zero, }, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, + ApplyExtrinsicResult, ExtrinsicInclusionMode, }; use sp_std::{marker::PhantomData, prelude::*}; @@ -198,7 +236,8 @@ impl< + OnInitialize> + OnIdle> + OnFinalize> - + OffchainWorker>, + + OffchainWorker> + + OnPoll>, COnRuntimeUpgrade: OnRuntimeUpgrade, > ExecuteBlock for Executive @@ -237,6 +276,7 @@ impl< + OnIdle> + OnFinalize> + OffchainWorker> + + OnPoll> + TryState> + TryDecodeEntireStorage, COnRuntimeUpgrade: OnRuntimeUpgrade, @@ -272,36 +312,50 @@ where select, ); - Self::initialize_block(block.header()); - Self::initial_checks(&block); - + let mode = Self::initialize_block(block.header()); + let num_inherents = Self::initial_checks(&block) as usize; let (header, extrinsics) = block.deconstruct(); + // Check if there are any forbidden non-inherents in the block. + if mode == ExtrinsicInclusionMode::OnlyInherents && extrinsics.len() > num_inherents { + return Err("Only inherents allowed".into()) + } + let try_apply_extrinsic = |uxt: Block::Extrinsic| -> ApplyExtrinsicResult { sp_io::init_tracing(); let encoded = uxt.encode(); let encoded_len = encoded.len(); + let is_inherent = System::is_inherent(&uxt); // skip signature verification. let xt = if signature_check { uxt.check(&Default::default()) } else { uxt.unchecked_into_checked_i_know_what_i_am_doing(&Default::default()) }?; - >::note_extrinsic(encoded); let dispatch_info = xt.get_dispatch_info(); + if !is_inherent && !>::inherents_applied() { + Self::inherents_applied(); + } + + >::note_extrinsic(encoded); let r = Applyable::apply::(xt, &dispatch_info, encoded_len)?; + if r.is_err() && dispatch_info.class == DispatchClass::Mandatory { + return Err(InvalidTransaction::BadMandatory.into()) + } + >::note_applied_extrinsic(&r, dispatch_info); Ok(r.map(|_| ()).map_err(|e| e.error)) }; - for e in extrinsics { + // Apply extrinsics: + for e in extrinsics.iter() { if let Err(err) = try_apply_extrinsic(e.clone()) { log::error!( - target: LOG_TARGET, "executing transaction {:?} failed due to {:?}. Aborting the rest of the block execution.", + target: LOG_TARGET, "transaction {:?} failed due to {:?}. Aborting the rest of the block execution.", e, err, ); @@ -309,9 +363,17 @@ where } } + // In this case there were no transactions to trigger this state transition: + if !>::inherents_applied() { + Self::inherents_applied(); + } + // post-extrinsics book-keeping >::note_finished_extrinsics(); - Self::idle_and_finalize_hook(*header.number()); + ::PostTransactions::post_transactions(); + + Self::on_idle_hook(*header.number()); + Self::on_finalize_hook(*header.number()); // run the try-state checks of all pallets, ensuring they don't alter any state. let _guard = frame_support::StorageNoopGuard::default(); @@ -449,7 +511,8 @@ impl< + OnInitialize> + OnIdle> + OnFinalize> - + OffchainWorker>, + + OffchainWorker> + + OnPoll>, COnRuntimeUpgrade: OnRuntimeUpgrade, > Executive where @@ -464,16 +527,36 @@ where pub fn execute_on_runtime_upgrade() -> Weight { let before_all_weight = ::before_all_runtime_migrations(); - <(COnRuntimeUpgrade, AllPalletsWithSystem) as OnRuntimeUpgrade>::on_runtime_upgrade() - .saturating_add(before_all_weight) + + let runtime_upgrade_weight = <( + COnRuntimeUpgrade, + ::SingleBlockMigrations, + // We want to run the migrations before we call into the pallets as they may + // access any state that would then not be migrated. + AllPalletsWithSystem, + ) as OnRuntimeUpgrade>::on_runtime_upgrade(); + + before_all_weight.saturating_add(runtime_upgrade_weight) } /// Start the execution of a particular block. - pub fn initialize_block(header: &frame_system::pallet_prelude::HeaderFor) { + pub fn initialize_block( + header: &frame_system::pallet_prelude::HeaderFor, + ) -> ExtrinsicInclusionMode { sp_io::init_tracing(); sp_tracing::enter_span!(sp_tracing::Level::TRACE, "init_block"); let digests = Self::extract_pre_digest(header); Self::initialize_block_impl(header.number(), header.parent_hash(), &digests); + + Self::extrinsic_mode() + } + + fn extrinsic_mode() -> ExtrinsicInclusionMode { + if ::MultiBlockMigrator::ongoing() { + ExtrinsicInclusionMode::OnlyInherents + } else { + ExtrinsicInclusionMode::AllExtrinsics + } } fn extract_pre_digest(header: &frame_system::pallet_prelude::HeaderFor) -> Digest { @@ -519,6 +602,7 @@ where ); frame_system::Pallet::::note_finished_initialize(); + ::PreInherents::pre_inherents(); } /// Returns if the runtime has been upgraded, based on [`frame_system::LastRuntimeUpgrade`]. @@ -529,7 +613,8 @@ where last.map(|v| v.was_upgraded(¤t)).unwrap_or(true) } - fn initial_checks(block: &Block) { + /// Returns the number of inherents in the block. + fn initial_checks(block: &Block) -> u32 { sp_tracing::enter_span!(sp_tracing::Level::TRACE, "initial_checks"); let header = block.header(); @@ -542,8 +627,9 @@ where "Parent hash should be valid.", ); - if let Err(i) = System::ensure_inherents_are_first(block) { - panic!("Invalid inherent position for extrinsic at index {}", i); + match System::ensure_inherents_are_first(block) { + Ok(num) => num, + Err(i) => panic!("Invalid inherent position for extrinsic at index {}", i), } } @@ -552,53 +638,90 @@ where sp_io::init_tracing(); sp_tracing::within_span! { sp_tracing::info_span!("execute_block", ?block); + // Execute `on_runtime_upgrade` and `on_initialize`. + let mode = Self::initialize_block(block.header()); + let num_inherents = Self::initial_checks(&block) as usize; + let (header, extrinsics) = block.deconstruct(); + let num_extrinsics = extrinsics.len(); - Self::initialize_block(block.header()); + if mode == ExtrinsicInclusionMode::OnlyInherents && num_extrinsics > num_inherents { + // Invalid block + panic!("Only inherents are allowed in this block") + } - // any initial checks - Self::initial_checks(&block); + Self::apply_extrinsics(extrinsics.into_iter()); - // execute extrinsics - let (header, extrinsics) = block.deconstruct(); - Self::execute_extrinsics_with_book_keeping(extrinsics, *header.number()); + // In this case there were no transactions to trigger this state transition: + if !>::inherents_applied() { + defensive_assert!(num_inherents == num_extrinsics); + Self::inherents_applied(); + } - // any final checks + >::note_finished_extrinsics(); + ::PostTransactions::post_transactions(); + + Self::on_idle_hook(*header.number()); + Self::on_finalize_hook(*header.number()); Self::final_checks(&header); } } - /// Execute given extrinsics and take care of post-extrinsics book-keeping. - fn execute_extrinsics_with_book_keeping( - extrinsics: Vec, - block_number: NumberFor, - ) { + /// Logic that runs directly after inherent application. + /// + /// It advances the Multi-Block-Migrations or runs the `on_poll` hook. + pub fn inherents_applied() { + >::note_inherents_applied(); + ::PostInherents::post_inherents(); + + if ::MultiBlockMigrator::ongoing() { + let used_weight = ::MultiBlockMigrator::step(); + >::register_extra_weight_unchecked( + used_weight, + DispatchClass::Mandatory, + ); + } else { + let block_number = >::block_number(); + Self::on_poll_hook(block_number); + } + } + + /// Execute given extrinsics. + fn apply_extrinsics(extrinsics: impl Iterator) { extrinsics.into_iter().for_each(|e| { if let Err(e) = Self::apply_extrinsic(e) { let err: &'static str = e.into(); panic!("{}", err) } }); - - // post-extrinsics book-keeping - >::note_finished_extrinsics(); - - Self::idle_and_finalize_hook(block_number); } /// Finalize the block - it is up the caller to ensure that all header fields are valid /// except state-root. + // Note: Only used by the block builder - not Executive itself. pub fn finalize_block() -> frame_system::pallet_prelude::HeaderFor { sp_io::init_tracing(); sp_tracing::enter_span!(sp_tracing::Level::TRACE, "finalize_block"); - >::note_finished_extrinsics(); - let block_number = >::block_number(); - Self::idle_and_finalize_hook(block_number); + // In this case there were no transactions to trigger this state transition: + if !>::inherents_applied() { + Self::inherents_applied(); + } + >::note_finished_extrinsics(); + ::PostTransactions::post_transactions(); + let block_number = >::block_number(); + Self::on_idle_hook(block_number); + Self::on_finalize_hook(block_number); >::finalize() } - fn idle_and_finalize_hook(block_number: NumberFor) { + /// Run the `on_idle` hook of all pallet, but only if there is weight remaining and there are no + /// ongoing MBMs. + fn on_idle_hook(block_number: NumberFor) { + if ::MultiBlockMigrator::ongoing() { + return + } + let weight = >::block_weight(); let max_weight = >::get().max_block; let remaining_weight = max_weight.saturating_sub(weight.total()); @@ -613,7 +736,33 @@ where DispatchClass::Mandatory, ); } + } + + fn on_poll_hook(block_number: NumberFor) { + defensive_assert!( + !::MultiBlockMigrator::ongoing(), + "on_poll should not be called during migrations" + ); + let weight = >::block_weight(); + let max_weight = >::get().max_block; + let remaining = max_weight.saturating_sub(weight.total()); + + if remaining.all_gt(Weight::zero()) { + let mut meter = WeightMeter::with_limit(remaining); + >>::on_poll( + block_number, + &mut meter, + ); + >::register_extra_weight_unchecked( + meter.consumed(), + DispatchClass::Mandatory, + ); + } + } + + /// Run the `on_finalize` hook of all pallet. + fn on_finalize_hook(block_number: NumberFor) { >>::on_finalize(block_number); } @@ -627,8 +776,18 @@ where let encoded_len = encoded.len(); sp_tracing::enter_span!(sp_tracing::info_span!("apply_extrinsic", ext=?sp_core::hexdisplay::HexDisplay::from(&encoded))); + + // We use the dedicated `is_inherent` check here, since just relying on `Mandatory` dispatch + // class does not capture optional inherents. + let is_inherent = System::is_inherent(&uxt); + // Verify that the signature is good. let xt = uxt.check(&Default::default())?; + let dispatch_info = xt.get_dispatch_info(); + + if !is_inherent && !>::inherents_applied() { + Self::inherents_applied(); + } // We don't need to make sure to `note_extrinsic` only after we know it's going to be // executed to prevent it from leaking in storage since at this point, it will either @@ -637,8 +796,6 @@ where // AUDIT: Under no circumstances may this function panic from here onwards. - // Decode parameters and dispatch - let dispatch_info = xt.get_dispatch_info(); let r = Applyable::apply::(xt, &dispatch_info, encoded_len)?; // Mandatory(inherents) are not allowed to fail. @@ -745,956 +902,3 @@ where ) } } - -#[cfg(test)] -mod tests { - use super::*; - - use sp_core::H256; - use sp_runtime::{ - generic::{DigestItem, Era}, - testing::{Block, Digest, Header}, - traits::{BlakeTwo256, Block as BlockT, Header as HeaderT, IdentityLookup}, - transaction_validity::{ - InvalidTransaction, TransactionValidityError, UnknownTransaction, ValidTransaction, - }, - BuildStorage, DispatchError, - }; - - use frame_support::{ - assert_err, derive_impl, parameter_types, - traits::{fungible, ConstU32, ConstU64, ConstU8, Currency}, - weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFee}, - }; - use frame_system::{ChainContext, LastRuntimeUpgrade, LastRuntimeUpgradeInfo}; - use pallet_balances::Call as BalancesCall; - use pallet_transaction_payment::CurrencyAdapter; - - const TEST_KEY: &[u8] = b":test:key:"; - - #[frame_support::pallet(dev_mode)] - mod custom { - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; - - #[pallet::pallet] - pub struct Pallet(_); - - #[pallet::config] - pub trait Config: frame_system::Config {} - - #[pallet::hooks] - impl Hooks> for Pallet { - // module hooks. - // one with block number arg and one without - fn on_initialize(n: BlockNumberFor) -> Weight { - println!("on_initialize({})", n); - Weight::from_parts(175, 0) - } - - fn on_idle(n: BlockNumberFor, remaining_weight: Weight) -> Weight { - println!("on_idle{}, {})", n, remaining_weight); - Weight::from_parts(175, 0) - } - - fn on_finalize(n: BlockNumberFor) { - println!("on_finalize({})", n); - } - - fn on_runtime_upgrade() -> Weight { - sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); - Weight::from_parts(200, 0) - } - - fn offchain_worker(n: BlockNumberFor) { - assert_eq!(BlockNumberFor::::from(1u32), n); - } - } - - #[pallet::call] - impl Pallet { - pub fn some_function(origin: OriginFor) -> DispatchResult { - // NOTE: does not make any different. - frame_system::ensure_signed(origin)?; - Ok(()) - } - - #[pallet::weight((200, DispatchClass::Operational))] - pub fn some_root_operation(origin: OriginFor) -> DispatchResult { - frame_system::ensure_root(origin)?; - Ok(()) - } - - pub fn some_unsigned_message(origin: OriginFor) -> DispatchResult { - frame_system::ensure_none(origin)?; - Ok(()) - } - - pub fn allowed_unsigned(origin: OriginFor) -> DispatchResult { - frame_system::ensure_root(origin)?; - Ok(()) - } - - pub fn unallowed_unsigned(origin: OriginFor) -> DispatchResult { - frame_system::ensure_root(origin)?; - Ok(()) - } - - #[pallet::weight((0, DispatchClass::Mandatory))] - pub fn inherent_call(origin: OriginFor) -> DispatchResult { - frame_system::ensure_none(origin)?; - Ok(()) - } - - pub fn calculate_storage_root(_origin: OriginFor) -> DispatchResult { - let root = sp_io::storage::root(sp_runtime::StateVersion::V1); - sp_io::storage::set("storage_root".as_bytes(), &root); - Ok(()) - } - } - - #[pallet::inherent] - impl ProvideInherent for Pallet { - type Call = Call; - - type Error = sp_inherents::MakeFatalError<()>; - - const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234"; - - fn create_inherent(_data: &InherentData) -> Option { - None - } - - fn is_inherent(call: &Self::Call) -> bool { - *call == Call::::inherent_call {} - } - } - - #[pallet::validate_unsigned] - impl ValidateUnsigned for Pallet { - type Call = Call; - - // Inherent call is accepted for being dispatched - fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { - match call { - Call::allowed_unsigned { .. } => Ok(()), - Call::inherent_call { .. } => Ok(()), - _ => Err(UnknownTransaction::NoUnsignedValidator.into()), - } - } - - // Inherent call is not validated as unsigned - fn validate_unsigned( - _source: TransactionSource, - call: &Self::Call, - ) -> TransactionValidity { - match call { - Call::allowed_unsigned { .. } => Ok(Default::default()), - _ => UnknownTransaction::NoUnsignedValidator.into(), - } - } - } - } - - frame_support::construct_runtime!( - pub enum Runtime { - System: frame_system, - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - Custom: custom, - } - ); - - parameter_types! { - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::builder() - .base_block(Weight::from_parts(10, 0)) - .for_class(DispatchClass::all(), |weights| weights.base_extrinsic = Weight::from_parts(5, 0)) - .for_class(DispatchClass::non_mandatory(), |weights| weights.max_total = Weight::from_parts(1024, u64::MAX).into()) - .build_or_panic(); - pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { - read: 10, - write: 100, - }; - } - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] - impl frame_system::Config for Runtime { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = BlockWeights; - type BlockLength = (); - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type Nonce = u64; - type RuntimeCall = RuntimeCall; - type Hash = sp_core::H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Block = TestBlock; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<250>; - type Version = RuntimeVersion; - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; - } - - type Balance = u64; - impl pallet_balances::Config for Runtime { - type Balance = Balance; - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ConstU64<1>; - type AccountStore = System; - type MaxLocks = (); - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type WeightInfo = (); - type FreezeIdentifier = (); - type MaxFreezes = ConstU32<1>; - type RuntimeHoldReason = (); - type RuntimeFreezeReason = (); - } - - parameter_types! { - pub const TransactionByteFee: Balance = 0; - } - impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = CurrencyAdapter; - type OperationalFeeMultiplier = ConstU8<5>; - type WeightToFee = IdentityFee; - type LengthToFee = ConstantMultiplier; - type FeeMultiplierUpdate = (); - } - impl custom::Config for Runtime {} - - pub struct RuntimeVersion; - impl frame_support::traits::Get for RuntimeVersion { - fn get() -> sp_version::RuntimeVersion { - RuntimeVersionTestValues::get().clone() - } - } - - parameter_types! { - pub static RuntimeVersionTestValues: sp_version::RuntimeVersion = - Default::default(); - } - - type SignedExtra = ( - frame_system::CheckEra, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, - ); - type TestXt = sp_runtime::testing::TestXt; - type TestBlock = Block; - - // Will contain `true` when the custom runtime logic was called. - const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime"; - - struct CustomOnRuntimeUpgrade; - impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { - fn on_runtime_upgrade() -> Weight { - sp_io::storage::set(TEST_KEY, "custom_upgrade".as_bytes()); - sp_io::storage::set(CUSTOM_ON_RUNTIME_KEY, &true.encode()); - System::deposit_event(frame_system::Event::CodeUpdated); - - assert_eq!(0, System::last_runtime_upgrade_spec_version()); - - Weight::from_parts(100, 0) - } - } - - type Executive = super::Executive< - Runtime, - Block, - ChainContext, - Runtime, - AllPalletsWithSystem, - CustomOnRuntimeUpgrade, - >; - - fn extra(nonce: u64, fee: Balance) -> SignedExtra { - ( - frame_system::CheckEra::from(Era::Immortal), - frame_system::CheckNonce::from(nonce), - frame_system::CheckWeight::new(), - pallet_transaction_payment::ChargeTransactionPayment::from(fee), - ) - } - - fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { - Some((who, extra(nonce, fee))) - } - - fn call_transfer(dest: u64, value: u64) -> RuntimeCall { - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }) - } - - #[test] - fn balance_transfer_dispatch_works() { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } - .assimilate_storage(&mut t) - .unwrap(); - let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0)); - let weight = xt.get_dispatch_info().weight + - ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - let fee: Balance = - ::WeightToFee::weight_to_fee(&weight); - let mut t = sp_io::TestExternalities::new(t); - t.execute_with(|| { - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - let r = Executive::apply_extrinsic(xt); - assert!(r.is_ok()); - assert_eq!(>::total_balance(&1), 142 - fee); - assert_eq!(>::total_balance(&2), 69); - }); - } - - fn new_test_ext(balance_factor: Balance) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } - .assimilate_storage(&mut t) - .unwrap(); - t.into() - } - - fn new_test_ext_v0(balance_factor: Balance) -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } - .assimilate_storage(&mut t) - .unwrap(); - (t, sp_runtime::StateVersion::V0).into() - } - - #[test] - fn block_import_works() { - block_import_works_inner( - new_test_ext_v0(1), - array_bytes::hex_n_into_unchecked( - "65e953676859e7a33245908af7ad3637d6861eb90416d433d485e95e2dd174a1", - ), - ); - block_import_works_inner( - new_test_ext(1), - array_bytes::hex_n_into_unchecked( - "5a19b3d6fdb7241836349fdcbe2d9df4d4f945b949d979e31ad50bff1cbcd1c2", - ), - ); - } - fn block_import_works_inner(mut ext: sp_io::TestExternalities, state_root: H256) { - ext.execute_with(|| { - Executive::execute_block(Block { - header: Header { - parent_hash: [69u8; 32].into(), - number: 1, - state_root, - extrinsics_root: array_bytes::hex_n_into_unchecked( - "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", - ), - digest: Digest { logs: vec![] }, - }, - extrinsics: vec![], - }); - }); - } - - #[test] - #[should_panic] - fn block_import_of_bad_state_root_fails() { - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block { - header: Header { - parent_hash: [69u8; 32].into(), - number: 1, - state_root: [0u8; 32].into(), - extrinsics_root: array_bytes::hex_n_into_unchecked( - "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", - ), - digest: Digest { logs: vec![] }, - }, - extrinsics: vec![], - }); - }); - } - - #[test] - #[should_panic] - fn block_import_of_bad_extrinsic_root_fails() { - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block { - header: Header { - parent_hash: [69u8; 32].into(), - number: 1, - state_root: array_bytes::hex_n_into_unchecked( - "75e7d8f360d375bbe91bcf8019c01ab6362448b4a89e3b329717eb9d910340e5", - ), - extrinsics_root: [0u8; 32].into(), - digest: Digest { logs: vec![] }, - }, - extrinsics: vec![], - }); - }); - } - - #[test] - fn bad_extrinsic_not_inserted() { - let mut t = new_test_ext(1); - // bad nonce check! - let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0)); - t.execute_with(|| { - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - assert_err!( - Executive::apply_extrinsic(xt), - TransactionValidityError::Invalid(InvalidTransaction::Future) - ); - assert_eq!(>::extrinsic_index(), Some(0)); - }); - } - - #[test] - fn block_weight_limit_enforced() { - let mut t = new_test_ext(10000); - // given: TestXt uses the encoded len as fixed Len: - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let encoded = xt.encode(); - let encoded_len = encoded.len() as u64; - // on_initialize weight + base block execution weight - let block_weights = ::BlockWeights::get(); - let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block; - let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight; - let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5); - t.execute_with(|| { - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - // Base block execution weight + `on_initialize` weight from the custom module. - assert_eq!(>::block_weight().total(), base_block_weight); - - for nonce in 0..=num_to_exhaust_block { - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { - dest: 33, - value: 0, - }), - sign_extra(1, nonce.into(), 0), - ); - let res = Executive::apply_extrinsic(xt); - if nonce != num_to_exhaust_block { - assert!(res.is_ok()); - assert_eq!( - >::block_weight().total(), - //--------------------- on_initialize + block_execution + extrinsic_base weight - Weight::from_parts((encoded_len + 5) * (nonce + 1), 0) + base_block_weight, - ); - assert_eq!( - >::extrinsic_index(), - Some(nonce as u32 + 1) - ); - } else { - assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); - } - } - }); - } - - #[test] - fn block_weight_and_size_is_stored_per_tx() { - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let x1 = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 1, 0), - ); - let x2 = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 2, 0), - ); - let len = xt.clone().encode().len() as u32; - let mut t = new_test_ext(1); - t.execute_with(|| { - // Block execution weight + on_initialize weight from custom module - let base_block_weight = Weight::from_parts(175, 0) + - ::BlockWeights::get().base_block; - - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - assert_eq!(>::block_weight().total(), base_block_weight); - assert_eq!(>::all_extrinsics_len(), 0); - - assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); - assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); - assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); - - // default weight for `TestXt` == encoded length. - let extrinsic_weight = Weight::from_parts(len as u64, 0) + - ::BlockWeights::get() - .get(DispatchClass::Normal) - .base_extrinsic; - assert_eq!( - >::block_weight().total(), - base_block_weight + 3u64 * extrinsic_weight, - ); - assert_eq!(>::all_extrinsics_len(), 3 * len); - - let _ = >::finalize(); - // All extrinsics length cleaned on `System::finalize` - assert_eq!(>::all_extrinsics_len(), 0); - - // New Block - Executive::initialize_block(&Header::new( - 2, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - // Block weight cleaned up on `System::initialize` - assert_eq!(>::block_weight().total(), base_block_weight); - }); - } - - #[test] - fn validate_unsigned() { - let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None); - let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None); - let mut t = new_test_ext(1); - - t.execute_with(|| { - assert_eq!( - Executive::validate_transaction( - TransactionSource::InBlock, - valid.clone(), - Default::default(), - ), - Ok(ValidTransaction::default()), - ); - assert_eq!( - Executive::validate_transaction( - TransactionSource::InBlock, - invalid.clone(), - Default::default(), - ), - Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)), - ); - assert_eq!(Executive::apply_extrinsic(valid), Ok(Err(DispatchError::BadOrigin))); - assert_eq!( - Executive::apply_extrinsic(invalid), - Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)) - ); - }); - } - - #[test] - fn can_not_pay_for_tx_fee_on_full_lock() { - let mut t = new_test_ext(1); - t.execute_with(|| { - as fungible::MutateFreeze>::set_freeze( - &(), - &1, - 110, - ) - .unwrap(); - let xt = TestXt::new( - RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }), - sign_extra(1, 0, 0), - ); - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - assert_eq!(Executive::apply_extrinsic(xt), Err(InvalidTransaction::Payment.into()),); - assert_eq!(>::total_balance(&1), 111); - }); - } - - #[test] - fn block_hooks_weight_is_stored() { - new_test_ext(1).execute_with(|| { - Executive::initialize_block(&Header::new_from_number(1)); - Executive::finalize_block(); - // NOTE: might need updates over time if new weights are introduced. - // For now it only accounts for the base block execution weight and - // the `on_initialize` weight defined in the custom test module. - assert_eq!( - >::block_weight().total(), - Weight::from_parts(175 + 175 + 10, 0) - ); - }) - } - - #[test] - fn runtime_upgraded_should_work() { - new_test_ext(1).execute_with(|| { - RuntimeVersionTestValues::mutate(|v| *v = Default::default()); - // It should be added at genesis - assert!(LastRuntimeUpgrade::::exists()); - assert!(!Executive::runtime_upgraded()); - - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - assert!(Executive::runtime_upgraded()); - - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { - spec_version: 1, - spec_name: "test".into(), - ..Default::default() - } - }); - assert!(Executive::runtime_upgraded()); - - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { - spec_version: 0, - impl_version: 2, - ..Default::default() - } - }); - assert!(!Executive::runtime_upgraded()); - - LastRuntimeUpgrade::::take(); - assert!(Executive::runtime_upgraded()); - }) - } - - #[test] - fn last_runtime_upgrade_was_upgraded_works() { - let test_data = vec![ - (0, "", 1, "", true), - (1, "", 1, "", false), - (1, "", 1, "test", true), - (1, "", 0, "", false), - (1, "", 0, "test", true), - ]; - - for (spec_version, spec_name, c_spec_version, c_spec_name, result) in test_data { - let current = sp_version::RuntimeVersion { - spec_version: c_spec_version, - spec_name: c_spec_name.into(), - ..Default::default() - }; - - let last = LastRuntimeUpgradeInfo { - spec_version: spec_version.into(), - spec_name: spec_name.into(), - }; - - assert_eq!(result, last.was_upgraded(¤t)); - } - } - - #[test] - fn custom_runtime_upgrade_is_called_before_modules() { - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); - assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); - assert_eq!( - Some(RuntimeVersionTestValues::get().into()), - LastRuntimeUpgrade::::get(), - ) - }); - } - - #[test] - fn event_from_runtime_upgrade_is_included() { - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - // set block number to non zero so events are not excluded - System::set_block_number(1); - - Executive::initialize_block(&Header::new( - 2, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - System::assert_last_event(frame_system::Event::::CodeUpdated.into()); - }); - } - - /// Regression test that ensures that the custom on runtime upgrade is called when executive is - /// used through the `ExecuteBlock` trait. - #[test] - fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { - let xt = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - - let header = new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - // Reset to get the correct new genesis below. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 0, ..Default::default() } - }); - - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called. - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - >>::execute_block(Block::new(header, vec![xt])); - - assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); - assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); - }); - } - - #[test] - fn all_weights_are_recorded_correctly() { - // Reset to get the correct new genesis below. - RuntimeVersionTestValues::take(); - - new_test_ext(1).execute_with(|| { - // Make sure `on_runtime_upgrade` is called for maximum complexity - RuntimeVersionTestValues::mutate(|v| { - *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } - }); - - let block_number = 1; - - Executive::initialize_block(&Header::new( - block_number, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - // Reset the last runtime upgrade info, to make the second call to `on_runtime_upgrade` - // succeed. - LastRuntimeUpgrade::::take(); - - // All weights that show up in the `initialize_block_impl` - let custom_runtime_upgrade_weight = CustomOnRuntimeUpgrade::on_runtime_upgrade(); - let runtime_upgrade_weight = - ::on_runtime_upgrade(); - let on_initialize_weight = - >::on_initialize(block_number); - let base_block_weight = - ::BlockWeights::get().base_block; - - // Weights are recorded correctly - assert_eq!( - frame_system::Pallet::::block_weight().total(), - custom_runtime_upgrade_weight + - runtime_upgrade_weight + - on_initialize_weight + base_block_weight, - ); - }); - } - - #[test] - fn offchain_worker_works_as_expected() { - new_test_ext(1).execute_with(|| { - let parent_hash = sp_core::H256::from([69u8; 32]); - let mut digest = Digest::default(); - digest.push(DigestItem::Seal([1, 2, 3, 4], vec![5, 6, 7, 8])); - - let header = - Header::new(1, H256::default(), H256::default(), parent_hash, digest.clone()); - - Executive::offchain_worker(&header); - - assert_eq!(digest, System::digest()); - assert_eq!(parent_hash, System::block_hash(0)); - assert_eq!(header.hash(), System::block_hash(1)); - }); - } - - #[test] - fn calculating_storage_root_twice_works() { - let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {}); - let xt = TestXt::new(call, sign_extra(1, 0, 0)); - - let header = new_test_ext(1).execute_with(|| { - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new(header, vec![xt])); - }); - } - - #[test] - #[should_panic(expected = "Invalid inherent position for extrinsic at index 1")] - fn invalid_inherent_position_fail() { - let xt1 = TestXt::new( - RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), - sign_extra(1, 0, 0), - ); - let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), None); - - let header = new_test_ext(1).execute_with(|| { - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); - Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new(header, vec![xt1, xt2])); - }); - } - - #[test] - fn valid_inherents_position_works() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), None); - let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); - - let header = new_test_ext(1).execute_with(|| { - // Let's build some fake block. - Executive::initialize_block(&Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - )); - - Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); - Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); - - Executive::finalize_block() - }); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new(header, vec![xt1, xt2])); - }); - } - - #[test] - #[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")] - fn invalid_inherents_fail_block_execution() { - let xt1 = - TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), sign_extra(1, 0, 0)); - - new_test_ext(1).execute_with(|| { - Executive::execute_block(Block::new( - Header::new( - 1, - H256::default(), - H256::default(), - [69u8; 32].into(), - Digest::default(), - ), - vec![xt1], - )); - }); - } - - // Inherents are created by the runtime and don't need to be validated. - #[test] - fn inherents_fail_validate_block() { - let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent_call {}), None); - - new_test_ext(1).execute_with(|| { - assert_eq!( - Executive::validate_transaction(TransactionSource::External, xt1, H256::random()) - .unwrap_err(), - InvalidTransaction::MandatoryValidation.into() - ); - }) - } -} diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs new file mode 100644 index 00000000000..70b55f6e855 --- /dev/null +++ b/substrate/frame/executive/src/tests.rs @@ -0,0 +1,1389 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Test the `frame-executive` crate. + +use super::*; + +use sp_core::H256; +use sp_runtime::{ + generic::{DigestItem, Era}, + testing::{Block, Digest, Header}, + traits::{Block as BlockT, Header as HeaderT}, + transaction_validity::{ + InvalidTransaction, TransactionValidityError, UnknownTransaction, ValidTransaction, + }, + BuildStorage, DispatchError, +}; + +use frame_support::{ + assert_err, assert_ok, derive_impl, + migrations::MultiStepMigrator, + pallet_prelude::*, + parameter_types, + traits::{fungible, ConstU8, Currency, IsInherent}, + weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightMeter, WeightToFee}, +}; +use frame_system::{pallet_prelude::*, ChainContext, LastRuntimeUpgrade, LastRuntimeUpgradeInfo}; +use pallet_balances::Call as BalancesCall; +use pallet_transaction_payment::CurrencyAdapter; + +const TEST_KEY: &[u8] = b":test:key:"; + +#[frame_support::pallet(dev_mode)] +mod custom { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::hooks] + impl Hooks> for Pallet { + // module hooks. + // one with block number arg and one without + fn on_initialize(_: BlockNumberFor) -> Weight { + Weight::from_parts(175, 0) + } + + fn on_idle(_: BlockNumberFor, _: Weight) -> Weight { + Weight::from_parts(175, 0) + } + + fn on_poll(_: BlockNumberFor, _: &mut WeightMeter) {} + + fn on_finalize(_: BlockNumberFor) {} + + fn on_runtime_upgrade() -> Weight { + sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); + Weight::from_parts(200, 0) + } + + fn offchain_worker(n: BlockNumberFor) { + assert_eq!(BlockNumberFor::::from(1u32), n); + } + } + + #[pallet::call] + impl Pallet { + pub fn some_function(origin: OriginFor) -> DispatchResult { + // NOTE: does not make any difference. + frame_system::ensure_signed(origin)?; + Ok(()) + } + + #[pallet::weight((200, DispatchClass::Operational))] + pub fn some_root_operation(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + pub fn some_unsigned_message(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + Ok(()) + } + + pub fn allowed_unsigned(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + pub fn unallowed_unsigned(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + #[pallet::weight((0, DispatchClass::Mandatory))] + pub fn inherent(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + Ok(()) + } + + pub fn calculate_storage_root(_origin: OriginFor) -> DispatchResult { + let root = sp_io::storage::root(sp_runtime::StateVersion::V1); + sp_io::storage::set("storage_root".as_bytes(), &root); + Ok(()) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + + type Error = sp_inherents::MakeFatalError<()>; + + const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234"; + + fn create_inherent(_data: &InherentData) -> Option { + None + } + + fn is_inherent(call: &Self::Call) -> bool { + *call == Call::::inherent {} + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + // Inherent call is accepted for being dispatched + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + match call { + Call::allowed_unsigned { .. } => Ok(()), + Call::inherent { .. } => Ok(()), + _ => Err(UnknownTransaction::NoUnsignedValidator.into()), + } + } + + // Inherent call is not validated as unsigned + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + match call { + Call::allowed_unsigned { .. } => Ok(Default::default()), + _ => UnknownTransaction::NoUnsignedValidator.into(), + } + } + } +} + +#[frame_support::pallet(dev_mode)] +mod custom2 { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::hooks] + impl Hooks> for Pallet { + // module hooks. + // one with block number arg and one without + fn on_initialize(_: BlockNumberFor) -> Weight { + assert!( + !MockedSystemCallbacks::pre_inherent_called(), + "Pre inherent hook goes after on_initialize" + ); + + Weight::from_parts(0, 0) + } + + fn on_idle(_: BlockNumberFor, _: Weight) -> Weight { + assert!( + MockedSystemCallbacks::post_transactions_called(), + "Post transactions hook goes before after on_idle" + ); + Weight::from_parts(0, 0) + } + + fn on_finalize(_: BlockNumberFor) { + assert!( + MockedSystemCallbacks::post_transactions_called(), + "Post transactions hook goes before after on_finalize" + ); + } + + fn on_runtime_upgrade() -> Weight { + sp_io::storage::set(super::TEST_KEY, "module".as_bytes()); + Weight::from_parts(0, 0) + } + } + + #[pallet::call] + impl Pallet { + pub fn allowed_unsigned(origin: OriginFor) -> DispatchResult { + frame_system::ensure_root(origin)?; + Ok(()) + } + + pub fn some_call(_: OriginFor) -> DispatchResult { + assert!(MockedSystemCallbacks::post_inherent_called()); + assert!(!MockedSystemCallbacks::post_transactions_called()); + assert!(System::inherents_applied()); + + Ok(()) + } + + #[pallet::weight({0})] + pub fn optional_inherent(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + + assert!(MockedSystemCallbacks::pre_inherent_called()); + assert!(!MockedSystemCallbacks::post_inherent_called(), "Should not already be called"); + assert!(!System::inherents_applied()); + + Ok(()) + } + + #[pallet::weight((0, DispatchClass::Mandatory))] + pub fn inherent(origin: OriginFor) -> DispatchResult { + frame_system::ensure_none(origin)?; + + assert!(MockedSystemCallbacks::pre_inherent_called()); + assert!(!MockedSystemCallbacks::post_inherent_called(), "Should not already be called"); + assert!(!System::inherents_applied()); + + Ok(()) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + + type Error = sp_inherents::MakeFatalError<()>; + + const INHERENT_IDENTIFIER: [u8; 8] = *b"test1235"; + + fn create_inherent(_data: &InherentData) -> Option { + None + } + + fn is_inherent(call: &Self::Call) -> bool { + matches!(call, Call::::inherent {} | Call::::optional_inherent {}) + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + // Inherent call is accepted for being dispatched + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + match call { + Call::allowed_unsigned { .. } | + Call::optional_inherent { .. } | + Call::inherent { .. } => Ok(()), + _ => Err(UnknownTransaction::NoUnsignedValidator.into()), + } + } + + // Inherent call is not validated as unsigned + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + match call { + Call::allowed_unsigned { .. } => Ok(Default::default()), + _ => UnknownTransaction::NoUnsignedValidator.into(), + } + } + } +} + +frame_support::construct_runtime!( + pub struct Runtime + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event}, + Custom: custom::{Pallet, Call, ValidateUnsigned, Inherent}, + Custom2: custom2::{Pallet, Call, ValidateUnsigned, Inherent}, + } +); + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::builder() + .base_block(Weight::from_parts(10, 0)) + .for_class(DispatchClass::all(), |weights| weights.base_extrinsic = Weight::from_parts(5, 0)) + .for_class(DispatchClass::non_mandatory(), |weights| weights.max_total = Weight::from_parts(1024, u64::MAX).into()) + .build_or_panic(); + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 10, + write: 100, + }; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type BlockWeights = BlockWeights; + type RuntimeOrigin = RuntimeOrigin; + type Nonce = u64; + type RuntimeCall = RuntimeCall; + type Block = TestBlock; + type RuntimeEvent = RuntimeEvent; + type Version = RuntimeVersion; + type AccountData = pallet_balances::AccountData; + type PreInherents = MockedSystemCallbacks; + type PostInherents = MockedSystemCallbacks; + type PostTransactions = MockedSystemCallbacks; + type MultiBlockMigrator = MockedModeGetter; +} + +type Balance = u64; + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type AccountStore = System; +} + +parameter_types! { + pub const TransactionByteFee: Balance = 0; +} +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = CurrencyAdapter; + type OperationalFeeMultiplier = ConstU8<5>; + type WeightToFee = IdentityFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = (); +} + +impl custom::Config for Runtime {} +impl custom2::Config for Runtime {} + +pub struct RuntimeVersion; +impl frame_support::traits::Get for RuntimeVersion { + fn get() -> sp_version::RuntimeVersion { + RuntimeVersionTestValues::get().clone() + } +} + +parameter_types! { + pub static RuntimeVersionTestValues: sp_version::RuntimeVersion = + Default::default(); +} + +type SignedExtra = ( + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); +type TestXt = sp_runtime::testing::TestXt; +type TestBlock = Block; + +// Will contain `true` when the custom runtime logic was called. +const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime"; + +struct CustomOnRuntimeUpgrade; +impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { + fn on_runtime_upgrade() -> Weight { + sp_io::storage::set(TEST_KEY, "custom_upgrade".as_bytes()); + sp_io::storage::set(CUSTOM_ON_RUNTIME_KEY, &true.encode()); + System::deposit_event(frame_system::Event::CodeUpdated); + + assert_eq!(0, System::last_runtime_upgrade_spec_version()); + + Weight::from_parts(100, 0) + } +} + +type Executive = super::Executive< + Runtime, + Block, + ChainContext, + Runtime, + AllPalletsWithSystem, + CustomOnRuntimeUpgrade, +>; + +parameter_types! { + pub static SystemCallbacksCalled: u32 = 0; +} + +pub struct MockedSystemCallbacks; +impl PreInherents for MockedSystemCallbacks { + fn pre_inherents() { + assert_eq!(SystemCallbacksCalled::get(), 0); + SystemCallbacksCalled::set(1); + // Change the storage to modify the root hash: + frame_support::storage::unhashed::put(b":pre_inherent", b"0"); + } +} + +impl PostInherents for MockedSystemCallbacks { + fn post_inherents() { + assert_eq!(SystemCallbacksCalled::get(), 1); + SystemCallbacksCalled::set(2); + // Change the storage to modify the root hash: + frame_support::storage::unhashed::put(b":post_inherent", b"0"); + } +} + +impl PostTransactions for MockedSystemCallbacks { + fn post_transactions() { + assert_eq!(SystemCallbacksCalled::get(), 2); + SystemCallbacksCalled::set(3); + // Change the storage to modify the root hash: + frame_support::storage::unhashed::put(b":post_transaction", b"0"); + } +} + +impl MockedSystemCallbacks { + fn pre_inherent_called() -> bool { + SystemCallbacksCalled::get() >= 1 + } + + fn post_inherent_called() -> bool { + SystemCallbacksCalled::get() >= 2 + } + + fn post_transactions_called() -> bool { + SystemCallbacksCalled::get() >= 3 + } + + fn reset() { + SystemCallbacksCalled::set(0); + frame_support::storage::unhashed::kill(b":pre_inherent"); + frame_support::storage::unhashed::kill(b":post_inherent"); + frame_support::storage::unhashed::kill(b":post_transaction"); + } +} + +parameter_types! { + pub static MbmActive: bool = false; +} + +pub struct MockedModeGetter; +impl MultiStepMigrator for MockedModeGetter { + fn ongoing() -> bool { + MbmActive::get() + } + + fn step() -> Weight { + Weight::zero() + } +} + +fn extra(nonce: u64, fee: Balance) -> SignedExtra { + ( + frame_system::CheckEra::from(Era::Immortal), + frame_system::CheckNonce::from(nonce), + frame_system::CheckWeight::new(), + pallet_transaction_payment::ChargeTransactionPayment::from(fee), + ) +} + +fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { + Some((who, extra(nonce, fee))) +} + +fn call_transfer(dest: u64, value: u64) -> RuntimeCall { + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }) +} + +#[test] +fn balance_transfer_dispatch_works() { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 211)] } + .assimilate_storage(&mut t) + .unwrap(); + let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0)); + let weight = xt.get_dispatch_info().weight + + ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + let fee: Balance = + ::WeightToFee::weight_to_fee(&weight); + let mut t = sp_io::TestExternalities::new(t); + t.execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + let r = Executive::apply_extrinsic(xt); + assert!(r.is_ok()); + assert_eq!(>::total_balance(&1), 142 - fee); + assert_eq!(>::total_balance(&2), 69); + }); +} + +fn new_test_ext(balance_factor: Balance) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext: sp_io::TestExternalities = t.into(); + ext.execute_with(|| { + SystemCallbacksCalled::set(0); + }); + ext +} + +fn new_test_ext_v0(balance_factor: Balance) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(1, 111 * balance_factor)] } + .assimilate_storage(&mut t) + .unwrap(); + (t, sp_runtime::StateVersion::V0).into() +} + +#[test] +fn block_import_works() { + block_import_works_inner( + new_test_ext_v0(1), + array_bytes::hex_n_into_unchecked( + "4826d3bdf87dbbc883d2ab274cbe272f58ed94a904619b59953e48294d1142d2", + ), + ); + block_import_works_inner( + new_test_ext(1), + array_bytes::hex_n_into_unchecked( + "d6b465f5a50c9f8d5a6edc0f01d285a6b19030f097d3aaf1649b7be81649f118", + ), + ); +} +fn block_import_works_inner(mut ext: sp_io::TestExternalities, state_root: H256) { + ext.execute_with(|| { + Executive::execute_block(Block { + header: Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root, + extrinsics_root: array_bytes::hex_n_into_unchecked( + "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", + ), + digest: Digest { logs: vec![] }, + }, + extrinsics: vec![], + }); + }); +} + +#[test] +#[should_panic] +fn block_import_of_bad_state_root_fails() { + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block { + header: Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root: [0u8; 32].into(), + extrinsics_root: array_bytes::hex_n_into_unchecked( + "03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", + ), + digest: Digest { logs: vec![] }, + }, + extrinsics: vec![], + }); + }); +} + +#[test] +#[should_panic] +fn block_import_of_bad_extrinsic_root_fails() { + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block { + header: Header { + parent_hash: [69u8; 32].into(), + number: 1, + state_root: array_bytes::hex_n_into_unchecked( + "75e7d8f360d375bbe91bcf8019c01ab6362448b4a89e3b329717eb9d910340e5", + ), + extrinsics_root: [0u8; 32].into(), + digest: Digest { logs: vec![] }, + }, + extrinsics: vec![], + }); + }); +} + +#[test] +fn bad_extrinsic_not_inserted() { + let mut t = new_test_ext(1); + // bad nonce check! + let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0)); + t.execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + assert_err!( + Executive::apply_extrinsic(xt), + TransactionValidityError::Invalid(InvalidTransaction::Future) + ); + assert_eq!(>::extrinsic_index(), Some(0)); + }); +} + +#[test] +fn block_weight_limit_enforced() { + let mut t = new_test_ext(10000); + // given: TestXt uses the encoded len as fixed Len: + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let encoded = xt.encode(); + let encoded_len = encoded.len() as u64; + // on_initialize weight + base block execution weight + let block_weights = ::BlockWeights::get(); + let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block; + let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight; + let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5); + t.execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + // Base block execution weight + `on_initialize` weight from the custom module. + assert_eq!(>::block_weight().total(), base_block_weight); + + for nonce in 0..=num_to_exhaust_block { + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, nonce.into(), 0), + ); + let res = Executive::apply_extrinsic(xt); + if nonce != num_to_exhaust_block { + assert!(res.is_ok()); + assert_eq!( + >::block_weight().total(), + //--------------------- on_initialize + block_execution + extrinsic_base weight + Weight::from_parts((encoded_len + 5) * (nonce + 1), 0) + base_block_weight, + ); + assert_eq!( + >::extrinsic_index(), + Some(nonce as u32 + 1) + ); + } else { + assert_eq!(res, Err(InvalidTransaction::ExhaustsResources.into())); + } + } + }); +} + +#[test] +fn block_weight_and_size_is_stored_per_tx() { + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let x1 = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 1, 0), + ); + let x2 = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 2, 0), + ); + let len = xt.clone().encode().len() as u32; + let mut t = new_test_ext(1); + t.execute_with(|| { + // Block execution weight + on_initialize weight from custom module + let base_block_weight = Weight::from_parts(175, 0) + + ::BlockWeights::get().base_block; + + Executive::initialize_block(&Header::new_from_number(1)); + + assert_eq!(>::block_weight().total(), base_block_weight); + assert_eq!(>::all_extrinsics_len(), 0); + + assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok()); + assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); + + // default weight for `TestXt` == encoded length. + let extrinsic_weight = Weight::from_parts(len as u64, 0) + + ::BlockWeights::get() + .get(DispatchClass::Normal) + .base_extrinsic; + assert_eq!( + >::block_weight().total(), + base_block_weight + 3u64 * extrinsic_weight, + ); + assert_eq!(>::all_extrinsics_len(), 3 * len); + + let _ = >::finalize(); + // All extrinsics length cleaned on `System::finalize` + assert_eq!(>::all_extrinsics_len(), 0); + + // Reset to a new block. + SystemCallbacksCalled::take(); + Executive::initialize_block(&Header::new_from_number(2)); + + // Block weight cleaned up on `System::initialize` + assert_eq!(>::block_weight().total(), base_block_weight); + }); +} + +#[test] +fn validate_unsigned() { + let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None); + let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None); + let mut t = new_test_ext(1); + + t.execute_with(|| { + assert_eq!( + Executive::validate_transaction( + TransactionSource::InBlock, + valid.clone(), + Default::default(), + ), + Ok(ValidTransaction::default()), + ); + assert_eq!( + Executive::validate_transaction( + TransactionSource::InBlock, + invalid.clone(), + Default::default(), + ), + Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)), + ); + // Need to initialize the block before applying extrinsics for the `MockedSystemCallbacks` + // check. + Executive::initialize_block(&Header::new_from_number(1)); + assert_eq!(Executive::apply_extrinsic(valid), Ok(Err(DispatchError::BadOrigin))); + assert_eq!( + Executive::apply_extrinsic(invalid), + Err(TransactionValidityError::Unknown(UnknownTransaction::NoUnsignedValidator)) + ); + }); +} + +#[test] +fn can_not_pay_for_tx_fee_on_full_lock() { + let mut t = new_test_ext(1); + t.execute_with(|| { + as fungible::MutateFreeze>::set_freeze(&(), &1, 110) + .unwrap(); + let xt = TestXt::new( + RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }), + sign_extra(1, 0, 0), + ); + Executive::initialize_block(&Header::new_from_number(1)); + + assert_eq!(Executive::apply_extrinsic(xt), Err(InvalidTransaction::Payment.into()),); + assert_eq!(>::total_balance(&1), 111); + }); +} + +#[test] +fn block_hooks_weight_is_stored() { + new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + Executive::finalize_block(); + // NOTE: might need updates over time if new weights are introduced. + // For now it only accounts for the base block execution weight and + // the `on_initialize` weight defined in the custom test module. + assert_eq!( + >::block_weight().total(), + Weight::from_parts(175 + 175 + 10, 0) + ); + }) +} + +#[test] +fn runtime_upgraded_should_work() { + new_test_ext(1).execute_with(|| { + RuntimeVersionTestValues::mutate(|v| *v = Default::default()); + // It should be added at genesis + assert!(LastRuntimeUpgrade::::exists()); + assert!(!Executive::runtime_upgraded()); + + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + assert!(Executive::runtime_upgraded()); + + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { + spec_version: 1, + spec_name: "test".into(), + ..Default::default() + } + }); + assert!(Executive::runtime_upgraded()); + + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { + spec_version: 0, + impl_version: 2, + ..Default::default() + } + }); + assert!(!Executive::runtime_upgraded()); + + LastRuntimeUpgrade::::take(); + assert!(Executive::runtime_upgraded()); + }) +} + +#[test] +fn last_runtime_upgrade_was_upgraded_works() { + let test_data = vec![ + (0, "", 1, "", true), + (1, "", 1, "", false), + (1, "", 1, "test", true), + (1, "", 0, "", false), + (1, "", 0, "test", true), + ]; + + for (spec_version, spec_name, c_spec_version, c_spec_name, result) in test_data { + let current = sp_version::RuntimeVersion { + spec_version: c_spec_version, + spec_name: c_spec_name.into(), + ..Default::default() + }; + + let last = LastRuntimeUpgradeInfo { + spec_version: spec_version.into(), + spec_name: spec_name.into(), + }; + + assert_eq!(result, last.was_upgraded(¤t)); + } +} + +#[test] +fn custom_runtime_upgrade_is_called_before_modules() { + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + Executive::initialize_block(&Header::new_from_number(1)); + + assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); + assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); + assert_eq!( + Some(RuntimeVersionTestValues::get().into()), + LastRuntimeUpgrade::::get(), + ) + }); +} + +#[test] +fn event_from_runtime_upgrade_is_included() { + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + // set block number to non zero so events are not excluded + System::set_block_number(1); + + Executive::initialize_block(&Header::new_from_number(2)); + System::assert_last_event(frame_system::Event::::CodeUpdated.into()); + }); +} + +/// Regression test that ensures that the custom on runtime upgrade is called when executive is +/// used through the `ExecuteBlock` trait. +#[test] +fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() { + let xt = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + + let header = new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + // Reset to get the correct new genesis below. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 0, ..Default::default() } + }); + + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called. + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + >>::execute_block(Block::new(header, vec![xt])); + + assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module"); + assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode()); + }); +} + +#[test] +fn all_weights_are_recorded_correctly() { + // Reset to get the correct new genesis below. + RuntimeVersionTestValues::take(); + + new_test_ext(1).execute_with(|| { + // Make sure `on_runtime_upgrade` is called for maximum complexity + RuntimeVersionTestValues::mutate(|v| { + *v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() } + }); + + let block_number = 1; + + Executive::initialize_block(&Header::new_from_number(block_number)); + + // Reset the last runtime upgrade info, to make the second call to `on_runtime_upgrade` + // succeed. + LastRuntimeUpgrade::::take(); + MockedSystemCallbacks::reset(); + + // All weights that show up in the `initialize_block_impl` + let custom_runtime_upgrade_weight = CustomOnRuntimeUpgrade::on_runtime_upgrade(); + let runtime_upgrade_weight = + ::on_runtime_upgrade(); + let on_initialize_weight = + >::on_initialize(block_number); + let base_block_weight = ::BlockWeights::get().base_block; + + // Weights are recorded correctly + assert_eq!( + frame_system::Pallet::::block_weight().total(), + custom_runtime_upgrade_weight + + runtime_upgrade_weight + + on_initialize_weight + + base_block_weight, + ); + }); +} + +#[test] +fn offchain_worker_works_as_expected() { + new_test_ext(1).execute_with(|| { + let parent_hash = sp_core::H256::from([69u8; 32]); + let mut digest = Digest::default(); + digest.push(DigestItem::Seal([1, 2, 3, 4], vec![5, 6, 7, 8])); + + let header = Header::new(1, H256::default(), H256::default(), parent_hash, digest.clone()); + + Executive::offchain_worker(&header); + + assert_eq!(digest, System::digest()); + assert_eq!(parent_hash, System::block_hash(0)); + assert_eq!(header.hash(), System::block_hash(1)); + }); +} + +#[test] +fn calculating_storage_root_twice_works() { + let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {}); + let xt = TestXt::new(call, sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt])); + }); +} + +#[test] +#[should_panic(expected = "Invalid inherent position for extrinsic at index 1")] +fn invalid_inherent_position_fail() { + let xt1 = TestXt::new( + RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }), + sign_extra(1, 0, 0), + ); + let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +#[test] +fn valid_inherents_position_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +#[test] +#[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")] +fn invalid_inherents_fail_block_execution() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), sign_extra(1, 0, 0)); + + new_test_ext(1).execute_with(|| { + Executive::execute_block(Block::new( + Header::new(1, H256::default(), H256::default(), [69u8; 32].into(), Digest::default()), + vec![xt1], + )); + }); +} + +// Inherents are created by the runtime and don't need to be validated. +#[test] +fn inherents_fail_validate_block() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + + new_test_ext(1).execute_with(|| { + assert_eq!( + Executive::validate_transaction(TransactionSource::External, xt1, H256::random()) + .unwrap_err(), + InvalidTransaction::MandatoryValidation.into() + ); + }) +} + +/// Inherents still work while `initialize_block` forbids transactions. +#[test] +fn inherents_ok_while_exts_forbidden_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + // This is not applied: + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + // Tell `initialize_block` to forbid extrinsics: + Executive::execute_block(Block::new(header, vec![xt1])); + }); +} + +/// Refuses to import blocks with transactions during `OnlyInherents` mode. +#[test] +#[should_panic = "Only inherents are allowed in this block"] +fn transactions_in_only_inherents_block_errors() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + MbmActive::set(true); + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +/// Same as above but no error. +#[test] +fn transactions_in_normal_block_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + // Tell `initialize_block` to forbid extrinsics: + Executive::execute_block(Block::new(header, vec![xt1, xt2])); + }); +} + +#[test] +#[cfg(feature = "try-runtime")] +fn try_execute_block_works() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + Executive::try_execute_block( + Block::new(header, vec![xt1, xt2]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + }); +} + +/// Same as `extrinsic_while_exts_forbidden_errors` but using the try-runtime function. +#[test] +#[cfg(feature = "try-runtime")] +#[should_panic = "Only inherents allowed"] +fn try_execute_tx_forbidden_errors() { + let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt2.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + MbmActive::set(true); + Executive::try_execute_block( + Block::new(header, vec![xt1, xt2]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + }); +} + +/// Check that `ensure_inherents_are_first` reports the correct indices. +#[test] +fn ensure_inherents_are_first_works() { + let in1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None); + let in2 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + + // Mocked empty header: + let header = new_test_ext(1).execute_with(|| { + Executive::initialize_block(&Header::new_from_number(1)); + Executive::finalize_block() + }); + + new_test_ext(1).execute_with(|| { + assert_ok!(Runtime::ensure_inherents_are_first(&Block::new(header.clone(), vec![]),), 0); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new(header.clone(), vec![xt2.clone()]),), + 0 + ); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new(header.clone(), vec![in1.clone()])), + 1 + ); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![in1.clone(), xt2.clone()] + ),), + 1 + ); + assert_ok!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![in2.clone(), in1.clone(), xt2.clone()] + ),), + 2 + ); + + assert_eq!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![xt2.clone(), in1.clone()] + ),), + Err(1) + ); + assert_eq!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![xt2.clone(), xt2.clone(), in1.clone()] + ),), + Err(2) + ); + assert_eq!( + Runtime::ensure_inherents_are_first(&Block::new( + header.clone(), + vec![xt2.clone(), xt2.clone(), xt2.clone(), in2.clone()] + ),), + Err(3) + ); + }); +} + +/// Check that block execution rejects blocks with transactions in them while MBMs are active and +/// also that all the system callbacks are called correctly. +#[test] +fn callbacks_in_block_execution_works() { + callbacks_in_block_execution_works_inner(false); + callbacks_in_block_execution_works_inner(true); +} + +fn callbacks_in_block_execution_works_inner(mbms_active: bool) { + MbmActive::set(mbms_active); + + for (n_in, n_tx) in (0..10usize).zip(0..10usize) { + let mut extrinsics = Vec::new(); + + let header = new_test_ext(10).execute_with(|| { + MockedSystemCallbacks::reset(); + Executive::initialize_block(&Header::new_from_number(1)); + assert_eq!(SystemCallbacksCalled::get(), 1); + + for i in 0..n_in { + let xt = if i % 2 == 0 { + TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None) + } else { + TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None) + }; + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + extrinsics.push(xt); + } + + for t in 0..n_tx { + let xt = TestXt::new( + RuntimeCall::Custom2(custom2::Call::some_call {}), + sign_extra(1, t as u64, 0), + ); + // Extrinsics can be applied even when MBMs are active. Only the `execute_block` + // will reject it. + Executive::apply_extrinsic(xt.clone()).unwrap().unwrap(); + extrinsics.push(xt); + } + + Executive::finalize_block() + }); + assert_eq!(SystemCallbacksCalled::get(), 3); + + new_test_ext(10).execute_with(|| { + let header = std::panic::catch_unwind(|| { + Executive::execute_block(Block::new(header, extrinsics)); + }); + + match header { + Err(e) => { + let err = e.downcast::<&str>().unwrap(); + assert_eq!(*err, "Only inherents are allowed in this block"); + assert!( + MbmActive::get() && n_tx > 0, + "Transactions should be rejected when MBMs are active" + ); + }, + Ok(_) => { + assert_eq!(SystemCallbacksCalled::get(), 3); + assert!( + !MbmActive::get() || n_tx == 0, + "MBMs should be deactivated after finalization" + ); + }, + } + }); + } +} + +#[test] +fn post_inherent_called_after_all_inherents() { + let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(in1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + #[cfg(feature = "try-runtime")] + new_test_ext(1).execute_with(|| { + Executive::try_execute_block( + Block::new(header.clone(), vec![in1.clone(), xt1.clone()]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); + + new_test_ext(1).execute_with(|| { + MockedSystemCallbacks::reset(); + Executive::execute_block(Block::new(header, vec![in1, xt1])); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); +} + +/// Regression test for AppSec finding #40. +#[test] +fn post_inherent_called_after_all_optional_inherents() { + let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); + let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0)); + + let header = new_test_ext(1).execute_with(|| { + // Let's build some fake block. + Executive::initialize_block(&Header::new_from_number(1)); + + Executive::apply_extrinsic(in1.clone()).unwrap().unwrap(); + Executive::apply_extrinsic(xt1.clone()).unwrap().unwrap(); + + Executive::finalize_block() + }); + + #[cfg(feature = "try-runtime")] + new_test_ext(1).execute_with(|| { + Executive::try_execute_block( + Block::new(header.clone(), vec![in1.clone(), xt1.clone()]), + true, + true, + frame_try_runtime::TryStateSelect::All, + ) + .unwrap(); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); + + new_test_ext(1).execute_with(|| { + MockedSystemCallbacks::reset(); + Executive::execute_block(Block::new(header, vec![in1, xt1])); + assert!(MockedSystemCallbacks::post_transactions_called()); + }); +} + +#[test] +fn is_inherent_works() { + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None); + assert!(Runtime::is_inherent(&ext)); + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None); + assert!(Runtime::is_inherent(&ext)); + + let ext = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0)); + assert!(!Runtime::is_inherent(&ext)); + + let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {}), None); + assert!(!Runtime::is_inherent(&ext), "Unsigned ext are not automatically inherents"); +} diff --git a/substrate/frame/migrations/Cargo.toml b/substrate/frame/migrations/Cargo.toml new file mode 100644 index 00000000000..2914aa9ea97 --- /dev/null +++ b/substrate/frame/migrations/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "pallet-migrations" +version = "1.0.0" +description = "FRAME pallet to execute multi-block migrations." +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +docify = "0.1.14" +impl-trait-for-tuples = "0.2.2" +log = "0.4.18" +scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } + +frame-benchmarking = { default-features = false, optional = true, path = "../benchmarking" } +frame-support = { default-features = false, path = "../support" } +frame-system = { default-features = false, path = "../system" } +sp-core = { path = "../../primitives/core", default-features = false } +sp-std = { path = "../../primitives/std", default-features = false } +sp-runtime = { path = "../../primitives/runtime", default-features = false } + +[dev-dependencies] +frame-executive = { path = "../executive" } +sp-api = { path = "../../primitives/api", features = ["std"] } +sp-block-builder = { path = "../../primitives/block-builder", features = ["std"] } +sp-io = { path = "../../primitives/io", features = ["std"] } +sp-tracing = { path = "../../primitives/tracing", features = ["std"] } +sp-version = { path = "../../primitives/version", features = ["std"] } + +pretty_assertions = "1.3.0" + +[features] +default = ["std"] + +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "log/std", + "scale-info/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] + +try-runtime = [ + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/substrate/frame/migrations/src/benchmarking.rs b/substrate/frame/migrations/src/benchmarking.rs new file mode 100644 index 00000000000..8ad1fa50d14 --- /dev/null +++ b/substrate/frame/migrations/src/benchmarking.rs @@ -0,0 +1,222 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_benchmarking::{v2::*, BenchmarkError}; +use frame_system::{Pallet as System, RawOrigin}; +use sp_runtime::traits::One; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} + +#[benchmarks] +mod benches { + use super::*; + use frame_support::traits::Hooks; + + #[benchmark] + fn onboard_new_mbms() { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert!(!Cursor::::exists()); + + #[block] + { + Pallet::::onboard_new_mbms(); + } + + assert_last_event::(Event::UpgradeStarted { migrations: 1 }.into()); + } + + #[benchmark] + fn progress_mbms_none() { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert!(!Cursor::::exists()); + + #[block] + { + Pallet::::progress_mbms(One::one()); + } + } + + /// All migrations completed. + #[benchmark] + fn exec_migration_completed() -> Result<(), BenchmarkError> { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 1, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::UpgradeCompleted {}.into()); + + Ok(()) + } + + /// No migration runs since it is skipped as historic. + #[benchmark] + fn exec_migration_skipped_historic() -> Result<(), BenchmarkError> { + T::Migrations::set_fail_after(0); // Should not be called anyway. + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + + let id: IdentifierOf = T::Migrations::nth_id(0).unwrap().try_into().unwrap(); + Historic::::insert(id, ()); + + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::MigrationSkipped { index: 0 }.into()); + + Ok(()) + } + + /// Advance a migration by one step. + #[benchmark] + fn exec_migration_advance() -> Result<(), BenchmarkError> { + T::Migrations::set_success_after(1); + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::MigrationAdvanced { index: 0, took: One::one() }.into()); + + Ok(()) + } + + /// Successfully complete a migration. + #[benchmark] + fn exec_migration_complete() -> Result<(), BenchmarkError> { + T::Migrations::set_success_after(0); + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::MigrationCompleted { index: 0, took: One::one() }.into()); + + Ok(()) + } + + #[benchmark] + fn exec_migration_fail() -> Result<(), BenchmarkError> { + T::Migrations::set_fail_after(0); + assert_eq!(T::Migrations::len(), 1, "Setup failed"); + let c = ActiveCursor { index: 0, inner_cursor: None, started_at: 0u32.into() }; + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + System::::set_block_number(1u32.into()); + + #[block] + { + Pallet::::exec_migration(c, false, &mut meter); + } + + assert_last_event::(Event::UpgradeFailed {}.into()); + + Ok(()) + } + + #[benchmark] + fn on_init_loop() { + T::Migrations::set_fail_after(0); // Should not be called anyway. + System::::set_block_number(1u32.into()); + Pallet::::on_runtime_upgrade(); + + #[block] + { + Pallet::::on_initialize(1u32.into()); + } + } + + #[benchmark] + fn force_set_cursor() { + #[extrinsic_call] + _(RawOrigin::Root, Some(cursor::())); + } + + #[benchmark] + fn force_set_active_cursor() { + #[extrinsic_call] + _(RawOrigin::Root, 0, None, None); + } + + #[benchmark] + fn force_onboard_mbms() { + #[extrinsic_call] + _(RawOrigin::Root); + } + + #[benchmark] + fn clear_historic(n: Linear<0, { DEFAULT_HISTORIC_BATCH_CLEAR_SIZE * 2 }>) { + let id_max_len = ::IdentifierMaxLen::get(); + assert!(id_max_len >= 4, "Precondition violated"); + + for i in 0..DEFAULT_HISTORIC_BATCH_CLEAR_SIZE * 2 { + let id = IdentifierOf::::truncate_from( + i.encode().into_iter().cycle().take(id_max_len as usize).collect::>(), + ); + + Historic::::insert(&id, ()); + } + + #[extrinsic_call] + _( + RawOrigin::Root, + HistoricCleanupSelector::Wildcard { limit: n.into(), previous_cursor: None }, + ); + } + + fn cursor() -> CursorOf { + // Note: The weight of a function can depend on the weight of reading the `inner_cursor`. + // `Cursor` is a user provided type. Now instead of requiring something like `Cursor: + // From`, we instead rely on the fact that it is MEL and the PoV benchmarking will + // therefore already take the MEL bound, even when the cursor in storage is `None`. + MigrationCursor::Active(ActiveCursor { + index: u32::MAX, + inner_cursor: None, + started_at: 0u32.into(), + }) + } + + // Implements a test for each benchmark. Execute with: + // `cargo test -p pallet-migrations --features runtime-benchmarks`. + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/substrate/frame/migrations/src/lib.rs b/substrate/frame/migrations/src/lib.rs new file mode 100644 index 00000000000..cd57d89f440 --- /dev/null +++ b/substrate/frame/migrations/src/lib.rs @@ -0,0 +1,746 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![deny(missing_docs)] +#![deny(rustdoc::broken_intra_doc_links)] + +//! # `pallet-migrations` +//! +//! Provides multi block migrations for FRAME runtimes. +//! +//! ## Overview +//! +//! The pallet takes care of executing a batch of multi-step migrations over multiple blocks. The +//! process starts on each runtime upgrade. Normal and operational transactions are paused while +//! migrations are on-going. +//! +//! ### Example +//! +//! This example demonstrates a simple mocked walk through of a basic success scenario. The pallet +//! is configured with two migrations: one succeeding after just one step, and the second one +//! succeeding after two steps. A runtime upgrade is then enacted and the block number is advanced +//! until all migrations finish executing. Afterwards, the recorded historic migrations are +//! checked and events are asserted. +#![doc = docify::embed!("substrate/frame/migrations/src/tests.rs", simple_works)] +//! +//! ## Pallet API +//! +//! See the [`pallet`] module for more information about the interfaces this pallet exposes, +//! including its configuration trait, dispatchables, storage items, events and errors. +//! +//! Otherwise noteworthy API of this pallet include its implementation of the +//! [`MultiStepMigrator`] trait. This must be plugged into +//! [`frame_system::Config::MultiBlockMigrator`] for proper function. +//! +//! The API contains some calls for emergency management. They are all prefixed with `force_` and +//! should normally not be needed. Pay special attention prior to using them. +//! +//! ### Design Goals +//! +//! 1. Must automatically execute migrations over multiple blocks. +//! 2. Must expose information about whether migrations are ongoing. +//! 3. Must respect pessimistic weight bounds of migrations. +//! 4. Must execute migrations in order. Skipping is not allowed; migrations are run on a +//! all-or-nothing basis. +//! 5. Must prevent re-execution of past migrations. +//! 6. Must provide transactional storage semantics for migrations. +//! 7. Must guarantee progress. +//! +//! ### Design +//! +//! Migrations are provided to the pallet through the associated type [`Config::Migrations`] of type +//! [`SteppedMigrations`]. This allows multiple migrations to be aggregated through a tuple. It +//! simplifies the trait bounds since all associated types of the trait must be provided by the +//! pallet. The actual progress of the pallet is stored in the [`Cursor`] storage item. This can +//! either be [`MigrationCursor::Active`] or [`MigrationCursor::Stuck`]. In the active case it +//! points to the currently active migration and stores its inner cursor. The inner cursor can then +//! be used by the migration to store its inner state and advance. Each time when the migration +//! returns `Some(cursor)`, it signals the pallet that it is not done yet. +//! The cursor is reset on each runtime upgrade. This ensures that it starts to execute at the +//! first migration in the vector. The pallets cursor is only ever incremented or set to `Stuck` +//! once it encounters an error (Goal 4). Once in the stuck state, the pallet will stay stuck until +//! it is fixed through manual governance intervention. +//! As soon as the cursor of the pallet becomes `Some(_)`; [`MultiStepMigrator::ongoing`] returns +//! `true` (Goal 2). This can be used by upstream code to possibly pause transactions. +//! In `on_initialize` the pallet will load the current migration and check whether it was already +//! executed in the past by checking for membership of its ID in the [`Historic`] set. Historic +//! migrations are skipped without causing an error. Each successfully executed migration is added +//! to this set (Goal 5). +//! This proceeds until no more migrations remain. At that point, the event `UpgradeCompleted` is +//! emitted (Goal 1). +//! The execution of each migration happens by calling [`SteppedMigration::transactional_step`]. +//! This function wraps the inner `step` function into a transactional layer to allow rollback in +//! the error case (Goal 6). +//! Weight limits must be checked by the migration itself. The pallet provides a [`WeightMeter`] for +//! that purpose. The pallet may return [`SteppedMigrationError::InsufficientWeight`] at any point. +//! In that scenario, one of two things will happen: if that migration was exclusively executed +//! in this block, and therefore required more than the maximum amount of weight possible, the +//! process becomes `Stuck`. Otherwise, one re-attempt is executed with the same logic in the next +//! block (Goal 3). Progress through the migrations is guaranteed by providing a timeout for each +//! migration via [`SteppedMigration::max_steps`]. The pallet **ONLY** guarantees progress if this +//! is set to sensible limits (Goal 7). +//! +//! ### Scenario: Governance cleanup +//! +//! Every now and then, governance can make use of the [`clear_historic`][Pallet::clear_historic] +//! call. This ensures that no old migrations pile up in the [`Historic`] set. This can be done very +//! rarely, since the storage should not grow quickly and the lookup weight does not suffer much. +//! Another possibility would be to have a synchronous single-block migration perpetually deployed +//! that cleans them up before the MBMs start. +//! +//! ### Scenario: Successful upgrade +//! +//! The standard procedure for a successful runtime upgrade can look like this: +//! 1. Migrations are configured in the `Migrations` config item. All migrations expose +//! [`max_steps`][SteppedMigration::max_steps], are error tolerant, check their weight bounds and +//! have a unique identifier. +//! 2. The runtime upgrade is enacted. An `UpgradeStarted` event is +//! followed by lots of `MigrationAdvanced` and `MigrationCompleted` events. Finally +//! `UpgradeCompleted` is emitted. +//! 3. Cleanup as described in the governance scenario be executed at any time after the migrations +//! completed. +//! +//! ### Advice: Failed upgrades +//! +//! Failed upgrades cannot be recovered from automatically and require governance intervention. Set +//! up monitoring for `UpgradeFailed` events to be made aware of any failures. The hook +//! [`FailedMigrationHandler::failed`] should be setup in a way that it allows governance to act, +//! but still prevent other transactions from interacting with the inconsistent storage state. Note +//! that this is paramount, since the inconsistent state might contain a faulty balance amount or +//! similar that could cause great harm if user transactions don't remain suspended. One way to +//! implement this would be to use the `SafeMode` or `TxPause` pallets that can prevent most user +//! interactions but still allow a whitelisted set of governance calls. +//! +//! ### Remark: Failed migrations +//! +//! Failed migrations are not added to the `Historic` set. This means that an erroneous +//! migration must be removed and fixed manually. This already applies, even before considering the +//! historic set. +//! +//! ### Remark: Transactional processing +//! +//! You can see the transactional semantics for migration steps as mostly useless, since in the +//! stuck case the state is already messed up. This just prevents it from becoming even more messed +//! up, but doesn't prevent it in the first place. + +#![cfg_attr(not(feature = "std"), no_std)] + +mod benchmarking; +mod mock; +pub mod mock_helpers; +mod tests; +pub mod weights; + +pub use pallet::*; +pub use weights::WeightInfo; + +use codec::{Decode, Encode, MaxEncodedLen}; +use core::ops::ControlFlow; +use frame_support::{ + defensive, defensive_assert, + migrations::*, + traits::Get, + weights::{Weight, WeightMeter}, + BoundedVec, +}; +use frame_system::{pallet_prelude::BlockNumberFor, Pallet as System}; +use sp_runtime::Saturating; +use sp_std::vec::Vec; + +/// Points to the next migration to execute. +#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] +pub enum MigrationCursor { + /// Points to the currently active migration and its inner cursor. + Active(ActiveCursor), + + /// Migration got stuck and cannot proceed. This is bad. + Stuck, +} + +impl MigrationCursor { + /// Try to return self as an [`ActiveCursor`]. + pub fn as_active(&self) -> Option<&ActiveCursor> { + match self { + MigrationCursor::Active(active) => Some(active), + MigrationCursor::Stuck => None, + } + } +} + +impl From> + for MigrationCursor +{ + fn from(active: ActiveCursor) -> Self { + MigrationCursor::Active(active) + } +} + +/// Points to the currently active migration and its inner cursor. +#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)] +pub struct ActiveCursor { + /// The index of the migration in the MBM tuple. + pub index: u32, + /// The cursor of the migration that is referenced by `index`. + pub inner_cursor: Option, + /// The block number that the migration started at. + /// + /// This is used to calculate how many blocks it took. + pub started_at: BlockNumber, +} + +impl ActiveCursor { + /// Advance the overarching cursor to the next migration. + pub(crate) fn goto_next_migration(&mut self, current_block: BlockNumber) { + self.index.saturating_inc(); + self.inner_cursor = None; + self.started_at = current_block; + } +} + +/// How to clear the records of historic migrations. +#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode, scale_info::TypeInfo)] +pub enum HistoricCleanupSelector { + /// Clear exactly these entries. + /// + /// This is the advised way of doing it. + Specific(Vec), + + /// Clear up to this many entries + Wildcard { + /// How many should be cleared in this call at most. + limit: Option, + /// The cursor that was emitted from any previous `HistoricCleared`. + /// + /// Does not need to be passed when clearing the first batch. + previous_cursor: Option>, + }, +} + +/// The default number of entries that should be cleared by a `HistoricCleanupSelector::Wildcard`. +/// +/// The caller can explicitly specify a higher amount. Benchmarks are run with twice this value. +const DEFAULT_HISTORIC_BATCH_CLEAR_SIZE: u32 = 128; + +impl HistoricCleanupSelector { + /// The maximal number of entries that this will remove. + /// + /// Needed for weight calculation. + pub fn limit(&self) -> u32 { + match self { + Self::Specific(ids) => ids.len() as u32, + Self::Wildcard { limit, .. } => limit.unwrap_or(DEFAULT_HISTORIC_BATCH_CLEAR_SIZE), + } + } +} + +/// Convenience alias for [`MigrationCursor`]. +pub type CursorOf = MigrationCursor, BlockNumberFor>; + +/// Convenience alias for the raw inner cursor of a migration. +pub type RawCursorOf = BoundedVec::CursorMaxLen>; + +/// Convenience alias for the identifier of a migration. +pub type IdentifierOf = BoundedVec::IdentifierMaxLen>; + +/// Convenience alias for [`ActiveCursor`]. +pub type ActiveCursorOf = ActiveCursor, BlockNumberFor>; + +/// Trait for a tuple of No-OP migrations with one element. +pub trait MockedMigrations: SteppedMigrations { + /// The migration should fail after `n` steps. + fn set_fail_after(n: u32); + /// The migration should succeed after `n` steps. + fn set_success_after(n: u32); +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type of the runtime. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// All the multi-block migrations to run. + /// + /// Should only be updated in a runtime-upgrade once all the old migrations have completed. + /// (Check that [`Cursor`] is `None`). + #[cfg(not(feature = "runtime-benchmarks"))] + type Migrations: SteppedMigrations; + + /// Mocked migrations for benchmarking only. + /// + /// Should be configured to [`crate::mock_helpers::MockedMigrations`] in benchmarks. + #[cfg(feature = "runtime-benchmarks")] + type Migrations: MockedMigrations; + + /// The maximal length of an encoded cursor. + /// + /// A good default needs to selected such that no migration will ever have a cursor with MEL + /// above this limit. This is statically checked in `integrity_test`. + #[pallet::constant] + type CursorMaxLen: Get; + + /// The maximal length of an encoded identifier. + /// + /// A good default needs to selected such that no migration will ever have an identifier + /// with MEL above this limit. This is statically checked in `integrity_test`. + #[pallet::constant] + type IdentifierMaxLen: Get; + + /// Notifications for status updates of a runtime upgrade. + /// + /// Could be used to pause XCM etc. + type MigrationStatusHandler: MigrationStatusHandler; + + /// Handler for failed migrations. + type FailedMigrationHandler: FailedMigrationHandler; + + /// The maximum weight to spend each block to execute migrations. + type MaxServiceWeight: Get; + + /// Weight information for the calls and functions of this pallet. + type WeightInfo: WeightInfo; + } + + /// The currently active migration to run and its cursor. + /// + /// `None` indicates that no migration is running. + #[pallet::storage] + pub type Cursor = StorageValue<_, CursorOf, OptionQuery>; + + /// Set of all successfully executed migrations. + /// + /// This is used as blacklist, to not re-execute migrations that have not been removed from the + /// codebase yet. Governance can regularly clear this out via `clear_historic`. + #[pallet::storage] + pub type Historic = StorageMap<_, Twox64Concat, IdentifierOf, (), OptionQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A Runtime upgrade started. + /// + /// Its end is indicated by `UpgradeCompleted` or `UpgradeFailed`. + UpgradeStarted { + /// The number of migrations that this upgrade contains. + /// + /// This can be used to design a progress indicator in combination with counting the + /// `MigrationCompleted` and `MigrationSkipped` events. + migrations: u32, + }, + /// The current runtime upgrade completed. + /// + /// This implies that all of its migrations completed successfully as well. + UpgradeCompleted, + /// Runtime upgrade failed. + /// + /// This is very bad and will require governance intervention. + UpgradeFailed, + /// A migration was skipped since it was already executed in the past. + MigrationSkipped { + /// The index of the skipped migration within the [`Config::Migrations`] list. + index: u32, + }, + /// A migration progressed. + MigrationAdvanced { + /// The index of the migration within the [`Config::Migrations`] list. + index: u32, + /// The number of blocks that this migration took so far. + took: BlockNumberFor, + }, + /// A Migration completed. + MigrationCompleted { + /// The index of the migration within the [`Config::Migrations`] list. + index: u32, + /// The number of blocks that this migration took so far. + took: BlockNumberFor, + }, + /// A Migration failed. + /// + /// This implies that the whole upgrade failed and governance intervention is required. + MigrationFailed { + /// The index of the migration within the [`Config::Migrations`] list. + index: u32, + /// The number of blocks that this migration took so far. + took: BlockNumberFor, + }, + /// The set of historical migrations has been cleared. + HistoricCleared { + /// Should be passed to `clear_historic` in a successive call. + next_cursor: Option>, + }, + } + + #[pallet::error] + pub enum Error { + /// The operation cannot complete since some MBMs are ongoing. + Ongoing, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + Self::onboard_new_mbms() + } + + #[cfg(feature = "std")] + fn integrity_test() { + // Check that the migrations tuple is legit. + frame_support::assert_ok!(T::Migrations::integrity_test()); + + // Very important! Ensure that the pallet is configured in `System::Config`. + { + assert!(!Cursor::::exists(), "Externalities storage should be clean"); + assert!(!::MultiBlockMigrator::ongoing()); + + Cursor::::put(MigrationCursor::Stuck); + assert!(::MultiBlockMigrator::ongoing()); + + Cursor::::kill(); + } + + // The per-block service weight is sane. + #[cfg(not(test))] + { + let want = T::MaxServiceWeight::get(); + let max = ::BlockWeights::get().max_block; + + assert!(want.all_lte(max), "Service weight is larger than a block: {want} > {max}",); + } + + // Cursor MEL + { + let mel = T::Migrations::cursor_max_encoded_len(); + let max_mel = T::CursorMaxLen::get() as usize; + assert!( + mel <= max_mel, + "A Cursor is not guaranteed to fit into the storage: {mel} > {max_mel}", + ); + } + + // Identifier MEL + { + let mel = T::Migrations::identifier_max_encoded_len(); + let max_mel = T::IdentifierMaxLen::get() as usize; + assert!( + mel <= max_mel, + "An Identifier is not guaranteed to fit into the storage: {mel} > {max_mel}", + ); + } + } + } + + #[pallet::call(weight = T::WeightInfo)] + impl Pallet { + /// Allows root to set a cursor to forcefully start, stop or forward the migration process. + /// + /// Should normally not be needed and is only in place as emergency measure. Note that + /// restarting the migration process in this manner will not call the + /// [`MigrationStatusHandler::started`] hook or emit an `UpgradeStarted` event. + #[pallet::call_index(0)] + pub fn force_set_cursor( + origin: OriginFor, + cursor: Option>, + ) -> DispatchResult { + ensure_root(origin)?; + + Cursor::::set(cursor); + + Ok(()) + } + + /// Allows root to set an active cursor to forcefully start/forward the migration process. + /// + /// This is an edge-case version of [`Self::force_set_cursor`] that allows to set the + /// `started_at` value to the next block number. Otherwise this would not be possible, since + /// `force_set_cursor` takes an absolute block number. Setting `started_at` to `None` + /// indicates that the current block number plus one should be used. + #[pallet::call_index(1)] + pub fn force_set_active_cursor( + origin: OriginFor, + index: u32, + inner_cursor: Option>, + started_at: Option>, + ) -> DispatchResult { + ensure_root(origin)?; + + let started_at = started_at.unwrap_or( + System::::block_number().saturating_add(sp_runtime::traits::One::one()), + ); + Cursor::::put(MigrationCursor::Active(ActiveCursor { + index, + inner_cursor, + started_at, + })); + + Ok(()) + } + + /// Forces the onboarding of the migrations. + /// + /// This process happens automatically on a runtime upgrade. It is in place as an emergency + /// measurement. The cursor needs to be `None` for this to succeed. + #[pallet::call_index(2)] + pub fn force_onboard_mbms(origin: OriginFor) -> DispatchResult { + ensure_root(origin)?; + + ensure!(!Cursor::::exists(), Error::::Ongoing); + Self::onboard_new_mbms(); + + Ok(()) + } + + /// Clears the `Historic` set. + /// + /// `map_cursor` must be set to the last value that was returned by the + /// `HistoricCleared` event. The first time `None` can be used. `limit` must be chosen in a + /// way that will result in a sensible weight. + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::clear_historic(selector.limit()))] + pub fn clear_historic( + origin: OriginFor, + selector: HistoricCleanupSelector>, + ) -> DispatchResult { + ensure_root(origin)?; + + match &selector { + HistoricCleanupSelector::Specific(ids) => { + for id in ids { + Historic::::remove(id); + } + Self::deposit_event(Event::HistoricCleared { next_cursor: None }); + }, + HistoricCleanupSelector::Wildcard { previous_cursor, .. } => { + let next = Historic::::clear(selector.limit(), previous_cursor.as_deref()); + Self::deposit_event(Event::HistoricCleared { next_cursor: next.maybe_cursor }); + }, + } + + Ok(()) + } + } +} + +impl Pallet { + /// Onboard all new Multi-Block-Migrations and start the process of executing them. + /// + /// Should only be called once all previous migrations completed. + fn onboard_new_mbms() -> Weight { + if let Some(cursor) = Cursor::::get() { + log::error!("Ongoing migrations interrupted - chain stuck"); + + let maybe_index = cursor.as_active().map(|c| c.index); + Self::upgrade_failed(maybe_index); + return T::WeightInfo::onboard_new_mbms() + } + + let migrations = T::Migrations::len(); + log::debug!("Onboarding {migrations} new MBM migrations"); + + if migrations > 0 { + // Set the cursor to the first migration: + Cursor::::set(Some( + ActiveCursor { + index: 0, + inner_cursor: None, + started_at: System::::block_number(), + } + .into(), + )); + Self::deposit_event(Event::UpgradeStarted { migrations }); + T::MigrationStatusHandler::started(); + } + + T::WeightInfo::onboard_new_mbms() + } + + /// Tries to make progress on the Multi-Block-Migrations process. + fn progress_mbms(n: BlockNumberFor) -> Weight { + let mut meter = WeightMeter::with_limit(T::MaxServiceWeight::get()); + meter.consume(T::WeightInfo::progress_mbms_none()); + + let mut cursor = match Cursor::::get() { + None => { + log::trace!("[Block {n:?}] Waiting for cursor to become `Some`."); + return meter.consumed() + }, + Some(MigrationCursor::Active(cursor)) => { + log::debug!("Progressing MBM #{}", cursor.index); + cursor + }, + Some(MigrationCursor::Stuck) => { + log::error!("Migration stuck. Governance intervention required."); + return meter.consumed() + }, + }; + debug_assert!(Self::ongoing()); + + // The limit here is a defensive measure to prevent an infinite loop. It expresses that we + // allow no more than 8 MBMs to finish in a single block. This should be harmless, since we + // generally expect *Multi*-Block-Migrations to take *multiple* blocks. + for i in 0..8 { + match Self::exec_migration(cursor, i == 0, &mut meter) { + None => return meter.consumed(), + Some(ControlFlow::Continue(next_cursor)) => { + cursor = next_cursor; + }, + Some(ControlFlow::Break(last_cursor)) => { + cursor = last_cursor; + break + }, + } + } + + Cursor::::set(Some(cursor.into())); + + meter.consumed() + } + + /// Try to make progress on the current migration. + /// + /// Returns whether processing should continue or break for this block. The return value means: + /// - `None`: The migration process is completely finished. + /// - `ControlFlow::Break`: Continue in the *next* block with the given cursor. + /// - `ControlFlow::Continue`: Continue in the *current* block with the given cursor. + fn exec_migration( + mut cursor: ActiveCursorOf, + is_first: bool, + meter: &mut WeightMeter, + ) -> Option, ActiveCursorOf>> { + // The differences between the single branches' weights is not that big. And since we do + // only one step per block, we can just use the maximum instead of more precise accounting. + if meter.try_consume(Self::exec_migration_max_weight()).is_err() { + defensive_assert!(!is_first, "There should be enough weight to do this at least once"); + return Some(ControlFlow::Break(cursor)) + } + + let Some(id) = T::Migrations::nth_id(cursor.index) else { + // No more migrations in the tuple - we are done. + defensive_assert!(cursor.index == T::Migrations::len(), "Inconsistent MBMs tuple"); + Self::deposit_event(Event::UpgradeCompleted); + Cursor::::kill(); + T::MigrationStatusHandler::completed(); + return None; + }; + + let Ok(bounded_id): Result, _> = id.try_into() else { + defensive!("integrity_test ensures that all identifiers' MEL bounds fit into CursorMaxLen; qed."); + Self::upgrade_failed(Some(cursor.index)); + return None + }; + + if Historic::::contains_key(&bounded_id) { + Self::deposit_event(Event::MigrationSkipped { index: cursor.index }); + cursor.goto_next_migration(System::::block_number()); + return Some(ControlFlow::Continue(cursor)) + } + + let max_steps = T::Migrations::nth_max_steps(cursor.index); + let next_cursor = T::Migrations::nth_transactional_step( + cursor.index, + cursor.inner_cursor.clone().map(|c| c.into_inner()), + meter, + ); + let Some((max_steps, next_cursor)) = max_steps.zip(next_cursor) else { + defensive!("integrity_test ensures that the tuple is valid; qed"); + Self::upgrade_failed(Some(cursor.index)); + return None + }; + + let took = System::::block_number().saturating_sub(cursor.started_at); + match next_cursor { + Ok(Some(next_cursor)) => { + let Ok(bound_next_cursor) = next_cursor.try_into() else { + defensive!("The integrity check ensures that all cursors' MEL bound fits into CursorMaxLen; qed"); + Self::upgrade_failed(Some(cursor.index)); + return None + }; + + Self::deposit_event(Event::MigrationAdvanced { index: cursor.index, took }); + cursor.inner_cursor = Some(bound_next_cursor); + + if max_steps.map_or(false, |max| took > max.into()) { + Self::deposit_event(Event::MigrationFailed { index: cursor.index, took }); + Self::upgrade_failed(Some(cursor.index)); + None + } else { + // A migration cannot progress more than one step per block, we therefore break. + Some(ControlFlow::Break(cursor)) + } + }, + Ok(None) => { + // A migration is done when it returns cursor `None`. + Self::deposit_event(Event::MigrationCompleted { index: cursor.index, took }); + Historic::::insert(&bounded_id, ()); + cursor.goto_next_migration(System::::block_number()); + Some(ControlFlow::Continue(cursor)) + }, + Err(SteppedMigrationError::InsufficientWeight { required }) => { + if is_first || required.any_gt(meter.limit()) { + Self::deposit_event(Event::MigrationFailed { index: cursor.index, took }); + Self::upgrade_failed(Some(cursor.index)); + None + } else { + // Retry and hope that there is more weight in the next block. + Some(ControlFlow::Break(cursor)) + } + }, + Err(SteppedMigrationError::InvalidCursor | SteppedMigrationError::Failed) => { + Self::deposit_event(Event::MigrationFailed { index: cursor.index, took }); + Self::upgrade_failed(Some(cursor.index)); + None + }, + } + } + + /// Fail the current runtime upgrade, caused by `migration`. + fn upgrade_failed(migration: Option) { + use FailedMigrationHandling::*; + Self::deposit_event(Event::UpgradeFailed); + + match T::FailedMigrationHandler::failed(migration) { + KeepStuck => Cursor::::set(Some(MigrationCursor::Stuck)), + ForceUnstuck => Cursor::::kill(), + Ignore => {}, + } + } + + fn exec_migration_max_weight() -> Weight { + T::WeightInfo::exec_migration_complete() + .max(T::WeightInfo::exec_migration_completed()) + .max(T::WeightInfo::exec_migration_skipped_historic()) + .max(T::WeightInfo::exec_migration_advance()) + .max(T::WeightInfo::exec_migration_fail()) + } +} + +impl MultiStepMigrator for Pallet { + fn ongoing() -> bool { + Cursor::::exists() + } + + fn step() -> Weight { + Self::progress_mbms(System::::block_number()) + } +} diff --git a/substrate/frame/migrations/src/mock.rs b/substrate/frame/migrations/src/mock.rs new file mode 100644 index 00000000000..37292647554 --- /dev/null +++ b/substrate/frame/migrations/src/mock.rs @@ -0,0 +1,163 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Mocked runtime for testing the migrations pallet. + +#![cfg(test)] + +use crate::{mock_helpers::*, Event, Historic}; + +use frame_support::{ + derive_impl, + migrations::*, + traits::{OnFinalize, OnInitialize}, + weights::Weight, +}; +use frame_system::EventRecord; +use sp_core::{ConstU32, H256}; + +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test { + System: frame_system, + Migrations: crate, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type Block = Block; + type PalletInfo = PalletInfo; + type MultiBlockMigrator = Migrations; +} + +frame_support::parameter_types! { + pub const MaxServiceWeight: Weight = Weight::MAX.div(10); +} + +impl crate::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Migrations = MockedMigrations; + type CursorMaxLen = ConstU32<65_536>; + type IdentifierMaxLen = ConstU32<256>; + type MigrationStatusHandler = MockedMigrationStatusHandler; + type FailedMigrationHandler = MockedFailedMigrationHandler; + type MaxServiceWeight = MaxServiceWeight; + type WeightInfo = (); +} + +frame_support::parameter_types! { + /// The number of started upgrades. + pub static UpgradesStarted: u32 = 0; + /// The number of completed upgrades. + pub static UpgradesCompleted: u32 = 0; + /// The migrations that failed. + pub static UpgradesFailed: Vec> = vec![]; + /// Return value of [`MockedFailedMigrationHandler::failed`]. + pub static FailedUpgradeResponse: FailedMigrationHandling = FailedMigrationHandling::KeepStuck; +} + +/// Records all started and completed upgrades in `UpgradesStarted` and `UpgradesCompleted`. +pub struct MockedMigrationStatusHandler; +impl MigrationStatusHandler for MockedMigrationStatusHandler { + fn started() { + log::info!("MigrationStatusHandler started"); + UpgradesStarted::mutate(|v| *v += 1); + } + + fn completed() { + log::info!("MigrationStatusHandler completed"); + UpgradesCompleted::mutate(|v| *v += 1); + } +} + +/// Records all failed upgrades in `UpgradesFailed`. +pub struct MockedFailedMigrationHandler; +impl FailedMigrationHandler for MockedFailedMigrationHandler { + fn failed(migration: Option) -> FailedMigrationHandling { + UpgradesFailed::mutate(|v| v.push(migration)); + let res = FailedUpgradeResponse::get(); + log::error!("FailedMigrationHandler failed at: {migration:?}, handling as {res:?}"); + res + } +} + +/// Returns the number of `(started, completed, failed)` upgrades and resets their numbers. +pub fn upgrades_started_completed_failed() -> (u32, u32, u32) { + (UpgradesStarted::take(), UpgradesCompleted::take(), UpgradesFailed::take().len() as u32) +} + +/// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_io::TestExternalities::new(Default::default()) +} + +/// Run this closure in test externalities. +pub fn test_closure(f: impl FnOnce() -> R) -> R { + let mut ext = new_test_ext(); + ext.execute_with(f) +} + +pub fn run_to_block(n: u32) { + while System::block_number() < n as u64 { + log::debug!("Block {}", System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + Migrations::on_initialize(System::block_number()); + // Executive calls this: + ::step(); + + Migrations::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + } +} + +/// Returns the historic migrations, sorted by their identifier. +pub fn historic() -> Vec { + let mut historic = Historic::::iter_keys().collect::>(); + historic.sort(); + historic +} + +// Traits to make using events less insufferable: +pub trait IntoRecord { + fn into_record(self) -> EventRecord<::RuntimeEvent, H256>; +} + +impl IntoRecord for Event { + fn into_record(self) -> EventRecord<::RuntimeEvent, H256> { + let re: ::RuntimeEvent = self.into(); + EventRecord { phase: frame_system::Phase::Initialization, event: re, topics: vec![] } + } +} + +pub trait IntoRecords { + fn into_records(self) -> Vec::RuntimeEvent, H256>>; +} + +impl IntoRecords for Vec { + fn into_records(self) -> Vec::RuntimeEvent, H256>> { + self.into_iter().map(|e| e.into_record()).collect() + } +} + +pub fn assert_events(events: Vec) { + pretty_assertions::assert_eq!(events.into_records(), System::events()); + System::reset_events(); +} diff --git a/substrate/frame/migrations/src/mock_helpers.rs b/substrate/frame/migrations/src/mock_helpers.rs new file mode 100644 index 00000000000..c5e23efb4e3 --- /dev/null +++ b/substrate/frame/migrations/src/mock_helpers.rs @@ -0,0 +1,142 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Test helpers for internal and external usage. + +#![allow(missing_docs)] + +use codec::{Decode, Encode}; +use frame_support::{ + migrations::*, + weights::{Weight, WeightMeter}, +}; +use sp_core::ConstU32; +use sp_runtime::BoundedVec; +use sp_std::{vec, vec::Vec}; + +/// Opaque identifier of a migration. +pub type MockedIdentifier = BoundedVec>; + +/// How a mocked migration should behave. +#[derive(Debug, Clone, Copy, Encode, Decode)] +pub enum MockedMigrationKind { + /// Succeed after its number of steps elapsed. + SucceedAfter, + /// Fail after its number of steps elapsed. + FailAfter, + /// Never terminate. + TimeoutAfter, + /// Cause an [`SteppedMigrationError::InsufficientWeight`] error after its number of steps + /// elapsed. + HighWeightAfter(Weight), +} +use MockedMigrationKind::*; // C style + +/// Creates a migration identifier with a specific `kind` and `steps`. +pub fn mocked_id(kind: MockedMigrationKind, steps: u32) -> MockedIdentifier { + (b"MockedMigration", kind, steps).encode().try_into().unwrap() +} + +frame_support::parameter_types! { + /// The configs for the migrations to run. + storage MIGRATIONS: Vec<(MockedMigrationKind, u32)> = vec![]; +} + +/// Allows to set the migrations to run at runtime instead of compile-time. +/// +/// It achieves this by using the storage to store the migrations to run. +pub struct MockedMigrations; +impl SteppedMigrations for MockedMigrations { + fn len() -> u32 { + MIGRATIONS::get().len() as u32 + } + + fn nth_id(n: u32) -> Option> { + let k = MIGRATIONS::get().get(n as usize).copied(); + k.map(|(kind, steps)| mocked_id(kind, steps).into_inner()) + } + + fn nth_step( + n: u32, + cursor: Option>, + _meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + let (kind, steps) = MIGRATIONS::get()[n as usize]; + + let mut count: u32 = + cursor.as_ref().and_then(|c| Decode::decode(&mut &c[..]).ok()).unwrap_or(0); + log::debug!("MockedMigration: Step {}", count); + if count != steps || matches!(kind, TimeoutAfter) { + count += 1; + return Some(Ok(Some(count.encode()))) + } + + Some(match kind { + SucceedAfter => { + log::debug!("MockedMigration: Succeeded after {} steps", count); + Ok(None) + }, + HighWeightAfter(required) => { + log::debug!("MockedMigration: Not enough weight after {} steps", count); + Err(SteppedMigrationError::InsufficientWeight { required }) + }, + FailAfter => { + log::debug!("MockedMigration: Failed after {} steps", count); + Err(SteppedMigrationError::Failed) + }, + TimeoutAfter => unreachable!(), + }) + } + + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + // This is a hack but should be fine. We dont need it in testing. + Self::nth_step(n, cursor, meter) + } + + fn nth_max_steps(n: u32) -> Option> { + MIGRATIONS::get().get(n as usize).map(|(_, s)| Some(*s)) + } + + fn cursor_max_encoded_len() -> usize { + 65_536 + } + + fn identifier_max_encoded_len() -> usize { + 256 + } +} + +impl MockedMigrations { + /// Set the migrations to run. + pub fn set(migrations: Vec<(MockedMigrationKind, u32)>) { + MIGRATIONS::set(&migrations); + } +} + +impl crate::MockedMigrations for MockedMigrations { + fn set_fail_after(steps: u32) { + MIGRATIONS::set(&vec![(FailAfter, steps)]); + } + + fn set_success_after(steps: u32) { + MIGRATIONS::set(&vec![(SucceedAfter, steps)]); + } +} diff --git a/substrate/frame/migrations/src/tests.rs b/substrate/frame/migrations/src/tests.rs new file mode 100644 index 00000000000..9c9043d37a6 --- /dev/null +++ b/substrate/frame/migrations/src/tests.rs @@ -0,0 +1,335 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use crate::{ + mock::{Test as T, *}, + mock_helpers::{MockedMigrationKind::*, *}, + Cursor, Event, FailedMigrationHandling, MigrationCursor, +}; +use frame_support::{pallet_prelude::Weight, traits::OnRuntimeUpgrade}; + +#[docify::export] +#[test] +fn simple_works() { + use Event::*; + test_closure(|| { + // Add three migrations, each taking one block longer than the previous. + MockedMigrations::set(vec![(SucceedAfter, 0), (SucceedAfter, 1), (SucceedAfter, 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Check that the executed migrations are recorded in `Historical`. + assert_eq!( + historic(), + vec![ + mocked_id(SucceedAfter, 0), + mocked_id(SucceedAfter, 1), + mocked_id(SucceedAfter, 2), + ] + ); + + // Check that we got all events. + assert_events(vec![ + UpgradeStarted { migrations: 3 }, + MigrationCompleted { index: 0, took: 1 }, + MigrationAdvanced { index: 1, took: 0 }, + MigrationCompleted { index: 1, took: 1 }, + MigrationAdvanced { index: 2, took: 0 }, + MigrationAdvanced { index: 2, took: 1 }, + MigrationCompleted { index: 2, took: 2 }, + UpgradeCompleted, + ]); + }); +} + +#[test] +fn failing_migration_sets_cursor_to_stuck() { + test_closure(|| { + FailedUpgradeResponse::set(FailedMigrationHandling::KeepStuck); + MockedMigrations::set(vec![(FailAfter, 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Failed migrations are not recorded in `Historical`. + assert!(historic().is_empty()); + // Check that we got all events. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationFailed { index: 0, took: 3 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(UpgradesStarted::take(), 1); + assert_eq!(UpgradesCompleted::take(), 0); + assert_eq!(UpgradesFailed::take(), vec![Some(0)]); + + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck), "Must stuck the chain"); + }); +} + +#[test] +fn failing_migration_force_unstuck_works() { + test_closure(|| { + FailedUpgradeResponse::set(FailedMigrationHandling::ForceUnstuck); + MockedMigrations::set(vec![(FailAfter, 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Failed migrations are not recorded in `Historical`. + assert!(historic().is_empty()); + // Check that we got all events. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationFailed { index: 0, took: 3 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(UpgradesStarted::take(), 1); + assert_eq!(UpgradesCompleted::take(), 0); + assert_eq!(UpgradesFailed::take(), vec![Some(0)]); + + assert!(Cursor::::get().is_none(), "Must unstuck the chain"); + }); +} + +/// A migration that reports not getting enough weight errors if it is the first one to run in that +/// block. +#[test] +fn high_weight_migration_singular_fails() { + test_closure(|| { + MockedMigrations::set(vec![(HighWeightAfter(Weight::zero()), 2)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Failed migrations are not recorded in `Historical`. + assert!(historic().is_empty()); + // Check that we got all events. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationFailed { index: 0, took: 3 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + }); +} + +/// A migration that reports of not getting enough weight is retried once, if it is not the first +/// one to run in a block. +#[test] +fn high_weight_migration_retries_once() { + test_closure(|| { + MockedMigrations::set(vec![(SucceedAfter, 0), (HighWeightAfter(Weight::zero()), 0)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + assert_eq!(historic(), vec![mocked_id(SucceedAfter, 0)]); + // Check that we got all events. + assert_events::>(vec![ + Event::UpgradeStarted { migrations: 2 }, + Event::MigrationCompleted { index: 0, took: 1 }, + // `took=1` means that it was retried once. + Event::MigrationFailed { index: 1, took: 1 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + }); +} + +/// If a migration uses more weight than the limit, then it will not retry but fail even when it is +/// not the first one in the block. +// Note: Same as `high_weight_migration_retries_once` but with different required weight for the +// migration. +#[test] +fn high_weight_migration_permanently_overweight_fails() { + test_closure(|| { + MockedMigrations::set(vec![(SucceedAfter, 0), (HighWeightAfter(Weight::MAX), 0)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + assert_eq!(historic(), vec![mocked_id(SucceedAfter, 0)]); + // Check that we got all events. + assert_events::>(vec![ + Event::UpgradeStarted { migrations: 2 }, + Event::MigrationCompleted { index: 0, took: 1 }, + // `blocks=0` means that it was not retried. + Event::MigrationFailed { index: 1, took: 0 }, + Event::UpgradeFailed, + ]); + + // Check that the handler was called correctly. + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + }); +} + +#[test] +fn historic_skipping_works() { + test_closure(|| { + MockedMigrations::set(vec![ + (SucceedAfter, 0), + (SucceedAfter, 0), // duplicate + (SucceedAfter, 1), + (SucceedAfter, 2), + (SucceedAfter, 1), // duplicate + ]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(10); + + // Just three historical ones, since two were added twice. + assert_eq!( + historic(), + vec![ + mocked_id(SucceedAfter, 0), + mocked_id(SucceedAfter, 1), + mocked_id(SucceedAfter, 2), + ] + ); + // Events received. + assert_events(vec![ + Event::UpgradeStarted { migrations: 5 }, + Event::MigrationCompleted { index: 0, took: 1 }, + Event::MigrationSkipped { index: 1 }, + Event::MigrationAdvanced { index: 2, took: 0 }, + Event::MigrationCompleted { index: 2, took: 1 }, + Event::MigrationAdvanced { index: 3, took: 0 }, + Event::MigrationAdvanced { index: 3, took: 1 }, + Event::MigrationCompleted { index: 3, took: 2 }, + Event::MigrationSkipped { index: 4 }, + Event::UpgradeCompleted, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 1, 0)); + + // Now go for another upgrade; just to make sure that it wont execute again. + System::reset_events(); + Migrations::on_runtime_upgrade(); + run_to_block(20); + + // Same historical ones as before. + assert_eq!( + historic(), + vec![ + mocked_id(SucceedAfter, 0), + mocked_id(SucceedAfter, 1), + mocked_id(SucceedAfter, 2), + ] + ); + + // Everything got skipped. + assert_events(vec![ + Event::UpgradeStarted { migrations: 5 }, + Event::MigrationSkipped { index: 0 }, + Event::MigrationSkipped { index: 1 }, + Event::MigrationSkipped { index: 2 }, + Event::MigrationSkipped { index: 3 }, + Event::MigrationSkipped { index: 4 }, + Event::UpgradeCompleted, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 1, 0)); + }); +} + +/// When another upgrade happens while a migration is still running, it should set the cursor to +/// stuck. +#[test] +fn upgrade_fails_when_migration_active() { + test_closure(|| { + MockedMigrations::set(vec![(SucceedAfter, 10)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(3); + + // Events received. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 0, 0)); + + // Upgrade again. + Migrations::on_runtime_upgrade(); + // -- Defensive path -- + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + assert_events(vec![Event::UpgradeFailed]); + assert_eq!(upgrades_started_completed_failed(), (0, 0, 1)); + }); +} + +#[test] +fn migration_timeout_errors() { + test_closure(|| { + MockedMigrations::set(vec![(TimeoutAfter, 3)]); + + System::set_block_number(1); + Migrations::on_runtime_upgrade(); + run_to_block(5); + + // Times out after taking more than 3 steps. + assert_events(vec![ + Event::UpgradeStarted { migrations: 1 }, + Event::MigrationAdvanced { index: 0, took: 1 }, + Event::MigrationAdvanced { index: 0, took: 2 }, + Event::MigrationAdvanced { index: 0, took: 3 }, + Event::MigrationAdvanced { index: 0, took: 4 }, + Event::MigrationFailed { index: 0, took: 4 }, + Event::UpgradeFailed, + ]); + assert_eq!(upgrades_started_completed_failed(), (1, 0, 1)); + + // Failed migrations are not black-listed. + assert!(historic().is_empty()); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + + Migrations::on_runtime_upgrade(); + run_to_block(6); + + assert_events(vec![Event::UpgradeFailed]); + assert_eq!(Cursor::::get(), Some(MigrationCursor::Stuck)); + assert_eq!(upgrades_started_completed_failed(), (0, 0, 1)); + }); +} diff --git a/substrate/frame/migrations/src/weights.rs b/substrate/frame/migrations/src/weights.rs new file mode 100644 index 00000000000..c9b63258c44 --- /dev/null +++ b/substrate/frame/migrations/src/weights.rs @@ -0,0 +1,358 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for `pallet_migrations` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `loud1`, CPU: `AMD EPYC 7282 16-Core Processor` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// target/release/substrate-node +// benchmark +// pallet +// --chain +// dev +// --pallet +// pallet-migrations +// --extrinsic +// +// --output +// weight.rs +// --template +// ../../polkadot-sdk/substrate/.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_migrations`. +pub trait WeightInfo { + fn onboard_new_mbms() -> Weight; + fn progress_mbms_none() -> Weight; + fn exec_migration_completed() -> Weight; + fn exec_migration_skipped_historic() -> Weight; + fn exec_migration_advance() -> Weight; + fn exec_migration_complete() -> Weight; + fn exec_migration_fail() -> Weight; + fn on_init_loop() -> Weight; + fn force_set_cursor() -> Weight; + fn force_set_active_cursor() -> Weight; + fn force_onboard_mbms() -> Weight; + fn clear_historic(n: u32, ) -> Weight; +} + +/// Weights for `pallet_migrations` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn onboard_new_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `67035` + // Minimum execution time: 13_980_000 picoseconds. + Weight::from_parts(14_290_000, 67035) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn progress_mbms_none() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `67035` + // Minimum execution time: 3_770_000 picoseconds. + Weight::from_parts(4_001_000, 67035) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_completed() -> Weight { + // Proof Size summary in bytes: + // Measured: `134` + // Estimated: `3599` + // Minimum execution time: 10_900_000 picoseconds. + Weight::from_parts(11_251_000, 3599) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_skipped_historic() -> Weight { + // Proof Size summary in bytes: + // Measured: `297` + // Estimated: `3762` + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_501_000, 3762) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_advance() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 18_271_000 picoseconds. + Weight::from_parts(18_740_000, 3731) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_complete() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 21_241_000 picoseconds. + Weight::from_parts(21_911_000, 3731) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 22_740_000 picoseconds. + Weight::from_parts(23_231_000, 3731) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + fn on_init_loop() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 440_000 picoseconds. + Weight::from_parts(500_000, 0) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_751_000 picoseconds. + Weight::from_parts(5_950_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_active_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_350_000 picoseconds. + Weight::from_parts(6_560_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn force_onboard_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `218` + // Estimated: `67035` + // Minimum execution time: 11_121_000 picoseconds. + Weight::from_parts(11_530_000, 67035) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 256]`. + fn clear_historic(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1089 + n * (271 ±0)` + // Estimated: `3834 + n * (2740 ±0)` + // Minimum execution time: 21_891_000 picoseconds. + Weight::from_parts(18_572_306, 3834) + // Standard Error: 3_236 + .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2740).saturating_mul(n.into())) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn onboard_new_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `67035` + // Minimum execution time: 13_980_000 picoseconds. + Weight::from_parts(14_290_000, 67035) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn progress_mbms_none() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `67035` + // Minimum execution time: 3_770_000 picoseconds. + Weight::from_parts(4_001_000, 67035) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_completed() -> Weight { + // Proof Size summary in bytes: + // Measured: `134` + // Estimated: `3599` + // Minimum execution time: 10_900_000 picoseconds. + Weight::from_parts(11_251_000, 3599) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_skipped_historic() -> Weight { + // Proof Size summary in bytes: + // Measured: `297` + // Estimated: `3762` + // Minimum execution time: 17_891_000 picoseconds. + Weight::from_parts(18_501_000, 3762) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_advance() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 18_271_000 picoseconds. + Weight::from_parts(18_740_000, 3731) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:1) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + fn exec_migration_complete() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 21_241_000 picoseconds. + Weight::from_parts(21_911_000, 3731) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Storage: `MultiBlockMigrations::Historic` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn exec_migration_fail() -> Weight { + // Proof Size summary in bytes: + // Measured: `243` + // Estimated: `3731` + // Minimum execution time: 22_740_000 picoseconds. + Weight::from_parts(23_231_000, 3731) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + fn on_init_loop() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 440_000 picoseconds. + Weight::from_parts(500_000, 0) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 5_751_000 picoseconds. + Weight::from_parts(5_950_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:0 w:1) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + fn force_set_active_cursor() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_350_000 picoseconds. + Weight::from_parts(6_560_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `MultiBlockMigrations::Cursor` (r:1 w:0) + /// Proof: `MultiBlockMigrations::Cursor` (`max_values`: Some(1), `max_size`: Some(65550), added: 66045, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x583359fe0e84d953a9dd84e8addb08a5` (r:1 w:0) + fn force_onboard_mbms() -> Weight { + // Proof Size summary in bytes: + // Measured: `218` + // Estimated: `67035` + // Minimum execution time: 11_121_000 picoseconds. + Weight::from_parts(11_530_000, 67035) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: `MultiBlockMigrations::Historic` (r:256 w:256) + /// Proof: `MultiBlockMigrations::Historic` (`max_values`: None, `max_size`: Some(266), added: 2741, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 256]`. + fn clear_historic(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `1089 + n * (271 ±0)` + // Estimated: `3834 + n * (2740 ±0)` + // Minimum execution time: 21_891_000 picoseconds. + Weight::from_parts(18_572_306, 3834) + // Standard Error: 3_236 + .saturating_add(Weight::from_parts(1_648_429, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into()))) + .saturating_add(Weight::from_parts(0, 2740).saturating_mul(n.into())) + } +} diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index a2e5d726fdd..52db7c34bfd 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -197,7 +197,7 @@ pub mod runtime { // Types often used in the runtime APIs. pub use sp_core::OpaqueMetadata; pub use sp_inherents::{CheckInherentsResult, InherentData}; - pub use sp_runtime::ApplyExtrinsicResult; + pub use sp_runtime::{ApplyExtrinsicResult, ExtrinsicInclusionMode}; pub use frame_system_rpc_runtime_api::*; pub use sp_api::{self, *}; diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs index 34b9d21d8ce..da483fa6cf0 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs @@ -204,47 +204,50 @@ pub fn expand_outer_inherent( } } + impl #scrate::traits::IsInherent<<#block as #scrate::sp_runtime::traits::Block>::Extrinsic> for #runtime { + fn is_inherent(ext: &<#block as #scrate::sp_runtime::traits::Block>::Extrinsic) -> bool { + use #scrate::inherent::ProvideInherent; + use #scrate::traits::{IsSubType, ExtrinsicCall}; + + if #scrate::sp_runtime::traits::Extrinsic::is_signed(ext).unwrap_or(false) { + // Signed extrinsics are never inherents. + return false + } + + #( + #pallet_attrs + { + let call = <#unchecked_extrinsic as ExtrinsicCall>::call(ext); + if let Some(call) = IsSubType::<_>::is_sub_type(call) { + if <#pallet_names as ProvideInherent>::is_inherent(&call) { + return true; + } + } + } + )* + false + } + } + impl #scrate::traits::EnsureInherentsAreFirst<#block> for #runtime { - fn ensure_inherents_are_first(block: &#block) -> Result<(), u32> { + fn ensure_inherents_are_first(block: &#block) -> Result { use #scrate::inherent::ProvideInherent; use #scrate::traits::{IsSubType, ExtrinsicCall}; use #scrate::sp_runtime::traits::Block as _; - let mut first_signed_observed = false; + let mut num_inherents = 0u32; for (i, xt) in block.extrinsics().iter().enumerate() { - let is_signed = #scrate::sp_runtime::traits::Extrinsic::is_signed(xt) - .unwrap_or(false); - - let is_inherent = if is_signed { - // Signed extrinsics are not inherents. - false - } else { - let mut is_inherent = false; - #( - #pallet_attrs - { - let call = <#unchecked_extrinsic as ExtrinsicCall>::call(xt); - if let Some(call) = IsSubType::<_>::is_sub_type(call) { - if #pallet_names::is_inherent(&call) { - is_inherent = true; - } - } - } - )* - is_inherent - }; - - if !is_inherent { - first_signed_observed = true; - } + if >::is_inherent(xt) { + if num_inherents != i as u32 { + return Err(i as u32); + } - if first_signed_observed && is_inherent { - return Err(i as u32) + num_inherents += 1; // Safe since we are in an `enumerate` loop. } } - Ok(()) + Ok(num_inherents) } } } diff --git a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs index 6b25ddcba1a..3623b595268 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/hooks.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/hooks.rs @@ -175,6 +175,22 @@ pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { } } + impl<#type_impl_gen> + #frame_support::traits::OnPoll<#frame_system::pallet_prelude::BlockNumberFor::> + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_poll( + n: #frame_system::pallet_prelude::BlockNumberFor::, + weight: &mut #frame_support::weights::WeightMeter + ) { + < + Self as #frame_support::traits::Hooks< + #frame_system::pallet_prelude::BlockNumberFor:: + > + >::on_poll(n, weight); + } + } + impl<#type_impl_gen> #frame_support::traits::OnInitialize<#frame_system::pallet_prelude::BlockNumberFor::> for #pallet_ident<#type_use_gen> #where_clause diff --git a/substrate/frame/support/src/migrations.rs b/substrate/frame/support/src/migrations.rs index f7541059023..2ceab44cb16 100644 --- a/substrate/frame/support/src/migrations.rs +++ b/substrate/frame/support/src/migrations.rs @@ -16,13 +16,21 @@ // limitations under the License. use crate::{ - traits::{GetStorageVersion, NoStorageVersionSet, PalletInfoAccess, StorageVersion}, - weights::{RuntimeDbWeight, Weight}, + defensive, + storage::transactional::with_transaction_opaque_err, + traits::{ + Defensive, GetStorageVersion, NoStorageVersionSet, PalletInfoAccess, SafeMode, + StorageVersion, + }, + weights::{RuntimeDbWeight, Weight, WeightMeter}, }; +use codec::{Decode, Encode, MaxEncodedLen}; use impl_trait_for_tuples::impl_for_tuples; +use sp_arithmetic::traits::Bounded; use sp_core::Get; use sp_io::{hashing::twox_128, storage::clear_prefix, KillStorageResult}; -use sp_std::marker::PhantomData; +use sp_runtime::traits::Zero; +use sp_std::{marker::PhantomData, vec::Vec}; /// Handles storage migration pallet versioning. /// @@ -91,7 +99,7 @@ pub struct VersionedMigration), @@ -118,7 +126,6 @@ impl< /// migration ran or not. #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { - use codec::Encode; let on_chain_version = Pallet::on_chain_storage_version(); if on_chain_version == FROM { Ok(VersionedPostUpgradeData::MigrationExecuted(Inner::pre_upgrade()?).encode()) @@ -361,3 +368,622 @@ impl, DbWeight: Get> frame_support::traits Ok(()) } } + +/// A migration that can proceed in multiple steps. +pub trait SteppedMigration { + /// The cursor type that stores the progress (aka. state) of this migration. + type Cursor: codec::FullCodec + codec::MaxEncodedLen; + + /// The unique identifier type of this migration. + type Identifier: codec::FullCodec + codec::MaxEncodedLen; + + /// The unique identifier of this migration. + /// + /// If two migrations have the same identifier, then they are assumed to be identical. + fn id() -> Self::Identifier; + + /// The maximum number of steps that this migration can take. + /// + /// This can be used to enforce progress and prevent migrations becoming stuck forever. A + /// migration that exceeds its max steps is treated as failed. `None` means that there is no + /// limit. + fn max_steps() -> Option { + None + } + + /// Try to migrate as much as possible with the given weight. + /// + /// **ANY STORAGE CHANGES MUST BE ROLLED-BACK BY THE CALLER UPON ERROR.** This is necessary + /// since the caller cannot return a cursor in the error case. [`Self::transactional_step`] is + /// provided as convenience for a caller. A cursor of `None` implies that the migration is at + /// its end. A migration that once returned `Nonce` is guaranteed to never be called again. + fn step( + cursor: Option, + meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError>; + + /// Same as [`Self::step`], but rolls back pending changes in the error case. + fn transactional_step( + mut cursor: Option, + meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + with_transaction_opaque_err(move || match Self::step(cursor, meter) { + Ok(new_cursor) => { + cursor = new_cursor; + sp_runtime::TransactionOutcome::Commit(Ok(cursor)) + }, + Err(err) => sp_runtime::TransactionOutcome::Rollback(Err(err)), + }) + .map_err(|()| SteppedMigrationError::Failed)? + } +} + +/// Error that can occur during a [`SteppedMigration`]. +#[derive(Debug, Encode, Decode, MaxEncodedLen, scale_info::TypeInfo)] +pub enum SteppedMigrationError { + // Transient errors: + /// The remaining weight is not enough to do anything. + /// + /// Can be resolved by calling with at least `required` weight. Note that calling it with + /// exactly `required` weight could cause it to not make any progress. + InsufficientWeight { + /// Amount of weight required to make progress. + required: Weight, + }, + // Permanent errors: + /// The migration cannot decode its cursor and therefore not proceed. + /// + /// This should not happen unless (1) the migration itself returned an invalid cursor in a + /// previous iteration, (2) the storage got corrupted or (3) there is a bug in the caller's + /// code. + InvalidCursor, + /// The migration encountered a permanent error and cannot continue. + Failed, +} + +/// Notification handler for status updates regarding Multi-Block-Migrations. +#[impl_trait_for_tuples::impl_for_tuples(8)] +pub trait MigrationStatusHandler { + /// Notifies of the start of a runtime migration. + fn started() {} + + /// Notifies of the completion of a runtime migration. + fn completed() {} +} + +/// Handles a failed runtime migration. +/// +/// This should never happen, but is here for completeness. +pub trait FailedMigrationHandler { + /// Infallibly handle a failed runtime migration. + /// + /// Gets passed in the optional index of the migration in the batch that caused the failure. + /// Returning `None` means that no automatic handling should take place and the callee decides + /// in the implementation what to do. + fn failed(migration: Option) -> FailedMigrationHandling; +} + +/// Do now allow any transactions to be processed after a runtime upgrade failed. +/// +/// This is **not a sane default**, since it prevents governance intervention. +pub struct FreezeChainOnFailedMigration; + +impl FailedMigrationHandler for FreezeChainOnFailedMigration { + fn failed(_migration: Option) -> FailedMigrationHandling { + FailedMigrationHandling::KeepStuck + } +} + +/// Enter safe mode on a failed runtime upgrade. +/// +/// This can be very useful to manually intervene and fix the chain state. `Else` is used in case +/// that the safe mode could not be entered. +pub struct EnterSafeModeOnFailedMigration( + PhantomData<(SM, Else)>, +); + +impl FailedMigrationHandler + for EnterSafeModeOnFailedMigration +where + ::BlockNumber: Bounded, +{ + fn failed(migration: Option) -> FailedMigrationHandling { + let entered = if SM::is_entered() { + SM::extend(Bounded::max_value()) + } else { + SM::enter(Bounded::max_value()) + }; + + // If we could not enter or extend safe mode (for whatever reason), then we try the next. + if entered.is_err() { + Else::failed(migration) + } else { + FailedMigrationHandling::KeepStuck + } + } +} + +/// How to proceed after a runtime upgrade failed. +/// +/// There is NO SANE DEFAULT HERE. All options are very dangerous and should be used with care. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FailedMigrationHandling { + /// Resume extrinsic processing of the chain. This will not resume the upgrade. + /// + /// This should be supplemented with additional measures to ensure that the broken chain state + /// does not get further messed up by user extrinsics. + ForceUnstuck, + /// Set the cursor to `Stuck` and keep blocking extrinsics. + KeepStuck, + /// Don't do anything with the cursor and let the handler decide. + /// + /// This can be useful in cases where the other two options would overwrite any changes that + /// were done by the handler to the cursor. + Ignore, +} + +/// Something that can do multi step migrations. +pub trait MultiStepMigrator { + /// Hint for whether [`Self::step`] should be called. + fn ongoing() -> bool; + + /// Do the next step in the MBM process. + /// + /// Must gracefully handle the case that it is currently not upgrading. + fn step() -> Weight; +} + +impl MultiStepMigrator for () { + fn ongoing() -> bool { + false + } + + fn step() -> Weight { + Weight::zero() + } +} + +/// Multiple [`SteppedMigration`]. +pub trait SteppedMigrations { + /// The number of migrations that `Self` aggregates. + fn len() -> u32; + + /// The `n`th [`SteppedMigration::id`]. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_id(n: u32) -> Option>; + + /// The [`SteppedMigration::max_steps`] of the `n`th migration. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_max_steps(n: u32) -> Option>; + + /// Do a [`SteppedMigration::step`] on the `n`th migration. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>>; + + /// Do a [`SteppedMigration::transactional_step`] on the `n`th migration. + /// + /// Is guaranteed to return `Some` if `n < Self::len()`. + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>>; + + /// The maximal encoded length across all cursors. + fn cursor_max_encoded_len() -> usize; + + /// The maximal encoded length across all identifiers. + fn identifier_max_encoded_len() -> usize; + + /// Assert the integrity of the migrations. + /// + /// Should be executed as part of a test prior to runtime usage. May or may not need + /// externalities. + #[cfg(feature = "std")] + fn integrity_test() -> Result<(), &'static str> { + use crate::ensure; + let l = Self::len(); + + for n in 0..l { + ensure!(Self::nth_id(n).is_some(), "id is None"); + ensure!(Self::nth_max_steps(n).is_some(), "steps is None"); + + // The cursor that we use does not matter. Hence use empty. + ensure!( + Self::nth_step(n, Some(vec![]), &mut WeightMeter::new()).is_some(), + "steps is None" + ); + ensure!( + Self::nth_transactional_step(n, Some(vec![]), &mut WeightMeter::new()).is_some(), + "steps is None" + ); + } + + Ok(()) + } +} + +impl SteppedMigrations for () { + fn len() -> u32 { + 0 + } + + fn nth_id(_n: u32) -> Option> { + None + } + + fn nth_max_steps(_n: u32) -> Option> { + None + } + + fn nth_step( + _n: u32, + _cursor: Option>, + _meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + None + } + + fn nth_transactional_step( + _n: u32, + _cursor: Option>, + _meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + None + } + + fn cursor_max_encoded_len() -> usize { + 0 + } + + fn identifier_max_encoded_len() -> usize { + 0 + } +} + +// A collection consisting of only a single migration. +impl SteppedMigrations for T { + fn len() -> u32 { + 1 + } + + fn nth_id(_n: u32) -> Option> { + Some(T::id().encode()) + } + + fn nth_max_steps(n: u32) -> Option> { + // It should be generally fine to call with n>0, but the code should not attempt to. + n.is_zero() + .then_some(T::max_steps()) + .defensive_proof("nth_max_steps should only be called with n==0") + } + + fn nth_step( + _n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + if !_n.is_zero() { + defensive!("nth_step should only be called with n==0"); + return None + } + + let cursor = match cursor { + Some(cursor) => match T::Cursor::decode(&mut &cursor[..]) { + Ok(cursor) => Some(cursor), + Err(_) => return Some(Err(SteppedMigrationError::InvalidCursor)), + }, + None => None, + }; + + Some(T::step(cursor, meter).map(|cursor| cursor.map(|cursor| cursor.encode()))) + } + + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + if n != 0 { + defensive!("nth_transactional_step should only be called with n==0"); + return None + } + + let cursor = match cursor { + Some(cursor) => match T::Cursor::decode(&mut &cursor[..]) { + Ok(cursor) => Some(cursor), + Err(_) => return Some(Err(SteppedMigrationError::InvalidCursor)), + }, + None => None, + }; + + Some( + T::transactional_step(cursor, meter).map(|cursor| cursor.map(|cursor| cursor.encode())), + ) + } + + fn cursor_max_encoded_len() -> usize { + T::Cursor::max_encoded_len() + } + + fn identifier_max_encoded_len() -> usize { + T::Identifier::max_encoded_len() + } +} + +#[impl_trait_for_tuples::impl_for_tuples(1, 30)] +impl SteppedMigrations for Tuple { + fn len() -> u32 { + for_tuples!( #( Tuple::len() )+* ) + } + + fn nth_id(n: u32) -> Option> { + let mut i = 0; + + for_tuples!( #( + if (i + Tuple::len()) > n { + return Tuple::nth_id(n - i) + } + + i += Tuple::len(); + )* ); + + None + } + + fn nth_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + let mut i = 0; + + for_tuples!( #( + if (i + Tuple::len()) > n { + return Tuple::nth_step(n - i, cursor, meter) + } + + i += Tuple::len(); + )* ); + + None + } + + fn nth_transactional_step( + n: u32, + cursor: Option>, + meter: &mut WeightMeter, + ) -> Option>, SteppedMigrationError>> { + let mut i = 0; + + for_tuples! ( #( + if (i + Tuple::len()) > n { + return Tuple::nth_transactional_step(n - i, cursor, meter) + } + + i += Tuple::len(); + )* ); + + None + } + + fn nth_max_steps(n: u32) -> Option> { + let mut i = 0; + + for_tuples!( #( + if (i + Tuple::len()) > n { + return Tuple::nth_max_steps(n - i) + } + + i += Tuple::len(); + )* ); + + None + } + + fn cursor_max_encoded_len() -> usize { + let mut max_len = 0; + + for_tuples!( #( + max_len = max_len.max(Tuple::cursor_max_encoded_len()); + )* ); + + max_len + } + + fn identifier_max_encoded_len() -> usize { + let mut max_len = 0; + + for_tuples!( #( + max_len = max_len.max(Tuple::identifier_max_encoded_len()); + )* ); + + max_len + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{assert_ok, storage::unhashed}; + + #[derive(Decode, Encode, MaxEncodedLen, Eq, PartialEq)] + pub enum Either { + Left(L), + Right(R), + } + + pub struct M0; + impl SteppedMigration for M0 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 0 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("M0"); + unhashed::put(&[0], &()); + Ok(None) + } + } + + pub struct M1; + impl SteppedMigration for M1 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 1 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("M1"); + unhashed::put(&[1], &()); + Ok(None) + } + + fn max_steps() -> Option { + Some(1) + } + } + + pub struct M2; + impl SteppedMigration for M2 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 2 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("M2"); + unhashed::put(&[2], &()); + Ok(None) + } + + fn max_steps() -> Option { + Some(2) + } + } + + pub struct F0; + impl SteppedMigration for F0 { + type Cursor = (); + type Identifier = u8; + + fn id() -> Self::Identifier { + 3 + } + + fn step( + _cursor: Option, + _meter: &mut WeightMeter, + ) -> Result, SteppedMigrationError> { + log::info!("F0"); + unhashed::put(&[3], &()); + Err(SteppedMigrationError::Failed) + } + } + + // Three migrations combined to execute in order: + type Triple = (M0, (M1, M2)); + // Six migrations, just concatenating the ones from before: + type Hextuple = (Triple, Triple); + + #[test] + fn singular_migrations_work() { + assert_eq!(M0::max_steps(), None); + assert_eq!(M1::max_steps(), Some(1)); + assert_eq!(M2::max_steps(), Some(2)); + + assert_eq!(<(M0, M1)>::nth_max_steps(0), Some(None)); + assert_eq!(<(M0, M1)>::nth_max_steps(1), Some(Some(1))); + assert_eq!(<(M0, M1, M2)>::nth_max_steps(2), Some(Some(2))); + + assert_eq!(<(M0, M1)>::nth_max_steps(2), None); + } + + #[test] + fn tuple_migrations_work() { + assert_eq!(<() as SteppedMigrations>::len(), 0); + assert_eq!(<((), ((), ())) as SteppedMigrations>::len(), 0); + assert_eq!(::len(), 3); + assert_eq!(::len(), 6); + + // Check the IDs. The index specific functions all return an Option, + // to account for the out-of-range case. + assert_eq!(::nth_id(0), Some(0u8.encode())); + assert_eq!(::nth_id(1), Some(1u8.encode())); + assert_eq!(::nth_id(2), Some(2u8.encode())); + + sp_io::TestExternalities::default().execute_with(|| { + for n in 0..3 { + ::nth_step( + n, + Default::default(), + &mut WeightMeter::new(), + ); + } + }); + } + + #[test] + fn integrity_test_works() { + sp_io::TestExternalities::default().execute_with(|| { + assert_ok!(<() as SteppedMigrations>::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + assert_ok!(::integrity_test()); + }); + } + + #[test] + fn transactional_rollback_works() { + sp_io::TestExternalities::default().execute_with(|| { + assert_ok!(<(M0, F0) as SteppedMigrations>::nth_transactional_step( + 0, + Default::default(), + &mut WeightMeter::new() + ) + .unwrap()); + assert!(unhashed::exists(&[0])); + + let _g = crate::StorageNoopGuard::new(); + assert!(<(M0, F0) as SteppedMigrations>::nth_transactional_step( + 1, + Default::default(), + &mut WeightMeter::new() + ) + .unwrap() + .is_err()); + assert!(<(F0, M1) as SteppedMigrations>::nth_transactional_step( + 0, + Default::default(), + &mut WeightMeter::new() + ) + .unwrap() + .is_err()); + }); + } +} diff --git a/substrate/frame/support/src/storage/transactional.rs b/substrate/frame/support/src/storage/transactional.rs index d42e1809e91..0671db4a3a8 100644 --- a/substrate/frame/support/src/storage/transactional.rs +++ b/substrate/frame/support/src/storage/transactional.rs @@ -127,6 +127,22 @@ where } } +/// Same as [`with_transaction`] but casts any internal error to `()`. +/// +/// This rids `E` of the `From` bound that is required by `with_transaction`. +pub fn with_transaction_opaque_err(f: F) -> Result, ()> +where + F: FnOnce() -> TransactionOutcome>, +{ + with_transaction(move || -> TransactionOutcome, DispatchError>> { + match f() { + TransactionOutcome::Commit(res) => TransactionOutcome::Commit(Ok(res)), + TransactionOutcome::Rollback(res) => TransactionOutcome::Rollback(Ok(res)), + } + }) + .map_err(|_| ()) +} + /// Same as [`with_transaction`] but without a limit check on nested transactional layers. /// /// This is mostly for backwards compatibility before there was a transactional layer limit. diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs index 3d0429f71b1..1997d8fc223 100644 --- a/substrate/frame/support/src/traits.rs +++ b/substrate/frame/support/src/traits.rs @@ -59,10 +59,10 @@ pub use misc::{ AccountTouch, Backing, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, DefensiveMax, DefensiveMin, DefensiveSaturating, DefensiveTruncateFrom, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, - ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType, - Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time, - TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, VariantCountOf, WrapperKeepOpaque, - WrapperOpaque, + ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsInherent, + IsSubType, IsType, Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, + SameOrOther, Time, TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, VariantCountOf, + WrapperKeepOpaque, WrapperOpaque, }; #[allow(deprecated)] pub use misc::{PreimageProvider, PreimageRecipient}; @@ -86,7 +86,8 @@ mod hooks; pub use hooks::GenesisBuild; pub use hooks::{ BeforeAllRuntimeMigrations, BuildGenesisConfig, Hooks, IntegrityTest, OnFinalize, OnGenesis, - OnIdle, OnInitialize, OnRuntimeUpgrade, OnTimestampSet, + OnIdle, OnInitialize, OnPoll, OnRuntimeUpgrade, OnTimestampSet, PostInherents, + PostTransactions, PreInherents, }; pub mod schedule; diff --git a/substrate/frame/support/src/traits/hooks.rs b/substrate/frame/support/src/traits/hooks.rs index c37fb0f54bc..7d0e5aa1e89 100644 --- a/substrate/frame/support/src/traits/hooks.rs +++ b/substrate/frame/support/src/traits/hooks.rs @@ -25,10 +25,74 @@ use crate::weights::Weight; use impl_trait_for_tuples::impl_for_tuples; use sp_runtime::traits::AtLeast32BitUnsigned; use sp_std::prelude::*; +use sp_weights::WeightMeter; #[cfg(feature = "try-runtime")] use sp_runtime::TryRuntimeError; +/// Provides a callback to execute logic before the all inherents. +pub trait PreInherents { + /// Called before all inherents were applied but after `on_initialize`. + fn pre_inherents() {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl PreInherents for Tuple { + fn pre_inherents() { + for_tuples!( #( Tuple::pre_inherents(); )* ); + } +} + +/// Provides a callback to execute logic after the all inherents. +pub trait PostInherents { + /// Called after all inherents were applied. + fn post_inherents() {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl PostInherents for Tuple { + fn post_inherents() { + for_tuples!( #( Tuple::post_inherents(); )* ); + } +} + +/// Provides a callback to execute logic before the all transactions. +pub trait PostTransactions { + /// Called after all transactions were applied but before `on_finalize`. + fn post_transactions() {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl PostTransactions for Tuple { + fn post_transactions() { + for_tuples!( #( Tuple::post_transactions(); )* ); + } +} + +/// Periodically executes logic. Is not guaranteed to run within a specific timeframe and should +/// only be used on logic that has no deadline. +pub trait OnPoll { + /// Code to execute every now and then at the beginning of the block after inherent application. + /// + /// The remaining weight limit must be respected. + fn on_poll(_n: BlockNumber, _weight: &mut WeightMeter) {} +} + +#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))] +#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))] +#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))] +impl OnPoll for Tuple { + fn on_poll(n: BlockNumber, weight: &mut WeightMeter) { + for_tuples!( #( Tuple::on_poll(n.clone(), weight); )* ); + } +} + /// See [`Hooks::on_initialize`]. pub trait OnInitialize { /// See [`Hooks::on_initialize`]. @@ -374,6 +438,12 @@ pub trait Hooks { Weight::zero() } + /// A hook to run logic after inherent application. + /// + /// Is not guaranteed to execute in a block and should therefore only be used in no-deadline + /// scenarios. + fn on_poll(_n: BlockNumber, _weight: &mut WeightMeter) {} + /// Hook executed when a code change (aka. a "runtime upgrade") is detected by the FRAME /// `Executive` pallet. /// diff --git a/substrate/frame/support/src/traits/misc.rs b/substrate/frame/support/src/traits/misc.rs index eafd9c8abdd..1f634a64282 100644 --- a/substrate/frame/support/src/traits/misc.rs +++ b/substrate/frame/support/src/traits/misc.rs @@ -23,6 +23,7 @@ use impl_trait_for_tuples::impl_for_tuples; use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter}; use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, One, Saturating}; use sp_core::bounded::bounded_vec::TruncateFrom; + #[doc(hidden)] pub use sp_runtime::traits::{ ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, ConstU32, @@ -895,11 +896,21 @@ pub trait GetBacking { /// A trait to ensure the inherent are before non-inherent in a block. /// /// This is typically implemented on runtime, through `construct_runtime!`. -pub trait EnsureInherentsAreFirst { +pub trait EnsureInherentsAreFirst: + IsInherent<::Extrinsic> +{ /// Ensure the position of inherent is correct, i.e. they are before non-inherents. /// - /// On error return the index of the inherent with invalid position (counting from 0). - fn ensure_inherents_are_first(block: &Block) -> Result<(), u32>; + /// On error return the index of the inherent with invalid position (counting from 0). On + /// success it returns the index of the last inherent. `0` therefore means that there are no + /// inherents. + fn ensure_inherents_are_first(block: &Block) -> Result; +} + +/// A trait to check if an extrinsic is an inherent. +pub trait IsInherent { + /// Whether this extrinsic is an inherent. + fn is_inherent(ext: &Extrinsic) -> bool; } /// An extrinsic on which we can get access to call. diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr index a4c7ecf7865..30005c07cb6 100644 --- a/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr +++ b/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr @@ -53,8 +53,9 @@ error[E0599]: no function or associated item named `is_inherent` found for struc | |_^ function or associated item not found in `Pallet` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `is_inherent`, perhaps you need to implement it: + = note: the following traits define an item `is_inherent`, perhaps you need to implement one of them: candidate #1: `ProvideInherent` + candidate #2: `IsInherent` = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0599]: no function or associated item named `check_inherent` found for struct `pallet::Pallet` in the current scope @@ -119,3 +120,23 @@ error[E0599]: no function or associated item named `is_inherent_required` found = note: the following trait defines an item `is_inherent_required`, perhaps you need to implement it: candidate #1: `ProvideInherent` = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `pallet::Pallet: ProvideInherent` is not satisfied + --> tests/construct_runtime_ui/undefined_inherent_part.rs:70:3 + | +70 | Pallet: pallet expanded::{}::{Pallet, Inherent}, + | ^^^^^^ the trait `ProvideInherent` is not implemented for `pallet::Pallet` + +error[E0277]: the trait bound `pallet::Pallet: ProvideInherent` is not satisfied + --> tests/construct_runtime_ui/undefined_inherent_part.rs:66:1 + | +66 | / construct_runtime! { +67 | | pub struct Runtime +68 | | { +69 | | System: frame_system expanded::{}::{Pallet, Call, Storage, Config, Event}, +70 | | Pallet: pallet expanded::{}::{Pallet, Inherent}, +71 | | } +72 | | } + | |_^ the trait `ProvideInherent` is not implemented for `pallet::Pallet` + | + = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs b/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs index 79e9d678671..33b96dea948 100644 --- a/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs +++ b/substrate/frame/support/test/tests/pallet_outer_enums_explicit.rs @@ -90,6 +90,7 @@ fn module_error_outer_enum_expand_explicit() { frame_system::Error::NonDefaultComposite => (), frame_system::Error::NonZeroRefCount => (), frame_system::Error::CallFiltered => (), + frame_system::Error::MultiBlockMigrationsOngoing => (), #[cfg(feature = "experimental")] frame_system::Error::InvalidTask => (), #[cfg(feature = "experimental")] diff --git a/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs b/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs index 4bd8ee0bb39..db006fe7935 100644 --- a/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs +++ b/substrate/frame/support/test/tests/pallet_outer_enums_implicit.rs @@ -90,6 +90,7 @@ fn module_error_outer_enum_expand_implicit() { frame_system::Error::NonDefaultComposite => (), frame_system::Error::NonZeroRefCount => (), frame_system::Error::CallFiltered => (), + frame_system::Error::MultiBlockMigrationsOngoing => (), #[cfg(feature = "experimental")] frame_system::Error::InvalidTask => (), #[cfg(feature = "experimental")] diff --git a/substrate/frame/support/test/tests/runtime_metadata.rs b/substrate/frame/support/test/tests/runtime_metadata.rs index bb7f7d2822e..40e70b219ba 100644 --- a/substrate/frame/support/test/tests/runtime_metadata.rs +++ b/substrate/frame/support/test/tests/runtime_metadata.rs @@ -101,7 +101,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } @@ -200,8 +200,8 @@ fn runtime_metadata() { name: "header", ty: meta_type::<&::Header>(), }], - output: meta_type::<()>(), - docs: maybe_docs(vec![" Initialize a block with the given header."]), + output: meta_type::(), + docs: maybe_docs(vec![" Initialize a block with the given header and return the runtime executive mode."]), }, ], docs: maybe_docs(vec![ diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 01df09106d9..3b659916379 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -130,11 +130,13 @@ use frame_support::{ DispatchResult, DispatchResultWithPostInfo, PerDispatchClass, PostDispatchInfo, }, ensure, impl_ensure_origin_with_arg_ignoring_arg, + migrations::MultiStepMigrator, pallet_prelude::Pays, storage::{self, StorageStreamIter}, traits::{ ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime, - OnKilledAccount, OnNewAccount, OriginTrait, PalletInfo, SortedMembers, StoredMap, TypedGet, + OnKilledAccount, OnNewAccount, OnRuntimeUpgrade, OriginTrait, PalletInfo, SortedMembers, + StoredMap, TypedGet, }, Parameter, }; @@ -169,6 +171,7 @@ pub use extensions::{ // Backward compatible re-export. pub use extensions::check_mortality::CheckMortality as CheckEra; pub use frame_support::dispatch::RawOrigin; +use frame_support::traits::{PostInherents, PostTransactions, PreInherents}; pub use weights::WeightInfo; const LOG_TARGET: &str = "runtime::system"; @@ -299,6 +302,11 @@ pub mod pallet { type BaseCallFilter = frame_support::traits::Everything; type BlockHashCount = frame_support::traits::ConstU64<10>; type OnSetCode = (); + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); } /// Default configurations of this pallet in a solo-chain environment. @@ -393,6 +401,11 @@ pub mod pallet { /// The set code logic, just the default since we're not a parachain. type OnSetCode = (); + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); } /// Default configurations of this pallet in a relay-chain environment. @@ -572,6 +585,35 @@ pub mod pallet { /// The maximum number of consumers allowed on a single account. type MaxConsumers: ConsumerLimits; + + /// All migrations that should run in the next runtime upgrade. + /// + /// These used to be formerly configured in `Executive`. Parachains need to ensure that + /// running all these migrations in one block will not overflow the weight limit of a block. + /// The migrations are run *before* the pallet `on_runtime_upgrade` hooks, just like the + /// `OnRuntimeUpgrade` migrations. + type SingleBlockMigrations: OnRuntimeUpgrade; + + /// The migrator that is used to run Multi-Block-Migrations. + /// + /// Can be set to [`pallet-migrations`] or an alternative implementation of the interface. + /// The diagram in `frame_executive::block_flowchart` explains when it runs. + type MultiBlockMigrator: MultiStepMigrator; + + /// A callback that executes in *every block* directly before all inherents were applied. + /// + /// See `frame_executive::block_flowchart` for a in-depth explanation when it runs. + type PreInherents: PreInherents; + + /// A callback that executes in *every block* directly after all inherents were applied. + /// + /// See `frame_executive::block_flowchart` for a in-depth explanation when it runs. + type PostInherents: PostInherents; + + /// A callback that executes in *every block* directly after all transactions were applied. + /// + /// See `frame_executive::block_flowchart` for a in-depth explanation when it runs. + type PostTransactions: PostTransactions; } #[pallet::pallet] @@ -619,6 +661,9 @@ pub mod pallet { } /// Set the new runtime code without doing any checks of the given `code`. + /// + /// Note that runtime upgrades will not run if this is called with a not-increasing spec + /// version! #[pallet::call_index(3)] #[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))] pub fn set_code_without_checks( @@ -814,6 +859,8 @@ pub mod pallet { NonZeroRefCount, /// The origin filter prevent the call to be dispatched. CallFiltered, + /// A multi-block migration is ongoing and prevents the current code from being replaced. + MultiBlockMigrationsOngoing, #[cfg(feature = "experimental")] /// The specified [`Task`] is not valid. InvalidTask, @@ -845,6 +892,10 @@ pub mod pallet { #[pallet::storage] pub(super) type ExtrinsicCount = StorageValue<_, u32>; + /// Whether all inherents have been applied. + #[pallet::storage] + pub type InherentsApplied = StorageValue<_, bool, ValueQuery>; + /// The current weight for the block. #[pallet::storage] #[pallet::whitelist_storage] @@ -1373,6 +1424,19 @@ impl Pallet { Self::deposit_event(Event::CodeUpdated); } + /// Whether all inherents have been applied. + pub fn inherents_applied() -> bool { + InherentsApplied::::get() + } + + /// Note that all inherents have been applied. + /// + /// Should be called immediately after all inherents have been applied. Must be called at least + /// once per block. + pub fn note_inherents_applied() { + InherentsApplied::::put(true); + } + /// Increment the reference counter on an account. #[deprecated = "Use `inc_consumers` instead"] pub fn inc_ref(who: &T::AccountId) { @@ -1692,6 +1756,7 @@ impl Pallet { >::put(digest); >::put(parent_hash); >::insert(*number - One::one(), parent_hash); + >::kill(); // Remove previous block data from storage BlockWeight::::kill(); @@ -1738,6 +1803,7 @@ impl Pallet { ExecutionPhase::::kill(); AllExtrinsicsLen::::kill(); storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY); + InherentsApplied::::kill(); // The following fields // @@ -1981,10 +2047,14 @@ impl Pallet { /// Determine whether or not it is possible to update the code. /// - /// Checks the given code if it is a valid runtime wasm blob by instantianting + /// Checks the given code if it is a valid runtime wasm blob by instantiating /// it and extracting the runtime version of it. It checks that the runtime version /// of the old and new runtime has the same spec name and that the spec version is increasing. pub fn can_set_code(code: &[u8]) -> Result<(), sp_runtime::DispatchError> { + if T::MultiBlockMigrator::ongoing() { + return Err(Error::::MultiBlockMigrationsOngoing.into()) + } + let current_version = T::Version::get(); let new_version = sp_io::misc::runtime_version(code) .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) diff --git a/substrate/frame/system/src/mock.rs b/substrate/frame/system/src/mock.rs index c4108099e39..7059845a7df 100644 --- a/substrate/frame/system/src/mock.rs +++ b/substrate/frame/system/src/mock.rs @@ -86,6 +86,22 @@ impl Config for Test { type Version = Version; type AccountData = u32; type OnKilledAccount = RecordKilled; + type MultiBlockMigrator = MockedMigrator; +} + +parameter_types! { + pub static Ongoing: bool = false; +} + +pub struct MockedMigrator; +impl frame_support::migrations::MultiStepMigrator for MockedMigrator { + fn ongoing() -> bool { + Ongoing::get() + } + + fn step() -> Weight { + Weight::zero() + } } pub type SysEvent = frame_system::Event; diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs index e437e7f9f39..b889b5ca046 100644 --- a/substrate/frame/system/src/tests.rs +++ b/substrate/frame/system/src/tests.rs @@ -675,6 +675,28 @@ fn set_code_with_real_wasm_blob() { }); } +#[test] +fn set_code_rejects_during_mbm() { + Ongoing::set(true); + + let executor = substrate_test_runtime_client::new_native_or_wasm_executor(); + let mut ext = new_test_ext(); + ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new(executor)); + ext.execute_with(|| { + System::set_block_number(1); + let res = System::set_code( + RawOrigin::Root.into(), + substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec(), + ); + assert_eq!( + res, + Err(DispatchErrorWithPostInfo::from(Error::::MultiBlockMigrationsOngoing)) + ); + + assert!(System::events().is_empty()); + }); +} + #[test] fn set_code_via_authorization_works() { let executor = substrate_test_runtime_client::new_native_or_wasm_executor(); diff --git a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs index 2b1e65ec885..e34e4c0e767 100644 --- a/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -456,6 +456,7 @@ impl<'a> ToClientSideDecl<'a> { |err| #crate_::ApiError::FailedToDecodeReturnValue { function: #function_name, error: err, + raw: r.clone(), } ) ) diff --git a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs index c1339ff6621..1761e0ac9db 100644 --- a/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -158,7 +158,7 @@ fn implement_common_api_traits(block_type: TypePath, self_ty: Type) -> Result::Hash, _: &<#block_type as #crate_::BlockT>::Header, - ) -> std::result::Result<(), #crate_::ApiError> { + ) -> std::result::Result<#crate_::__private::ExtrinsicInclusionMode, #crate_::ApiError> { unimplemented!("`Core::initialize_block` not implemented for runtime api mocks") } } diff --git a/substrate/primitives/api/src/lib.rs b/substrate/primitives/api/src/lib.rs index 190de1ab3fd..a945b9f21f3 100644 --- a/substrate/primitives/api/src/lib.rs +++ b/substrate/primitives/api/src/lib.rs @@ -101,7 +101,7 @@ pub mod __private { generic::BlockId, traits::{Block as BlockT, Hash as HashT, HashingFor, Header as HeaderT, NumberFor}, transaction_validity::TransactionValidity, - RuntimeString, TransactionOutcome, + ExtrinsicInclusionMode, RuntimeString, TransactionOutcome, }; pub use sp_std::{mem, slice, vec}; pub use sp_version::{create_apis_vec, ApiId, ApisVec, RuntimeVersion}; @@ -115,11 +115,11 @@ pub use sp_core::traits::CallContext; use sp_core::OpaqueMetadata; #[cfg(feature = "std")] use sp_externalities::{Extension, Extensions}; -use sp_runtime::traits::Block as BlockT; #[cfg(feature = "std")] use sp_runtime::traits::HashingFor; #[cfg(feature = "std")] pub use sp_runtime::TransactionOutcome; +use sp_runtime::{traits::Block as BlockT, ExtrinsicInclusionMode}; #[cfg(feature = "std")] pub use sp_state_machine::StorageProof; #[cfg(feature = "std")] @@ -280,7 +280,7 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// ```rust /// use sp_version::create_runtime_str; /// # -/// # use sp_runtime::traits::Block as BlockT; +/// # use sp_runtime::{ExtrinsicInclusionMode, traits::Block as BlockT}; /// # use sp_test_primitives::Block; /// # /// # /// The declaration of the `Runtime` type is done by the `construct_runtime!` macro @@ -307,7 +307,9 @@ pub use sp_api_proc_macro::decl_runtime_apis; /// # unimplemented!() /// # } /// # fn execute_block(_block: Block) {} -/// # fn initialize_block(_header: &::Header) {} +/// # fn initialize_block(_header: &::Header) -> ExtrinsicInclusionMode { +/// # unimplemented!() +/// # } /// # } /// /// impl self::Balance for Runtime { @@ -540,11 +542,12 @@ pub fn init_runtime_logger() { #[cfg(feature = "std")] #[derive(Debug, thiserror::Error)] pub enum ApiError { - #[error("Failed to decode return value of {function}")] + #[error("Failed to decode return value of {function}: {error} raw data: {raw:?}")] FailedToDecodeReturnValue { function: &'static str, #[source] error: codec::Error, + raw: Vec, }, #[error("Failed to convert return value from runtime to node of {function}")] FailedToConvertReturnValue { @@ -800,15 +803,18 @@ pub fn deserialize_runtime_api_info(bytes: [u8; RUNTIME_API_INFO_SIZE]) -> ([u8; decl_runtime_apis! { /// The `Core` runtime api that every Substrate runtime needs to implement. #[core_trait] - #[api_version(4)] + #[api_version(5)] pub trait Core { /// Returns the version of the runtime. fn version() -> RuntimeVersion; /// Execute the given block. fn execute_block(block: Block); /// Initialize a block with the given header. + #[changed_in(5)] #[renamed("initialise_block", 2)] fn initialize_block(header: &::Header); + /// Initialize a block with the given header and return the runtime executive mode. + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode; } /// The `Metadata` api trait that returns metadata for the runtime. diff --git a/substrate/primitives/api/test/tests/decl_and_impl.rs b/substrate/primitives/api/test/tests/decl_and_impl.rs index d68470551d2..211a08561fd 100644 --- a/substrate/primitives/api/test/tests/decl_and_impl.rs +++ b/substrate/primitives/api/test/tests/decl_and_impl.rs @@ -139,7 +139,7 @@ impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs b/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs index 43718e4cd04..262a874213a 100644 --- a/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs +++ b/substrate/primitives/api/test/tests/ui/impl_incorrect_method_signature.rs @@ -40,7 +40,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/impl_missing_version.rs b/substrate/primitives/api/test/tests/ui/impl_missing_version.rs index 560257b5168..58850ab343f 100644 --- a/substrate/primitives/api/test/tests/ui/impl_missing_version.rs +++ b/substrate/primitives/api/test/tests/ui/impl_missing_version.rs @@ -45,7 +45,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs b/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs index 6ead545f85a..70f75d06515 100644 --- a/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs +++ b/substrate/primitives/api/test/tests/ui/missing_versioned_method.rs @@ -44,7 +44,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs b/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs index 8eebc1d79ba..63032000040 100644 --- a/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs +++ b/substrate/primitives/api/test/tests/ui/missing_versioned_method_multiple_vers.rs @@ -47,7 +47,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs b/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs index 594556d57be..0858813bc99 100644 --- a/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs +++ b/substrate/primitives/api/test/tests/ui/positive_cases/custom_where_bound.rs @@ -51,7 +51,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs b/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs index ae573238ffe..3e0cb79156c 100644 --- a/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs +++ b/substrate/primitives/api/test/tests/ui/positive_cases/default_impls.rs @@ -46,7 +46,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs b/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs index 921bf0d0435..b2caea7ab7e 100644 --- a/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs +++ b/substrate/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.rs @@ -42,7 +42,7 @@ sp_api::impl_runtime_apis! { fn execute_block(_: Block) { unimplemented!() } - fn initialize_block(_: &::Header) { + fn initialize_block(_: &::Header) -> sp_runtime::ExtrinsicInclusionMode { unimplemented!() } } diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs index ddf92554c83..44bf3c969e5 100644 --- a/substrate/primitives/runtime/src/lib.rs +++ b/substrate/primitives/runtime/src/lib.rs @@ -998,6 +998,16 @@ impl TransactionOutcome { } } +/// Confines the kind of extrinsics that can be included in a block. +#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo)] +pub enum ExtrinsicInclusionMode { + /// All extrinsics are allowed to be included in this block. + #[default] + AllExtrinsics, + /// Inherents are allowed to be included. + OnlyInherents, +} + #[cfg(test)] mod tests { use crate::traits::BlakeTwo256; diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs index db9ff187b70..63e0aa6e137 100644 --- a/substrate/test-utils/runtime/src/lib.rs +++ b/substrate/test-utils/runtime/src/lib.rs @@ -61,7 +61,7 @@ use sp_runtime::{ create_runtime_str, impl_opaque_keys, traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, NumberFor, Verify}, transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, - ApplyExtrinsicResult, Perbill, + ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill, }; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; @@ -480,9 +480,9 @@ impl_runtime_apis! { Executive::execute_block(block); } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode { log::trace!(target: LOG_TARGET, "initialize_block: {header:#?}"); - Executive::initialize_block(header); + Executive::initialize_block(header) } } -- GitLab From 833bafdbf7b178b639f895e0d43c43eb502de30c Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Thu, 29 Feb 2024 01:43:53 +0200 Subject: [PATCH 275/283] Fixup multi-collator parachain transition to async backing (#3510) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing: ``` Verification failed for block 0x07bbf1e04121d70a4bdb21cc055132b53ac2390fa95c4d05497fc91b1e8bf7f5 received from (12D3KooWJzLd8skcAgA24EcJey7aJAhYctfUxWGjSP5Usk9wbpPZ): "Header 0x07bbf1e04121d70a4bdb21cc055132b53ac2390fa95c4d05497fc91b1e8bf7f5 rejected: too far in the future" ``` --------- Signed-off-by: Alexandru Gheorghe Co-authored-by: Dmitry Sinyavin Co-authored-by: s0me0ne-unkn0wn <48632512+s0me0ne-unkn0wn@users.noreply.github.com> Co-authored-by: Bastian Köcher --- cumulus/client/consensus/aura/src/lib.rs | 5 ++- cumulus/polkadot-parachain/src/service.rs | 33 +++++++++++-------- prdoc/pr_3510.prdoc | 13 ++++++++ .../bin/node-template/node/src/service.rs | 26 +++++++++------ 4 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 prdoc/pr_3510.prdoc diff --git a/cumulus/client/consensus/aura/src/lib.rs b/cumulus/client/consensus/aura/src/lib.rs index 8e4bc658e44..ed6f5bdd4d6 100644 --- a/cumulus/client/consensus/aura/src/lib.rs +++ b/cumulus/client/consensus/aura/src/lib.rs @@ -54,7 +54,10 @@ use std::{ mod import_queue; pub use import_queue::{build_verifier, import_queue, BuildVerifierParams, ImportQueueParams}; -pub use sc_consensus_aura::{slot_duration, AuraVerifier, BuildAuraWorkerParams, SlotProportion}; +pub use sc_consensus_aura::{ + slot_duration, standalone::slot_duration_at, AuraVerifier, BuildAuraWorkerParams, + SlotProportion, +}; pub use sc_consensus_slots::InherentDataProviderExt; pub mod collator; diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index 4e06cd38f1d..386551102e4 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -1251,28 +1251,33 @@ where <::Pair as Pair>::Signature: TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, { - let client2 = client.clone(); + let verifier_client = client.clone(); let aura_verifier = move || { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client2).unwrap(); - Box::new(cumulus_client_consensus_aura::build_verifier::< ::Pair, _, _, _, >(cumulus_client_consensus_aura::BuildVerifierParams { - client: client2.clone(), - create_inherent_data_providers: move |_, _| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - - Ok((slot, timestamp)) + client: verifier_client.clone(), + create_inherent_data_providers: move |parent_hash, _| { + let cidp_client = verifier_client.clone(); + async move { + let slot_duration = cumulus_client_consensus_aura::slot_duration_at( + &*cidp_client, + parent_hash, + )?; + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((slot, timestamp)) + } }, telemetry: telemetry_handle, })) as Box<_> diff --git a/prdoc/pr_3510.prdoc b/prdoc/pr_3510.prdoc new file mode 100644 index 00000000000..6ee2f9a81f7 --- /dev/null +++ b/prdoc/pr_3510.prdoc @@ -0,0 +1,13 @@ +title: "Fix multi-collator parachain transition to async backing" + +doc: + - audience: Node Operator + description: | + The dynamic Aura slot duration, introduced in PR#3211, didn't take the block import pipeline + into account. The result was the parachain backed by multiple collators not being able to + keep producing blocks after its runtime was upgraded to support async backing, requiring to + restart all the collator nodes. This change fixes the issue, introducing the dynamic Aura + slot duration into the block import pipeline. + +crates: + - name: "polkadot-parachain-bin" diff --git a/substrate/bin/node-template/node/src/service.rs b/substrate/bin/node-template/node/src/service.rs index 25cd6511784..125cca13927 100644 --- a/substrate/bin/node-template/node/src/service.rs +++ b/substrate/bin/node-template/node/src/service.rs @@ -80,23 +80,29 @@ pub fn new_partial(config: &Configuration) -> Result { telemetry.as_ref().map(|x| x.handle()), )?; - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - + let cidp_client = client.clone(); let import_queue = sc_consensus_aura::import_queue::(ImportQueueParams { block_import: grandpa_block_import.clone(), justification_import: Some(Box::new(grandpa_block_import.clone())), client: client.clone(), - create_inherent_data_providers: move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + create_inherent_data_providers: move |parent_hash, _| { + let cidp_client = cidp_client.clone(); + async move { + let slot_duration = sc_consensus_aura::standalone::slot_duration_at( + &*cidp_client, + parent_hash, + )?; + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); - Ok((slot, timestamp)) + Ok((slot, timestamp)) + } }, spawner: &task_manager.spawn_essential_handle(), registry: config.prometheus_registry(), -- GitLab From a22319cdd5fcdcec3bbedfe41f6d11a6b5446cf9 Mon Sep 17 00:00:00 2001 From: philoniare Date: Thu, 29 Feb 2024 13:17:24 +0800 Subject: [PATCH 276/283] [Deprecation] Remove sp_weights::OldWeight (#3491) # Description *Removes `sp_weights::OldWeight` and its usage* Fixes #144 --------- Co-authored-by: Liam Aharon --- prdoc/pr_3491.prdoc | 12 +++ substrate/frame/contracts/src/wasm/mod.rs | 11 --- substrate/primitives/weights/src/lib.rs | 27 +------ .../primitives/weights/src/weight_meter.rs | 81 ++++++++----------- 4 files changed, 47 insertions(+), 84 deletions(-) create mode 100644 prdoc/pr_3491.prdoc diff --git a/prdoc/pr_3491.prdoc b/prdoc/pr_3491.prdoc new file mode 100644 index 00000000000..e36afb916a6 --- /dev/null +++ b/prdoc/pr_3491.prdoc @@ -0,0 +1,12 @@ +# 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: Remove Deprecated OldWeight + +doc: + - audience: Runtime Dev + description: | + Removed deprecated sp_weights::OldWeight type. Use [`weight_v2::Weight`] instead. + +crates: + - name: frame-support diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs index c96c2856509..34b45cba5d2 100644 --- a/substrate/frame/contracts/src/wasm/mod.rs +++ b/substrate/frame/contracts/src/wasm/mod.rs @@ -1821,17 +1821,6 @@ mod tests { assert!(weight_left.all_gt(actual_left), "gas_left must be greater than final"); } - /// Test that [`frame_support::weights::OldWeight`] en/decodes the same as our - /// [`crate::OldWeight`]. - #[test] - fn old_weight_decode() { - #![allow(deprecated)] - let sp = frame_support::weights::OldWeight(42).encode(); - let our = crate::OldWeight::decode(&mut &*sp).unwrap(); - - assert_eq!(our, 42); - } - const CODE_VALUE_TRANSFERRED: &str = r#" (module (import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32))) diff --git a/substrate/primitives/weights/src/lib.rs b/substrate/primitives/weights/src/lib.rs index aede9473535..b2c956266e2 100644 --- a/substrate/primitives/weights/src/lib.rs +++ b/substrate/primitives/weights/src/lib.rs @@ -18,9 +18,6 @@ //! # Primitives for transaction weighting. #![cfg_attr(not(feature = "std"), no_std)] -// TODO remove once `OldWeight` is gone. I dont know why this is needed, maybe by one of the macros -// of `OldWeight`. -#![allow(deprecated)] extern crate self as sp_weights; @@ -28,7 +25,7 @@ mod weight_meter; mod weight_v2; use bounded_collections::Get; -use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; +use codec::{Decode, Encode}; use scale_info::TypeInfo; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -52,28 +49,6 @@ pub mod constants { pub const WEIGHT_PROOF_SIZE_PER_KB: u64 = 1024; } -/// The old weight type. -/// -/// NOTE: This type exists purely for compatibility purposes! Use [`weight_v2::Weight`] in all other -/// cases. -#[derive( - Decode, - Encode, - CompactAs, - PartialEq, - Eq, - Clone, - Copy, - RuntimeDebug, - Default, - MaxEncodedLen, - TypeInfo, -)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(transparent))] -#[deprecated(note = "Will be removed soon; use `Weight` instead.")] -pub struct OldWeight(pub u64); - /// The weight of database operations that the runtime can invoke. /// /// NOTE: This is currently only measured in computational time, and will probably diff --git a/substrate/primitives/weights/src/weight_meter.rs b/substrate/primitives/weights/src/weight_meter.rs index 1738948e4c3..cfe8396ae6d 100644 --- a/substrate/primitives/weights/src/weight_meter.rs +++ b/substrate/primitives/weights/src/weight_meter.rs @@ -118,13 +118,6 @@ impl WeightMeter { debug_assert!(self.consumed.all_lte(self.limit), "Weight counter overflow"); } - /// Consume the given weight after checking that it can be consumed and return `true`. Otherwise - /// do nothing and return `false`. - #[deprecated(note = "Use `try_consume` instead. Will be removed after December 2023.")] - pub fn check_accrue(&mut self, w: Weight) -> bool { - self.try_consume(w).is_ok() - } - /// Consume the given weight after checking that it can be consumed. /// /// Returns `Ok` if the weight can be consumed or otherwise an `Err`. @@ -139,12 +132,6 @@ impl WeightMeter { }) } - /// Check if the given weight can be consumed. - #[deprecated(note = "Use `can_consume` instead. Will be removed after December 2023.")] - pub fn can_accrue(&self, w: Weight) -> bool { - self.can_consume(w) - } - /// Check if the given weight can be consumed. pub fn can_consume(&self, w: Weight) -> bool { self.consumed.checked_add(&w).map_or(false, |t| t.all_lte(self.limit)) @@ -165,80 +152,80 @@ mod tests { fn weight_meter_remaining_works() { let mut meter = WeightMeter::with_limit(Weight::from_parts(10, 20)); - assert!(meter.check_accrue(Weight::from_parts(5, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(5, 0)), Ok(())); assert_eq!(meter.consumed, Weight::from_parts(5, 0)); assert_eq!(meter.remaining(), Weight::from_parts(5, 20)); - assert!(meter.check_accrue(Weight::from_parts(2, 10))); + assert_eq!(meter.try_consume(Weight::from_parts(2, 10)), Ok(())); assert_eq!(meter.consumed, Weight::from_parts(7, 10)); assert_eq!(meter.remaining(), Weight::from_parts(3, 10)); - assert!(meter.check_accrue(Weight::from_parts(3, 10))); + assert_eq!(meter.try_consume(Weight::from_parts(3, 10)), Ok(())); assert_eq!(meter.consumed, Weight::from_parts(10, 20)); assert_eq!(meter.remaining(), Weight::from_parts(0, 0)); } #[test] - fn weight_meter_can_accrue_works() { + fn weight_meter_can_consume_works() { let meter = WeightMeter::with_limit(Weight::from_parts(1, 1)); - assert!(meter.can_accrue(Weight::from_parts(0, 0))); - assert!(meter.can_accrue(Weight::from_parts(1, 1))); - assert!(!meter.can_accrue(Weight::from_parts(0, 2))); - assert!(!meter.can_accrue(Weight::from_parts(2, 0))); - assert!(!meter.can_accrue(Weight::from_parts(2, 2))); + assert!(meter.can_consume(Weight::from_parts(0, 0))); + assert!(meter.can_consume(Weight::from_parts(1, 1))); + assert!(!meter.can_consume(Weight::from_parts(0, 2))); + assert!(!meter.can_consume(Weight::from_parts(2, 0))); + assert!(!meter.can_consume(Weight::from_parts(2, 2))); } #[test] - fn weight_meter_check_accrue_works() { + fn weight_meter_try_consume_works() { let mut meter = WeightMeter::with_limit(Weight::from_parts(2, 2)); - assert!(meter.check_accrue(Weight::from_parts(0, 0))); - assert!(meter.check_accrue(Weight::from_parts(1, 1))); - assert!(!meter.check_accrue(Weight::from_parts(0, 2))); - assert!(!meter.check_accrue(Weight::from_parts(2, 0))); - assert!(!meter.check_accrue(Weight::from_parts(2, 2))); - assert!(meter.check_accrue(Weight::from_parts(0, 1))); - assert!(meter.check_accrue(Weight::from_parts(1, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 0)), Ok(())); + assert_eq!(meter.try_consume(Weight::from_parts(1, 1)), Ok(())); + assert_eq!(meter.try_consume(Weight::from_parts(0, 2)), Err(())); + assert_eq!(meter.try_consume(Weight::from_parts(2, 0)), Err(())); + assert_eq!(meter.try_consume(Weight::from_parts(2, 2)), Err(())); + assert_eq!(meter.try_consume(Weight::from_parts(0, 1)), Ok(())); + assert_eq!(meter.try_consume(Weight::from_parts(1, 0)), Ok(())); } #[test] - fn weight_meter_check_and_can_accrue_works() { + fn weight_meter_check_and_can_consume_works() { let mut meter = WeightMeter::new(); - assert!(meter.can_accrue(Weight::from_parts(u64::MAX, 0))); - assert!(meter.check_accrue(Weight::from_parts(u64::MAX, 0))); + assert!(meter.can_consume(Weight::from_parts(u64::MAX, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(u64::MAX, 0)), Ok(())); - assert!(meter.can_accrue(Weight::from_parts(0, u64::MAX))); - assert!(meter.check_accrue(Weight::from_parts(0, u64::MAX))); + assert!(meter.can_consume(Weight::from_parts(0, u64::MAX))); + assert_eq!(meter.try_consume(Weight::from_parts(0, u64::MAX)), Ok(())); - assert!(!meter.can_accrue(Weight::from_parts(0, 1))); - assert!(!meter.check_accrue(Weight::from_parts(0, 1))); + assert!(!meter.can_consume(Weight::from_parts(0, 1))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 1)), Err(())); - assert!(!meter.can_accrue(Weight::from_parts(1, 0))); - assert!(!meter.check_accrue(Weight::from_parts(1, 0))); + assert!(!meter.can_consume(Weight::from_parts(1, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(1, 0)), Err(())); - assert!(meter.can_accrue(Weight::zero())); - assert!(meter.check_accrue(Weight::zero())); + assert!(meter.can_consume(Weight::zero())); + assert_eq!(meter.try_consume(Weight::zero()), Ok(())); } #[test] fn consumed_ratio_works() { let mut meter = WeightMeter::with_limit(Weight::from_parts(10, 20)); - assert!(meter.check_accrue(Weight::from_parts(5, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(5, 0)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(50)); - assert!(meter.check_accrue(Weight::from_parts(0, 12))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 12)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(60)); - assert!(meter.check_accrue(Weight::from_parts(2, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(2, 0)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(70)); - assert!(meter.check_accrue(Weight::from_parts(0, 4))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 4)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(80)); - assert!(meter.check_accrue(Weight::from_parts(3, 0))); + assert_eq!(meter.try_consume(Weight::from_parts(3, 0)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); - assert!(meter.check_accrue(Weight::from_parts(0, 4))); + assert_eq!(meter.try_consume(Weight::from_parts(0, 4)), Ok(())); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); } -- GitLab From a035dc9be718c6327420c87fecb7a752954492f4 Mon Sep 17 00:00:00 2001 From: Tsvetomir Dimitrov Date: Thu, 29 Feb 2024 09:12:02 +0200 Subject: [PATCH 277/283] Remove `AssignmentProviderConfig` and use parameters from `HostConfiguration` instead (#3181) This PR removes `AssignmentProviderConfig` and uses the corresponding ondemand parameters from `HostConfiguration` instead. Additionally `scheduling_lookahead` and all coretime/ondemand related parameters are extracted in a separate struct - `SchedulerParams`. The most relevant commit from the PR is [this one](https://github.com/paritytech/polkadot-sdk/pull/3181/commits/830bc0f5e858944474171bbe33382ad96040b535). Fixes https://github.com/paritytech/polkadot-sdk/issues/2268 --------- Co-authored-by: command-bot <> --- .../zombienet/tests/0002-pov_recovery.toml | 2 +- polkadot/node/service/src/chain_spec.rs | 16 +- polkadot/node/test/service/src/chain_spec.rs | 11 +- polkadot/primitives/src/vstaging/mod.rs | 76 ++++ .../implementers-guide/src/types/runtime.md | 118 +----- .../src/assigner_coretime/mock_helpers.rs | 11 +- .../parachains/src/assigner_coretime/mod.rs | 16 +- .../src/assigner_on_demand/benchmarking.rs | 2 +- .../src/assigner_on_demand/mock_helpers.rs | 11 +- .../parachains/src/assigner_on_demand/mod.rs | 18 +- .../parachains/src/assigner_parachains.rs | 12 +- .../src/assigner_parachains/mock_helpers.rs | 11 +- polkadot/runtime/parachains/src/builder.rs | 19 +- .../runtime/parachains/src/configuration.rs | 133 +++---- .../src/configuration/benchmarking.rs | 2 + .../parachains/src/configuration/migration.rs | 1 + .../src/configuration/migration/v11.rs | 113 +++++- .../src/configuration/migration/v12.rs | 349 ++++++++++++++++++ .../parachains/src/configuration/tests.rs | 51 ++- .../parachains/src/coretime/migration.rs | 19 +- .../runtime/parachains/src/coretime/mod.rs | 4 +- .../runtime/parachains/src/inclusion/tests.rs | 10 +- polkadot/runtime/parachains/src/mock.rs | 23 +- .../runtime/parachains/src/paras/tests.rs | 7 +- .../parachains/src/paras_inherent/tests.rs | 11 +- polkadot/runtime/parachains/src/scheduler.rs | 43 +-- .../parachains/src/scheduler/common.rs | 19 +- .../runtime/parachains/src/scheduler/tests.rs | 81 ++-- .../parachains/src/session_info/tests.rs | 4 +- polkadot/runtime/rococo/src/lib.rs | 1 + .../runtime_parachains_configuration.rs | 50 ++- polkadot/runtime/westend/src/lib.rs | 1 + .../runtime_parachains_configuration.rs | 50 ++- .../functional/0002-parachains-disputes.toml | 4 +- .../0004-parachains-garbage-candidate.toml | 4 +- ...0005-parachains-disputes-past-session.toml | 4 +- .../0006-parachains-max-tranche0.toml | 4 +- .../0007-dispute-freshly-finalized.toml | 4 +- .../0008-dispute-old-finalized.toml | 4 +- .../functional/0010-validator-disabling.toml | 4 +- .../0011-async-backing-6-seconds-rate.toml | 7 +- .../functional/0012-elastic-scaling-mvp.toml | 6 +- .../zombienet_tests/misc/0001-paritydb.toml | 4 +- 43 files changed, 901 insertions(+), 439 deletions(-) create mode 100644 polkadot/runtime/parachains/src/configuration/migration/v12.rs diff --git a/cumulus/zombienet/tests/0002-pov_recovery.toml b/cumulus/zombienet/tests/0002-pov_recovery.toml index fe42fd4b2f6..15a61eba2a0 100644 --- a/cumulus/zombienet/tests/0002-pov_recovery.toml +++ b/cumulus/zombienet/tests/0002-pov_recovery.toml @@ -4,7 +4,7 @@ default_command = "polkadot" chain = "rococo-local" -[relaychain.genesis.runtimeGenesis.patch.configuration.config] +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] # set parameters such that collators only connect to 1 validator as a backing group max_validators_per_core = 1 group_rotation_frequency = 100 # 10 mins diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index af241d1cbc5..af05af87a46 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -24,6 +24,8 @@ use polkadot_primitives::{AccountId, AccountPublic, AssignmentId, ValidatorId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_consensus_babe::AuthorityId as BabeId; +#[cfg(any(feature = "rococo-native", feature = "westend-native",))] +use polkadot_primitives::vstaging::SchedulerParams; #[cfg(feature = "rococo-native")] use rococo_runtime as rococo; #[cfg(feature = "rococo-native")] @@ -129,8 +131,6 @@ fn default_parachains_host_configuration( max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, - group_rotation_frequency: 20, - paras_availability_period: 4, max_upward_queue_count: 8, max_upward_queue_size: 1024 * 1024, max_downward_message_size: 1024 * 1024, @@ -151,11 +151,16 @@ fn default_parachains_host_configuration( relay_vrf_modulo_samples: 2, zeroth_delay_tranche_width: 0, minimum_validation_upgrade_delay: 5, - scheduling_lookahead: 2, async_backing_params: AsyncBackingParams { max_candidate_depth: 3, allowed_ancestry_len: 2, }, + scheduler_params: SchedulerParams { + lookahead: 2, + group_rotation_frequency: 20, + paras_availability_period: 4, + ..Default::default() + }, ..Default::default() } } @@ -891,7 +896,10 @@ pub fn rococo_testnet_genesis( "sudo": { "key": Some(root_key.clone()) }, "configuration": { "config": polkadot_runtime_parachains::configuration::HostConfiguration { - max_validators_per_core: Some(1), + scheduler_params: SchedulerParams { + max_validators_per_core: Some(1), + ..default_parachains_host_configuration().scheduler_params + }, ..default_parachains_host_configuration() }, }, diff --git a/polkadot/node/test/service/src/chain_spec.rs b/polkadot/node/test/service/src/chain_spec.rs index 4cc387317c3..f14fa9fde58 100644 --- a/polkadot/node/test/service/src/chain_spec.rs +++ b/polkadot/node/test/service/src/chain_spec.rs @@ -19,7 +19,9 @@ use babe_primitives::AuthorityId as BabeId; use grandpa::AuthorityId as GrandpaId; use pallet_staking::Forcing; -use polkadot_primitives::{AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE}; +use polkadot_primitives::{ + vstaging::SchedulerParams, AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE, +}; use polkadot_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions}; use polkadot_test_runtime::BABE_GENESIS_EPOCH_CONFIG; use sc_chain_spec::{ChainSpec, ChainType}; @@ -165,11 +167,14 @@ fn polkadot_testnet_genesis( max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, - group_rotation_frequency: 20, - paras_availability_period: 4, no_show_slots: 10, minimum_validation_upgrade_delay: 5, max_downward_message_size: 1024, + scheduler_params: SchedulerParams { + group_rotation_frequency: 20, + paras_availability_period: 4, + ..Default::default() + }, ..Default::default() }, } diff --git a/polkadot/primitives/src/vstaging/mod.rs b/polkadot/primitives/src/vstaging/mod.rs index 39d9dfc02c5..bd2a5106c44 100644 --- a/polkadot/primitives/src/vstaging/mod.rs +++ b/polkadot/primitives/src/vstaging/mod.rs @@ -23,6 +23,7 @@ use sp_std::prelude::*; use parity_scale_codec::{Decode, Encode}; use primitives::RuntimeDebug; use scale_info::TypeInfo; +use sp_arithmetic::Perbill; /// Approval voting configuration parameters #[derive( @@ -50,6 +51,81 @@ impl Default for ApprovalVotingParams { } } +/// Scheduler configuration parameters. All coretime/ondemand parameters are here. +#[derive( + RuntimeDebug, + Copy, + Clone, + PartialEq, + Encode, + Decode, + TypeInfo, + serde::Serialize, + serde::Deserialize, +)] +pub struct SchedulerParams { + /// How often parachain groups should be rotated across parachains. + /// + /// Must be non-zero. + pub group_rotation_frequency: BlockNumber, + /// Availability timeout for a block on a core, measured in blocks. + /// + /// This is the maximum amount of blocks after a core became occupied that validators have time + /// to make the block available. + /// + /// This value only has effect on group rotations. If backers backed something at the end of + /// their rotation, the occupied core affects the backing group that comes afterwards. We limit + /// the effect one backing group can have on the next to `paras_availability_period` blocks. + /// + /// Within a group rotation there is no timeout as backers are only affecting themselves. + /// + /// Must be at least 1. With a value of 1, the previous group will not be able to negatively + /// affect the following group at the expense of a tight availability timeline at group + /// rotation boundaries. + pub paras_availability_period: BlockNumber, + /// The maximum number of validators to have per core. + /// + /// `None` means no maximum. + pub max_validators_per_core: Option, + /// The amount of blocks ahead to schedule paras. + pub lookahead: u32, + /// How many cores are managed by the coretime chain. + pub num_cores: u32, + /// The max number of times a claim can time out in availability. + pub max_availability_timeouts: u32, + /// The maximum queue size of the pay as you go module. + pub on_demand_queue_max_size: u32, + /// The target utilization of the spot price queue in percentages. + pub on_demand_target_queue_utilization: Perbill, + /// How quickly the fee rises in reaction to increased utilization. + /// The lower the number the slower the increase. + pub on_demand_fee_variability: Perbill, + /// The minimum amount needed to claim a slot in the spot pricing queue. + pub on_demand_base_fee: Balance, + /// The number of blocks a claim stays in the scheduler's claimqueue before getting cleared. + /// This number should go reasonably higher than the number of blocks in the async backing + /// lookahead. + pub ttl: BlockNumber, +} + +impl> Default for SchedulerParams { + fn default() -> Self { + Self { + group_rotation_frequency: 1u32.into(), + paras_availability_period: 1u32.into(), + max_validators_per_core: Default::default(), + lookahead: 1, + num_cores: Default::default(), + max_availability_timeouts: Default::default(), + on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + on_demand_target_queue_utilization: Perbill::from_percent(25), + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_base_fee: 10_000_000u128, + ttl: 5u32.into(), + } + } +} + use bitvec::vec::BitVec; /// Bit indices in the `HostConfiguration.node_features` that correspond to different node features. diff --git a/polkadot/roadmap/implementers-guide/src/types/runtime.md b/polkadot/roadmap/implementers-guide/src/types/runtime.md index 4b97409f8df..1dfabd96db7 100644 --- a/polkadot/roadmap/implementers-guide/src/types/runtime.md +++ b/polkadot/roadmap/implementers-guide/src/types/runtime.md @@ -4,106 +4,24 @@ Types used within the runtime exclusively and pervasively. ## Host Configuration -The internal-to-runtime configuration of the parachain host. This is expected to be altered only by governance procedures. - -```rust -struct HostConfiguration { - /// The minimum period, in blocks, between which parachains can update their validation code. - pub validation_upgrade_cooldown: BlockNumber, - /// The delay, in blocks, before a validation upgrade is applied. - pub validation_upgrade_delay: BlockNumber, - /// How long to keep code on-chain, in blocks. This should be sufficiently long that disputes - /// have concluded. - pub code_retention_period: BlockNumber, - /// The maximum validation code size, in bytes. - pub max_code_size: u32, - /// The maximum head-data size, in bytes. - pub max_head_data_size: u32, - /// The amount of availability cores to dedicate to parathreads (on-demand parachains). - pub parathread_cores: u32, - /// The number of retries that a parathread (on-demand parachain) author has to submit their block. - pub parathread_retries: u32, - /// How often parachain groups should be rotated across parachains. - pub group_rotation_frequency: BlockNumber, - /// The availability period, in blocks, for parachains. This is the amount of blocks - /// after inclusion that validators have to make the block available and signal its availability to - /// the chain. Must be at least 1. - pub chain_availability_period: BlockNumber, - /// The availability period, in blocks, for parathreads (on-demand parachains). Same as the `chain_availability_period`, - /// but a differing timeout due to differing requirements. Must be at least 1. - pub thread_availability_period: BlockNumber, - /// The amount of blocks ahead to schedule on-demand parachains. - pub scheduling_lookahead: u32, - /// The maximum number of validators to have per core. `None` means no maximum. - pub max_validators_per_core: Option, - /// The maximum number of validators to use for parachains, in total. `None` means no maximum. - pub max_validators: Option, - /// The amount of sessions to keep for disputes. - pub dispute_period: SessionIndex, - /// How long after dispute conclusion to accept statements. - pub dispute_post_conclusion_acceptance_period: BlockNumber, - /// The maximum number of dispute spam slots - pub dispute_max_spam_slots: u32, - /// The amount of consensus slots that must pass between submitting an assignment and - /// submitting an approval vote before a validator is considered a no-show. - /// Must be at least 1. - pub no_show_slots: u32, - /// The number of delay tranches in total. - pub n_delay_tranches: u32, - /// The width of the zeroth delay tranche for approval assignments. This many delay tranches - /// beyond 0 are all consolidated to form a wide 0 tranche. - pub zeroth_delay_tranche_width: u32, - /// The number of validators needed to approve a block. - pub needed_approvals: u32, - /// The number of samples to use in `RelayVRFModulo` or `RelayVRFModuloCompact` approval assignment criterions. - pub relay_vrf_modulo_samples: u32, - /// Total number of individual messages allowed in the parachain -> relay-chain message queue. - pub max_upward_queue_count: u32, - /// Total size of messages allowed in the parachain -> relay-chain message queue before which - /// no further messages may be added to it. If it exceeds this then the queue may contain only - /// a single message. - pub max_upward_queue_size: u32, - /// The maximum size of an upward message that can be sent by a candidate. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub max_upward_message_size: u32, - /// The maximum number of messages that a candidate can contain. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub max_upward_message_num_per_candidate: u32, - /// The maximum size of a message that can be put in a downward message queue. - /// - /// Since we require receiving at least one DMP message the obvious upper bound of the size is - /// the PoV size. Of course, there is a lot of other different things that a parachain may - /// decide to do with its PoV so this value in practice will be picked as a fraction of the PoV - /// size. - pub max_downward_message_size: u32, - /// The deposit that the sender should provide for opening an HRMP channel. - pub hrmp_sender_deposit: u32, - /// The deposit that the recipient should provide for accepting opening an HRMP channel. - pub hrmp_recipient_deposit: u32, - /// The maximum number of messages allowed in an HRMP channel at once. - pub hrmp_channel_max_capacity: u32, - /// The maximum total size of messages in bytes allowed in an HRMP channel at once. - pub hrmp_channel_max_total_size: u32, - /// The maximum number of inbound HRMP channels a parachain is allowed to accept. - pub hrmp_max_parachain_inbound_channels: u32, - /// The maximum number of inbound HRMP channels a parathread (on-demand parachain) is allowed to accept. - pub hrmp_max_parathread_inbound_channels: u32, - /// The maximum size of a message that could ever be put into an HRMP channel. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub hrmp_channel_max_message_size: u32, - /// The maximum number of outbound HRMP channels a parachain is allowed to open. - pub hrmp_max_parachain_outbound_channels: u32, - /// The maximum number of outbound HRMP channels a parathread (on-demand parachain) is allowed to open. - pub hrmp_max_parathread_outbound_channels: u32, - /// The maximum number of outbound HRMP messages can be sent by a candidate. - /// - /// This parameter affects the upper bound of size of `CandidateCommitments`. - pub hrmp_max_message_num_per_candidate: u32, -} -``` +The internal-to-runtime configuration of the parachain host is kept in `struct HostConfiguration`. This is expected to +be altered only by governance procedures or via migrations from the Polkadot-SDK codebase. The latest definition of +`HostConfiguration` can be found in the project repo +[here](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/runtime/parachains/src/configuration.rs). Each +parameter has got a doc comment so for any details please refer to the code. + +Some related parameters in `HostConfiguration` are grouped together so that they can be managed easily. These are: +* `async_backing_params` in `struct AsyncBackingParams` +* `executor_params` in `struct ExecutorParams` +* `approval_voting_params` in `struct ApprovalVotingParams` +* `scheduler_params` in `struct SchedulerParams` + +Check the definitions of these structs for further details. + +### Configuration migrations +Modifying `HostConfiguration` requires a storage migration. These migrations are located in the +[`migrations`](https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/runtime/parachains/src/configuration.rs) +subfolder of Polkadot-SDK repo. ## ParaInherentData diff --git a/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs index 71c3f1fa39f..e2ba0b4f7ea 100644 --- a/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs +++ b/polkadot/runtime/parachains/src/assigner_coretime/mock_helpers.rs @@ -64,11 +64,12 @@ impl GenesisConfigBuilder { pub(super) fn build(self) -> MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; - config.coretime_cores = self.on_demand_cores; - config.on_demand_base_fee = self.on_demand_base_fee; - config.on_demand_fee_variability = self.on_demand_fee_variability; - config.on_demand_queue_max_size = self.on_demand_max_queue_size; - config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + config.scheduler_params.num_cores = self.on_demand_cores; + config.scheduler_params.on_demand_base_fee = self.on_demand_base_fee; + config.scheduler_params.on_demand_fee_variability = self.on_demand_fee_variability; + config.scheduler_params.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.scheduler_params.on_demand_target_queue_utilization = + self.on_demand_target_queue_utilization; let paras = &mut genesis.paras.paras; for para_id in self.onboarded_on_demand_chains { diff --git a/polkadot/runtime/parachains/src/assigner_coretime/mod.rs b/polkadot/runtime/parachains/src/assigner_coretime/mod.rs index 9da81dc816c..e2da89fadd4 100644 --- a/polkadot/runtime/parachains/src/assigner_coretime/mod.rs +++ b/polkadot/runtime/parachains/src/assigner_coretime/mod.rs @@ -30,7 +30,7 @@ mod tests; use crate::{ assigner_on_demand, configuration, paras::AssignCoretime, - scheduler::common::{Assignment, AssignmentProvider, AssignmentProviderConfig}, + scheduler::common::{Assignment, AssignmentProvider}, ParaId, }; @@ -316,14 +316,6 @@ impl AssignmentProvider> for Pallet { } } - fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig> { - let config = >::config(); - AssignmentProviderConfig { - max_availability_timeouts: config.on_demand_retries, - ttl: config.on_demand_ttl, - } - } - #[cfg(any(feature = "runtime-benchmarks", test))] fn get_mock_assignment(_: CoreIndex, para_id: primitives::Id) -> Assignment { // Given that we are not tracking anything in `Bulk` assignments, it is safe to always @@ -333,7 +325,7 @@ impl AssignmentProvider> for Pallet { fn session_core_count() -> u32 { let config = >::config(); - config.coretime_cores + config.scheduler_params.num_cores } } @@ -482,8 +474,8 @@ impl AssignCoretime for Pallet { // Add a new core and assign the para to it. let mut config = >::config(); - let core = config.coretime_cores; - config.coretime_cores.saturating_inc(); + let core = config.scheduler_params.num_cores; + config.scheduler_params.num_cores.saturating_inc(); // `assign_coretime` is only called at genesis or by root, so setting the active // config here is fine. diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs b/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs index 5a6060cd2b4..8360e7a78d0 100644 --- a/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs +++ b/polkadot/runtime/parachains/src/assigner_on_demand/benchmarking.rs @@ -43,7 +43,7 @@ where { ParasShared::::set_session_index(SESSION_INDEX); let mut config = HostConfiguration::default(); - config.coretime_cores = 1; + config.scheduler_params.num_cores = 1; ConfigurationPallet::::force_set_active_config(config); let mut parachains = ParachainsCache::new(); ParasPallet::::initialize_para_now( diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs index de30330ac84..f8d1a894f0e 100644 --- a/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs +++ b/polkadot/runtime/parachains/src/assigner_on_demand/mock_helpers.rs @@ -63,11 +63,12 @@ impl GenesisConfigBuilder { pub(super) fn build(self) -> MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; - config.coretime_cores = self.on_demand_cores; - config.on_demand_base_fee = self.on_demand_base_fee; - config.on_demand_fee_variability = self.on_demand_fee_variability; - config.on_demand_queue_max_size = self.on_demand_max_queue_size; - config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + config.scheduler_params.num_cores = self.on_demand_cores; + config.scheduler_params.on_demand_base_fee = self.on_demand_base_fee; + config.scheduler_params.on_demand_fee_variability = self.on_demand_fee_variability; + config.scheduler_params.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.scheduler_params.on_demand_target_queue_utilization = + self.on_demand_target_queue_utilization; let paras = &mut genesis.paras.paras; for para_id in self.onboarded_on_demand_chains { diff --git a/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs b/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs index 1b746e88694..bc450dc7812 100644 --- a/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs +++ b/polkadot/runtime/parachains/src/assigner_on_demand/mod.rs @@ -201,10 +201,10 @@ pub mod pallet { let old_traffic = SpotTraffic::::get(); match Self::calculate_spot_traffic( old_traffic, - config.on_demand_queue_max_size, + config.scheduler_params.on_demand_queue_max_size, Self::queue_size(), - config.on_demand_target_queue_utilization, - config.on_demand_fee_variability, + config.scheduler_params.on_demand_target_queue_utilization, + config.scheduler_params.on_demand_fee_variability, ) { Ok(new_traffic) => { // Only update storage on change @@ -330,8 +330,9 @@ where let traffic = SpotTraffic::::get(); // Calculate spot price - let spot_price: BalanceOf = - traffic.saturating_mul_int(config.on_demand_base_fee.saturated_into::>()); + let spot_price: BalanceOf = traffic.saturating_mul_int( + config.scheduler_params.on_demand_base_fee.saturated_into::>(), + ); // Is the current price higher than `max_amount` ensure!(spot_price.le(&max_amount), Error::::SpotPriceHigherThanMaxAmount); @@ -450,7 +451,10 @@ where OnDemandQueue::::try_mutate(|queue| { // Abort transaction if queue is too large - ensure!(Self::queue_size() < config.on_demand_queue_max_size, Error::::QueueFull); + ensure!( + Self::queue_size() < config.scheduler_params.on_demand_queue_max_size, + Error::::QueueFull + ); match location { QueuePushDirection::Back => queue.push_back(order), QueuePushDirection::Front => queue.push_front(order), @@ -472,7 +476,7 @@ where target: LOG_TARGET, "Failed to fetch the on demand queue size, returning the max size." ); - return config.on_demand_queue_max_size + return config.scheduler_params.on_demand_queue_max_size }, } } diff --git a/polkadot/runtime/parachains/src/assigner_parachains.rs b/polkadot/runtime/parachains/src/assigner_parachains.rs index 34b5d3c1ec5..b5f342563e9 100644 --- a/polkadot/runtime/parachains/src/assigner_parachains.rs +++ b/polkadot/runtime/parachains/src/assigner_parachains.rs @@ -27,7 +27,7 @@ use primitives::CoreIndex; use crate::{ configuration, paras, - scheduler::common::{Assignment, AssignmentProvider, AssignmentProviderConfig}, + scheduler::common::{Assignment, AssignmentProvider}, }; pub use pallet::*; @@ -58,16 +58,6 @@ impl AssignmentProvider> for Pallet { /// this is a no-op in the case of a bulk assignment slot. fn push_back_assignment(_: Assignment) {} - fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig> { - AssignmentProviderConfig { - // The next assignment already goes to the same [`ParaId`], no timeout tracking needed. - max_availability_timeouts: 0, - // The next assignment already goes to the same [`ParaId`], this can be any number - // that's high enough to clear the time it takes to clear backing/availability. - ttl: 10u32.into(), - } - } - #[cfg(any(feature = "runtime-benchmarks", test))] fn get_mock_assignment(_: CoreIndex, para_id: primitives::Id) -> Assignment { Assignment::Bulk(para_id) diff --git a/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs b/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs index e6e9fb074aa..a46e114daea 100644 --- a/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs +++ b/polkadot/runtime/parachains/src/assigner_parachains/mock_helpers.rs @@ -60,11 +60,12 @@ impl GenesisConfigBuilder { pub(super) fn build(self) -> MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; - config.coretime_cores = self.on_demand_cores; - config.on_demand_base_fee = self.on_demand_base_fee; - config.on_demand_fee_variability = self.on_demand_fee_variability; - config.on_demand_queue_max_size = self.on_demand_max_queue_size; - config.on_demand_target_queue_utilization = self.on_demand_target_queue_utilization; + config.scheduler_params.num_cores = self.on_demand_cores; + config.scheduler_params.on_demand_base_fee = self.on_demand_base_fee; + config.scheduler_params.on_demand_fee_variability = self.on_demand_fee_variability; + config.scheduler_params.on_demand_queue_max_size = self.on_demand_max_queue_size; + config.scheduler_params.on_demand_target_queue_utilization = + self.on_demand_target_queue_utilization; let paras = &mut genesis.paras.paras; for para_id in self.onboarded_on_demand_chains { diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 500bc70cfa7..0e4e659fef2 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -18,11 +18,7 @@ use crate::{ configuration, inclusion, initializer, paras, paras::ParaKind, paras_inherent, - scheduler::{ - self, - common::{AssignmentProvider, AssignmentProviderConfig}, - CoreOccupied, ParasEntry, - }, + scheduler::{self, common::AssignmentProvider, CoreOccupied, ParasEntry}, session_info, shared, }; use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; @@ -197,7 +193,10 @@ impl BenchBuilder { /// Maximum number of validators per core (a.k.a. max validators per group). This value is used /// if none is explicitly set on the builder. pub(crate) fn fallback_max_validators_per_core() -> u32 { - configuration::Pallet::::config().max_validators_per_core.unwrap_or(5) + configuration::Pallet::::config() + .scheduler_params + .max_validators_per_core + .unwrap_or(5) } /// Specify a mapping of core index/ para id to the number of dispute statements for the @@ -684,7 +683,7 @@ impl BenchBuilder { // We are currently in Session 0, so these changes will take effect in Session 2. Self::setup_para_ids(used_cores); configuration::ActiveConfig::::mutate(|c| { - c.coretime_cores = used_cores; + c.scheduler_params.num_cores = used_cores; }); let validator_ids = Self::generate_validator_pairs(self.max_validators()); @@ -715,8 +714,7 @@ impl BenchBuilder { let cores = (0..used_cores) .into_iter() .map(|i| { - let AssignmentProviderConfig { ttl, .. } = - scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + let ttl = configuration::Pallet::::config().scheduler_params.ttl; // Load an assignment into provider so that one is present to pop let assignment = ::AssignmentProvider::get_mock_assignment( CoreIndex(i), @@ -731,8 +729,7 @@ impl BenchBuilder { let cores = (0..used_cores) .into_iter() .map(|i| { - let AssignmentProviderConfig { ttl, .. } = - scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + let ttl = configuration::Pallet::::config().scheduler_params.ttl; // Load an assignment into provider so that one is present to pop let assignment = ::AssignmentProvider::get_mock_assignment( diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index b0e9d03df88..364a15215d3 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -29,7 +29,6 @@ use primitives::{ vstaging::{ApprovalVotingParams, NodeFeatures}, AsyncBackingParams, Balance, ExecutorParamError, ExecutorParams, SessionIndex, LEGACY_MIN_BACKING_VOTES, MAX_CODE_SIZE, MAX_HEAD_DATA_SIZE, MAX_POV_SIZE, - ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, }; use sp_runtime::{traits::Zero, Perbill}; use sp_std::prelude::*; @@ -43,6 +42,7 @@ mod benchmarking; pub mod migration; pub use pallet::*; +use primitives::vstaging::SchedulerParams; const LOG_TARGET: &str = "runtime::configuration"; @@ -118,9 +118,9 @@ pub struct HostConfiguration { /// been completed. /// /// Note, there are situations in which `expected_at` in the past. For example, if - /// [`paras_availability_period`](Self::paras_availability_period) is less than the delay set - /// by this field or if PVF pre-check took more time than the delay. In such cases, the upgrade - /// is further at the earliest possible time determined by + /// [`paras_availability_period`](SchedulerParams::paras_availability_period) is less than the + /// delay set by this field or if PVF pre-check took more time than the delay. In such cases, + /// the upgrade is further at the earliest possible time determined by /// [`minimum_validation_upgrade_delay`](Self::minimum_validation_upgrade_delay). /// /// The rationale for this delay has to do with relay-chain reversions. In case there is an @@ -172,48 +172,7 @@ pub struct HostConfiguration { /// How long to keep code on-chain, in blocks. This should be sufficiently long that disputes /// have concluded. pub code_retention_period: BlockNumber, - /// How many cores are managed by the coretime chain. - pub coretime_cores: u32, - /// The number of retries that a on demand author has to submit their block. - pub on_demand_retries: u32, - /// The maximum queue size of the pay as you go module. - pub on_demand_queue_max_size: u32, - /// The target utilization of the spot price queue in percentages. - pub on_demand_target_queue_utilization: Perbill, - /// How quickly the fee rises in reaction to increased utilization. - /// The lower the number the slower the increase. - pub on_demand_fee_variability: Perbill, - /// The minimum amount needed to claim a slot in the spot pricing queue. - pub on_demand_base_fee: Balance, - /// The number of blocks an on demand claim stays in the scheduler's claimqueue before getting - /// cleared. This number should go reasonably higher than the number of blocks in the async - /// backing lookahead. - pub on_demand_ttl: BlockNumber, - /// How often parachain groups should be rotated across parachains. - /// - /// Must be non-zero. - pub group_rotation_frequency: BlockNumber, - /// The minimum availability period, in blocks. - /// - /// This is the minimum amount of blocks after a core became occupied that validators have time - /// to make the block available. - /// - /// This value only has effect on group rotations. If backers backed something at the end of - /// their rotation, the occupied core affects the backing group that comes afterwards. We limit - /// the effect one backing group can have on the next to `paras_availability_period` blocks. - /// - /// Within a group rotation there is no timeout as backers are only affecting themselves. - /// - /// Must be at least 1. With a value of 1, the previous group will not be able to negatively - /// affect the following group at the expense of a tight availability timeline at group - /// rotation boundaries. - pub paras_availability_period: BlockNumber, - /// The amount of blocks ahead to schedule paras. - pub scheduling_lookahead: u32, - /// The maximum number of validators to have per core. - /// - /// `None` means no maximum. - pub max_validators_per_core: Option, + /// The maximum number of validators to use for parachain consensus, period. /// /// `None` means no maximum. @@ -257,7 +216,7 @@ pub struct HostConfiguration { /// scheduled. This number is controlled by this field. /// /// This value should be greater than - /// [`paras_availability_period`](Self::paras_availability_period). + /// [`paras_availability_period`](SchedulerParams::paras_availability_period). pub minimum_validation_upgrade_delay: BlockNumber, /// The minimum number of valid backing statements required to consider a parachain candidate /// backable. @@ -266,6 +225,8 @@ pub struct HostConfiguration { pub node_features: NodeFeatures, /// Params used by approval-voting pub approval_voting_params: ApprovalVotingParams, + /// Scheduler parameters + pub scheduler_params: SchedulerParams, } impl> Default for HostConfiguration { @@ -275,8 +236,6 @@ impl> Default for HostConfiguration> Default for HostConfiguration> Default for HostConfiguration { ZeroMinimumBackingVotes, /// `executor_params` are inconsistent. InconsistentExecutorParams { inner: ExecutorParamError }, + /// TTL should be bigger than lookahead + LookaheadExceedsTTL, } impl HostConfiguration @@ -373,11 +326,11 @@ where pub fn check_consistency(&self) -> Result<(), InconsistentError> { use InconsistentError::*; - if self.group_rotation_frequency.is_zero() { + if self.scheduler_params.group_rotation_frequency.is_zero() { return Err(ZeroGroupRotationFrequency) } - if self.paras_availability_period.is_zero() { + if self.scheduler_params.paras_availability_period.is_zero() { return Err(ZeroParasAvailabilityPeriod) } @@ -399,10 +352,11 @@ where return Err(MaxPovSizeExceedHardLimit { max_pov_size: self.max_pov_size }) } - if self.minimum_validation_upgrade_delay <= self.paras_availability_period { + if self.minimum_validation_upgrade_delay <= self.scheduler_params.paras_availability_period + { return Err(MinimumValidationUpgradeDelayLessThanChainAvailabilityPeriod { minimum_validation_upgrade_delay: self.minimum_validation_upgrade_delay.clone(), - paras_availability_period: self.paras_availability_period.clone(), + paras_availability_period: self.scheduler_params.paras_availability_period.clone(), }) } @@ -447,6 +401,10 @@ where return Err(InconsistentExecutorParams { inner }) } + if self.scheduler_params.ttl < self.scheduler_params.lookahead.into() { + return Err(LookaheadExceedsTTL) + } + Ok(()) } @@ -471,6 +429,7 @@ pub trait WeightInfo { fn set_config_with_executor_params() -> Weight; fn set_config_with_perbill() -> Weight; fn set_node_feature() -> Weight; + fn set_config_with_scheduler_params() -> Weight; } pub struct TestWeightInfo; @@ -499,6 +458,9 @@ impl WeightInfo for TestWeightInfo { fn set_node_feature() -> Weight { Weight::MAX } + fn set_config_with_scheduler_params() -> Weight { + Weight::MAX + } } #[frame_support::pallet] @@ -520,7 +482,8 @@ pub mod pallet { /// v8-v9: /// v9-v10: /// v10-11: - const STORAGE_VERSION: StorageVersion = StorageVersion::new(11); + /// v11-12: + const STORAGE_VERSION: StorageVersion = StorageVersion::new(12); #[pallet::pallet] #[pallet::storage_version(STORAGE_VERSION)] @@ -679,16 +642,16 @@ pub mod pallet { Self::set_coretime_cores_unchecked(new) } - /// Set the number of retries for a particular on demand. + /// Set the max number of times a claim may timeout on a core before it is abandoned #[pallet::call_index(7)] #[pallet::weight(( T::WeightInfo::set_config_with_u32(), DispatchClass::Operational, ))] - pub fn set_on_demand_retries(origin: OriginFor, new: u32) -> DispatchResult { + pub fn set_max_availability_timeouts(origin: OriginFor, new: u32) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_retries = new; + config.scheduler_params.max_availability_timeouts = new; }) } @@ -704,7 +667,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.group_rotation_frequency = new; + config.scheduler_params.group_rotation_frequency = new; }) } @@ -720,7 +683,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.paras_availability_period = new; + config.scheduler_params.paras_availability_period = new; }) } @@ -733,7 +696,7 @@ pub mod pallet { pub fn set_scheduling_lookahead(origin: OriginFor, new: u32) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.scheduling_lookahead = new; + config.scheduler_params.lookahead = new; }) } @@ -749,7 +712,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.max_validators_per_core = new; + config.scheduler_params.max_validators_per_core = new; }) } @@ -1141,7 +1104,7 @@ pub mod pallet { pub fn set_on_demand_base_fee(origin: OriginFor, new: Balance) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_base_fee = new; + config.scheduler_params.on_demand_base_fee = new; }) } @@ -1154,7 +1117,7 @@ pub mod pallet { pub fn set_on_demand_fee_variability(origin: OriginFor, new: Perbill) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_fee_variability = new; + config.scheduler_params.on_demand_fee_variability = new; }) } @@ -1167,7 +1130,7 @@ pub mod pallet { pub fn set_on_demand_queue_max_size(origin: OriginFor, new: u32) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_queue_max_size = new; + config.scheduler_params.on_demand_queue_max_size = new; }) } /// Set the on demand (parathreads) fee variability. @@ -1182,7 +1145,7 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_target_queue_utilization = new; + config.scheduler_params.on_demand_target_queue_utilization = new; }) } /// Set the on demand (parathreads) ttl in the claimqueue. @@ -1194,7 +1157,7 @@ pub mod pallet { pub fn set_on_demand_ttl(origin: OriginFor, new: BlockNumberFor) -> DispatchResult { ensure_root(origin)?; Self::schedule_config_update(|config| { - config.on_demand_ttl = new; + config.scheduler_params.ttl = new; }) } @@ -1244,6 +1207,22 @@ pub mod pallet { config.approval_voting_params = new; }) } + + /// Set scheduler-params. + #[pallet::call_index(55)] + #[pallet::weight(( + T::WeightInfo::set_config_with_scheduler_params(), + DispatchClass::Operational, + ))] + pub fn set_scheduler_params( + origin: OriginFor, + new: SchedulerParams>, + ) -> DispatchResult { + ensure_root(origin)?; + Self::schedule_config_update(|config| { + config.scheduler_params = new; + }) + } } impl Pallet { @@ -1252,7 +1231,7 @@ pub mod pallet { /// To be used if authorization is checked otherwise. pub fn set_coretime_cores_unchecked(new: u32) -> DispatchResult { Self::schedule_config_update(|config| { - config.coretime_cores = new; + config.scheduler_params.num_cores = new; }) } } @@ -1393,7 +1372,7 @@ impl Pallet { let base_config_consistent = base_config.check_consistency().is_ok(); // Now, we need to decide what the new configuration should be. - // We also move the `base_config` to `new_config` to empahsize that the base config was + // We also move the `base_config` to `new_config` to emphasize that the base config was // destroyed by the `updater`. updater(&mut base_config); let new_config = base_config; diff --git a/polkadot/runtime/parachains/src/configuration/benchmarking.rs b/polkadot/runtime/parachains/src/configuration/benchmarking.rs index 67daf1c4598..882b5aab096 100644 --- a/polkadot/runtime/parachains/src/configuration/benchmarking.rs +++ b/polkadot/runtime/parachains/src/configuration/benchmarking.rs @@ -51,6 +51,8 @@ benchmarks! { set_node_feature{}: set_node_feature(RawOrigin::Root, 255, true) + set_config_with_scheduler_params {} : set_scheduler_params(RawOrigin::Root, SchedulerParams::default()) + impl_benchmark_test_suite!( Pallet, crate::mock::new_test_ext(Default::default()), diff --git a/polkadot/runtime/parachains/src/configuration/migration.rs b/polkadot/runtime/parachains/src/configuration/migration.rs index 2838b73092d..87b30b177e7 100644 --- a/polkadot/runtime/parachains/src/configuration/migration.rs +++ b/polkadot/runtime/parachains/src/configuration/migration.rs @@ -18,6 +18,7 @@ pub mod v10; pub mod v11; +pub mod v12; pub mod v6; pub mod v7; pub mod v8; diff --git a/polkadot/runtime/parachains/src/configuration/migration/v11.rs b/polkadot/runtime/parachains/src/configuration/migration/v11.rs index a69061ac138..f6e0e043164 100644 --- a/polkadot/runtime/parachains/src/configuration/migration/v11.rs +++ b/polkadot/runtime/parachains/src/configuration/migration/v11.rs @@ -21,13 +21,122 @@ use frame_support::{ migrations::VersionedMigration, pallet_prelude::*, traits::Defensive, weights::Weight, }; use frame_system::pallet_prelude::BlockNumberFor; -use primitives::{vstaging::ApprovalVotingParams, SessionIndex}; +use primitives::{ + vstaging::ApprovalVotingParams, AsyncBackingParams, ExecutorParams, SessionIndex, + LEGACY_MIN_BACKING_VOTES, ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, +}; use sp_std::vec::Vec; use frame_support::traits::OnRuntimeUpgrade; +use polkadot_core_primitives::Balance; +use primitives::vstaging::NodeFeatures; +use sp_arithmetic::Perbill; use super::v10::V10HostConfiguration; -type V11HostConfiguration = configuration::HostConfiguration; + +#[derive(Clone, Encode, PartialEq, Decode, Debug)] +pub struct V11HostConfiguration { + pub max_code_size: u32, + pub max_head_data_size: u32, + pub max_upward_queue_count: u32, + pub max_upward_queue_size: u32, + pub max_upward_message_size: u32, + pub max_upward_message_num_per_candidate: u32, + pub hrmp_max_message_num_per_candidate: u32, + pub validation_upgrade_cooldown: BlockNumber, + pub validation_upgrade_delay: BlockNumber, + pub async_backing_params: AsyncBackingParams, + pub max_pov_size: u32, + pub max_downward_message_size: u32, + pub hrmp_max_parachain_outbound_channels: u32, + pub hrmp_sender_deposit: Balance, + pub hrmp_recipient_deposit: Balance, + pub hrmp_channel_max_capacity: u32, + pub hrmp_channel_max_total_size: u32, + pub hrmp_max_parachain_inbound_channels: u32, + pub hrmp_channel_max_message_size: u32, + pub executor_params: ExecutorParams, + pub code_retention_period: BlockNumber, + pub coretime_cores: u32, + pub on_demand_retries: u32, + pub on_demand_queue_max_size: u32, + pub on_demand_target_queue_utilization: Perbill, + pub on_demand_fee_variability: Perbill, + pub on_demand_base_fee: Balance, + pub on_demand_ttl: BlockNumber, + pub group_rotation_frequency: BlockNumber, + pub paras_availability_period: BlockNumber, + pub scheduling_lookahead: u32, + pub max_validators_per_core: Option, + pub max_validators: Option, + pub dispute_period: SessionIndex, + pub dispute_post_conclusion_acceptance_period: BlockNumber, + pub no_show_slots: u32, + pub n_delay_tranches: u32, + pub zeroth_delay_tranche_width: u32, + pub needed_approvals: u32, + pub relay_vrf_modulo_samples: u32, + pub pvf_voting_ttl: SessionIndex, + pub minimum_validation_upgrade_delay: BlockNumber, + pub minimum_backing_votes: u32, + pub node_features: NodeFeatures, + pub approval_voting_params: ApprovalVotingParams, +} + +impl> Default for V11HostConfiguration { + fn default() -> Self { + Self { + async_backing_params: AsyncBackingParams { + max_candidate_depth: 0, + allowed_ancestry_len: 0, + }, + group_rotation_frequency: 1u32.into(), + paras_availability_period: 1u32.into(), + no_show_slots: 1u32.into(), + validation_upgrade_cooldown: Default::default(), + validation_upgrade_delay: 2u32.into(), + code_retention_period: Default::default(), + max_code_size: Default::default(), + max_pov_size: Default::default(), + max_head_data_size: Default::default(), + coretime_cores: Default::default(), + on_demand_retries: Default::default(), + scheduling_lookahead: 1, + max_validators_per_core: Default::default(), + max_validators: None, + dispute_period: 6, + dispute_post_conclusion_acceptance_period: 100.into(), + n_delay_tranches: Default::default(), + zeroth_delay_tranche_width: Default::default(), + needed_approvals: Default::default(), + relay_vrf_modulo_samples: Default::default(), + max_upward_queue_count: Default::default(), + max_upward_queue_size: Default::default(), + max_downward_message_size: Default::default(), + max_upward_message_size: Default::default(), + max_upward_message_num_per_candidate: Default::default(), + hrmp_sender_deposit: Default::default(), + hrmp_recipient_deposit: Default::default(), + hrmp_channel_max_capacity: Default::default(), + hrmp_channel_max_total_size: Default::default(), + hrmp_max_parachain_inbound_channels: Default::default(), + hrmp_channel_max_message_size: Default::default(), + hrmp_max_parachain_outbound_channels: Default::default(), + hrmp_max_message_num_per_candidate: Default::default(), + pvf_voting_ttl: 2u32.into(), + minimum_validation_upgrade_delay: 2.into(), + executor_params: Default::default(), + approval_voting_params: ApprovalVotingParams { max_approval_coalesce_count: 1 }, + on_demand_queue_max_size: ON_DEMAND_DEFAULT_QUEUE_MAX_SIZE, + on_demand_base_fee: 10_000_000u128, + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_target_queue_utilization: Perbill::from_percent(25), + on_demand_ttl: 5u32.into(), + minimum_backing_votes: LEGACY_MIN_BACKING_VOTES, + node_features: NodeFeatures::EMPTY, + } + } +} mod v10 { use super::*; diff --git a/polkadot/runtime/parachains/src/configuration/migration/v12.rs b/polkadot/runtime/parachains/src/configuration/migration/v12.rs new file mode 100644 index 00000000000..4295a79893e --- /dev/null +++ b/polkadot/runtime/parachains/src/configuration/migration/v12.rs @@ -0,0 +1,349 @@ +// 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 . + +//! A module that is responsible for migration of storage. + +use crate::configuration::{self, migration::v11::V11HostConfiguration, Config, Pallet}; +use frame_support::{ + migrations::VersionedMigration, + pallet_prelude::*, + traits::{Defensive, OnRuntimeUpgrade}, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use primitives::vstaging::SchedulerParams; +use sp_core::Get; +use sp_staking::SessionIndex; +use sp_std::vec::Vec; + +type V12HostConfiguration = configuration::HostConfiguration; + +mod v11 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V11HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V11HostConfiguration>)>, + OptionQuery, + >; +} + +mod v12 { + use super::*; + + #[frame_support::storage_alias] + pub(crate) type ActiveConfig = + StorageValue, V12HostConfiguration>, OptionQuery>; + + #[frame_support::storage_alias] + pub(crate) type PendingConfigs = StorageValue< + Pallet, + Vec<(SessionIndex, V12HostConfiguration>)>, + OptionQuery, + >; +} + +pub type MigrateToV12 = VersionedMigration< + 11, + 12, + UncheckedMigrateToV12, + Pallet, + ::DbWeight, +>; + +pub struct UncheckedMigrateToV12(sp_std::marker::PhantomData); + +impl OnRuntimeUpgrade for UncheckedMigrateToV12 { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running pre_upgrade() for HostConfiguration MigrateToV12"); + Ok(Vec::new()) + } + + fn on_runtime_upgrade() -> Weight { + log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV12 started"); + let weight_consumed = migrate_to_v12::(); + + log::info!(target: configuration::LOG_TARGET, "HostConfiguration MigrateToV12 executed successfully"); + + weight_consumed + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + log::trace!(target: crate::configuration::LOG_TARGET, "Running post_upgrade() for HostConfiguration MigrateToV12"); + ensure!( + StorageVersion::get::>() >= 12, + "Storage version should be >= 12 after the migration" + ); + + Ok(()) + } +} + +fn migrate_to_v12() -> Weight { + // Unusual formatting is justified: + // - make it easier to verify that fields assign what they supposed to assign. + // - this code is transient and will be removed after all migrations are done. + // - this code is important enough to optimize for legibility sacrificing consistency. + #[rustfmt::skip] + let translate = + |pre: V11HostConfiguration>| -> + V12HostConfiguration> + { + V12HostConfiguration { + max_code_size : pre.max_code_size, + max_head_data_size : pre.max_head_data_size, + max_upward_queue_count : pre.max_upward_queue_count, + max_upward_queue_size : pre.max_upward_queue_size, + max_upward_message_size : pre.max_upward_message_size, + max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, + hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, + validation_upgrade_cooldown : pre.validation_upgrade_cooldown, + validation_upgrade_delay : pre.validation_upgrade_delay, + max_pov_size : pre.max_pov_size, + max_downward_message_size : pre.max_downward_message_size, + hrmp_sender_deposit : pre.hrmp_sender_deposit, + hrmp_recipient_deposit : pre.hrmp_recipient_deposit, + hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, + hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, + hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, + hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, + hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, + code_retention_period : pre.code_retention_period, + max_validators : pre.max_validators, + dispute_period : pre.dispute_period, + dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, + no_show_slots : pre.no_show_slots, + n_delay_tranches : pre.n_delay_tranches, + zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, + needed_approvals : pre.needed_approvals, + relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, + pvf_voting_ttl : pre.pvf_voting_ttl, + minimum_validation_upgrade_delay : pre.minimum_validation_upgrade_delay, + async_backing_params : pre.async_backing_params, + executor_params : pre.executor_params, + minimum_backing_votes : pre.minimum_backing_votes, + node_features : pre.node_features, + approval_voting_params : pre.approval_voting_params, + scheduler_params: SchedulerParams { + group_rotation_frequency : pre.group_rotation_frequency, + paras_availability_period : pre.paras_availability_period, + max_validators_per_core : pre.max_validators_per_core, + lookahead : pre.scheduling_lookahead, + num_cores : pre.coretime_cores, + max_availability_timeouts : pre.on_demand_retries, + on_demand_queue_max_size : pre.on_demand_queue_max_size, + on_demand_target_queue_utilization : pre.on_demand_target_queue_utilization, + on_demand_fee_variability : pre.on_demand_fee_variability, + on_demand_base_fee : pre.on_demand_base_fee, + ttl : pre.on_demand_ttl, + } + } + }; + + let v11 = v11::ActiveConfig::::get() + .defensive_proof("Could not decode old config") + .unwrap_or_default(); + let v12 = translate(v11); + v12::ActiveConfig::::set(Some(v12)); + + // Allowed to be empty. + let pending_v11 = v11::PendingConfigs::::get().unwrap_or_default(); + let mut pending_v12 = Vec::new(); + + for (session, v11) in pending_v11.into_iter() { + let v12 = translate(v11); + pending_v12.push((session, v12)); + } + v12::PendingConfigs::::set(Some(pending_v12.clone())); + + let num_configs = (pending_v12.len() + 1) as u64; + T::DbWeight::get().reads_writes(num_configs, num_configs) +} + +#[cfg(test)] +mod tests { + use primitives::LEGACY_MIN_BACKING_VOTES; + use sp_arithmetic::Perbill; + + use super::*; + use crate::mock::{new_test_ext, Test}; + + #[test] + fn v12_deserialized_from_actual_data() { + // Example how to get new `raw_config`: + // We'll obtain the raw_config at a specified a block + // Steps: + // 1. Go to Polkadot.js -> Developer -> Chain state -> Storage: https://polkadot.js.org/apps/#/chainstate + // 2. Set these parameters: + // 2.1. selected state query: configuration; activeConfig(): + // PolkadotRuntimeParachainsConfigurationHostConfiguration + // 2.2. blockhash to query at: + // 0xf89d3ab5312c5f70d396dc59612f0aa65806c798346f9db4b35278baed2e0e53 (the hash of + // the block) + // 2.3. Note the value of encoded storage key -> + // 0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385 for the + // referenced block. + // 2.4. You'll also need the decoded values to update the test. + // 3. Go to Polkadot.js -> Developer -> Chain state -> Raw storage + // 3.1 Enter the encoded storage key and you get the raw config. + + // This exceeds the maximal line width length, but that's fine, since this is not code and + // doesn't need to be read and also leaving it as one line allows to easily copy it. + let raw_config = + hex_literal::hex![ + "0000300000800000080000000000100000c8000005000000050000000200000002000000000000000000000000005000000010000400000000000000000000000000000000000000000000000000000000000000000000000800000000200000040000000000100000b004000000060000006400000002000000190000000000000002000000020000000200000005000000020000000001000000140000000400000001010000000100000001000000000000001027000080b2e60e80c3c9018096980000000000000000000000000005000000" + ]; + + let v12 = + V12HostConfiguration::::decode(&mut &raw_config[..]).unwrap(); + + // We check only a sample of the values here. If we missed any fields or messed up data + // types that would skew all the fields coming after. + assert_eq!(v12.max_code_size, 3_145_728); + assert_eq!(v12.validation_upgrade_cooldown, 2); + assert_eq!(v12.max_pov_size, 5_242_880); + assert_eq!(v12.hrmp_channel_max_message_size, 1_048_576); + assert_eq!(v12.n_delay_tranches, 25); + assert_eq!(v12.minimum_validation_upgrade_delay, 5); + assert_eq!(v12.minimum_backing_votes, LEGACY_MIN_BACKING_VOTES); + assert_eq!(v12.approval_voting_params.max_approval_coalesce_count, 1); + assert_eq!(v12.scheduler_params.group_rotation_frequency, 20); + assert_eq!(v12.scheduler_params.paras_availability_period, 4); + assert_eq!(v12.scheduler_params.lookahead, 1); + assert_eq!(v12.scheduler_params.num_cores, 1); + assert_eq!(v12.scheduler_params.max_availability_timeouts, 0); + assert_eq!(v12.scheduler_params.on_demand_queue_max_size, 10_000); + assert_eq!( + v12.scheduler_params.on_demand_target_queue_utilization, + Perbill::from_percent(25) + ); + assert_eq!(v12.scheduler_params.on_demand_fee_variability, Perbill::from_percent(3)); + assert_eq!(v12.scheduler_params.on_demand_base_fee, 10_000_000); + assert_eq!(v12.scheduler_params.ttl, 5); + } + + #[test] + fn test_migrate_to_v12() { + // Host configuration has lots of fields. However, in this migration we only add one + // field. The most important part to check are a couple of the last fields. We also pick + // extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and + // also their type. + // + // We specify only the picked fields and the rest should be provided by the `Default` + // implementation. That implementation is copied over between the two types and should work + // fine. + let v11 = V11HostConfiguration:: { + needed_approvals: 69, + paras_availability_period: 55, + hrmp_recipient_deposit: 1337, + max_pov_size: 1111, + minimum_validation_upgrade_delay: 20, + on_demand_ttl: 3, + on_demand_retries: 10, + ..Default::default() + }; + + let mut pending_configs = Vec::new(); + pending_configs.push((100, v11.clone())); + pending_configs.push((300, v11.clone())); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v10 version in the state. + v11::ActiveConfig::::set(Some(v11.clone())); + v11::PendingConfigs::::set(Some(pending_configs)); + + migrate_to_v12::(); + + let v12 = v12::ActiveConfig::::get().unwrap(); + assert_eq!(v12.approval_voting_params.max_approval_coalesce_count, 1); + + let mut configs_to_check = v12::PendingConfigs::::get().unwrap(); + configs_to_check.push((0, v12.clone())); + + for (_, v12) in configs_to_check { + #[rustfmt::skip] + { + assert_eq!(v11.max_code_size , v12.max_code_size); + assert_eq!(v11.max_head_data_size , v12.max_head_data_size); + assert_eq!(v11.max_upward_queue_count , v12.max_upward_queue_count); + assert_eq!(v11.max_upward_queue_size , v12.max_upward_queue_size); + assert_eq!(v11.max_upward_message_size , v12.max_upward_message_size); + assert_eq!(v11.max_upward_message_num_per_candidate , v12.max_upward_message_num_per_candidate); + assert_eq!(v11.hrmp_max_message_num_per_candidate , v12.hrmp_max_message_num_per_candidate); + assert_eq!(v11.validation_upgrade_cooldown , v12.validation_upgrade_cooldown); + assert_eq!(v11.validation_upgrade_delay , v12.validation_upgrade_delay); + assert_eq!(v11.max_pov_size , v12.max_pov_size); + assert_eq!(v11.max_downward_message_size , v12.max_downward_message_size); + assert_eq!(v11.hrmp_max_parachain_outbound_channels , v12.hrmp_max_parachain_outbound_channels); + assert_eq!(v11.hrmp_sender_deposit , v12.hrmp_sender_deposit); + assert_eq!(v11.hrmp_recipient_deposit , v12.hrmp_recipient_deposit); + assert_eq!(v11.hrmp_channel_max_capacity , v12.hrmp_channel_max_capacity); + assert_eq!(v11.hrmp_channel_max_total_size , v12.hrmp_channel_max_total_size); + assert_eq!(v11.hrmp_max_parachain_inbound_channels , v12.hrmp_max_parachain_inbound_channels); + assert_eq!(v11.hrmp_channel_max_message_size , v12.hrmp_channel_max_message_size); + assert_eq!(v11.code_retention_period , v12.code_retention_period); + assert_eq!(v11.max_validators , v12.max_validators); + assert_eq!(v11.dispute_period , v12.dispute_period); + assert_eq!(v11.no_show_slots , v12.no_show_slots); + assert_eq!(v11.n_delay_tranches , v12.n_delay_tranches); + assert_eq!(v11.zeroth_delay_tranche_width , v12.zeroth_delay_tranche_width); + assert_eq!(v11.needed_approvals , v12.needed_approvals); + assert_eq!(v11.relay_vrf_modulo_samples , v12.relay_vrf_modulo_samples); + assert_eq!(v11.pvf_voting_ttl , v12.pvf_voting_ttl); + assert_eq!(v11.minimum_validation_upgrade_delay , v12.minimum_validation_upgrade_delay); + assert_eq!(v11.async_backing_params.allowed_ancestry_len, v12.async_backing_params.allowed_ancestry_len); + assert_eq!(v11.async_backing_params.max_candidate_depth , v12.async_backing_params.max_candidate_depth); + assert_eq!(v11.executor_params , v12.executor_params); + assert_eq!(v11.minimum_backing_votes , v12.minimum_backing_votes); + assert_eq!(v11.group_rotation_frequency , v12.scheduler_params.group_rotation_frequency); + assert_eq!(v11.paras_availability_period , v12.scheduler_params.paras_availability_period); + assert_eq!(v11.max_validators_per_core , v12.scheduler_params.max_validators_per_core); + assert_eq!(v11.scheduling_lookahead , v12.scheduler_params.lookahead); + assert_eq!(v11.coretime_cores , v12.scheduler_params.num_cores); + assert_eq!(v11.on_demand_retries , v12.scheduler_params.max_availability_timeouts); + assert_eq!(v11.on_demand_queue_max_size , v12.scheduler_params.on_demand_queue_max_size); + assert_eq!(v11.on_demand_target_queue_utilization , v12.scheduler_params.on_demand_target_queue_utilization); + assert_eq!(v11.on_demand_fee_variability , v12.scheduler_params.on_demand_fee_variability); + assert_eq!(v11.on_demand_base_fee , v12.scheduler_params.on_demand_base_fee); + assert_eq!(v11.on_demand_ttl , v12.scheduler_params.ttl); + }; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression. + } + }); + } + + // Test that migration doesn't panic in case there are no pending configurations upgrades in + // pallet's storage. + #[test] + fn test_migrate_to_v12_no_pending() { + let v11 = V11HostConfiguration::::default(); + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v10 version in the state. + v11::ActiveConfig::::set(Some(v11)); + // Ensure there are no pending configs. + v12::PendingConfigs::::set(None); + + // Shouldn't fail. + migrate_to_v12::(); + }); + } +} diff --git a/polkadot/runtime/parachains/src/configuration/tests.rs b/polkadot/runtime/parachains/src/configuration/tests.rs index f1570017dd7..254511231ca 100644 --- a/polkadot/runtime/parachains/src/configuration/tests.rs +++ b/polkadot/runtime/parachains/src/configuration/tests.rs @@ -226,8 +226,11 @@ fn invariants() { ); ActiveConfig::::put(HostConfiguration { - paras_availability_period: 10, minimum_validation_upgrade_delay: 11, + scheduler_params: SchedulerParams { + paras_availability_period: 10, + ..Default::default() + }, ..Default::default() }); assert_err!( @@ -283,12 +286,6 @@ fn setting_pending_config_members() { max_code_size: 100_000, max_pov_size: 1024, max_head_data_size: 1_000, - coretime_cores: 2, - on_demand_retries: 5, - group_rotation_frequency: 20, - paras_availability_period: 10, - scheduling_lookahead: 3, - max_validators_per_core: None, max_validators: None, dispute_period: 239, dispute_post_conclusion_acceptance_period: 10, @@ -314,13 +311,21 @@ fn setting_pending_config_members() { minimum_validation_upgrade_delay: 20, executor_params: Default::default(), approval_voting_params: ApprovalVotingParams { max_approval_coalesce_count: 1 }, - on_demand_queue_max_size: 10_000u32, - on_demand_base_fee: 10_000_000u128, - on_demand_fee_variability: Perbill::from_percent(3), - on_demand_target_queue_utilization: Perbill::from_percent(25), - on_demand_ttl: 5u32, minimum_backing_votes: 5, node_features: bitvec![u8, Lsb0; 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], + scheduler_params: SchedulerParams { + group_rotation_frequency: 20, + paras_availability_period: 10, + max_validators_per_core: None, + lookahead: 3, + num_cores: 2, + max_availability_timeouts: 5, + on_demand_queue_max_size: 10_000u32, + on_demand_base_fee: 10_000_000u128, + on_demand_fee_variability: Perbill::from_percent(3), + on_demand_target_queue_utilization: Perbill::from_percent(25), + ttl: 5u32, + }, }; Configuration::set_validation_upgrade_cooldown( @@ -342,13 +347,19 @@ fn setting_pending_config_members() { Configuration::set_max_pov_size(RuntimeOrigin::root(), new_config.max_pov_size).unwrap(); Configuration::set_max_head_data_size(RuntimeOrigin::root(), new_config.max_head_data_size) .unwrap(); - Configuration::set_coretime_cores(RuntimeOrigin::root(), new_config.coretime_cores) - .unwrap(); - Configuration::set_on_demand_retries(RuntimeOrigin::root(), new_config.on_demand_retries) - .unwrap(); + Configuration::set_coretime_cores( + RuntimeOrigin::root(), + new_config.scheduler_params.num_cores, + ) + .unwrap(); + Configuration::set_max_availability_timeouts( + RuntimeOrigin::root(), + new_config.scheduler_params.max_availability_timeouts, + ) + .unwrap(); Configuration::set_group_rotation_frequency( RuntimeOrigin::root(), - new_config.group_rotation_frequency, + new_config.scheduler_params.group_rotation_frequency, ) .unwrap(); // This comes out of order to satisfy the validity criteria for the chain and thread @@ -360,17 +371,17 @@ fn setting_pending_config_members() { .unwrap(); Configuration::set_paras_availability_period( RuntimeOrigin::root(), - new_config.paras_availability_period, + new_config.scheduler_params.paras_availability_period, ) .unwrap(); Configuration::set_scheduling_lookahead( RuntimeOrigin::root(), - new_config.scheduling_lookahead, + new_config.scheduler_params.lookahead, ) .unwrap(); Configuration::set_max_validators_per_core( RuntimeOrigin::root(), - new_config.max_validators_per_core, + new_config.scheduler_params.max_validators_per_core, ) .unwrap(); Configuration::set_max_validators(RuntimeOrigin::root(), new_config.max_validators) diff --git a/polkadot/runtime/parachains/src/coretime/migration.rs b/polkadot/runtime/parachains/src/coretime/migration.rs index 9bc0a20ef5b..03fecc58570 100644 --- a/polkadot/runtime/parachains/src/coretime/migration.rs +++ b/polkadot/runtime/parachains/src/coretime/migration.rs @@ -114,7 +114,7 @@ mod v_coretime { let legacy_paras = paras::Parachains::::get(); let config = >::config(); - let total_core_count = config.coretime_cores + legacy_paras.len() as u32; + let total_core_count = config.scheduler_params.num_cores + legacy_paras.len() as u32; let dmp_queue_size = crate::dmp::Pallet::::dmq_contents(T::BrokerId::get().into()).len() as u32; @@ -150,7 +150,7 @@ mod v_coretime { // Migrate to Coretime. // - // NOTE: Also migrates coretime_cores config value in configuration::ActiveConfig. + // NOTE: Also migrates `num_cores` config value in configuration::ActiveConfig. fn migrate_to_coretime< T: Config, SendXcm: xcm::v4::SendXcm, @@ -176,8 +176,8 @@ mod v_coretime { } let config = >::config(); - // coretime_cores was on_demand_cores until now: - for on_demand in 0..config.coretime_cores { + // num_cores was on_demand_cores until now: + for on_demand in 0..config.scheduler_params.num_cores { let core = CoreIndex(legacy_count.saturating_add(on_demand as _)); let r = assigner_coretime::Pallet::::assign_core( core, @@ -189,9 +189,9 @@ mod v_coretime { log::error!("Creating assignment for existing on-demand core, failed: {:?}", err); } } - let total_cores = config.coretime_cores + legacy_count; + let total_cores = config.scheduler_params.num_cores + legacy_count; configuration::ActiveConfig::::mutate(|c| { - c.coretime_cores = total_cores; + c.scheduler_params.num_cores = total_cores; }); if let Err(err) = migrate_send_assignments_to_coretime_chain::() { @@ -200,7 +200,9 @@ mod v_coretime { let single_weight = ::WeightInfo::assign_core(1); single_weight - .saturating_mul(u64::from(legacy_count.saturating_add(config.coretime_cores))) + .saturating_mul(u64::from( + legacy_count.saturating_add(config.scheduler_params.num_cores), + )) // Second read from sending assignments to the coretime chain. .saturating_add(T::DbWeight::get().reads_writes(2, 1)) } @@ -244,7 +246,8 @@ mod v_coretime { Some(mk_coretime_call(crate::coretime::CoretimeCalls::SetLease(p.into(), time_slice))) }); - let core_count: u16 = configuration::Pallet::::config().coretime_cores.saturated_into(); + let core_count: u16 = + configuration::Pallet::::config().scheduler_params.num_cores.saturated_into(); let set_core_count = iter::once(mk_coretime_call( crate::coretime::CoretimeCalls::NotifyCoreCount(core_count), )); diff --git a/polkadot/runtime/parachains/src/coretime/mod.rs b/polkadot/runtime/parachains/src/coretime/mod.rs index 531f5c2e4e4..eb9646d7e86 100644 --- a/polkadot/runtime/parachains/src/coretime/mod.rs +++ b/polkadot/runtime/parachains/src/coretime/mod.rs @@ -214,8 +214,8 @@ impl Pallet { } pub fn initializer_on_new_session(notification: &SessionChangeNotification>) { - let old_core_count = notification.prev_config.coretime_cores; - let new_core_count = notification.new_config.coretime_cores; + let old_core_count = notification.prev_config.scheduler_params.num_cores; + let new_core_count = notification.new_config.scheduler_params.num_cores; if new_core_count != old_core_count { let core_count: u16 = new_core_count.saturated_into(); let message = Xcm(vec![ diff --git a/polkadot/runtime/parachains/src/inclusion/tests.rs b/polkadot/runtime/parachains/src/inclusion/tests.rs index d2b5a67c3e4..3fe7d7f0c7d 100644 --- a/polkadot/runtime/parachains/src/inclusion/tests.rs +++ b/polkadot/runtime/parachains/src/inclusion/tests.rs @@ -47,10 +47,10 @@ use test_helpers::{dummy_collator, dummy_collator_signature, dummy_validation_co fn default_config() -> HostConfiguration { let mut config = HostConfiguration::default(); - config.coretime_cores = 1; + config.scheduler_params.num_cores = 1; config.max_code_size = 0b100000; config.max_head_data_size = 0b100000; - config.group_rotation_frequency = u32::MAX; + config.scheduler_params.group_rotation_frequency = u32::MAX; config } @@ -224,7 +224,7 @@ pub(crate) fn run_to_block( } pub(crate) fn expected_bits() -> usize { - Paras::parachains().len() + Configuration::config().coretime_cores as usize + Paras::parachains().len() + Configuration::config().scheduler_params.num_cores as usize } fn default_bitfield() -> AvailabilityBitfield { @@ -386,7 +386,7 @@ fn collect_pending_cleans_up_pending() { (thread_a, ParaKind::Parathread), ]; let mut config = genesis_config(paras); - config.configuration.config.group_rotation_frequency = 3; + config.configuration.config.scheduler_params.group_rotation_frequency = 3; new_test_ext(config).execute_with(|| { let default_candidate = TestCandidateBuilder::default().build(); >::insert( @@ -2062,7 +2062,7 @@ fn check_allowed_relay_parents() { } let validator_public = validator_pubkeys(&validators); let mut config = genesis_config(paras); - config.configuration.config.group_rotation_frequency = 1; + config.configuration.config.scheduler_params.group_rotation_frequency = 1; new_test_ext(config).execute_with(|| { shared::Pallet::::set_active_validators_ascending(validator_public.clone()); diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index 1925ca19501..e18be03bdeb 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -23,7 +23,7 @@ use crate::{ initializer, origin, paras, paras::ParaKind, paras_inherent, scheduler, - scheduler::common::{AssignmentProvider, AssignmentProviderConfig}, + scheduler::common::AssignmentProvider, session_info, shared, ParaId, }; use frame_support::pallet_prelude::*; @@ -463,10 +463,6 @@ pub mod mock_assigner { pub(super) type MockAssignmentQueue = StorageValue<_, VecDeque, ValueQuery>; - #[pallet::storage] - pub(super) type MockProviderConfig = - StorageValue<_, AssignmentProviderConfig, OptionQuery>; - #[pallet::storage] pub(super) type MockCoreCount = StorageValue<_, u32, OptionQuery>; } @@ -478,12 +474,6 @@ pub mod mock_assigner { MockAssignmentQueue::::mutate(|queue| queue.push_back(assignment)); } - // This configuration needs to be customized to service `get_provider_config` in - // scheduler tests. - pub fn set_assignment_provider_config(config: AssignmentProviderConfig) { - MockProviderConfig::::set(Some(config)); - } - // Allows for customized core count in scheduler tests, rather than a core count // derived from on-demand config + parachain count. pub fn set_core_count(count: u32) { @@ -512,17 +502,6 @@ pub mod mock_assigner { // in the mock assigner. fn push_back_assignment(_assignment: Assignment) {} - // Gets the provider config we set earlier using `set_assignment_provider_config`, falling - // back to the on demand parachain configuration if none was set. - fn get_provider_config(_core_idx: CoreIndex) -> AssignmentProviderConfig { - match MockProviderConfig::::get() { - Some(config) => config, - None => AssignmentProviderConfig { - max_availability_timeouts: 1, - ttl: BlockNumber::from(5u32), - }, - } - } #[cfg(any(feature = "runtime-benchmarks", test))] fn get_mock_assignment(_: CoreIndex, para_id: ParaId) -> Assignment { Assignment::Bulk(para_id) diff --git a/polkadot/runtime/parachains/src/paras/tests.rs b/polkadot/runtime/parachains/src/paras/tests.rs index 24ea919ec87..262ec9d3fdb 100644 --- a/polkadot/runtime/parachains/src/paras/tests.rs +++ b/polkadot/runtime/parachains/src/paras/tests.rs @@ -17,7 +17,7 @@ use super::*; use frame_support::{assert_err, assert_ok, assert_storage_noop}; use keyring::Sr25519Keyring; -use primitives::{BlockNumber, PARACHAIN_KEY_TYPE_ID}; +use primitives::{vstaging::SchedulerParams, BlockNumber, PARACHAIN_KEY_TYPE_ID}; use sc_keystore::LocalKeystore; use sp_keystore::{Keystore, KeystorePtr}; use std::sync::Arc; @@ -909,7 +909,10 @@ fn full_parachain_cleanup_storage() { minimum_validation_upgrade_delay: 2, // Those are not relevant to this test. However, HostConfiguration is still a // subject for the consistency check. - paras_availability_period: 1, + scheduler_params: SchedulerParams { + paras_availability_period: 1, + ..Default::default() + }, ..Default::default() }, }, diff --git a/polkadot/runtime/parachains/src/paras_inherent/tests.rs b/polkadot/runtime/parachains/src/paras_inherent/tests.rs index defb2f4404f..b7285ec884a 100644 --- a/polkadot/runtime/parachains/src/paras_inherent/tests.rs +++ b/polkadot/runtime/parachains/src/paras_inherent/tests.rs @@ -27,13 +27,14 @@ mod enter { builder::{Bench, BenchBuilder}, mock::{mock_assigner, new_test_ext, BlockLength, BlockWeights, MockGenesisConfig, Test}, scheduler::{ - common::{Assignment, AssignmentProvider, AssignmentProviderConfig}, + common::{Assignment, AssignmentProvider}, ParasEntry, }, }; use assert_matches::assert_matches; use frame_support::assert_ok; use frame_system::limits; + use primitives::vstaging::SchedulerParams; use sp_runtime::Perbill; use sp_std::collections::btree_map::BTreeMap; @@ -87,7 +88,7 @@ mod enter { // `create_inherent` and will not cause `enter` to early. fn include_backed_candidates() { let config = MockGenesisConfig::default(); - assert!(config.configuration.config.scheduling_lookahead > 0); + assert!(config.configuration.config.scheduler_params.lookahead > 0); new_test_ext(config).execute_with(|| { let dispute_statements = BTreeMap::new(); @@ -625,7 +626,7 @@ mod enter { #[test] fn limit_candidates_over_weight_1() { let config = MockGenesisConfig::default(); - assert!(config.configuration.config.scheduling_lookahead > 0); + assert!(config.configuration.config.scheduler_params.lookahead > 0); new_test_ext(config).execute_with(|| { // Create the inherent data for this block @@ -706,8 +707,8 @@ mod enter { let cores = (0..used_cores) .into_iter() .map(|i| { - let AssignmentProviderConfig { ttl, .. } = - scheduler::Pallet::::assignment_provider_config(CoreIndex(i)); + let SchedulerParams { ttl, .. } = + >::config().scheduler_params; // Load an assignment into provider so that one is present to pop let assignment = ::AssignmentProvider::get_mock_assignment( diff --git a/polkadot/runtime/parachains/src/scheduler.rs b/polkadot/runtime/parachains/src/scheduler.rs index 3dbb050fb4e..61ab36dbe96 100644 --- a/polkadot/runtime/parachains/src/scheduler.rs +++ b/polkadot/runtime/parachains/src/scheduler.rs @@ -51,7 +51,7 @@ use sp_std::{ pub mod common; -use common::{Assignment, AssignmentProvider, AssignmentProviderConfig}; +use common::{Assignment, AssignmentProvider}; pub use pallet::*; @@ -222,7 +222,7 @@ impl Pallet { let n_cores = core::cmp::max( T::AssignmentProvider::session_core_count(), - match config.max_validators_per_core { + match config.scheduler_params.max_validators_per_core { Some(x) if x != 0 => validators.len() as u32 / x, _ => 0, }, @@ -350,6 +350,7 @@ impl Pallet { fn drop_expired_claims_from_claimqueue() { let now = >::block_number(); let availability_cores = AvailabilityCores::::get(); + let ttl = >::config().scheduler_params.ttl; ClaimQueue::::mutate(|cq| { for (idx, _) in (0u32..).zip(availability_cores) { @@ -382,8 +383,6 @@ impl Pallet { if let Some(assignment) = T::AssignmentProvider::pop_assignment_for_core(core_idx) { - let AssignmentProviderConfig { ttl, .. } = - T::AssignmentProvider::get_provider_config(core_idx); core_claimqueue.push_back(ParasEntry::new(assignment, now + ttl)); } } @@ -428,7 +427,7 @@ impl Pallet { } let rotations_since_session_start: BlockNumberFor = - (at - session_start_block) / config.group_rotation_frequency; + (at - session_start_block) / config.scheduler_params.group_rotation_frequency; let rotations_since_session_start = as TryInto>::try_into(rotations_since_session_start) @@ -460,9 +459,9 @@ impl Pallet { // Note: blocks backed in this rotation will never time out here as backed_in + // config.paras_availability_period will always be > now for these blocks, as // otherwise above condition would not be true. - pending_since + config.paras_availability_period + pending_since + config.scheduler_params.paras_availability_period } else { - next_rotation + config.paras_availability_period + next_rotation + config.scheduler_params.paras_availability_period }; AvailabilityTimeoutStatus { timed_out: time_out_at <= now, live_until: time_out_at } @@ -478,7 +477,8 @@ impl Pallet { let now = >::block_number() + One::one(); let rotation_info = Self::group_rotation_info(now); - let current_window = rotation_info.last_rotation_at() + config.paras_availability_period; + let current_window = + rotation_info.last_rotation_at() + config.scheduler_params.paras_availability_period; now < current_window } @@ -488,7 +488,7 @@ impl Pallet { ) -> GroupRotationInfo> { let session_start_block = Self::session_start_block(); let group_rotation_frequency = - >::config().group_rotation_frequency; + >::config().scheduler_params.group_rotation_frequency; GroupRotationInfo { session_start_block, now, group_rotation_frequency } } @@ -508,6 +508,8 @@ impl Pallet { /// Return the next thing that will be scheduled on this core assuming it is currently /// occupied and the candidate occupying it times out. pub(crate) fn next_up_on_time_out(core: CoreIndex) -> Option { + let max_availability_timeouts = + >::config().scheduler_params.max_availability_timeouts; Self::next_up_on_available(core).or_else(|| { // Or, if none, the claim currently occupying the core, // as it would be put back on the queue after timing out if number of retries is not at @@ -515,16 +517,12 @@ impl Pallet { let cores = AvailabilityCores::::get(); cores.get(core.0 as usize).and_then(|c| match c { CoreOccupied::Free => None, - CoreOccupied::Paras(pe) => { - let AssignmentProviderConfig { max_availability_timeouts, .. } = - T::AssignmentProvider::get_provider_config(core); - + CoreOccupied::Paras(pe) => if pe.availability_timeouts < max_availability_timeouts { Some(Self::paras_entry_to_scheduled_core(pe)) } else { None - } - }, + }, }) }) } @@ -566,7 +564,7 @@ impl Pallet { // ClaimQueue related functions // fn claimqueue_lookahead() -> u32 { - >::config().scheduling_lookahead + >::config().scheduler_params.lookahead } /// Frees cores and fills the free claimqueue spots by popping from the `AssignmentProvider`. @@ -585,15 +583,15 @@ impl Pallet { let n_lookahead = Self::claimqueue_lookahead().max(1); let n_session_cores = T::AssignmentProvider::session_core_count(); let cq = ClaimQueue::::get(); - let ttl = >::config().on_demand_ttl; + let config = >::config(); + let max_availability_timeouts = config.scheduler_params.max_availability_timeouts; + let ttl = config.scheduler_params.ttl; for core_idx in 0..n_session_cores { let core_idx = CoreIndex::from(core_idx); // add previously timedout paras back into the queue if let Some(mut entry) = timedout_paras.remove(&core_idx) { - let AssignmentProviderConfig { max_availability_timeouts, .. } = - T::AssignmentProvider::get_provider_config(core_idx); if entry.availability_timeouts < max_availability_timeouts { // Increment the timeout counter. entry.availability_timeouts += 1; @@ -668,13 +666,6 @@ impl Pallet { .filter_map(|(core_idx, v)| v.front().map(|e| (core_idx, e.assignment.para_id()))) } - #[cfg(any(feature = "runtime-benchmarks", test))] - pub(crate) fn assignment_provider_config( - core_idx: CoreIndex, - ) -> AssignmentProviderConfig> { - T::AssignmentProvider::get_provider_config(core_idx) - } - #[cfg(any(feature = "try-runtime", test))] fn claimqueue_len() -> usize { ClaimQueue::::get().iter().map(|la_vec| la_vec.1.len()).sum() diff --git a/polkadot/runtime/parachains/src/scheduler/common.rs b/polkadot/runtime/parachains/src/scheduler/common.rs index 2eb73385803..66a4e6d30be 100644 --- a/polkadot/runtime/parachains/src/scheduler/common.rs +++ b/polkadot/runtime/parachains/src/scheduler/common.rs @@ -48,22 +48,10 @@ impl Assignment { } } -#[derive(Encode, Decode, TypeInfo)] -/// A set of variables required by the scheduler in order to operate. -pub struct AssignmentProviderConfig { - /// How many times a collation can time out on availability. - /// Zero timeouts still means that a collation can be provided as per the slot auction - /// assignment provider. - pub max_availability_timeouts: u32, - - /// How long the collator has to provide a collation to the backing group before being dropped. - pub ttl: BlockNumber, -} - pub trait AssignmentProvider { /// Pops an [`Assignment`] from the provider for a specified [`CoreIndex`]. /// - /// This is where assignments come into existance. + /// This is where assignments come into existence. fn pop_assignment_for_core(core_idx: CoreIndex) -> Option; /// A previously popped `Assignment` has been fully processed. @@ -77,14 +65,11 @@ pub trait AssignmentProvider { /// Push back a previously popped assignment. /// /// If the assignment could not be processed within the current session, it can be pushed back - /// to the assignment provider in order to be poppped again later. + /// to the assignment provider in order to be popped again later. /// /// This is the second way the life of an assignment can come to an end. fn push_back_assignment(assignment: Assignment); - /// Returns a set of variables needed by the scheduler - fn get_provider_config(core_idx: CoreIndex) -> AssignmentProviderConfig; - /// Push some assignment for mocking/benchmarks purposes. /// /// Useful for benchmarks and testing. The returned assignment is "valid" and can if need be diff --git a/polkadot/runtime/parachains/src/scheduler/tests.rs b/polkadot/runtime/parachains/src/scheduler/tests.rs index 9af23ce64bd..28b3a6b4f5d 100644 --- a/polkadot/runtime/parachains/src/scheduler/tests.rs +++ b/polkadot/runtime/parachains/src/scheduler/tests.rs @@ -18,7 +18,9 @@ use super::*; use frame_support::assert_ok; use keyring::Sr25519Keyring; -use primitives::{BlockNumber, SessionIndex, ValidationCode, ValidatorId}; +use primitives::{ + vstaging::SchedulerParams, BlockNumber, SessionIndex, ValidationCode, ValidatorId, +}; use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet}; use crate::{ @@ -103,15 +105,19 @@ fn run_to_end_of_block( fn default_config() -> HostConfiguration { HostConfiguration { - coretime_cores: 3, - group_rotation_frequency: 10, - paras_availability_period: 3, - scheduling_lookahead: 2, // This field does not affect anything that scheduler does. However, `HostConfiguration` // is still a subject to consistency test. It requires that // `minimum_validation_upgrade_delay` is greater than `chain_availability_period` and // `thread_availability_period`. minimum_validation_upgrade_delay: 6, + scheduler_params: SchedulerParams { + group_rotation_frequency: 10, + paras_availability_period: 3, + lookahead: 2, + num_cores: 3, + max_availability_timeouts: 1, + ..Default::default() + }, ..Default::default() } } @@ -155,7 +161,7 @@ fn scheduled_entries() -> impl Iterator(vec![para_a])); } else { assert!(!claimqueue_contains_para_ids::(vec![para_a])); @@ -822,7 +825,7 @@ fn on_demand_claims_are_pruned_after_timing_out() { assert!(!availability_cores_contains_para_ids::(vec![para_a])); // #25 - now += max_retries + 2; + now += max_timeouts + 2; // Add assignment back to the mix. MockAssigner::add_test_assignment(assignment_a.clone()); @@ -833,7 +836,7 @@ fn on_demand_claims_are_pruned_after_timing_out() { // #26 now += 1; // Run to block #n but this time have group 1 conclude the availabilty. - for n in now..=(now + max_retries + 1) { + for n in now..=(now + max_timeouts + 1) { // #n run_to_block(n, |_| None); // Time out core 0 if group 0 is assigned to it, if group 1 is assigned, conclude. @@ -874,10 +877,8 @@ fn on_demand_claims_are_pruned_after_timing_out() { fn availability_predicate_works() { let genesis_config = genesis_config(&default_config()); - let HostConfiguration { group_rotation_frequency, paras_availability_period, .. } = - default_config(); - - assert!(paras_availability_period < group_rotation_frequency); + let SchedulerParams { group_rotation_frequency, paras_availability_period, .. } = + default_config().scheduler_params; new_test_ext(genesis_config).execute_with(|| { run_to_block(1 + paras_availability_period, |_| None); @@ -1044,7 +1045,7 @@ fn next_up_on_time_out_reuses_claim_if_nothing_queued() { #[test] fn session_change_requires_reschedule_dropping_removed_paras() { let mut config = default_config(); - config.scheduling_lookahead = 1; + config.scheduler_params.lookahead = 1; let genesis_config = genesis_config(&config); let para_a = ParaId::from(1_u32); @@ -1056,7 +1057,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { new_test_ext(genesis_config).execute_with(|| { // Setting explicit core count MockAssigner::set_core_count(5); - let assignment_provider_ttl = MockAssigner::get_provider_config(CoreIndex::from(0)).ttl; + let coretime_ttl = >::config().scheduler_params.ttl; schedule_blank_para(para_a); schedule_blank_para(para_b); @@ -1120,7 +1121,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { vec![ParasEntry::new( Assignment::Bulk(para_a), // At end of block 2 - assignment_provider_ttl + 2 + coretime_ttl + 2 )] .into_iter() .collect() @@ -1169,7 +1170,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { vec![ParasEntry::new( Assignment::Bulk(para_a), // At block 3 - assignment_provider_ttl + 3 + coretime_ttl + 3 )] .into_iter() .collect() @@ -1179,7 +1180,7 @@ fn session_change_requires_reschedule_dropping_removed_paras() { vec![ParasEntry::new( Assignment::Bulk(para_b), // At block 3 - assignment_provider_ttl + 3 + coretime_ttl + 3 )] .into_iter() .collect() diff --git a/polkadot/runtime/parachains/src/session_info/tests.rs b/polkadot/runtime/parachains/src/session_info/tests.rs index 92a50575ded..a5bfeae0745 100644 --- a/polkadot/runtime/parachains/src/session_info/tests.rs +++ b/polkadot/runtime/parachains/src/session_info/tests.rs @@ -25,7 +25,7 @@ use crate::{ util::take_active_subset, }; use keyring::Sr25519Keyring; -use primitives::{BlockNumber, ValidatorId, ValidatorIndex}; +use primitives::{vstaging::SchedulerParams, BlockNumber, ValidatorId, ValidatorIndex}; fn run_to_block( to: BlockNumber, @@ -62,9 +62,9 @@ fn run_to_block( fn default_config() -> HostConfiguration { HostConfiguration { - coretime_cores: 1, dispute_period: 2, needed_approvals: 3, + scheduler_params: SchedulerParams { num_cores: 1, ..Default::default() }, ..Default::default() } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 173301e1ad9..f3c0c3d6bd8 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1658,6 +1658,7 @@ pub mod migrations { parachains_configuration::migration::v11::MigrateToV11, // This needs to come after the `parachains_configuration` above as we are reading the configuration. coretime::migration::MigrateToCoretime, + parachains_configuration::migration::v12::MigrateToV12, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs index 34541b83597..ca0575cb1b6 100644 --- a/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `runtime_parachains::configuration` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -58,8 +58,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_793_000 picoseconds. - Weight::from_parts(8_192_000, 0) + // Minimum execution time: 7_789_000 picoseconds. + Weight::from_parts(8_269_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -74,8 +74,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_819_000 picoseconds. - Weight::from_parts(8_004_000, 0) + // Minimum execution time: 7_851_000 picoseconds. + Weight::from_parts(8_152_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +90,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_760_000 picoseconds. - Weight::from_parts(8_174_000, 0) + // Minimum execution time: 7_960_000 picoseconds. + Weight::from_parts(8_276_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,8 +116,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_814_000 picoseconds. - Weight::from_parts(8_098_000, 0) + // Minimum execution time: 7_912_000 picoseconds. + Weight::from_parts(8_164_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -132,8 +132,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_028_000 picoseconds. - Weight::from_parts(10_386_000, 0) + // Minimum execution time: 9_782_000 picoseconds. + Weight::from_parts(10_373_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -148,8 +148,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_867_000 picoseconds. - Weight::from_parts(8_191_000, 0) + // Minimum execution time: 7_870_000 picoseconds. + Weight::from_parts(8_274_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -164,8 +164,24 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_158_000 picoseconds. - Weight::from_parts(10_430_000, 0) + // Minimum execution time: 9_960_000 picoseconds. + Weight::from_parts(10_514_000, 0) + .saturating_add(Weight::from_parts(0, 1636)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_scheduler_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `151` + // Estimated: `1636` + // Minimum execution time: 7_913_000 picoseconds. + Weight::from_parts(8_338_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 91047d953f5..a7772303a95 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1699,6 +1699,7 @@ pub mod migrations { // Migrate Identity pallet for Usernames pallet_identity::migration::versioned::V0ToV1, parachains_configuration::migration::v11::MigrateToV11, + parachains_configuration::migration::v12::MigrateToV12, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, // Migrate from legacy lease to coretime. Needs to run after configuration v11 diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs index 3a4813b667c..8fa3207c644 100644 --- a/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_configuration.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `runtime_parachains::configuration` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -58,8 +58,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 8_065_000 picoseconds. - Weight::from_parts(8_389_000, 0) + // Minimum execution time: 7_775_000 picoseconds. + Weight::from_parts(8_036_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -74,8 +74,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 8_038_000 picoseconds. - Weight::from_parts(8_463_000, 0) + // Minimum execution time: 7_708_000 picoseconds. + Weight::from_parts(7_971_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -90,8 +90,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_843_000 picoseconds. - Weight::from_parts(8_216_000, 0) + // Minimum execution time: 7_746_000 picoseconds. + Weight::from_parts(8_028_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -116,8 +116,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_969_000 picoseconds. - Weight::from_parts(8_362_000, 0) + // Minimum execution time: 7_729_000 picoseconds. + Weight::from_parts(7_954_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -132,8 +132,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_084_000 picoseconds. - Weight::from_parts(10_451_000, 0) + // Minimum execution time: 9_871_000 picoseconds. + Weight::from_parts(10_075_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -148,8 +148,8 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 7_948_000 picoseconds. - Weight::from_parts(8_268_000, 0) + // Minimum execution time: 7_869_000 picoseconds. + Weight::from_parts(8_000_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -164,8 +164,24 @@ impl runtime_parachains::configuration::WeightInfo for // Proof Size summary in bytes: // Measured: `151` // Estimated: `1636` - // Minimum execution time: 10_257_000 picoseconds. - Weight::from_parts(10_584_000, 0) + // Minimum execution time: 9_797_000 picoseconds. + Weight::from_parts(10_373_000, 0) + .saturating_add(Weight::from_parts(0, 1636)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `Configuration::PendingConfigs` (r:1 w:1) + /// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0) + /// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0) + /// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_config_with_scheduler_params() -> Weight { + // Proof Size summary in bytes: + // Measured: `151` + // Estimated: `1636` + // Minimum execution time: 7_718_000 picoseconds. + Weight::from_parts(7_984_000, 0) .saturating_add(Weight::from_parts(0, 1636)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) diff --git a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml index f6bdfeb4877..2561661de1f 100644 --- a/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml +++ b/polkadot/zombienet_tests/functional/0002-parachains-disputes.toml @@ -2,9 +2,11 @@ timeout = 1000 [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 5 needed_approvals = 8 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 5 + [relaychain.genesis.runtimeGenesis.patch.configuration.config.approval_voting_params] max_approval_coalesce_count = 5 diff --git a/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml b/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml index 5d6f299d461..a2a2621f842 100644 --- a/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml +++ b/polkadot/zombienet_tests/functional/0004-parachains-garbage-candidate.toml @@ -2,8 +2,10 @@ timeout = 1000 bootnode = true -[relaychain.genesis.runtimeGenesis.patch.configuration.config] +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] max_validators_per_core = 1 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config] needed_approvals = 2 [relaychain] diff --git a/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml b/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml index e2fbec079b1..a3bbc82e74b 100644 --- a/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml +++ b/polkadot/zombienet_tests/functional/0005-parachains-disputes-past-session.toml @@ -3,8 +3,10 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 2 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 group_rotation_frequency = 2 [relaychain] diff --git a/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml b/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml index bef54cb8ca4..858f87b9cfe 100644 --- a/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml +++ b/polkadot/zombienet_tests/functional/0006-parachains-max-tranche0.toml @@ -3,10 +3,12 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 7 relay_vrf_modulo_samples = 5 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" diff --git a/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml b/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml index 69eb0804d8c..573ccf96138 100644 --- a/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml +++ b/polkadot/zombienet_tests/functional/0007-dispute-freshly-finalized.toml @@ -2,9 +2,11 @@ timeout = 1000 [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 1 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" diff --git a/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml b/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml index 1ea385c3a42..ea1c93a1403 100644 --- a/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml +++ b/polkadot/zombienet_tests/functional/0008-dispute-old-finalized.toml @@ -2,9 +2,11 @@ timeout = 1000 [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 1 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" diff --git a/polkadot/zombienet_tests/functional/0010-validator-disabling.toml b/polkadot/zombienet_tests/functional/0010-validator-disabling.toml index 6701d60d74d..c9d79c5f8f2 100644 --- a/polkadot/zombienet_tests/functional/0010-validator-disabling.toml +++ b/polkadot/zombienet_tests/functional/0010-validator-disabling.toml @@ -3,8 +3,10 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 2 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 group_rotation_frequency = 10 [relaychain] diff --git a/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml b/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml index 5a6832b149b..b776622fdce 100644 --- a/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml +++ b/polkadot/zombienet_tests/functional/0011-async-backing-6-seconds-rate.toml @@ -8,13 +8,16 @@ chain = "rococo-local" [relaychain.genesis.runtimeGenesis.patch.configuration.config] needed_approvals = 4 relay_vrf_modulo_samples = 6 - scheduling_lookahead = 2 - group_rotation_frequency = 4 [relaychain.genesis.runtimeGenesis.patch.configuration.config.async_backing_params] max_candidate_depth = 3 allowed_ancestry_len = 2 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + lookahead = 2 + group_rotation_frequency = 4 + + [relaychain.default_resources] limits = { memory = "4G", cpu = "2" } requests = { memory = "2G", cpu = "1" } diff --git a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml index 0dfd814e10a..9b3576eaa3c 100644 --- a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml +++ b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.toml @@ -3,9 +3,11 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 2 needed_approvals = 4 - coretime_cores = 2 + +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 2 + num_cores = 2 [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" diff --git a/polkadot/zombienet_tests/misc/0001-paritydb.toml b/polkadot/zombienet_tests/misc/0001-paritydb.toml index 399f848d3ac..b3ce2081b11 100644 --- a/polkadot/zombienet_tests/misc/0001-paritydb.toml +++ b/polkadot/zombienet_tests/misc/0001-paritydb.toml @@ -3,9 +3,11 @@ timeout = 1000 bootnode = true [relaychain.genesis.runtimeGenesis.patch.configuration.config] - max_validators_per_core = 1 needed_approvals = 3 +[relaychain.genesis.runtimeGenesis.patch.configuration.config.scheduler_params] + max_validators_per_core = 1 + [relaychain] default_image = "{{ZOMBIENET_INTEGRATION_TEST_IMAGE}}" chain = "rococo-local" -- GitLab From 761937ecdc8f208361ae2a1154e0f1e6ecf57429 Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghe <49718502+alexggh@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:21:00 +0200 Subject: [PATCH 278/283] Fix accidental no-shows on node restart (#3277) If approval was in progress we didn't actually restart it, so we end up in a situation where we distribute our assignment, but we don't distribute any approval. --------- Signed-off-by: Alexandru Gheorghe --- polkadot/node/core/approval-voting/src/lib.rs | 85 +- .../approval-voting/src/persisted_entries.rs | 7 + .../node/core/approval-voting/src/tests.rs | 744 +++++++++++++++++- 3 files changed, 780 insertions(+), 56 deletions(-) diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index 456ae319787..8cc16a6e1ec 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -1253,13 +1253,20 @@ async fn handle_actions( Action::BecomeActive => { *mode = Mode::Active; - let messages = distribution_messages_for_activation( + let (messages, next_actions) = distribution_messages_for_activation( + ctx, overlayed_db, state, delayed_approvals_timers, - )?; + session_info_provider, + ) + .await?; ctx.send_messages(messages.into_iter()).await; + let next_actions: Vec = + next_actions.into_iter().map(|v| v.clone()).chain(actions_iter).collect(); + + actions_iter = next_actions.into_iter(); }, Action::Conclude => { conclude = true; @@ -1313,15 +1320,19 @@ fn get_assignment_core_indices( } } -fn distribution_messages_for_activation( +#[overseer::contextbounds(ApprovalVoting, prefix = self::overseer)] +async fn distribution_messages_for_activation( + ctx: &mut Context, db: &OverlayedBackend<'_, impl Backend>, state: &State, delayed_approvals_timers: &mut DelayedApprovalTimer, -) -> SubsystemResult> { + session_info_provider: &mut RuntimeInfo, +) -> SubsystemResult<(Vec, Vec)> { let all_blocks: Vec = db.load_all_blocks()?; let mut approval_meta = Vec::with_capacity(all_blocks.len()); let mut messages = Vec::new(); + let mut actions = Vec::new(); messages.push(ApprovalDistributionMessage::NewBlocks(Vec::new())); // dummy value. @@ -1396,16 +1407,60 @@ fn distribution_messages_for_activation( &claimed_core_indices, &block_entry, ) { - Ok(bitfield) => messages.push( - ApprovalDistributionMessage::DistributeAssignment( - IndirectAssignmentCertV2 { - block_hash, - validator: assignment.validator_index(), - cert: assignment.cert().clone(), - }, - bitfield, - ), - ), + Ok(bitfield) => { + gum::debug!( + target: LOG_TARGET, + candidate_hash = ?candidate_entry.candidate_receipt().hash(), + ?block_hash, + "Discovered, triggered assignment, not approved yet", + ); + + let indirect_cert = IndirectAssignmentCertV2 { + block_hash, + validator: assignment.validator_index(), + cert: assignment.cert().clone(), + }; + messages.push( + ApprovalDistributionMessage::DistributeAssignment( + indirect_cert.clone(), + bitfield.clone(), + ), + ); + + if !block_entry + .candidate_is_pending_signature(*candidate_hash) + { + let ExtendedSessionInfo { ref executor_params, .. } = + match get_extended_session_info( + session_info_provider, + ctx.sender(), + block_entry.block_hash(), + block_entry.session(), + ) + .await + { + Some(i) => i, + None => continue, + }; + + actions.push(Action::LaunchApproval { + claimed_candidate_indices: bitfield, + candidate_hash: candidate_entry + .candidate_receipt() + .hash(), + indirect_cert, + assignment_tranche: assignment.tranche(), + relay_block_hash: block_hash, + session: block_entry.session(), + executor_params: executor_params.clone(), + candidate: candidate_entry + .candidate_receipt() + .clone(), + backing_group: approval_entry.backing_group(), + distribute_assignment: false, + }); + } + }, Err(err) => { // Should never happen. If we fail here it means the // assignment is null (no cores claimed). @@ -1496,7 +1551,7 @@ fn distribution_messages_for_activation( } messages[0] = ApprovalDistributionMessage::NewBlocks(approval_meta); - Ok(messages) + Ok((messages, actions)) } // Handle an incoming signal from the overseer. Returns true if execution should conclude. diff --git a/polkadot/node/core/approval-voting/src/persisted_entries.rs b/polkadot/node/core/approval-voting/src/persisted_entries.rs index ef47bdb2213..b924a1b52cc 100644 --- a/polkadot/node/core/approval-voting/src/persisted_entries.rs +++ b/polkadot/node/core/approval-voting/src/persisted_entries.rs @@ -588,6 +588,13 @@ impl BlockEntry { !self.candidates_pending_signature.is_empty() } + /// Returns true if candidate hash is in the queue for a signature. + pub fn candidate_is_pending_signature(&self, candidate_hash: CandidateHash) -> bool { + self.candidates_pending_signature + .values() + .any(|context| context.candidate_hash == candidate_hash) + } + /// Candidate hashes for candidates pending signatures fn candidate_hashes_pending_signature(&self) -> Vec { self.candidates_pending_signature diff --git a/polkadot/node/core/approval-voting/src/tests.rs b/polkadot/node/core/approval-voting/src/tests.rs index 9220e84a255..c9053232a4c 100644 --- a/polkadot/node/core/approval-voting/src/tests.rs +++ b/polkadot/node/core/approval-voting/src/tests.rs @@ -78,6 +78,7 @@ struct TestSyncOracle { struct TestSyncOracleHandle { done_syncing_receiver: oneshot::Receiver<()>, + is_major_syncing: Arc, } impl TestSyncOracleHandle { @@ -108,8 +109,9 @@ impl SyncOracle for TestSyncOracle { fn make_sync_oracle(val: bool) -> (Box, TestSyncOracleHandle) { let (tx, rx) = oneshot::channel(); let flag = Arc::new(AtomicBool::new(val)); - let oracle = TestSyncOracle { flag, done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }; - let handle = TestSyncOracleHandle { done_syncing_receiver: rx }; + let oracle = + TestSyncOracle { flag: flag.clone(), done_syncing_sender: Arc::new(Mutex::new(Some(tx))) }; + let handle = TestSyncOracleHandle { done_syncing_receiver: rx, is_major_syncing: flag }; (Box::new(oracle), handle) } @@ -465,6 +467,7 @@ struct HarnessConfigBuilder { clock: Option, backend: Option, assignment_criteria: Option>, + major_syncing: bool, } impl HarnessConfigBuilder { @@ -476,9 +479,19 @@ impl HarnessConfigBuilder { self } + pub fn major_syncing(&mut self, value: bool) -> &mut Self { + self.major_syncing = value; + self + } + + pub fn backend(&mut self, store: TestStore) -> &mut Self { + self.backend = Some(store); + self + } + pub fn build(&mut self) -> HarnessConfig { let (sync_oracle, sync_oracle_handle) = - self.sync_oracle.take().unwrap_or_else(|| make_sync_oracle(false)); + self.sync_oracle.take().unwrap_or_else(|| make_sync_oracle(self.major_syncing)); let assignment_criteria = self .assignment_criteria @@ -736,11 +749,13 @@ struct BlockConfig { slot: Slot, candidates: Option>, session_info: Option, + end_syncing: bool, } struct ChainBuilder { blocks_by_hash: HashMap, blocks_at_height: BTreeMap>, + is_major_syncing: Arc, } impl ChainBuilder { @@ -748,16 +763,28 @@ impl ChainBuilder { const GENESIS_PARENT_HASH: Hash = Hash::repeat_byte(0x00); pub fn new() -> Self { - let mut builder = - Self { blocks_by_hash: HashMap::new(), blocks_at_height: BTreeMap::new() }; + let mut builder = Self { + blocks_by_hash: HashMap::new(), + blocks_at_height: BTreeMap::new(), + is_major_syncing: Arc::new(AtomicBool::new(false)), + }; builder.add_block_inner( Self::GENESIS_HASH, Self::GENESIS_PARENT_HASH, 0, - BlockConfig { slot: Slot::from(0), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(0), + candidates: None, + session_info: None, + end_syncing: false, + }, ); builder } + pub fn major_syncing(&mut self, major_syncing: Arc) -> &mut Self { + self.is_major_syncing = major_syncing; + self + } pub fn add_block( &mut self, @@ -808,8 +835,16 @@ impl ChainBuilder { } ancestry.reverse(); - import_block(overseer, ancestry.as_ref(), *number, block_config, false, i > 0) - .await; + import_block( + overseer, + ancestry.as_ref(), + *number, + block_config, + false, + i > 0, + self.is_major_syncing.clone(), + ) + .await; let _: Option<()> = future::pending().timeout(Duration::from_millis(100)).await; } } @@ -863,6 +898,7 @@ async fn import_block( config: &BlockConfig, gap: bool, fork: bool, + major_syncing: Arc, ) { let (new_head, new_header) = &hashes[hashes.len() - 1]; let candidates = config.candidates.clone().unwrap_or(vec![( @@ -891,6 +927,12 @@ async fn import_block( h_tx.send(Ok(Some(new_header.clone()))).unwrap(); } ); + + let is_major_syncing = major_syncing.load(Ordering::SeqCst); + if config.end_syncing { + major_syncing.store(false, Ordering::SeqCst); + } + if !fork { let mut _ancestry_step = 0; if gap { @@ -931,7 +973,7 @@ async fn import_block( } } - if number > 0 { + if number > 0 && !is_major_syncing { assert_matches!( overseer_recv(overseer).await, AllMessages::RuntimeApi( @@ -944,7 +986,6 @@ async fn import_block( c_tx.send(Ok(inclusion_events)).unwrap(); } ); - assert_matches!( overseer_recv(overseer).await, AllMessages::RuntimeApi( @@ -984,14 +1025,14 @@ async fn import_block( ); } - if number == 0 { + if number == 0 && !is_major_syncing { assert_matches!( overseer_recv(overseer).await, AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks(v)) => { assert_eq!(v.len(), 0usize); } ); - } else { + } else if number > 0 && !is_major_syncing { if !fork { // SessionInfo won't be called for forks - it's already cached assert_matches!( @@ -1031,20 +1072,23 @@ async fn import_block( ); } - assert_matches!( - overseer_recv(overseer).await, - AllMessages::ApprovalDistribution( - ApprovalDistributionMessage::NewBlocks(mut approval_vec) - ) => { - assert_eq!(approval_vec.len(), 1); - let metadata = approval_vec.pop().unwrap(); - let hash = &hashes[number as usize]; - let parent_hash = &hashes[(number - 1) as usize]; - assert_eq!(metadata.hash, hash.0.clone()); - assert_eq!(metadata.parent_hash, parent_hash.0.clone()); - assert_eq!(metadata.slot, config.slot); - } - ); + if !is_major_syncing { + assert_matches!( + overseer_recv(overseer).await, + + AllMessages::ApprovalDistribution( + ApprovalDistributionMessage::NewBlocks(mut approval_vec) + ) => { + assert_eq!(approval_vec.len(), 1); + let metadata = approval_vec.pop().unwrap(); + let hash = &hashes[number as usize]; + let parent_hash = &hashes[(number - 1) as usize]; + assert_eq!(metadata.hash, hash.0.clone()); + assert_eq!(metadata.parent_hash, parent_hash.0.clone()); + assert_eq!(metadata.slot, config.slot); + } + ); + } } } @@ -1072,7 +1116,7 @@ fn subsystem_rejects_bad_assignment_ok_criteria() { block_hash, head, 1, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); builder.build(&mut virtual_overseer).await; @@ -1135,7 +1179,7 @@ fn subsystem_rejects_bad_assignment_err_criteria() { block_hash, head, 1, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); builder.build(&mut virtual_overseer).await; @@ -1240,6 +1284,7 @@ fn subsystem_rejects_approval_if_no_candidate_entry() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(1), GroupIndex(1))]), session_info: None, + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -1345,7 +1390,12 @@ fn subsystem_rejects_approval_before_assignment() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1398,7 +1448,12 @@ fn subsystem_rejects_assignment_in_future() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(0), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(0), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1472,6 +1527,7 @@ fn subsystem_accepts_duplicate_assignment() { (candidate_receipt2, CoreIndex(1), GroupIndex(1)), ]), session_info: None, + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -1537,7 +1593,12 @@ fn subsystem_rejects_assignment_with_unknown_candidate() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1582,7 +1643,12 @@ fn subsystem_rejects_oversized_bitfields() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1650,7 +1716,12 @@ fn subsystem_accepts_and_imports_approval_after_assignment() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1741,6 +1812,7 @@ fn subsystem_second_approval_import_only_schedules_wakeups() { slot: Slot::from(0), candidates: None, session_info: Some(session_info), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -1824,7 +1896,12 @@ fn subsystem_assignment_import_updates_candidate_entry_and_schedules_wakeup() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1873,7 +1950,12 @@ fn subsystem_process_wakeup_schedules_wakeup() { block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot: Slot::from(1), candidates: None, session_info: None }, + BlockConfig { + slot: Slot::from(1), + candidates: None, + session_info: None, + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -1925,7 +2007,7 @@ fn linear_import_act_on_leaf() { hash, head, i, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); head = hash; } @@ -1983,7 +2065,7 @@ fn forkful_import_at_same_height_act_on_leaf() { hash, head, i, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); head = hash; } @@ -1997,7 +2079,7 @@ fn forkful_import_at_same_height_act_on_leaf() { hash, head, session, - BlockConfig { slot, candidates: None, session_info: None }, + BlockConfig { slot, candidates: None, session_info: None, end_syncing: false }, ); } builder.build(&mut virtual_overseer).await; @@ -2168,6 +2250,7 @@ fn import_checked_approval_updates_entries_and_schedules() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), session_info: Some(session_info), + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -2323,6 +2406,7 @@ fn subsystem_import_checked_approval_sets_one_block_bit_at_a_time() { (candidate_receipt2, CoreIndex(1), GroupIndex(1)), ]), session_info: Some(session_info), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -2445,6 +2529,7 @@ fn approved_ancestor_test( slot: Slot::from(i as u64), candidates: Some(vec![(candidate_receipt, CoreIndex(0), GroupIndex(0))]), session_info: None, + end_syncing: false, }, ); } @@ -2623,13 +2708,19 @@ fn subsystem_validate_approvals_cache() { slot, candidates: candidates.clone(), session_info: Some(session_info.clone()), + end_syncing: false, }, ) .add_block( fork_block_hash, ChainBuilder::GENESIS_HASH, 1, - BlockConfig { slot, candidates, session_info: Some(session_info) }, + BlockConfig { + slot, + candidates, + session_info: Some(session_info), + end_syncing: false, + }, ) .build(&mut virtual_overseer) .await; @@ -2740,6 +2831,7 @@ fn subsystem_doesnt_distribute_duplicate_compact_assignments() { (candidate_receipt2.clone(), CoreIndex(1), GroupIndex(1)), ]), session_info: None, + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -2997,6 +3089,7 @@ where slot, candidates: Some(vec![(candidate_receipt, CoreIndex(0), GroupIndex(2))]), session_info: Some(session_info), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -3314,6 +3407,7 @@ fn pre_covers_dont_stall_approval() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), session_info: Some(session_info), + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -3491,6 +3585,7 @@ fn waits_until_approving_assignments_are_old_enough() { slot, candidates: Some(vec![(candidate_descriptor, CoreIndex(0), GroupIndex(0))]), session_info: Some(session_info), + end_syncing: false, }, ); builder.build(&mut virtual_overseer).await; @@ -3705,6 +3800,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_count() { slot, candidates: candidates.clone(), session_info: Some(session_info.clone()), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -3943,8 +4039,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { let store = config.backend(); test_harness(config, |test_harness| async move { - let TestHarness { mut virtual_overseer, clock, sync_oracle_handle: _sync_oracle_handle } = - test_harness; + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle: _ } = test_harness; assert_matches!( overseer_recv(&mut virtual_overseer).await, @@ -4006,6 +4101,7 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { slot, candidates: candidates.clone(), session_info: Some(session_info.clone()), + end_syncing: false, }, ) .build(&mut virtual_overseer) @@ -4040,3 +4136,569 @@ fn test_approval_is_sent_on_max_approval_coalesce_wait() { virtual_overseer }); } + +// Builds a chain with a fork where both relay blocks include the same candidate. +async fn build_chain_with_two_blocks_with_one_candidate_each( + block_hash1: Hash, + block_hash2: Hash, + slot: Slot, + sync_oracle_handle: TestSyncOracleHandle, + candidate_receipt: CandidateReceipt, +) -> (ChainBuilder, SessionInfo) { + let validators = vec![ + Sr25519Keyring::Alice, + Sr25519Keyring::Bob, + Sr25519Keyring::Charlie, + Sr25519Keyring::Dave, + Sr25519Keyring::Eve, + ]; + let session_info = SessionInfo { + validator_groups: IndexedVec::>::from(vec![ + vec![ValidatorIndex(0), ValidatorIndex(1)], + vec![ValidatorIndex(2)], + vec![ValidatorIndex(3), ValidatorIndex(4)], + ]), + ..session_info(&validators) + }; + + let candidates = Some(vec![(candidate_receipt.clone(), CoreIndex(0), GroupIndex(0))]); + let mut chain_builder = ChainBuilder::new(); + + chain_builder + .major_syncing(sync_oracle_handle.is_major_syncing.clone()) + .add_block( + block_hash1, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates: candidates.clone(), + session_info: Some(session_info.clone()), + end_syncing: false, + }, + ) + .add_block( + block_hash2, + ChainBuilder::GENESIS_HASH, + 1, + BlockConfig { + slot, + candidates, + session_info: Some(session_info.clone()), + end_syncing: true, + }, + ); + (chain_builder, session_info) +} + +async fn setup_overseer_with_two_blocks_each_with_one_assignment_triggered( + virtual_overseer: &mut VirtualOverseer, + store: TestStore, + clock: &Box, + sync_oracle_handle: TestSyncOracleHandle, +) { + assert_matches!( + overseer_recv(virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let candidate_hash = candidate_receipt.hash(); + let slot = Slot::from(1); + let (chain_builder, _session_info) = build_chain_with_two_blocks_with_one_candidate_each( + block_hash, + fork_block_hash, + slot, + sync_oracle_handle, + candidate_receipt, + ) + .await; + chain_builder.build(virtual_overseer).await; + + assert!(!clock.inner.lock().current_wakeup_is(1)); + clock.inner.lock().wakeup_all(1); + + assert!(clock.inner.lock().current_wakeup_is(slot_to_tick(slot))); + clock.inner.lock().wakeup_all(slot_to_tick(slot)); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + clock.inner.lock().wakeup_all(slot_to_tick(slot + 2)); + + assert_eq!(clock.inner.lock().wakeups.len(), 0); + + futures_timer::Delay::new(Duration::from_millis(200)).await; + + let candidate_entry = store.load_candidate_entry(&candidate_hash).unwrap().unwrap(); + let our_assignment = + candidate_entry.approval_entry(&block_hash).unwrap().our_assignment().unwrap(); + assert!(our_assignment.triggered()); +} + +// Tests that for candidates that we did not approve yet, for which we triggered the assignment and +// the approval work we restart the work to approve it. +#[test] +fn subsystem_relaunches_approval_work_on_restart() { + let assignment_criteria = Box::new(MockAssignmentCriteria( + || { + let mut assignments = HashMap::new(); + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }) + .into(), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert_v2(AssignmentCertKindV2::RelayVRFModuloCompact { + core_bitfield: vec![CoreIndex(0), CoreIndex(1), CoreIndex(2)] + .try_into() + .unwrap(), + }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + |_| Ok(0), + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + let store_clone = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + setup_overseer_with_two_blocks_each_with_one_assignment_triggered( + &mut virtual_overseer, + store, + &clock, + sync_oracle_handle, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _ + )) => { + } + ); + + // Bail early after the assignment has been distributed but before we answer with the mocked + // approval from CandidateValidation. + virtual_overseer + }); + + // Restart a new approval voting subsystem with the same database and major syncing true untill + // the last leaf. + let config = HarnessConfigBuilder::default().backend(store_clone).major_syncing(true).build(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let slot = Slot::from(1); + clock.inner.lock().set_tick(slot_to_tick(slot + 2)); + let (chain_builder, session_info) = build_chain_with_two_blocks_with_one_candidate_each( + block_hash, + fork_block_hash, + slot, + sync_oracle_handle, + candidate_receipt, + ) + .await; + + chain_builder.build(&mut virtual_overseer).await; + + futures_timer::Delay::new(Duration::from_millis(2000)).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, si_tx), + ) + ) => { + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionExecutorParams(_, si_tx), + ) + ) => { + // Make sure all SessionExecutorParams calls are not made for the leaf (but for its relay parent) + si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), ) + ) => { + si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap(); + } + ); + + // On major syncing ending Approval voting should send all the necessary messages for a + // candidate to be approved. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks( + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + // Guarantees the approval work has been relaunched. + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive { + exec_kind, + response_sender, + .. + }) if exec_kind == PvfExecKind::Approval => { + response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); +} + +// Test that cached approvals, which are candidates that we approved but we didn't issue +// the signature yet because we want to coalesce it with more candidate are sent after restart. +#[test] +fn subsystem_sends_pending_approvals_on_approval_restart() { + let assignment_criteria = Box::new(MockAssignmentCriteria( + || { + let mut assignments = HashMap::new(); + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert(AssignmentCertKind::RelayVRFModulo { sample: 0 }) + .into(), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + + let _ = assignments.insert( + CoreIndex(0), + approval_db::v2::OurAssignment { + cert: garbage_assignment_cert_v2(AssignmentCertKindV2::RelayVRFModuloCompact { + core_bitfield: vec![CoreIndex(0), CoreIndex(1), CoreIndex(2)] + .try_into() + .unwrap(), + }), + tranche: 0, + validator_index: ValidatorIndex(0), + triggered: false, + } + .into(), + ); + assignments + }, + |_| Ok(0), + )); + let config = HarnessConfigBuilder::default().assignment_criteria(assignment_criteria).build(); + let store = config.backend(); + let store_clone = config.backend(); + + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + setup_overseer_with_two_blocks_each_with_one_assignment_triggered( + &mut virtual_overseer, + store, + &clock, + sync_oracle_handle, + ) + .await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + recover_available_data(&mut virtual_overseer).await; + fetch_validation_code(&mut virtual_overseer).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _ + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::CandidateValidation(CandidateValidationMessage::ValidateFromExhaustive { + exec_kind, + response_sender, + .. + }) if exec_kind == PvfExecKind::Approval => { + response_sender.send(Ok(ValidationResult::Valid(Default::default(), Default::default()))) + .unwrap(); + } + ); + + // Configure a big coalesce number, so that the signature is cached instead of being sent to + // approval-distribution. + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 6, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 6, + })); + } + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); + + let config = HarnessConfigBuilder::default().backend(store_clone).major_syncing(true).build(); + // On restart signatures should be sent to approval-distribution without relaunching the + // approval work. + test_harness(config, |test_harness| async move { + let TestHarness { mut virtual_overseer, clock, sync_oracle_handle } = test_harness; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ChainApi(ChainApiMessage::FinalizedBlockNumber(rx)) => { + rx.send(Ok(0)).unwrap(); + } + ); + + let block_hash = Hash::repeat_byte(0x01); + let fork_block_hash = Hash::repeat_byte(0x02); + let candidate_commitments = CandidateCommitments::default(); + let mut candidate_receipt = dummy_candidate_receipt(block_hash); + candidate_receipt.commitments_hash = candidate_commitments.hash(); + let slot = Slot::from(1); + + clock.inner.lock().set_tick(slot_to_tick(slot + 2)); + let (chain_builder, session_info) = build_chain_with_two_blocks_with_one_candidate_each( + block_hash, + fork_block_hash, + slot, + sync_oracle_handle, + candidate_receipt, + ) + .await; + chain_builder.build(&mut virtual_overseer).await; + + futures_timer::Delay::new(Duration::from_millis(2000)).await; + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NewBlocks( + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeAssignment( + _, + _, + )) => { + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionInfo(_, si_tx), + ) + ) => { + si_tx.send(Ok(Some(session_info.clone()))).unwrap(); + } + ); + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request( + _, + RuntimeApiRequest::SessionExecutorParams(_, si_tx), + ) + ) => { + // Make sure all SessionExecutorParams calls are not made for the leaf (but for its relay parent) + si_tx.send(Ok(Some(ExecutorParams::default()))).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi( + RuntimeApiMessage::Request(_, RuntimeApiRequest::NodeFeatures(_, si_tx), ) + ) => { + si_tx.send(Ok(NodeFeatures::EMPTY)).unwrap(); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::RuntimeApi(RuntimeApiMessage::Request(_, RuntimeApiRequest::ApprovalVotingParams(_, sender))) => { + let _ = sender.send(Ok(ApprovalVotingParams { + max_approval_coalesce_count: 1, + })); + } + ); + + assert_matches!( + overseer_recv(&mut virtual_overseer).await, + AllMessages::ApprovalDistribution(ApprovalDistributionMessage::DistributeApproval(_)) + ); + + // Assert that there are no more messages being sent by the subsystem + assert!(overseer_recv(&mut virtual_overseer).timeout(TIMEOUT / 2).await.is_none()); + + virtual_overseer + }); +} -- GitLab From c244a94e4a77c0798c5a45d3004ec2389378b394 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 29 Feb 2024 11:41:11 +0000 Subject: [PATCH 279/283] update development setup in sdk-docs (#3506) Co-authored-by: Liam Aharon --- .../development_environment_advice.rs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/sdk/src/reference_docs/development_environment_advice.rs b/docs/sdk/src/reference_docs/development_environment_advice.rs index 43176959793..21bbe78836c 100644 --- a/docs/sdk/src/reference_docs/development_environment_advice.rs +++ b/docs/sdk/src/reference_docs/development_environment_advice.rs @@ -111,3 +111,74 @@ //! If you have a powerful remote server available, you may consider using //! [cargo-remote](https://github.com/sgeisler/cargo-remote) to execute cargo commands on it, //! freeing up local resources for other tasks like `rust-analyzer`. +//! +//! When using `cargo-remote`, you can configure your editor to perform the the typical +//! "check-on-save" remotely as well. The configuration for VSCode is as follows: +//! +//! ```json +//! { +//! "rust-analyzer.cargo.buildScripts.overrideCommand": [ +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! ], +//! "rust-analyzer.check.overrideCommand": [ +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--workspace", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! ], +//! } +//! ``` +//! +//! //! and the same in Lua for `neovim/nvim-lspconfig`: +//! +//! ```lua +//! ["rust-analyzer"] = { +//! cargo = { +//! buildScripts = { +//! overrideCommand = { +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! }, +//! }, +//! check = { +//! overrideCommand = { +//! "cargo", +//! "remote", +//! "--build-env", +//! "SKIP_WASM_BUILD=1", +//! "--", +//! "check", +//! "--workspace", +//! "--message-format=json", +//! "--all-targets", +//! "--all-features", +//! "--target-dir=target/rust-analyzer" +//! }, +//! }, +//! }, +//! }, +//! ``` -- GitLab From 7f5d308d2983dcce324a8625edf3f2a838209da8 Mon Sep 17 00:00:00 2001 From: Andrei Sandu <54316454+sandreim@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:32:58 +0200 Subject: [PATCH 280/283] Enable elastic scaling node feature in local testnets genesis (#3509) Signed-off-by: Andrei Sandu --- Cargo.lock | 1 + polkadot/node/service/Cargo.toml | 5 ++- polkadot/node/service/src/chain_spec.rs | 7 +++- polkadot/runtime/parachains/src/builder.rs | 24 ++++++++---- .../functional/0012-elastic-scaling-mvp.zndsl | 11 +----- .../functional/0012-enable-node-feature.js | 37 ------------------- 6 files changed, 27 insertions(+), 58 deletions(-) delete mode 100644 polkadot/zombienet_tests/functional/0012-enable-node-feature.js diff --git a/Cargo.lock b/Cargo.lock index 3838ed0e94a..991541ee84e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13526,6 +13526,7 @@ version = "7.0.0" dependencies = [ "assert_matches", "async-trait", + "bitvec", "env_logger 0.9.3", "frame-benchmarking", "frame-benchmarking-cli", diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml index 8fd9f20b7bc..734dcbdeb44 100644 --- a/polkadot/node/service/Cargo.toml +++ b/polkadot/node/service/Cargo.toml @@ -93,6 +93,7 @@ kvdb-rocksdb = { version = "0.19.0", optional = true } parity-db = { version = "0.4.12", optional = true } codec = { package = "parity-scale-codec", version = "3.6.1" } parking_lot = "0.12.1" +bitvec = { version = "1.0.1", optional = true } # Polkadot polkadot-core-primitives = { path = "../../core-primitives" } @@ -184,8 +185,8 @@ full-node = [ ] # Configure the native runtimes to use. -westend-native = ["westend-runtime", "westend-runtime-constants"] -rococo-native = ["rococo-runtime", "rococo-runtime-constants"] +westend-native = ["bitvec", "westend-runtime", "westend-runtime-constants"] +rococo-native = ["bitvec", "rococo-runtime", "rococo-runtime-constants"] runtime-benchmarks = [ "frame-benchmarking-cli/runtime-benchmarks", diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index af05af87a46..1c44b17b6fd 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -122,7 +122,9 @@ pub fn wococo_config() -> Result { fn default_parachains_host_configuration( ) -> polkadot_runtime_parachains::configuration::HostConfiguration { - use polkadot_primitives::{AsyncBackingParams, MAX_CODE_SIZE, MAX_POV_SIZE}; + use polkadot_primitives::{ + vstaging::node_features::FeatureIndex, AsyncBackingParams, MAX_CODE_SIZE, MAX_POV_SIZE, + }; polkadot_runtime_parachains::configuration::HostConfiguration { validation_upgrade_cooldown: 2u32, @@ -155,6 +157,9 @@ fn default_parachains_host_configuration( max_candidate_depth: 3, allowed_ancestry_len: 2, }, + node_features: bitvec::vec::BitVec::from_element( + 1u8 << (FeatureIndex::ElasticScalingMVP as usize), + ), scheduler_params: SchedulerParams { lookahead: 2, group_rotation_frequency: 20, diff --git a/polkadot/runtime/parachains/src/builder.rs b/polkadot/runtime/parachains/src/builder.rs index 0e4e659fef2..5b218addb1a 100644 --- a/polkadot/runtime/parachains/src/builder.rs +++ b/polkadot/runtime/parachains/src/builder.rs @@ -25,12 +25,13 @@ use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec}; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use primitives::{ - collator_signature_payload, AvailabilityBitfield, BackedCandidate, CandidateCommitments, - CandidateDescriptor, CandidateHash, CollatorId, CollatorSignature, CommittedCandidateReceipt, - CompactStatement, CoreIndex, DisputeStatement, DisputeStatementSet, GroupIndex, HeadData, - Id as ParaId, IndexedVec, InherentData as ParachainsInherentData, InvalidDisputeStatementKind, - PersistedValidationData, SessionIndex, SigningContext, UncheckedSigned, - ValidDisputeStatementKind, ValidationCode, ValidatorId, ValidatorIndex, ValidityAttestation, + collator_signature_payload, vstaging::node_features::FeatureIndex, AvailabilityBitfield, + BackedCandidate, CandidateCommitments, CandidateDescriptor, CandidateHash, CollatorId, + CollatorSignature, CommittedCandidateReceipt, CompactStatement, CoreIndex, DisputeStatement, + DisputeStatementSet, GroupIndex, HeadData, Id as ParaId, IndexedVec, + InherentData as ParachainsInherentData, InvalidDisputeStatementKind, PersistedValidationData, + SessionIndex, SigningContext, UncheckedSigned, ValidDisputeStatementKind, ValidationCode, + ValidatorId, ValidatorIndex, ValidityAttestation, }; use sp_core::{sr25519, H256}; use sp_runtime::{ @@ -509,7 +510,7 @@ impl BenchBuilder { .iter() .map(|(seed, num_votes)| { assert!(*num_votes <= validators.len() as u32); - let (para_id, _core_idx, group_idx) = self.create_indexes(*seed); + let (para_id, core_idx, group_idx) = self.create_indexes(*seed); // This generates a pair and adds it to the keystore, returning just the public. let collator_public = CollatorId::generate_pair(None); @@ -586,11 +587,18 @@ impl BenchBuilder { }) .collect(); + // Check if the elastic scaling bit is set, if so we need to supply the core index + // in the generated candidate. + let core_idx = configuration::Pallet::::config() + .node_features + .get(FeatureIndex::ElasticScalingMVP as usize) + .map(|_the_bit| core_idx); + BackedCandidate::::new( candidate, validity_votes, bitvec::bitvec![u8, bitvec::order::Lsb0; 1; group_validators.len()], - None, + core_idx, ) }) .collect() diff --git a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl index a7193c9282b..edc87c802a0 100644 --- a/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl +++ b/polkadot/zombienet_tests/functional/0012-elastic-scaling-mvp.zndsl @@ -1,4 +1,4 @@ -Description: Test that a paraid acquiring multiple cores does not brick itself if ElasticScalingMVP feature is enabled +Description: Test that a paraid acquiring multiple cores does not brick itself if ElasticScalingMVP feature is enabled in genesis Network: ./0012-elastic-scaling-mvp.toml Creds: config @@ -15,14 +15,5 @@ alice: js-script ./0012-register-para.js return is 0 within 600 seconds validator: reports substrate_block_height{status="finalized"} is at least 35 within 100 seconds -# Parachain will now be stalled -validator: parachain 2000 block height is lower than 20 within 300 seconds - -# Enable the ElasticScalingMVP node feature. -alice: js-script ./0012-enable-node-feature.js with "1" return is 0 within 600 seconds - -# Wait two sessions for the config to be updated. -sleep 120 seconds - # Ensure parachain is now making progress. validator: parachain 2000 block height is at least 30 within 200 seconds diff --git a/polkadot/zombienet_tests/functional/0012-enable-node-feature.js b/polkadot/zombienet_tests/functional/0012-enable-node-feature.js deleted file mode 100644 index 4822e1f6644..00000000000 --- a/polkadot/zombienet_tests/functional/0012-enable-node-feature.js +++ /dev/null @@ -1,37 +0,0 @@ -async function run(nodeName, networkInfo, index) { - const { wsUri, userDefinedTypes } = networkInfo.nodesByName[nodeName]; - const api = await zombie.connect(wsUri, userDefinedTypes); - - await zombie.util.cryptoWaitReady(); - - // account to submit tx - const keyring = new zombie.Keyring({ type: "sr25519" }); - const alice = keyring.addFromUri("//Alice"); - - await new Promise(async (resolve, reject) => { - const unsub = await api.tx.sudo - .sudo(api.tx.configuration.setNodeFeature(Number(index), true)) - .signAndSend(alice, ({ status, isError }) => { - if (status.isInBlock) { - console.log( - `Transaction included at blockhash ${status.asInBlock}`, - ); - } else if (status.isFinalized) { - console.log( - `Transaction finalized at blockHash ${status.asFinalized}`, - ); - unsub(); - return resolve(); - } else if (isError) { - console.log(`Transaction error`); - reject(`Transaction error`); - } - }); - }); - - - - return 0; -} - -module.exports = { run }; -- GitLab From c0e52a9ed61451152c4e096c58f24fb4e329bd64 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:08:08 +0000 Subject: [PATCH 281/283] Fix call enum's metadata regression (#3513) This fixes an issue introduced in https://github.com/paritytech/substrate/pull/14101, in which I removed the `Call` enum's documentation and replaced it with a link to the `Pallet` struct, but this also removed any docs related to call from the metadata. I tried to add a regression test for this, but it seems to me that this is not possible, given that using `type-info` we only assert in type-ids for `Call`, `Event` and `Error`. I removed some doc comments from a test setup in `frame-support-test` to demonstrate the issue there. @jsdw do you have any comments on this? I also fixed a small issue in the custom html/css of `polkadot-sdk-doc` crate, making sure it does not affect the rust-doc page of all other crates. - [x] Investigate a regression test - [x] prdoc --- docs/sdk/headers/header.html | 111 +++++++++--------- docs/sdk/headers/theme.css | 25 ++-- prdoc/pr_3513.prdoc | 18 +++ substrate/frame/support/Cargo.toml | 21 +++- .../procedural/src/pallet/expand/call.rs | 21 +--- substrate/frame/support/test/tests/pallet.rs | 64 +++++++--- 6 files changed, 157 insertions(+), 103 deletions(-) create mode 100644 prdoc/pr_3513.prdoc diff --git a/docs/sdk/headers/header.html b/docs/sdk/headers/header.html index 68dc5d5509e..e28458c4ccc 100644 --- a/docs/sdk/headers/header.html +++ b/docs/sdk/headers/header.html @@ -54,7 +54,7 @@ sidebarElems.style.display = 'none'; // Add click event listener to the button - expandButton.addEventListener('click', function() { + expandButton.addEventListener('click', function () { // Toggle the display of the '.sidebar-elems' if (sidebarElems.style.display === 'none') { sidebarElems.style.display = 'block'; @@ -72,6 +72,9 @@ if (!crate_name.textContent.startsWith("polkadot_sdk_docs")) { console.log("skipping -- not `polkadot_sdk_docs`"); return; + } else { + // insert class 'sdk-docs' to the body, so it enables the custom css rules. + document.body.classList.add("sdk-docs"); } createToC(); @@ -82,58 +85,60 @@ diff --git a/docs/sdk/headers/theme.css b/docs/sdk/headers/theme.css index bb9254ec4a8..a488e15c36b 100644 --- a/docs/sdk/headers/theme.css +++ b/docs/sdk/headers/theme.css @@ -1,16 +1,17 @@ :root { - --polkadot-pink: #E6007A ; - --polkadot-green: #56F39A ; - --polkadot-lime: #D3FF33 ; - --polkadot-cyan: #00B2FF ; - --polkadot-purple: #552BBF ; - } - -body > nav.sidebar > div.sidebar-crate > a > img { - /* logo width, given that the sidebar width is 200px; */ - width: 190px; + --polkadot-pink: #E6007A; + --polkadot-green: #56F39A; + --polkadot-lime: #D3FF33; + --polkadot-cyan: #00B2FF; + --polkadot-purple: #552BBF; } -body nav.sidebar { - flex: 0 0 250px; +body.sdk-docs { + nav.sidebar>div.sidebar-crate>a>img { + width: 190px; + } + + nav.sidebar { + flex: 0 0 250px; + } } diff --git a/prdoc/pr_3513.prdoc b/prdoc/pr_3513.prdoc new file mode 100644 index 00000000000..e1f2afe280a --- /dev/null +++ b/prdoc/pr_3513.prdoc @@ -0,0 +1,18 @@ +# 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: Fix call enum's metadata regression + +doc: + - audience: Runtime Dev + - audience: Runtime User + description: | + This PR fixes an issue where in the metadata of all FRAME-based chains, the documentation for + all extrinsic/call/transactions has been replaced by a single line saying "see Pallet::name". + + Many wallets display the metadata of transactions to the user before signing, and this bug + might have affected this process. + +crates: + - name: frame + - name: frame-support diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml index 72e2d0bfa56..c19f478c803 100644 --- a/substrate/frame/support/Cargo.toml +++ b/substrate/frame/support/Cargo.toml @@ -18,13 +18,24 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] array-bytes = { version = "6.1", default-features = false } serde = { features = ["alloc", "derive"], workspace = true } -codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive", "max-encoded-len"] } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "16.0.0", default-features = false, features = ["current"] } -sp-api = { path = "../../primitives/api", default-features = false, features = ["frame-metadata"] } +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ + "derive", + "max-encoded-len", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } +frame-metadata = { version = "16.0.0", default-features = false, features = [ + "current", +] } +sp-api = { path = "../../primitives/api", default-features = false, features = [ + "frame-metadata", +] } sp-std = { path = "../../primitives/std", default-features = false } sp-io = { path = "../../primitives/io", default-features = false } -sp-runtime = { path = "../../primitives/runtime", default-features = false, features = ["serde"] } +sp-runtime = { path = "../../primitives/runtime", default-features = false, features = [ + "serde", +] } sp-tracing = { path = "../../primitives/tracing", default-features = false } sp-core = { path = "../../primitives/core", default-features = false } sp-arithmetic = { path = "../../primitives/arithmetic", default-features = false } diff --git a/substrate/frame/support/procedural/src/pallet/expand/call.rs b/substrate/frame/support/procedural/src/pallet/expand/call.rs index f43faba1ee0..f395872c8a8 100644 --- a/substrate/frame/support/procedural/src/pallet/expand/call.rs +++ b/substrate/frame/support/procedural/src/pallet/expand/call.rs @@ -18,7 +18,7 @@ use crate::{ pallet::{ expand::warnings::{weight_constant_warning, weight_witness_warning}, - parse::call::{CallVariantDef, CallWeightDef}, + parse::call::CallWeightDef, Def, }, COUNTER, @@ -112,22 +112,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { } debug_assert_eq!(fn_weight.len(), methods.len()); - let map_fn_docs = if !def.dev_mode { - // Emit the [`Pallet::method`] documentation only for non-dev modes. - |method: &CallVariantDef| { - let reference = format!("See [`Pallet::{}`].", method.name); - quote!(#reference) - } - } else { - // For the dev-mode do not provide a documenation link as it will break the - // `cargo doc` if the pallet is private inside a test. - |method: &CallVariantDef| { - let reference = format!("See `Pallet::{}`.", method.name); - quote!(#reference) - } - }; - - let fn_doc = methods.iter().map(map_fn_docs).collect::>(); + let fn_doc = methods.iter().map(|method| &method.docs).collect::>(); let args_name = methods .iter() @@ -309,7 +294,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { ), #( #cfg_attrs - #[doc = #fn_doc] + #( #[doc = #fn_doc] )* #[codec(index = #call_index)] #fn_name { #( diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs index 7bee4b7c820..607f54ccc13 100644 --- a/substrate/frame/support/test/tests/pallet.rs +++ b/substrate/frame/support/test/tests/pallet.rs @@ -209,7 +209,7 @@ pub mod pallet { where T::AccountId: From + From + SomeAssociation1, { - /// Doc comment put in metadata + /// call foo doc comment put in metadata #[pallet::call_index(0)] #[pallet::weight(Weight::from_parts(*foo as u64, 0))] pub fn foo( @@ -225,7 +225,7 @@ pub mod pallet { Ok(().into()) } - /// Doc comment put in metadata + /// call foo_storage_layer doc comment put in metadata #[pallet::call_index(1)] #[pallet::weight({1})] pub fn foo_storage_layer( @@ -270,7 +270,7 @@ pub mod pallet { #[pallet::error] #[derive(PartialEq, Eq)] pub enum Error { - /// doc comment put into metadata + /// error doc comment put in metadata InsufficientProposersBalance, NonExistentStorageValue, Code(u8), @@ -287,9 +287,8 @@ pub mod pallet { where T::AccountId: SomeAssociation1 + From, { - /// doc comment put in metadata + /// event doc comment put in metadata Proposed(::AccountId), - /// doc Spending(BalanceOf), Something(u32), SomethingElse(::_1), @@ -750,8 +749,7 @@ pub type UncheckedExtrinsic = sp_runtime::testing::TestXt>; frame_support::construct_runtime!( - pub struct Runtime - { + pub struct Runtime { // Exclude part `Storage` in order not to check its metadata in tests. System: frame_system exclude_parts { Pallet, Storage }, Example: pallet, @@ -772,6 +770,14 @@ fn _ensure_call_is_correctly_excluded_and_included(call: RuntimeCall) { } } +fn maybe_docs(doc: Vec<&'static str>) -> Vec<&'static str> { + if cfg!(feature = "no-metadata-docs") { + vec![] + } else { + doc + } +} + #[test] fn transactional_works() { TestExternalities::default().execute_with(|| { @@ -1362,19 +1368,47 @@ fn migrate_from_pallet_version_to_storage_version() { }); } +#[test] +fn pallet_item_docs_in_metadata() { + // call + let call_variants = match meta_type::>().type_info().type_def { + scale_info::TypeDef::Variant(variants) => variants.variants, + _ => unreachable!(), + }; + + assert_eq!(call_variants[0].docs, maybe_docs(vec!["call foo doc comment put in metadata"])); + assert_eq!( + call_variants[1].docs, + maybe_docs(vec!["call foo_storage_layer doc comment put in metadata"]) + ); + assert!(call_variants[2].docs.is_empty()); + + // event + let event_variants = match meta_type::>().type_info().type_def { + scale_info::TypeDef::Variant(variants) => variants.variants, + _ => unreachable!(), + }; + + assert_eq!(event_variants[0].docs, maybe_docs(vec!["event doc comment put in metadata"])); + assert!(event_variants[1].docs.is_empty()); + + // error + let error_variants = match meta_type::>().type_info().type_def { + scale_info::TypeDef::Variant(variants) => variants.variants, + _ => unreachable!(), + }; + + assert_eq!(error_variants[0].docs, maybe_docs(vec!["error doc comment put in metadata"])); + assert!(error_variants[1].docs.is_empty()); + + // storage is already covered in the main `fn metadata` test. +} + #[test] fn metadata() { use codec::Decode; use frame_metadata::{v15::*, *}; - fn maybe_docs(doc: Vec<&'static str>) -> Vec<&'static str> { - if cfg!(feature = "no-metadata-docs") { - vec![] - } else { - doc - } - } - let readme = "Support code for the runtime.\n\nLicense: Apache-2.0\n"; let expected_pallet_doc = vec![" Pallet documentation", readme, readme]; -- GitLab From 650886683d42de45fbcb92645d988248dda6dbba Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Fri, 1 Mar 2024 08:31:48 +0100 Subject: [PATCH 282/283] Add `claim_assets` extrinsic to `pallet-xcm` (#3403) If an XCM execution fails or ends with leftover assets, these will be trapped. In order to claim them, a custom XCM has to be executed, with the `ClaimAsset` instruction. However, arbitrary XCM execution is not allowed everywhere yet and XCM itself is still not easy enough to use for users out there with trapped assets. This new extrinsic in `pallet-xcm` will allow these users to easily claim their assets, without concerning themselves with writing arbitrary XCMs. Part of fixing https://github.com/paritytech/polkadot-sdk/issues/3495 --------- Co-authored-by: command-bot <> Co-authored-by: Adrian Catangiu --- .../assets/asset-hub-rococo/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 146 ++++--- .../assets/asset-hub-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 150 ++++--- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 142 +++--- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 146 ++++--- .../collectives-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 142 +++--- .../contracts/contracts-rococo/src/lib.rs | 7 + .../coretime/coretime-rococo/src/lib.rs | 7 + .../coretime-rococo/src/weights/pallet_xcm.rs | 154 ++++--- .../coretime/coretime-westend/src/lib.rs | 7 + .../src/weights/pallet_xcm.rs | 94 ++-- .../runtimes/people/people-rococo/src/lib.rs | 7 + .../people-rococo/src/weights/pallet_xcm.rs | 412 +++++++++--------- .../runtimes/people/people-westend/src/lib.rs | 7 + .../people-westend/src/weights/pallet_xcm.rs | 412 +++++++++--------- polkadot/runtime/rococo/src/lib.rs | 7 + .../runtime/rococo/src/weights/pallet_xcm.rs | 230 ++++++---- polkadot/runtime/westend/src/lib.rs | 7 + .../runtime/westend/src/weights/pallet_xcm.rs | 238 ++++++---- polkadot/xcm/pallet-xcm/src/benchmarking.rs | 21 +- polkadot/xcm/pallet-xcm/src/lib.rs | 63 +++ polkadot/xcm/pallet-xcm/src/mock.rs | 6 +- polkadot/xcm/pallet-xcm/src/tests/mod.rs | 51 +++ polkadot/xcm/src/lib.rs | 31 +- prdoc/pr_3403.prdoc | 22 + 29 files changed, 1501 insertions(+), 1043 deletions(-) create mode 100644 prdoc/pr_3403.prdoc diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 1c4f49fea0e..a64d4bc2365 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1454,6 +1454,13 @@ impl_runtime_apis! { }); Some((assets, fee_index as u32, dest, verify)) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } impl XcmBridgeHubRouterConfig for Runtime { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs index f8820bbb58c..51b6543bae8 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 25_003_000 picoseconds. - Weight::from_parts(25_800_000, 0) + // Minimum execution time: 22_136_000 picoseconds. + Weight::from_parts(22_518_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 88_832_000 picoseconds. - Weight::from_parts(90_491_000, 0) + // Minimum execution time: 92_277_000 picoseconds. + Weight::from_parts(94_843_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -118,8 +118,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `400` // Estimated: `6196` - // Minimum execution time: 138_911_000 picoseconds. - Weight::from_parts(142_483_000, 0) + // Minimum execution time: 120_110_000 picoseconds. + Weight::from_parts(122_968_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(5)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `496` // Estimated: `6208` - // Minimum execution time: 146_932_000 picoseconds. - Weight::from_parts(153_200_000, 0) + // Minimum execution time: 143_116_000 picoseconds. + Weight::from_parts(147_355_000, 0) .saturating_add(Weight::from_parts(0, 6208)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(7)) @@ -170,8 +170,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_081_000 picoseconds. - Weight::from_parts(7_397_000, 0) + // Minimum execution time: 6_517_000 picoseconds. + Weight::from_parts(6_756_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -181,8 +181,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_007_000 picoseconds. - Weight::from_parts(2_183_000, 0) + // Minimum execution time: 1_894_000 picoseconds. + Weight::from_parts(2_024_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -208,8 +208,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 28_790_000 picoseconds. - Weight::from_parts(29_767_000, 0) + // Minimum execution time: 27_314_000 picoseconds. + Weight::from_parts(28_787_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -234,8 +234,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `363` // Estimated: `3828` - // Minimum execution time: 30_951_000 picoseconds. - Weight::from_parts(31_804_000, 0) + // Minimum execution time: 29_840_000 picoseconds. + Weight::from_parts(30_589_000, 0) .saturating_add(Weight::from_parts(0, 3828)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -246,45 +246,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_164_000 picoseconds. - Weight::from_parts(2_311_000, 0) + // Minimum execution time: 1_893_000 picoseconds. + Weight::from_parts(2_017_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `162` - // Estimated: `11052` - // Minimum execution time: 16_906_000 picoseconds. - Weight::from_parts(17_612_000, 0) - .saturating_add(Weight::from_parts(0, 11052)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `159` + // Estimated: `13524` + // Minimum execution time: 19_211_000 picoseconds. + Weight::from_parts(19_552_000, 0) + .saturating_add(Weight::from_parts(0, 13524)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `166` - // Estimated: `11056` - // Minimum execution time: 17_443_000 picoseconds. - Weight::from_parts(18_032_000, 0) - .saturating_add(Weight::from_parts(0, 11056)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `163` + // Estimated: `13528` + // Minimum execution time: 19_177_000 picoseconds. + Weight::from_parts(19_704_000, 0) + .saturating_add(Weight::from_parts(0, 13528)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `173` - // Estimated: `13538` - // Minimum execution time: 18_992_000 picoseconds. - Weight::from_parts(19_464_000, 0) - .saturating_add(Weight::from_parts(0, 13538)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `16013` + // Minimum execution time: 20_449_000 picoseconds. + Weight::from_parts(21_075_000, 0) + .saturating_add(Weight::from_parts(0, 16013)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -304,36 +304,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `212` // Estimated: `6152` - // Minimum execution time: 28_011_000 picoseconds. - Weight::from_parts(28_716_000, 0) + // Minimum execution time: 26_578_000 picoseconds. + Weight::from_parts(27_545_000, 0) .saturating_add(Weight::from_parts(0, 6152)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `206` - // Estimated: `8621` - // Minimum execution time: 9_533_000 picoseconds. - Weight::from_parts(9_856_000, 0) - .saturating_add(Weight::from_parts(0, 8621)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11096` + // Minimum execution time: 11_646_000 picoseconds. + Weight::from_parts(11_944_000, 0) + .saturating_add(Weight::from_parts(0, 11096)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `173` - // Estimated: `11063` - // Minimum execution time: 17_628_000 picoseconds. - Weight::from_parts(18_146_000, 0) - .saturating_add(Weight::from_parts(0, 11063)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `170` + // Estimated: `13535` + // Minimum execution time: 19_301_000 picoseconds. + Weight::from_parts(19_664_000, 0) + .saturating_add(Weight::from_parts(0, 13535)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -349,12 +349,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `11105` - // Minimum execution time: 34_877_000 picoseconds. - Weight::from_parts(35_607_000, 0) - .saturating_add(Weight::from_parts(0, 11105)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `212` + // Estimated: `13577` + // Minimum execution time: 35_715_000 picoseconds. + Weight::from_parts(36_915_000, 0) + .saturating_add(Weight::from_parts(0, 13577)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -365,8 +365,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `1588` - // Minimum execution time: 5_370_000 picoseconds. - Weight::from_parts(5_616_000, 0) + // Minimum execution time: 4_871_000 picoseconds. + Weight::from_parts(5_066_000, 0) .saturating_add(Weight::from_parts(0, 1588)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -377,10 +377,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7740` // Estimated: `11205` - // Minimum execution time: 26_820_000 picoseconds. - Weight::from_parts(27_143_000, 0) + // Minimum execution time: 25_150_000 picoseconds. + Weight::from_parts(26_119_000, 0) .saturating_add(Weight::from_parts(0, 11205)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `3625` + // Minimum execution time: 38_248_000 picoseconds. + Weight::from_parts(39_122_000, 0) + .saturating_add(Weight::from_parts(0, 3625)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index e015c7bfca3..5778ed362ee 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1526,6 +1526,13 @@ impl_runtime_apis! { }); Some((assets, fee_index as u32, dest, verify)) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use pallet_xcm_bridge_hub_router::benchmarking::{ diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs index 504731f4a9e..71facff87d3 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 25_482_000 picoseconds. - Weight::from_parts(26_622_000, 0) + // Minimum execution time: 21_630_000 picoseconds. + Weight::from_parts(22_306_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 87_319_000 picoseconds. - Weight::from_parts(89_764_000, 0) + // Minimum execution time: 91_802_000 picoseconds. + Weight::from_parts(93_672_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -118,8 +118,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `367` // Estimated: `6196` - // Minimum execution time: 139_133_000 picoseconds. - Weight::from_parts(141_507_000, 0) + // Minimum execution time: 118_930_000 picoseconds. + Weight::from_parts(122_306_000, 0) .saturating_add(Weight::from_parts(0, 6196)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(5)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `496` // Estimated: `6208` - // Minimum execution time: 144_241_000 picoseconds. - Weight::from_parts(149_709_000, 0) + // Minimum execution time: 140_527_000 picoseconds. + Weight::from_parts(144_501_000, 0) .saturating_add(Weight::from_parts(0, 6208)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(7)) @@ -158,8 +158,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_392_000 picoseconds. - Weight::from_parts(10_779_000, 0) + // Minimum execution time: 7_556_000 picoseconds. + Weight::from_parts(7_798_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `PolkadotXcm::SupportedVersion` (r:0 w:1) @@ -168,8 +168,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_088_000 picoseconds. - Weight::from_parts(7_257_000, 0) + // Minimum execution time: 6_373_000 picoseconds. + Weight::from_parts(6_603_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -179,8 +179,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_095_000 picoseconds. - Weight::from_parts(2_136_000, 0) + // Minimum execution time: 1_941_000 picoseconds. + Weight::from_parts(2_088_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -206,8 +206,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 28_728_000 picoseconds. - Weight::from_parts(29_349_000, 0) + // Minimum execution time: 27_080_000 picoseconds. + Weight::from_parts(27_820_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -232,8 +232,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `363` // Estimated: `3828` - // Minimum execution time: 30_605_000 picoseconds. - Weight::from_parts(31_477_000, 0) + // Minimum execution time: 28_850_000 picoseconds. + Weight::from_parts(29_506_000, 0) .saturating_add(Weight::from_parts(0, 3828)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -244,45 +244,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_137_000 picoseconds. - Weight::from_parts(2_303_000, 0) + // Minimum execution time: 2_033_000 picoseconds. + Weight::from_parts(2_201_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `162` - // Estimated: `11052` - // Minimum execution time: 16_719_000 picoseconds. - Weight::from_parts(17_329_000, 0) - .saturating_add(Weight::from_parts(0, 11052)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `159` + // Estimated: `13524` + // Minimum execution time: 18_844_000 picoseconds. + Weight::from_parts(19_197_000, 0) + .saturating_add(Weight::from_parts(0, 13524)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `166` - // Estimated: `11056` - // Minimum execution time: 16_687_000 picoseconds. - Weight::from_parts(17_405_000, 0) - .saturating_add(Weight::from_parts(0, 11056)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `163` + // Estimated: `13528` + // Minimum execution time: 18_940_000 picoseconds. + Weight::from_parts(19_450_000, 0) + .saturating_add(Weight::from_parts(0, 13528)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `173` - // Estimated: `13538` - // Minimum execution time: 18_751_000 picoseconds. - Weight::from_parts(19_130_000, 0) - .saturating_add(Weight::from_parts(0, 13538)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `16013` + // Minimum execution time: 20_521_000 picoseconds. + Weight::from_parts(21_076_000, 0) + .saturating_add(Weight::from_parts(0, 16013)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -302,36 +302,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `212` // Estimated: `6152` - // Minimum execution time: 27_189_000 picoseconds. - Weight::from_parts(27_760_000, 0) + // Minimum execution time: 26_007_000 picoseconds. + Weight::from_parts(26_448_000, 0) .saturating_add(Weight::from_parts(0, 6152)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `206` - // Estimated: `8621` - // Minimum execution time: 9_307_000 picoseconds. - Weight::from_parts(9_691_000, 0) - .saturating_add(Weight::from_parts(0, 8621)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11096` + // Minimum execution time: 11_584_000 picoseconds. + Weight::from_parts(12_080_000, 0) + .saturating_add(Weight::from_parts(0, 11096)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `173` - // Estimated: `11063` - // Minimum execution time: 17_607_000 picoseconds. - Weight::from_parts(18_090_000, 0) - .saturating_add(Weight::from_parts(0, 11063)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `170` + // Estimated: `13535` + // Minimum execution time: 19_157_000 picoseconds. + Weight::from_parts(19_513_000, 0) + .saturating_add(Weight::from_parts(0, 13535)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -347,12 +347,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `11105` - // Minimum execution time: 34_322_000 picoseconds. - Weight::from_parts(35_754_000, 0) - .saturating_add(Weight::from_parts(0, 11105)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `212` + // Estimated: `13577` + // Minimum execution time: 34_878_000 picoseconds. + Weight::from_parts(35_623_000, 0) + .saturating_add(Weight::from_parts(0, 13577)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -363,8 +363,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `1588` - // Minimum execution time: 4_513_000 picoseconds. - Weight::from_parts(4_754_000, 0) + // Minimum execution time: 3_900_000 picoseconds. + Weight::from_parts(4_161_000, 0) .saturating_add(Weight::from_parts(0, 1588)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -375,10 +375,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7740` // Estimated: `11205` - // Minimum execution time: 27_860_000 picoseconds. - Weight::from_parts(28_279_000, 0) + // Minimum execution time: 25_731_000 picoseconds. + Weight::from_parts(26_160_000, 0) .saturating_add(Weight::from_parts(0, 11205)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `3625` + // Minimum execution time: 37_251_000 picoseconds. + Weight::from_parts(38_075_000, 0) + .saturating_add(Weight::from_parts(0, 3625)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 0f6af1b51f1..ee472f006fa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1148,6 +1148,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs index 5faded42aa8..a732e1a5734 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 23_683_000 picoseconds. - Weight::from_parts(24_199_000, 0) + // Minimum execution time: 18_513_000 picoseconds. + Weight::from_parts(19_156_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `70` // Estimated: `3593` - // Minimum execution time: 89_524_000 picoseconds. - Weight::from_parts(91_401_000, 0) + // Minimum execution time: 88_096_000 picoseconds. + Weight::from_parts(89_732_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -126,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `70` // Estimated: `3593` - // Minimum execution time: 91_890_000 picoseconds. - Weight::from_parts(93_460_000, 0) + // Minimum execution time: 88_239_000 picoseconds. + Weight::from_parts(89_729_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_152_000 picoseconds. - Weight::from_parts(7_355_000, 0) + // Minimum execution time: 5_955_000 picoseconds. + Weight::from_parts(6_266_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -159,8 +159,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_081_000 picoseconds. - Weight::from_parts(2_258_000, 0) + // Minimum execution time: 1_868_000 picoseconds. + Weight::from_parts(1_961_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 28_067_000 picoseconds. - Weight::from_parts(28_693_000, 0) + // Minimum execution time: 24_388_000 picoseconds. + Weight::from_parts(25_072_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -212,8 +212,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `255` // Estimated: `3720` - // Minimum execution time: 30_420_000 picoseconds. - Weight::from_parts(31_373_000, 0) + // Minimum execution time: 26_762_000 picoseconds. + Weight::from_parts(27_631_000, 0) .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,45 +224,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_087_000 picoseconds. - Weight::from_parts(2_243_000, 0) + // Minimum execution time: 1_856_000 picoseconds. + Weight::from_parts(2_033_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 15_142_000 picoseconds. - Weight::from_parts(15_598_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 17_718_000 picoseconds. + Weight::from_parts(18_208_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 15_041_000 picoseconds. - Weight::from_parts(15_493_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 17_597_000 picoseconds. + Weight::from_parts(18_090_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 16_624_000 picoseconds. - Weight::from_parts(17_031_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 19_533_000 picoseconds. + Weight::from_parts(20_164_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,36 +282,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 26_398_000 picoseconds. - Weight::from_parts(26_847_000, 0) + // Minimum execution time: 24_958_000 picoseconds. + Weight::from_parts(25_628_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_741_000 picoseconds. - Weight::from_parts(8_954_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 12_209_000 picoseconds. + Weight::from_parts(12_612_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 15_306_000 picoseconds. - Weight::from_parts(15_760_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_844_000 picoseconds. + Weight::from_parts(18_266_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -327,12 +327,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_127_000 picoseconds. - Weight::from_parts(33_938_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 34_131_000 picoseconds. + Weight::from_parts(34_766_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -343,8 +343,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 4_290_000 picoseconds. - Weight::from_parts(4_450_000, 0) + // Minimum execution time: 3_525_000 picoseconds. + Weight::from_parts(3_724_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -355,10 +355,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 26_408_000 picoseconds. - Weight::from_parts(26_900_000, 0) + // Minimum execution time: 24_975_000 picoseconds. + Weight::from_parts(25_517_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 33_761_000 picoseconds. + Weight::from_parts(34_674_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 206743ba6ac..60d959b4053 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -843,6 +843,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs index 83e4260e771..a78ff2355ef 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 23_219_000 picoseconds. - Weight::from_parts(23_818_000, 0) + // Minimum execution time: 19_527_000 picoseconds. + Weight::from_parts(19_839_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -88,10 +88,10 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn teleport_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `70` + // Measured: `107` // Estimated: `3593` - // Minimum execution time: 90_120_000 picoseconds. - Weight::from_parts(92_545_000, 0) + // Minimum execution time: 90_938_000 picoseconds. + Weight::from_parts(92_822_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -124,10 +124,10 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `70` + // Measured: `107` // Estimated: `3593` - // Minimum execution time: 91_339_000 picoseconds. - Weight::from_parts(93_204_000, 0) + // Minimum execution time: 90_133_000 picoseconds. + Weight::from_parts(92_308_000, 0) .saturating_add(Weight::from_parts(0, 3593)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_976_000 picoseconds. - Weight::from_parts(7_284_000, 0) + // Minimum execution time: 6_205_000 picoseconds. + Weight::from_parts(6_595_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -159,8 +159,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_044_000 picoseconds. - Weight::from_parts(2_223_000, 0) + // Minimum execution time: 1_927_000 picoseconds. + Weight::from_parts(2_062_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 27_778_000 picoseconds. - Weight::from_parts(28_318_000, 0) + // Minimum execution time: 25_078_000 picoseconds. + Weight::from_parts(25_782_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -212,8 +212,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `255` // Estimated: `3720` - // Minimum execution time: 30_446_000 picoseconds. - Weight::from_parts(31_925_000, 0) + // Minimum execution time: 28_188_000 picoseconds. + Weight::from_parts(28_826_000, 0) .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,45 +224,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_037_000 picoseconds. - Weight::from_parts(2_211_000, 0) + // Minimum execution time: 1_886_000 picoseconds. + Weight::from_parts(1_991_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 15_620_000 picoseconds. - Weight::from_parts(15_984_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 17_443_000 picoseconds. + Weight::from_parts(17_964_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 15_689_000 picoseconds. - Weight::from_parts(16_093_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 17_357_000 picoseconds. + Weight::from_parts(18_006_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 16_946_000 picoseconds. - Weight::from_parts(17_192_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 18_838_000 picoseconds. + Weight::from_parts(19_688_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,36 +282,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 27_164_000 picoseconds. - Weight::from_parts(27_760_000, 0) + // Minimum execution time: 25_517_000 picoseconds. + Weight::from_parts(26_131_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_689_000 picoseconds. - Weight::from_parts(8_874_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_587_000 picoseconds. + Weight::from_parts(11_963_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 15_944_000 picoseconds. - Weight::from_parts(16_381_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_490_000 picoseconds. + Weight::from_parts(18_160_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -327,12 +327,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_826_000 picoseconds. - Weight::from_parts(34_784_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 34_088_000 picoseconds. + Weight::from_parts(34_598_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -343,8 +343,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 4_257_000 picoseconds. - Weight::from_parts(4_383_000, 0) + // Minimum execution time: 3_566_000 picoseconds. + Weight::from_parts(3_754_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -355,10 +355,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 26_924_000 picoseconds. - Weight::from_parts(27_455_000, 0) + // Minimum execution time: 25_078_000 picoseconds. + Weight::from_parts(25_477_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_661_000 picoseconds. + Weight::from_parts(35_411_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 3ed9d6e8e16..9a88ca174df 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -1032,6 +1032,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } let whitelist: Vec = vec![ diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs index 50dfbffde01..5d427d85004 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-r43aesjn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 24_540_000 picoseconds. - Weight::from_parts(25_439_000, 0) + // Minimum execution time: 21_813_000 picoseconds. + Weight::from_parts(22_332_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -90,8 +90,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `214` // Estimated: `3679` - // Minimum execution time: 86_614_000 picoseconds. - Weight::from_parts(88_884_000, 0) + // Minimum execution time: 93_243_000 picoseconds. + Weight::from_parts(95_650_000, 0) .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -126,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `214` // Estimated: `3679` - // Minimum execution time: 87_915_000 picoseconds. - Weight::from_parts(90_219_000, 0) + // Minimum execution time: 96_199_000 picoseconds. + Weight::from_parts(98_620_000, 0) .saturating_add(Weight::from_parts(0, 3679)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) @@ -148,8 +148,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_872_000 picoseconds. - Weight::from_parts(7_110_000, 0) + // Minimum execution time: 6_442_000 picoseconds. + Weight::from_parts(6_682_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -159,8 +159,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_009_000 picoseconds. - Weight::from_parts(2_163_000, 0) + // Minimum execution time: 1_833_000 picoseconds. + Weight::from_parts(1_973_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `145` // Estimated: `3610` - // Minimum execution time: 28_858_000 picoseconds. - Weight::from_parts(29_355_000, 0) + // Minimum execution time: 27_318_000 picoseconds. + Weight::from_parts(28_224_000, 0) .saturating_add(Weight::from_parts(0, 3610)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -212,8 +212,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `363` // Estimated: `3828` - // Minimum execution time: 30_598_000 picoseconds. - Weight::from_parts(31_168_000, 0) + // Minimum execution time: 29_070_000 picoseconds. + Weight::from_parts(30_205_000, 0) .saturating_add(Weight::from_parts(0, 3828)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,45 +224,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_090_000 picoseconds. - Weight::from_parts(2_253_000, 0) + // Minimum execution time: 1_904_000 picoseconds. + Weight::from_parts(2_033_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `162` - // Estimated: `11052` - // Minimum execution time: 16_133_000 picoseconds. - Weight::from_parts(16_433_000, 0) - .saturating_add(Weight::from_parts(0, 11052)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `159` + // Estimated: `13524` + // Minimum execution time: 18_348_000 picoseconds. + Weight::from_parts(18_853_000, 0) + .saturating_add(Weight::from_parts(0, 13524)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `166` - // Estimated: `11056` - // Minimum execution time: 16_012_000 picoseconds. - Weight::from_parts(16_449_000, 0) - .saturating_add(Weight::from_parts(0, 11056)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `163` + // Estimated: `13528` + // Minimum execution time: 17_964_000 picoseconds. + Weight::from_parts(18_548_000, 0) + .saturating_add(Weight::from_parts(0, 13528)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `173` - // Estimated: `13538` - // Minimum execution time: 17_922_000 picoseconds. - Weight::from_parts(18_426_000, 0) - .saturating_add(Weight::from_parts(0, 13538)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `16013` + // Minimum execution time: 19_708_000 picoseconds. + Weight::from_parts(20_157_000, 0) + .saturating_add(Weight::from_parts(0, 16013)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -282,36 +282,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `212` // Estimated: `6152` - // Minimum execution time: 27_280_000 picoseconds. - Weight::from_parts(28_026_000, 0) + // Minimum execution time: 26_632_000 picoseconds. + Weight::from_parts(27_314_000, 0) .saturating_add(Weight::from_parts(0, 6152)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `206` - // Estimated: `8621` - // Minimum execution time: 9_387_000 picoseconds. - Weight::from_parts(9_644_000, 0) - .saturating_add(Weight::from_parts(0, 8621)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11096` + // Minimum execution time: 11_929_000 picoseconds. + Weight::from_parts(12_304_000, 0) + .saturating_add(Weight::from_parts(0, 11096)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `173` - // Estimated: `11063` - // Minimum execution time: 16_649_000 picoseconds. - Weight::from_parts(17_025_000, 0) - .saturating_add(Weight::from_parts(0, 11063)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `170` + // Estimated: `13535` + // Minimum execution time: 18_599_000 picoseconds. + Weight::from_parts(19_195_000, 0) + .saturating_add(Weight::from_parts(0, 13535)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -327,12 +327,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `215` - // Estimated: `11105` - // Minimum execution time: 34_355_000 picoseconds. - Weight::from_parts(35_295_000, 0) - .saturating_add(Weight::from_parts(0, 11105)) - .saturating_add(T::DbWeight::get().reads(10)) + // Measured: `212` + // Estimated: `13577` + // Minimum execution time: 35_524_000 picoseconds. + Weight::from_parts(36_272_000, 0) + .saturating_add(Weight::from_parts(0, 13577)) + .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -343,8 +343,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `1588` - // Minimum execution time: 4_527_000 picoseconds. - Weight::from_parts(4_699_000, 0) + // Minimum execution time: 4_044_000 picoseconds. + Weight::from_parts(4_238_000, 0) .saturating_add(Weight::from_parts(0, 1588)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -355,10 +355,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7740` // Estimated: `11205` - // Minimum execution time: 27_011_000 picoseconds. - Weight::from_parts(27_398_000, 0) + // Minimum execution time: 25_741_000 picoseconds. + Weight::from_parts(26_301_000, 0) .saturating_add(Weight::from_parts(0, 11205)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `3625` + // Minimum execution time: 35_925_000 picoseconds. + Weight::from_parts(36_978_000, 0) + .saturating_add(Weight::from_parts(0, 3625)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index c4df5b9a565..c73d2225ebd 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -764,6 +764,13 @@ impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(EXISTENTIAL_DEPOSIT), + } + } } let whitelist: Vec = vec![ diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index 0cdfebce742..d95e68d85c4 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -740,6 +740,13 @@ impl_runtime_apis! { // Reserve transfers are disabled None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs index 0e34cba4aaf..c5d315467c1 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_xcm.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-01-12, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=coretime-rococo-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* // --steps=50 // --repeat=20 -// --json +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=coretime-rococo-dev // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/ @@ -64,8 +62,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 22_669_000 picoseconds. - Weight::from_parts(23_227_000, 0) + // Minimum execution time: 35_051_000 picoseconds. + Weight::from_parts(35_200_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -86,8 +84,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 64_486_000 picoseconds. - Weight::from_parts(65_247_000, 0) + // Minimum execution time: 56_235_000 picoseconds. + Weight::from_parts(58_178_000, 0) .saturating_add(Weight::from_parts(0, 3571)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -128,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_020_000 picoseconds. - Weight::from_parts(7_300_000, 0) + // Minimum execution time: 6_226_000 picoseconds. + Weight::from_parts(6_403_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -139,8 +137,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_022_000 picoseconds. - Weight::from_parts(2_141_000, 0) + // Minimum execution time: 2_020_000 picoseconds. + Weight::from_parts(2_100_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -164,8 +162,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 26_893_000 picoseconds. - Weight::from_parts(27_497_000, 0) + // Minimum execution time: 24_387_000 picoseconds. + Weight::from_parts(24_814_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) @@ -188,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292` // Estimated: `3757` - // Minimum execution time: 29_673_000 picoseconds. - Weight::from_parts(30_693_000, 0) + // Minimum execution time: 27_039_000 picoseconds. + Weight::from_parts(27_693_000, 0) .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) @@ -200,45 +198,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_990_000 picoseconds. - Weight::from_parts(2_105_000, 0) + // Minimum execution time: 1_920_000 picoseconds. + Weight::from_parts(2_082_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `PolkadotXcm::SupportedVersion` (r:4 w:2) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 14_819_000 picoseconds. - Weight::from_parts(15_180_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 17_141_000 picoseconds. + Weight::from_parts(17_500_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifiers` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 14_935_000 picoseconds. - Weight::from_parts(15_335_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 17_074_000 picoseconds. + Weight::from_parts(17_431_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 16_278_000 picoseconds. - Weight::from_parts(16_553_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 19_139_000 picoseconds. + Weight::from_parts(19_474_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -256,36 +254,36 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `6082` - // Minimum execution time: 26_360_000 picoseconds. - Weight::from_parts(26_868_000, 0) + // Minimum execution time: 24_346_000 picoseconds. + Weight::from_parts(25_318_000, 0) .saturating_add(Weight::from_parts(0, 6082)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:3 w:0) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_615_000 picoseconds. - Weight::from_parts(8_903_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_777_000 picoseconds. + Weight::from_parts(12_051_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 15_284_000 picoseconds. - Weight::from_parts(15_504_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_538_000 picoseconds. + Weight::from_parts(17_832_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:2) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -299,12 +297,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `148` - // Estimated: `11038` - // Minimum execution time: 32_675_000 picoseconds. - Weight::from_parts(33_816_000, 0) - .saturating_add(Weight::from_parts(0, 11038)) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `142` + // Estimated: `13507` + // Minimum execution time: 33_623_000 picoseconds. + Weight::from_parts(34_186_000, 0) + .saturating_add(Weight::from_parts(0, 13507)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -315,8 +313,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 4_058_000 picoseconds. - Weight::from_parts(4_170_000, 0) + // Minimum execution time: 3_363_000 picoseconds. + Weight::from_parts(3_511_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -327,10 +325,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 25_375_000 picoseconds. - Weight::from_parts(26_026_000, 0) + // Minimum execution time: 23_969_000 picoseconds. + Weight::from_parts(24_347_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_071_000 picoseconds. + Weight::from_parts(35_031_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 7797329b526..4b9b180321d 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -731,6 +731,13 @@ impl_runtime_apis! { // Reserve transfers are disabled None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } parameter_types! { diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs index d821a581b0d..0082db3099d 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_xcm.rs @@ -17,25 +17,23 @@ //! Autogenerated weights for `pallet_xcm` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=coretime-westend-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --extrinsic=* // --steps=50 // --repeat=20 -// --json +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=coretime-westend-dev // --header=./cumulus/file_header.txt // --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/ @@ -64,8 +62,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 17_946_000 picoseconds. - Weight::from_parts(18_398_000, 0) + // Minimum execution time: 18_410_000 picoseconds. + Weight::from_parts(18_657_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -86,8 +84,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `3571` - // Minimum execution time: 47_982_000 picoseconds. - Weight::from_parts(49_215_000, 0) + // Minimum execution time: 56_616_000 picoseconds. + Weight::from_parts(57_751_000, 0) .saturating_add(Weight::from_parts(0, 3571)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) @@ -128,8 +126,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_042_000 picoseconds. - Weight::from_parts(6_257_000, 0) + // Minimum execution time: 6_014_000 picoseconds. + Weight::from_parts(6_412_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -139,8 +137,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_845_000 picoseconds. - Weight::from_parts(1_993_000, 0) + // Minimum execution time: 1_844_000 picoseconds. + Weight::from_parts(1_957_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -164,8 +162,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `74` // Estimated: `3539` - // Minimum execution time: 24_062_000 picoseconds. - Weight::from_parts(24_666_000, 0) + // Minimum execution time: 24_067_000 picoseconds. + Weight::from_parts(24_553_000, 0) .saturating_add(Weight::from_parts(0, 3539)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) @@ -188,8 +186,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `292` // Estimated: `3757` - // Minimum execution time: 26_486_000 picoseconds. - Weight::from_parts(27_528_000, 0) + // Minimum execution time: 27_023_000 picoseconds. + Weight::from_parts(27_620_000, 0) .saturating_add(Weight::from_parts(0, 3757)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) @@ -200,8 +198,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_881_000 picoseconds. - Weight::from_parts(2_008_000, 0) + // Minimum execution time: 1_866_000 picoseconds. + Weight::from_parts(1_984_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -211,8 +209,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `89` // Estimated: `13454` - // Minimum execution time: 15_971_000 picoseconds. - Weight::from_parts(16_455_000, 0) + // Minimum execution time: 16_425_000 picoseconds. + Weight::from_parts(16_680_000, 0) .saturating_add(Weight::from_parts(0, 13454)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -223,8 +221,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `93` // Estimated: `13458` - // Minimum execution time: 16_603_000 picoseconds. - Weight::from_parts(17_037_000, 0) + // Minimum execution time: 16_171_000 picoseconds. + Weight::from_parts(16_564_000, 0) .saturating_add(Weight::from_parts(0, 13458)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -235,8 +233,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `106` // Estimated: `15946` - // Minimum execution time: 17_821_000 picoseconds. - Weight::from_parts(18_200_000, 0) + // Minimum execution time: 17_785_000 picoseconds. + Weight::from_parts(18_123_000, 0) .saturating_add(Weight::from_parts(0, 15946)) .saturating_add(T::DbWeight::get().reads(6)) } @@ -256,8 +254,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `6082` - // Minimum execution time: 23_878_000 picoseconds. - Weight::from_parts(24_721_000, 0) + // Minimum execution time: 23_903_000 picoseconds. + Weight::from_parts(24_769_000, 0) .saturating_add(Weight::from_parts(0, 6082)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -268,8 +266,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `136` // Estimated: `11026` - // Minimum execution time: 10_566_000 picoseconds. - Weight::from_parts(11_053_000, 0) + // Minimum execution time: 10_617_000 picoseconds. + Weight::from_parts(10_843_000, 0) .saturating_add(Weight::from_parts(0, 11026)) .saturating_add(T::DbWeight::get().reads(4)) } @@ -279,8 +277,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `100` // Estimated: `13465` - // Minimum execution time: 16_020_000 picoseconds. - Weight::from_parts(16_619_000, 0) + // Minimum execution time: 16_656_000 picoseconds. + Weight::from_parts(17_106_000, 0) .saturating_add(Weight::from_parts(0, 13465)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -301,8 +299,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `142` // Estimated: `13507` - // Minimum execution time: 32_136_000 picoseconds. - Weight::from_parts(32_610_000, 0) + // Minimum execution time: 31_721_000 picoseconds. + Weight::from_parts(32_547_000, 0) .saturating_add(Weight::from_parts(0, 13507)) .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) @@ -315,8 +313,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `1517` - // Minimum execution time: 3_336_000 picoseconds. - Weight::from_parts(3_434_000, 0) + // Minimum execution time: 3_439_000 picoseconds. + Weight::from_parts(3_619_000, 0) .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -327,10 +325,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7669` // Estimated: `11134` - // Minimum execution time: 23_977_000 picoseconds. - Weight::from_parts(24_413_000, 0) + // Minimum execution time: 24_657_000 picoseconds. + Weight::from_parts(24_971_000, 0) .saturating_add(Weight::from_parts(0, 11134)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_028_000 picoseconds. + Weight::from_parts(34_697_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 616da5519a5..28b8062e0e0 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -710,6 +710,13 @@ impl_runtime_apis! { fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs index 0f793524de9..fabce29b5fd 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_xcm.rs @@ -1,40 +1,41 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 +// This file is part of Cumulus. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm4`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("people-kusama-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024 // Executed Command: -// ./artifacts/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=people-kusama-dev -// --execution=wasm -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --extrinsic=* // --steps=50 // --repeat=20 -// --json -// --header=./file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-kusama/src/weights/pallet_xcm.rs +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=people-rococo-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,57 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_931_000 picoseconds. - Weight::from_parts(26_340_000, 0) + // Minimum execution time: 17_830_000 picoseconds. + Weight::from_parts(18_411_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: ParachainInfo ParachainId (r:1 w:0) - /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - fn teleport_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `32` - // Estimated: `1489` - // Minimum execution time: 25_691_000 picoseconds. - Weight::from_parts(25_971_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) - fn reserve_transfer_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -108,18 +80,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `70` + // Estimated: `3535` + // Minimum execution time: 55_456_000 picoseconds. + Weight::from_parts(56_808_000, 0) + .saturating_add(Weight::from_parts(0, 3535)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `496` - // Estimated: `6208` - // Minimum execution time: 146_932_000 picoseconds. - Weight::from_parts(153_200_000, 0) - .saturating_add(Weight::from_parts(0, 6208)) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn execute() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -128,189 +120,189 @@ impl pallet_xcm::WeightInfo for WeightInfo { Weight::from_parts(18_446_744_073_709_551_000, 0) .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: PolkadotXcm SupportedVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_572_000 picoseconds. - Weight::from_parts(9_924_000, 0) + // Minimum execution time: 5_996_000 picoseconds. + Weight::from_parts(6_154_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SafeXcmVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_default_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_997_000 picoseconds. - Weight::from_parts(3_136_000, 0) + // Minimum execution time: 1_768_000 picoseconds. + Weight::from_parts(1_914_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm QueryCounter (r:1 w:1) - /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) + /// Proof: `PolkadotXcm::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 30_271_000 picoseconds. - Weight::from_parts(30_819_000, 0) + // Minimum execution time: 24_120_000 picoseconds. + Weight::from_parts(24_745_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `220` - // Estimated: `3685` - // Minimum execution time: 32_302_000 picoseconds. - Weight::from_parts(32_807_000, 0) - .saturating_add(Weight::from_parts(0, 3685)) + // Measured: `255` + // Estimated: `3720` + // Minimum execution time: 26_630_000 picoseconds. + Weight::from_parts(27_289_000, 0) + .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: PolkadotXcm XcmExecutionSuspended (r:0 w:1) - /// Proof Skipped: PolkadotXcm XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::XcmExecutionSuspended` (r:0 w:1) + /// Proof: `PolkadotXcm::XcmExecutionSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_suspension() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_960_000 picoseconds. - Weight::from_parts(3_094_000, 0) + // Minimum execution time: 1_821_000 picoseconds. + Weight::from_parts(1_946_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SupportedVersion (r:4 w:2) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 14_877_000 picoseconds. - Weight::from_parts(15_296_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 16_586_000 picoseconds. + Weight::from_parts(16_977_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifiers (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 14_835_000 picoseconds. - Weight::from_parts(15_115_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 16_923_000 picoseconds. + Weight::from_parts(17_415_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:5 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 15_368_000 picoseconds. - Weight::from_parts(15_596_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 18_596_000 picoseconds. + Weight::from_parts(18_823_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:2 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 28_025_000 picoseconds. - Weight::from_parts(28_524_000, 0) + // Minimum execution time: 23_817_000 picoseconds. + Weight::from_parts(24_520_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:3 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_166_000 picoseconds. - Weight::from_parts(8_314_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_042_000 picoseconds. + Weight::from_parts(11_578_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 14_871_000 picoseconds. - Weight::from_parts(15_374_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 17_306_000 picoseconds. + Weight::from_parts(17_817_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_611_000 picoseconds. - Weight::from_parts(34_008_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 32_141_000 picoseconds. + Weight::from_parts(32_954_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -319,11 +311,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn new_query() -> Weight { // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `1588` - // Minimum execution time: 5_496_000 picoseconds. - Weight::from_parts(5_652_000, 0) - .saturating_add(Weight::from_parts(0, 1588)) + // Measured: `32` + // Estimated: `1517` + // Minimum execution time: 3_410_000 picoseconds. + Weight::from_parts(3_556_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -331,11 +323,23 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn take_response() -> Weight { // Proof Size summary in bytes: - // Measured: `7740` - // Estimated: `11205` - // Minimum execution time: 26_140_000 picoseconds. - Weight::from_parts(26_824_000, 0) - .saturating_add(Weight::from_parts(0, 11205)) + // Measured: `7669` + // Estimated: `11134` + // Minimum execution time: 25_021_000 picoseconds. + Weight::from_parts(25_240_000, 0) + .saturating_add(Weight::from_parts(0, 11134)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 33_801_000 picoseconds. + Weight::from_parts(34_655_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index 9f572330cac..b2b32445613 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -710,6 +710,13 @@ impl_runtime_apis! { fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> { None } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::parent()), + fun: Fungible(ExistentialDeposit::get()), + } + } } use xcm::latest::prelude::*; diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs index d3b60471b85..c337289243b 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_xcm.rs @@ -1,40 +1,41 @@ // Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 +// This file is part of Cumulus. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `bm4`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("people-polkadot-dev"), DB CACHE: 1024 +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./artifacts/polkadot-parachain +// target/production/polkadot-parachain // benchmark // pallet -// --chain=people-polkadot-dev -// --execution=wasm -// --wasm-execution=compiled -// --pallet=pallet_xcm -// --extrinsic=* // --steps=50 // --repeat=20 -// --json -// --header=./file_header.txt -// --output=./cumulus/parachains/runtimes/people/people-polkadot/src/weights/pallet_xcm.rs +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=people-westend-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -47,57 +48,28 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_783_000 picoseconds. - Weight::from_parts(26_398_000, 0) + // Minimum execution time: 17_856_000 picoseconds. + Weight::from_parts(18_473_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: ParachainInfo ParachainId (r:1 w:0) - /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - fn teleport_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `32` - // Estimated: `1489` - // Minimum execution time: 25_511_000 picoseconds. - Weight::from_parts(26_120_000, 0) - .saturating_add(Weight::from_parts(0, 1489)) - .saturating_add(T::DbWeight::get().reads(1)) - } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) - fn reserve_transfer_assets() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) - } /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Assets::Asset` (r:1 w:1) - /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) - /// Storage: `Assets::Account` (r:2 w:2) - /// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:2) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) - /// Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -108,18 +80,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn teleport_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `70` + // Estimated: `3535` + // Minimum execution time: 56_112_000 picoseconds. + Weight::from_parts(57_287_000, 0) + .saturating_add(Weight::from_parts(0, 3535)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn reserve_transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `496` - // Estimated: `6208` - // Minimum execution time: 146_932_000 picoseconds. - Weight::from_parts(153_200_000, 0) - .saturating_add(Weight::from_parts(0, 6208)) - .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(7)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: Benchmark Override (r:0 w:0) - /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) fn execute() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -128,189 +120,189 @@ impl pallet_xcm::WeightInfo for WeightInfo { Weight::from_parts(18_446_744_073_709_551_000, 0) .saturating_add(Weight::from_parts(0, 0)) } - /// Storage: PolkadotXcm SupportedVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_707_000 picoseconds. - Weight::from_parts(9_874_000, 0) + // Minimum execution time: 6_186_000 picoseconds. + Weight::from_parts(6_420_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SafeXcmVersion (r:0 w:1) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:0 w:1) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_default_xcm_version() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_073_000 picoseconds. - Weight::from_parts(3_183_000, 0) + // Minimum execution time: 1_824_000 picoseconds. + Weight::from_parts(1_999_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm QueryCounter (r:1 w:1) - /// Proof Skipped: PolkadotXcm QueryCounter (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) + /// Proof: `PolkadotXcm::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 30_999_000 picoseconds. - Weight::from_parts(31_641_000, 0) + // Minimum execution time: 23_833_000 picoseconds. + Weight::from_parts(24_636_000, 0) .saturating_add(Weight::from_parts(0, 3503)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: PolkadotXcm VersionNotifiers (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm Queries (r:0 w:1) - /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::Queries` (r:0 w:1) + /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `220` - // Estimated: `3685` - // Minimum execution time: 33_036_000 picoseconds. - Weight::from_parts(33_596_000, 0) - .saturating_add(Weight::from_parts(0, 3685)) + // Measured: `255` + // Estimated: `3720` + // Minimum execution time: 26_557_000 picoseconds. + Weight::from_parts(27_275_000, 0) + .saturating_add(Weight::from_parts(0, 3720)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: PolkadotXcm XcmExecutionSuspended (r:0 w:1) - /// Proof Skipped: PolkadotXcm XcmExecutionSuspended (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::XcmExecutionSuspended` (r:0 w:1) + /// Proof: `PolkadotXcm::XcmExecutionSuspended` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn force_suspension() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_035_000 picoseconds. - Weight::from_parts(3_154_000, 0) + // Minimum execution time: 1_921_000 picoseconds. + Weight::from_parts(2_040_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: PolkadotXcm SupportedVersion (r:4 w:2) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::SupportedVersion` (r:5 w:2) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `95` - // Estimated: `10985` - // Minimum execution time: 14_805_000 picoseconds. - Weight::from_parts(15_120_000, 0) - .saturating_add(Weight::from_parts(0, 10985)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `89` + // Estimated: `13454` + // Minimum execution time: 16_832_000 picoseconds. + Weight::from_parts(17_312_000, 0) + .saturating_add(Weight::from_parts(0, 13454)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifiers (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifiers (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifiers` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `99` - // Estimated: `10989` - // Minimum execution time: 14_572_000 picoseconds. - Weight::from_parts(14_909_000, 0) - .saturating_add(Weight::from_parts(0, 10989)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `93` + // Estimated: `13458` + // Minimum execution time: 16_687_000 picoseconds. + Weight::from_parts(17_123_000, 0) + .saturating_add(Weight::from_parts(0, 13458)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:5 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:6 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `106` - // Estimated: `13471` - // Minimum execution time: 15_341_000 picoseconds. - Weight::from_parts(15_708_000, 0) - .saturating_add(Weight::from_parts(0, 13471)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15946` + // Minimum execution time: 18_164_000 picoseconds. + Weight::from_parts(18_580_000, 0) + .saturating_add(Weight::from_parts(0, 15946)) + .saturating_add(T::DbWeight::get().reads(6)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:2 w:1) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:2 w:1) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: // Measured: `106` // Estimated: `6046` - // Minimum execution time: 27_840_000 picoseconds. - Weight::from_parts(28_248_000, 0) + // Minimum execution time: 23_577_000 picoseconds. + Weight::from_parts(24_324_000, 0) .saturating_add(Weight::from_parts(0, 6046)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:3 w:0) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:4 w:0) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `136` - // Estimated: `8551` - // Minimum execution time: 8_245_000 picoseconds. - Weight::from_parts(8_523_000, 0) - .saturating_add(Weight::from_parts(0, 8551)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `11026` + // Minimum execution time: 11_014_000 picoseconds. + Weight::from_parts(11_223_000, 0) + .saturating_add(Weight::from_parts(0, 11026)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `106` - // Estimated: `10996` - // Minimum execution time: 14_780_000 picoseconds. - Weight::from_parts(15_173_000, 0) - .saturating_add(Weight::from_parts(0, 10996)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `100` + // Estimated: `13465` + // Minimum execution time: 16_887_000 picoseconds. + Weight::from_parts(17_361_000, 0) + .saturating_add(Weight::from_parts(0, 13465)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: PolkadotXcm VersionNotifyTargets (r:4 w:2) - /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) - /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) - /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) - /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem HostConfiguration (r:1 w:0) - /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) - /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: `PolkadotXcm::VersionNotifyTargets` (r:5 w:2) + /// Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `112` - // Estimated: `11002` - // Minimum execution time: 33_422_000 picoseconds. - Weight::from_parts(34_076_000, 0) - .saturating_add(Weight::from_parts(0, 11002)) - .saturating_add(T::DbWeight::get().reads(9)) + // Measured: `106` + // Estimated: `13471` + // Minimum execution time: 31_705_000 picoseconds. + Weight::from_parts(32_166_000, 0) + .saturating_add(Weight::from_parts(0, 13471)) + .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `PolkadotXcm::QueryCounter` (r:1 w:1) @@ -319,11 +311,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn new_query() -> Weight { // Proof Size summary in bytes: - // Measured: `103` - // Estimated: `1588` - // Minimum execution time: 5_496_000 picoseconds. - Weight::from_parts(5_652_000, 0) - .saturating_add(Weight::from_parts(0, 1588)) + // Measured: `32` + // Estimated: `1517` + // Minimum execution time: 3_568_000 picoseconds. + Weight::from_parts(3_669_000, 0) + .saturating_add(Weight::from_parts(0, 1517)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -331,11 +323,23 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn take_response() -> Weight { // Proof Size summary in bytes: - // Measured: `7740` - // Estimated: `11205` - // Minimum execution time: 26_140_000 picoseconds. - Weight::from_parts(26_824_000, 0) - .saturating_add(Weight::from_parts(0, 11205)) + // Measured: `7669` + // Estimated: `11134` + // Minimum execution time: 24_823_000 picoseconds. + Weight::from_parts(25_344_000, 0) + .saturating_add(Weight::from_parts(0, 11134)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) + /// Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `90` + // Estimated: `3555` + // Minimum execution time: 34_516_000 picoseconds. + Weight::from_parts(35_478_000, 0) + .saturating_add(Weight::from_parts(0, 3555)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index f3c0c3d6bd8..48395f45238 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2336,6 +2336,13 @@ sp_api::impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::here()), + fun: Fungible(ExistentialDeposit::get()), + } + } } impl pallet_xcm_benchmarks::Config for Runtime { type XcmConfig = XcmConfig; diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs index 177407ef708..5544ca44658 100644 --- a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs @@ -16,10 +16,10 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -48,10 +48,6 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - fn transfer_assets() -> Weight { - // TODO: run benchmarks - Weight::zero() - } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) @@ -62,36 +58,80 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 27_328_000 picoseconds. - Weight::from_parts(27_976_000, 0) - .saturating_add(Weight::from_parts(0, 3607)) + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 25_043_000 picoseconds. + Weight::from_parts(25_682_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn teleport_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 16_280_000 picoseconds. - Weight::from_parts(16_904_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 107_570_000 picoseconds. + Weight::from_parts(109_878_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reserve_transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 15_869_000 picoseconds. - Weight::from_parts(16_264_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `232` + // Estimated: `3697` + // Minimum execution time: 106_341_000 picoseconds. + Weight::from_parts(109_135_000, 0) + .saturating_add(Weight::from_parts(0, 3697)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 108_372_000 picoseconds. + Weight::from_parts(112_890_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) } fn execute() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_923_000 picoseconds. - Weight::from_parts(7_432_000, 0) + // Minimum execution time: 6_957_000 picoseconds. + Weight::from_parts(7_417_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::SupportedVersion` (r:0 w:1) @@ -100,8 +140,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_333_000 picoseconds. - Weight::from_parts(7_566_000, 0) + // Minimum execution time: 7_053_000 picoseconds. + Weight::from_parts(7_462_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -109,8 +149,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_219_000 picoseconds. - Weight::from_parts(2_375_000, 0) + // Minimum execution time: 1_918_000 picoseconds. + Weight::from_parts(2_037_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1) @@ -129,11 +169,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `142` - // Estimated: `3607` - // Minimum execution time: 30_650_000 picoseconds. - Weight::from_parts(31_683_000, 0) - .saturating_add(Weight::from_parts(0, 3607)) + // Measured: `180` + // Estimated: `3645` + // Minimum execution time: 30_417_000 picoseconds. + Weight::from_parts(31_191_000, 0) + .saturating_add(Weight::from_parts(0, 3645)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -151,11 +191,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `322` - // Estimated: `3787` - // Minimum execution time: 37_666_000 picoseconds. - Weight::from_parts(38_920_000, 0) - .saturating_add(Weight::from_parts(0, 3787)) + // Measured: `360` + // Estimated: `3825` + // Minimum execution time: 36_666_000 picoseconds. + Weight::from_parts(37_779_000, 0) + .saturating_add(Weight::from_parts(0, 3825)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -165,45 +205,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_244_000 picoseconds. - Weight::from_parts(2_425_000, 0) + // Minimum execution time: 1_869_000 picoseconds. + Weight::from_parts(2_003_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `XcmPallet::SupportedVersion` (r:4 w:2) + /// Storage: `XcmPallet::SupportedVersion` (r:5 w:2) /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `26` - // Estimated: `10916` - // Minimum execution time: 14_710_000 picoseconds. - Weight::from_parts(15_156_000, 0) - .saturating_add(Weight::from_parts(0, 10916)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `22` + // Estimated: `13387` + // Minimum execution time: 16_188_000 picoseconds. + Weight::from_parts(16_435_000, 0) + .saturating_add(Weight::from_parts(0, 13387)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifiers` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifiers` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `30` - // Estimated: `10920` - // Minimum execution time: 14_630_000 picoseconds. - Weight::from_parts(15_290_000, 0) - .saturating_add(Weight::from_parts(0, 10920)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `26` + // Estimated: `13391` + // Minimum execution time: 16_431_000 picoseconds. + Weight::from_parts(16_935_000, 0) + .saturating_add(Weight::from_parts(0, 13391)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:6 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `40` - // Estimated: `13405` - // Minimum execution time: 16_686_000 picoseconds. - Weight::from_parts(17_332_000, 0) - .saturating_add(Weight::from_parts(0, 13405)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15880` + // Minimum execution time: 18_460_000 picoseconds. + Weight::from_parts(18_885_000, 0) + .saturating_add(Weight::from_parts(0, 15880)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:2 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -217,38 +257,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `178` - // Estimated: `6118` - // Minimum execution time: 30_180_000 picoseconds. - Weight::from_parts(31_351_000, 0) - .saturating_add(Weight::from_parts(0, 6118)) + // Measured: `216` + // Estimated: `6156` + // Minimum execution time: 29_623_000 picoseconds. + Weight::from_parts(30_661_000, 0) + .saturating_add(Weight::from_parts(0, 6156)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:3 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `69` - // Estimated: `8484` - // Minimum execution time: 9_624_000 picoseconds. - Weight::from_parts(10_029_000, 0) - .saturating_add(Weight::from_parts(0, 8484)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `10959` + // Minimum execution time: 12_043_000 picoseconds. + Weight::from_parts(12_360_000, 0) + .saturating_add(Weight::from_parts(0, 10959)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `37` - // Estimated: `10927` - // Minimum execution time: 15_139_000 picoseconds. - Weight::from_parts(15_575_000, 0) - .saturating_add(Weight::from_parts(0, 10927)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `33` + // Estimated: `13398` + // Minimum execution time: 16_511_000 picoseconds. + Weight::from_parts(17_011_000, 0) + .saturating_add(Weight::from_parts(0, 13398)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -260,12 +300,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `182` - // Estimated: `11072` - // Minimum execution time: 37_871_000 picoseconds. - Weight::from_parts(38_940_000, 0) - .saturating_add(Weight::from_parts(0, 11072)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `216` + // Estimated: `13581` + // Minimum execution time: 39_041_000 picoseconds. + Weight::from_parts(39_883_000, 0) + .saturating_add(Weight::from_parts(0, 13581)) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `XcmPallet::QueryCounter` (r:1 w:1) @@ -276,8 +316,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_732_000 picoseconds. - Weight::from_parts(2_892_000, 0) + // Minimum execution time: 2_030_000 picoseconds. + Weight::from_parts(2_150_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -288,10 +328,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7576` // Estimated: `11041` - // Minimum execution time: 23_813_000 picoseconds. - Weight::from_parts(24_201_000, 0) + // Minimum execution time: 22_615_000 picoseconds. + Weight::from_parts(23_008_000, 0) .saturating_add(Weight::from_parts(0, 11041)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `XcmPallet::AssetTraps` (r:1 w:1) + /// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `23` + // Estimated: `3488` + // Minimum execution time: 34_438_000 picoseconds. + Weight::from_parts(35_514_000, 0) + .saturating_add(Weight::from_parts(0, 3488)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index a7772303a95..4ac2202b8fc 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2412,6 +2412,13 @@ sp_api::impl_runtime_apis! { dest ) } + + fn get_asset() -> Asset { + Asset { + id: AssetId(Location::here()), + fun: Fungible(ExistentialDeposit::get()), + } + } } impl frame_system_benchmarking::Config for Runtime {} impl pallet_nomination_pools_benchmarking::Config for Runtime {} diff --git a/polkadot/runtime/westend/src/weights/pallet_xcm.rs b/polkadot/runtime/westend/src/weights/pallet_xcm.rs index 493acd0f9e7..10725cecf24 100644 --- a/polkadot/runtime/westend/src/weights/pallet_xcm.rs +++ b/polkadot/runtime/westend/src/weights/pallet_xcm.rs @@ -16,26 +16,24 @@ //! Autogenerated weights for `pallet_xcm` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot +// target/production/polkadot // benchmark // pallet -// --chain=westend-dev // --steps=50 // --repeat=20 -// --no-storage-info -// --no-median-slopes -// --no-min-squares -// --pallet=pallet_xcm // --extrinsic=* -// --execution=wasm // --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm +// --chain=westend-dev // --header=./polkadot/file_header.txt // --output=./polkadot/runtime/westend/src/weights/ @@ -50,10 +48,6 @@ use core::marker::PhantomData; /// Weight functions for `pallet_xcm`. pub struct WeightInfo(PhantomData); impl pallet_xcm::WeightInfo for WeightInfo { - fn transfer_assets() -> Weight { - // TODO: run benchmarks - Weight::zero() - } /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) @@ -64,29 +58,73 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn send() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 28_098_000 picoseconds. - Weight::from_parts(28_887_000, 0) - .saturating_add(Weight::from_parts(0, 3574)) + // Measured: `147` + // Estimated: `3612` + // Minimum execution time: 25_725_000 picoseconds. + Weight::from_parts(26_174_000, 0) + .saturating_add(Weight::from_parts(0, 3612)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn teleport_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 17_609_000 picoseconds. - Weight::from_parts(18_000_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `250` + // Estimated: `6196` + // Minimum execution time: 113_140_000 picoseconds. + Weight::from_parts(116_204_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn reserve_transfer_assets() -> Weight { // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 17_007_000 picoseconds. - Weight::from_parts(17_471_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Measured: `302` + // Estimated: `6196` + // Minimum execution time: 108_571_000 picoseconds. + Weight::from_parts(110_650_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmPallet::SupportedVersion` (r:1 w:0) + /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1) + /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn transfer_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `250` + // Estimated: `6196` + // Minimum execution time: 111_836_000 picoseconds. + Weight::from_parts(114_435_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `Benchmark::Override` (r:0 w:0) /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -104,8 +142,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_444_000 picoseconds. - Weight::from_parts(7_671_000, 0) + // Minimum execution time: 7_160_000 picoseconds. + Weight::from_parts(7_477_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -113,8 +151,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_126_000 picoseconds. - Weight::from_parts(2_253_000, 0) + // Minimum execution time: 1_934_000 picoseconds. + Weight::from_parts(2_053_000, 0) .saturating_add(Weight::from_parts(0, 0)) } /// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1) @@ -133,11 +171,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_subscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 31_318_000 picoseconds. - Weight::from_parts(32_413_000, 0) - .saturating_add(Weight::from_parts(0, 3574)) + // Measured: `147` + // Estimated: `3612` + // Minimum execution time: 31_123_000 picoseconds. + Weight::from_parts(31_798_000, 0) + .saturating_add(Weight::from_parts(0, 3612)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -155,11 +193,11 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) fn force_unsubscribe_version_notify() -> Weight { // Proof Size summary in bytes: - // Measured: `289` - // Estimated: `3754` - // Minimum execution time: 35_282_000 picoseconds. - Weight::from_parts(35_969_000, 0) - .saturating_add(Weight::from_parts(0, 3754)) + // Measured: `327` + // Estimated: `3792` + // Minimum execution time: 35_175_000 picoseconds. + Weight::from_parts(36_098_000, 0) + .saturating_add(Weight::from_parts(0, 3792)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -169,45 +207,45 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_247_000 picoseconds. - Weight::from_parts(2_381_000, 0) + // Minimum execution time: 1_974_000 picoseconds. + Weight::from_parts(2_096_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `XcmPallet::SupportedVersion` (r:4 w:2) + /// Storage: `XcmPallet::SupportedVersion` (r:5 w:2) /// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_supported_version() -> Weight { // Proof Size summary in bytes: - // Measured: `26` - // Estimated: `10916` - // Minimum execution time: 14_512_000 picoseconds. - Weight::from_parts(15_042_000, 0) - .saturating_add(Weight::from_parts(0, 10916)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `22` + // Estimated: `13387` + // Minimum execution time: 16_626_000 picoseconds. + Weight::from_parts(17_170_000, 0) + .saturating_add(Weight::from_parts(0, 13387)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifiers` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifiers` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifiers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notifiers() -> Weight { // Proof Size summary in bytes: - // Measured: `30` - // Estimated: `10920` - // Minimum execution time: 14_659_000 picoseconds. - Weight::from_parts(15_164_000, 0) - .saturating_add(Weight::from_parts(0, 10920)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `26` + // Estimated: `13391` + // Minimum execution time: 16_937_000 picoseconds. + Weight::from_parts(17_447_000, 0) + .saturating_add(Weight::from_parts(0, 13391)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:6 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn already_notified_target() -> Weight { // Proof Size summary in bytes: // Measured: `40` - // Estimated: `13405` - // Minimum execution time: 16_261_000 picoseconds. - Weight::from_parts(16_986_000, 0) - .saturating_add(Weight::from_parts(0, 13405)) - .saturating_add(T::DbWeight::get().reads(5)) + // Estimated: `15880` + // Minimum execution time: 19_157_000 picoseconds. + Weight::from_parts(19_659_000, 0) + .saturating_add(Weight::from_parts(0, 15880)) + .saturating_add(T::DbWeight::get().reads(6)) } /// Storage: `XcmPallet::VersionNotifyTargets` (r:2 w:1) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -221,38 +259,38 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_current_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `145` - // Estimated: `6085` - // Minimum execution time: 30_539_000 picoseconds. - Weight::from_parts(31_117_000, 0) - .saturating_add(Weight::from_parts(0, 6085)) + // Measured: `183` + // Estimated: `6123` + // Minimum execution time: 30_699_000 picoseconds. + Weight::from_parts(31_537_000, 0) + .saturating_add(Weight::from_parts(0, 6123)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:3 w:0) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:0) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn notify_target_migration_fail() -> Weight { // Proof Size summary in bytes: // Measured: `69` - // Estimated: `8484` - // Minimum execution time: 9_463_000 picoseconds. - Weight::from_parts(9_728_000, 0) - .saturating_add(Weight::from_parts(0, 8484)) - .saturating_add(T::DbWeight::get().reads(3)) + // Estimated: `10959` + // Minimum execution time: 12_303_000 picoseconds. + Weight::from_parts(12_670_000, 0) + .saturating_add(Weight::from_parts(0, 10959)) + .saturating_add(T::DbWeight::get().reads(4)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_version_notify_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `37` - // Estimated: `10927` - // Minimum execution time: 15_169_000 picoseconds. - Weight::from_parts(15_694_000, 0) - .saturating_add(Weight::from_parts(0, 10927)) - .saturating_add(T::DbWeight::get().reads(4)) + // Measured: `33` + // Estimated: `13398` + // Minimum execution time: 17_129_000 picoseconds. + Weight::from_parts(17_668_000, 0) + .saturating_add(Weight::from_parts(0, 13398)) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } - /// Storage: `XcmPallet::VersionNotifyTargets` (r:4 w:2) + /// Storage: `XcmPallet::VersionNotifyTargets` (r:5 w:2) /// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0) /// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -264,12 +302,12 @@ impl pallet_xcm::WeightInfo for WeightInfo { /// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`) fn migrate_and_notify_old_targets() -> Weight { // Proof Size summary in bytes: - // Measured: `149` - // Estimated: `11039` - // Minimum execution time: 37_549_000 picoseconds. - Weight::from_parts(38_203_000, 0) - .saturating_add(Weight::from_parts(0, 11039)) - .saturating_add(T::DbWeight::get().reads(8)) + // Measured: `183` + // Estimated: `13548` + // Minimum execution time: 39_960_000 picoseconds. + Weight::from_parts(41_068_000, 0) + .saturating_add(Weight::from_parts(0, 13548)) + .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } /// Storage: `XcmPallet::QueryCounter` (r:1 w:1) @@ -280,8 +318,8 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `1485` - // Minimum execution time: 2_947_000 picoseconds. - Weight::from_parts(3_117_000, 0) + // Minimum execution time: 2_333_000 picoseconds. + Weight::from_parts(2_504_000, 0) .saturating_add(Weight::from_parts(0, 1485)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(2)) @@ -292,10 +330,22 @@ impl pallet_xcm::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `7576` // Estimated: `11041` - // Minimum execution time: 24_595_000 picoseconds. - Weight::from_parts(24_907_000, 0) + // Minimum execution time: 22_932_000 picoseconds. + Weight::from_parts(23_307_000, 0) .saturating_add(Weight::from_parts(0, 11041)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `XcmPallet::AssetTraps` (r:1 w:1) + /// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn claim_assets() -> Weight { + // Proof Size summary in bytes: + // Measured: `23` + // Estimated: `3488` + // Minimum execution time: 34_558_000 picoseconds. + Weight::from_parts(35_299_000, 0) + .saturating_add(Weight::from_parts(0, 3488)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } } diff --git a/polkadot/xcm/pallet-xcm/src/benchmarking.rs b/polkadot/xcm/pallet-xcm/src/benchmarking.rs index e3ea2fb8c06..ed42f93692b 100644 --- a/polkadot/xcm/pallet-xcm/src/benchmarking.rs +++ b/polkadot/xcm/pallet-xcm/src/benchmarking.rs @@ -79,6 +79,13 @@ pub trait Config: crate::Config { fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box)> { None } + + /// Gets an asset that can be handled by the AssetTransactor. + /// + /// Used only in benchmarks. + /// + /// Used, for example, in the benchmark for `claim_assets`. + fn get_asset() -> Asset; } benchmarks! { @@ -341,11 +348,23 @@ benchmarks! { u32::MAX, ).unwrap()).collect::>(); crate::Pallet::::expect_response(query_id, Response::PalletsInfo(infos.try_into().unwrap())); - }: { as QueryHandler>::take_response(query_id); } + claim_assets { + let claim_origin = RawOrigin::Signed(whitelisted_caller()); + let claim_location = T::ExecuteXcmOrigin::try_origin(claim_origin.clone().into()).map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let asset: Asset = T::get_asset(); + // Trap assets for claiming later + crate::Pallet::::drop_assets( + &claim_location, + asset.clone().into(), + &XcmContext { origin: None, message_id: [0u8; 32], topic: None } + ); + let versioned_assets = VersionedAssets::V4(asset.into()); + }: _>(claim_origin.into(), Box::new(versioned_assets), Box::new(VersionedLocation::V4(claim_location))) + impl_benchmark_test_suite!( Pallet, crate::mock::new_test_ext_with_balances(Vec::new()), diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs index 5e1a3e55f9b..1a1f8b402a3 100644 --- a/polkadot/xcm/pallet-xcm/src/lib.rs +++ b/polkadot/xcm/pallet-xcm/src/lib.rs @@ -85,6 +85,7 @@ pub trait WeightInfo { fn migrate_and_notify_old_targets() -> Weight; fn new_query() -> Weight; fn take_response() -> Weight; + fn claim_assets() -> Weight; } /// fallback implementation @@ -165,6 +166,10 @@ impl WeightInfo for TestWeightInfo { fn take_response() -> Weight { Weight::from_parts(100_000_000, 0) } + + fn claim_assets() -> Weight { + Weight::from_parts(100_000_000, 0) + } } #[frame_support::pallet] @@ -1386,6 +1391,64 @@ pub mod pallet { weight_limit, ) } + + /// Claims assets trapped on this pallet because of leftover assets during XCM execution. + /// + /// - `origin`: Anyone can call this extrinsic. + /// - `assets`: The exact assets that were trapped. Use the version to specify what version + /// was the latest when they were trapped. + /// - `beneficiary`: The location/account where the claimed assets will be deposited. + #[pallet::call_index(12)] + #[pallet::weight({ + let assets_version = assets.identify_version(); + let maybe_assets: Result = (*assets.clone()).try_into(); + let maybe_beneficiary: Result = (*beneficiary.clone()).try_into(); + match (maybe_assets, maybe_beneficiary) { + (Ok(assets), Ok(beneficiary)) => { + let ticket: Location = GeneralIndex(assets_version as u128).into(); + let mut message = Xcm(vec![ + ClaimAsset { assets: assets.clone(), ticket }, + DepositAsset { assets: AllCounted(assets.len() as u32).into(), beneficiary }, + ]); + T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::claim_assets().saturating_add(w)) + } + _ => Weight::MAX + } + })] + pub fn claim_assets( + origin: OriginFor, + assets: Box, + beneficiary: Box, + ) -> DispatchResult { + let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?; + log::debug!(target: "xcm::pallet_xcm::claim_assets", "origin: {:?}, assets: {:?}, beneficiary: {:?}", origin_location, assets, beneficiary); + // Extract version from `assets`. + let assets_version = assets.identify_version(); + let assets: Assets = (*assets).try_into().map_err(|()| Error::::BadVersion)?; + let number_of_assets = assets.len() as u32; + let beneficiary: Location = + (*beneficiary).try_into().map_err(|()| Error::::BadVersion)?; + let ticket: Location = GeneralIndex(assets_version as u128).into(); + let mut message = Xcm(vec![ + ClaimAsset { assets, ticket }, + DepositAsset { assets: AllCounted(number_of_assets).into(), beneficiary }, + ]); + let weight = + T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; + let mut hash = message.using_encoded(sp_io::hashing::blake2_256); + let outcome = T::XcmExecutor::prepare_and_execute( + origin_location, + message, + &mut hash, + weight, + weight, + ); + outcome.ensure_complete().map_err(|error| { + log::error!(target: "xcm::pallet_xcm::claim_assets", "XCM execution failed with error: {:?}", error); + Error::::LocalExecutionIncomplete + })?; + Ok(()) + } } } diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs index 17c181387dd..d5ba7312a3a 100644 --- a/polkadot/xcm/pallet-xcm/src/mock.rs +++ b/polkadot/xcm/pallet-xcm/src/mock.rs @@ -172,7 +172,7 @@ impl SendXcm for TestSendXcm { msg: &mut Option>, ) -> SendResult<(Location, Xcm<()>)> { if FAIL_SEND_XCM.with(|q| *q.borrow()) { - return Err(SendError::Transport("Intentional send failure used in tests")) + return Err(SendError::Transport("Intentional send failure used in tests")); } let pair = (dest.take().unwrap(), msg.take().unwrap()); Ok((pair, Assets::new())) @@ -654,6 +654,10 @@ impl super::benchmarking::Config for Test { }); Some((assets, fee_index as u32, dest, verify)) } + + fn get_asset() -> Asset { + Asset { id: AssetId(Location::here()), fun: Fungible(ExistentialDeposit::get()) } + } } pub(crate) fn last_event() -> RuntimeEvent { diff --git a/polkadot/xcm/pallet-xcm/src/tests/mod.rs b/polkadot/xcm/pallet-xcm/src/tests/mod.rs index 28c7d197443..13022d9a8b1 100644 --- a/polkadot/xcm/pallet-xcm/src/tests/mod.rs +++ b/polkadot/xcm/pallet-xcm/src/tests/mod.rs @@ -467,6 +467,57 @@ fn trapped_assets_can_be_claimed() { }); } +// Like `trapped_assets_can_be_claimed` but using the `claim_assets` extrinsic. +#[test] +fn claim_assets_works() { + let balances = vec![(ALICE, INITIAL_BALANCE)]; + new_test_ext_with_balances(balances).execute_with(|| { + // First trap some assets. + let trapping_program = + Xcm::builder_unsafe().withdraw_asset((Here, SEND_AMOUNT).into()).build(); + // Even though assets are trapped, the extrinsic returns success. + assert_ok!(XcmPallet::execute( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedXcm::V4(trapping_program)), + BaseXcmWeight::get() * 2, + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT); + + // Expected `AssetsTrapped` event info. + let source: Location = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); + let versioned_assets = VersionedAssets::V4(Assets::from((Here, SEND_AMOUNT))); + let hash = BlakeTwo256::hash_of(&(source.clone(), versioned_assets.clone())); + + // Assets were indeed trapped. + assert_eq!( + last_events(2), + vec![ + RuntimeEvent::XcmPallet(crate::Event::AssetsTrapped { + hash, + origin: source, + assets: versioned_assets + }), + RuntimeEvent::XcmPallet(crate::Event::Attempted { + outcome: Outcome::Complete { used: BaseXcmWeight::get() * 1 } + }) + ], + ); + let trapped = AssetTraps::::iter().collect::>(); + assert_eq!(trapped, vec![(hash, 1)]); + + // Now claim them with the extrinsic. + assert_ok!(XcmPallet::claim_assets( + RuntimeOrigin::signed(ALICE), + Box::new(VersionedAssets::V4((Here, SEND_AMOUNT).into())), + Box::new(VersionedLocation::V4( + AccountId32 { network: None, id: ALICE.clone().into() }.into() + )), + )); + assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); + assert_eq!(AssetTraps::::iter().collect::>(), vec![]); + }); +} + /// Test failure to complete execution reverts intermediate side-effects. /// /// XCM program will withdraw and deposit some assets, then fail execution of a further withdraw. diff --git a/polkadot/xcm/src/lib.rs b/polkadot/xcm/src/lib.rs index c90ad25c0d8..ba8d726aecf 100644 --- a/polkadot/xcm/src/lib.rs +++ b/polkadot/xcm/src/lib.rs @@ -165,6 +165,15 @@ macro_rules! versioned_type { <$v3>::max_encoded_len() } } + impl IdentifyVersion for $n { + fn identify_version(&self) -> Version { + use $n::*; + match self { + V3(_) => v3::VERSION, + V4(_) => v4::VERSION, + } + } + } }; ($(#[$attr:meta])* pub enum $n:ident { @@ -287,6 +296,16 @@ macro_rules! versioned_type { <$v3>::max_encoded_len() } } + impl IdentifyVersion for $n { + fn identify_version(&self) -> Version { + use $n::*; + match self { + V2(_) => v2::VERSION, + V3(_) => v3::VERSION, + V4(_) => v4::VERSION, + } + } + } }; } @@ -493,6 +512,12 @@ pub trait WrapVersion { ) -> Result, ()>; } +/// Used to get the version out of a versioned type. +// TODO(XCMv5): This could be `GetVersion` and we change the current one to `GetVersionFor`. +pub trait IdentifyVersion { + fn identify_version(&self) -> Version; +} + /// Check and return the `Version` that should be used for the `Xcm` datum for the destination /// `Location`, which will interpret it. pub trait GetVersion { @@ -572,9 +597,9 @@ pub type AlwaysLts = AlwaysV4; pub mod prelude { pub use super::{ latest::prelude::*, AlwaysLatest, AlwaysLts, AlwaysV2, AlwaysV3, AlwaysV4, GetVersion, - IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, VersionedAssetId, - VersionedAssets, VersionedInteriorLocation, VersionedLocation, VersionedResponse, - VersionedXcm, WrapVersion, + IdentifyVersion, IntoVersion, Unsupported, Version as XcmVersion, VersionedAsset, + VersionedAssetId, VersionedAssets, VersionedInteriorLocation, VersionedLocation, + VersionedResponse, VersionedXcm, WrapVersion, }; } diff --git a/prdoc/pr_3403.prdoc b/prdoc/pr_3403.prdoc new file mode 100644 index 00000000000..086e769da3c --- /dev/null +++ b/prdoc/pr_3403.prdoc @@ -0,0 +1,22 @@ +# 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: "Add `claim_assets` extrinsic to `pallet-xcm`" + +doc: + - audience: Runtime User + description: | + There's a new extrinsic in `pallet-xcm` for claiming assets. + This means that if your assets ever get trapped while teleporting or doing reserve asset transfers, + you can easily claim them by calling this new extrinsic. + - audience: Runtime Dev + description: | + There's a new extrinsic in `pallet-xcm` that needs a new configuration item for its benchmarks. + It's a simple function in `pallet_xcm::benchmarking::Config`, `get_asset`, that returns a valid asset + handled by the AssetTransactor of the chain. + If you're already using `pallet-xcm-benchmarks`, then you already have this function there and can + just copy and paste it. + +crates: + - name: pallet-xcm + - name: staging-xcm -- GitLab From 59b2661444de2a25f2125a831bd786035a9fac4b Mon Sep 17 00:00:00 2001 From: Egor_P Date: Fri, 1 Mar 2024 15:51:53 +0700 Subject: [PATCH 283/283] [Backport] Node version and spec_version bumps and ordering of the prdoc files from 1.8.0 (#3508) This PR backports Node version and `spec_version` bumps to `1.8.0` from the latest release and orders prdoc files related to it. --- .../runtimes/assets/asset-hub-rococo/src/lib.rs | 4 ++-- .../runtimes/assets/asset-hub-westend/src/lib.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 2 +- .../collectives/collectives-westend/src/lib.rs | 2 +- .../runtimes/contracts/contracts-rococo/src/lib.rs | 2 +- .../runtimes/coretime/coretime-rococo/src/lib.rs | 2 +- .../runtimes/coretime/coretime-westend/src/lib.rs | 2 +- .../runtimes/glutton/glutton-westend/src/lib.rs | 2 +- .../runtimes/people/people-rococo/src/lib.rs | 2 +- .../runtimes/people/people-westend/src/lib.rs | 2 +- .../runtimes/testing/rococo-parachain/src/lib.rs | 2 +- polkadot/node/primitives/src/lib.rs | 2 +- polkadot/runtime/rococo/src/lib.rs | 2 +- polkadot/runtime/westend/src/lib.rs | 2 +- prdoc/{ => 1.8.0}/pr_1660.prdoc | 0 prdoc/{ => 1.8.0}/pr_2061.prdoc | 0 prdoc/{ => 1.8.0}/pr_2290.prdoc | 0 prdoc/{ => 1.8.0}/pr_2903.prdoc | 0 ...9-async-backing-on-all-testnet-system-chains.prdoc | 0 prdoc/{ => 1.8.0}/pr_3007.prdoc | 0 prdoc/{ => 1.8.0}/pr_3052.prdoc | 0 prdoc/{ => 1.8.0}/pr_3060.prdoc | 0 prdoc/{ => 1.8.0}/pr_3079.prdoc | 0 prdoc/{ => 1.8.0}/pr_3154.prdoc | 0 prdoc/{ => 1.8.0}/pr_3160.prdoc | 0 prdoc/{ => 1.8.0}/pr_3166.prdoc | 0 prdoc/{ => 1.8.0}/pr_3184.prdoc | 0 prdoc/{ => 1.8.0}/pr_3212.prdoc | 0 prdoc/{ => 1.8.0}/pr_3225.prdoc | 0 prdoc/{ => 1.8.0}/pr_3230.prdoc | 0 prdoc/{ => 1.8.0}/pr_3232.prdoc | 0 prdoc/{ => 1.8.0}/pr_3243.prdoc | 0 prdoc/{ => 1.8.0}/pr_3244.prdoc | 0 prdoc/{ => 1.8.0}/pr_3272.prdoc | 0 prdoc/{ => 1.8.0}/pr_3301.prdoc | 0 prdoc/{ => 1.8.0}/pr_3308.prdoc | 0 prdoc/{ => 1.8.0}/pr_3319.prdoc | 0 prdoc/{ => 1.8.0}/pr_3325.prdoc | 0 prdoc/{ => 1.8.0}/pr_3358.prdoc | 0 prdoc/{ => 1.8.0}/pr_3361.prdoc | 0 prdoc/{ => 1.8.0}/pr_3364.prdoc | 0 prdoc/{ => 1.8.0}/pr_3370.prdoc | 0 prdoc/{ => 1.8.0}/pr_3384.prdoc | 0 prdoc/{ => 1.8.0}/pr_3395.prdoc | 0 prdoc/{ => 1.8.0}/pr_3415.prdoc | 0 prdoc/{ => 1.8.0}/pr_3435.prdoc | 0 prdoc/1.8.0/pr_3477.prdoc | 11 +++++++++++ 48 files changed, 27 insertions(+), 16 deletions(-) rename prdoc/{ => 1.8.0}/pr_1660.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2061.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2290.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2903.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_2949-async-backing-on-all-testnet-system-chains.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3007.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3052.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3060.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3079.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3154.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3160.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3166.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3184.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3212.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3225.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3230.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3232.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3243.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3244.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3272.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3301.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3308.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3319.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3325.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3358.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3361.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3364.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3370.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3384.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3395.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3415.prdoc (100%) rename prdoc/{ => 1.8.0}/pr_3435.prdoc (100%) create mode 100644 prdoc/1.8.0/pr_3477.prdoc diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index a64d4bc2365..17a12dd2f6f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("statemine"), impl_name: create_runtime_str!("statemine"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5778ed362ee..1ead2897855 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -110,7 +110,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westmint"), impl_name: create_runtime_str!("westmint"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 14, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index ee472f006fa..0b48d1717fa 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -202,7 +202,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-rococo"), impl_name: create_runtime_str!("bridge-hub-rococo"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 60d959b4053..e1344fce63d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -176,7 +176,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("bridge-hub-westend"), impl_name: create_runtime_str!("bridge-hub-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index 9a88ca174df..6bcf98c428f 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -117,7 +117,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("collectives-westend"), impl_name: create_runtime_str!("collectives-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 5, diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index c73d2225ebd..0668b9a4c7d 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("contracts-rococo"), impl_name: create_runtime_str!("contracts-rococo"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index d95e68d85c4..cdff371c505 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-rococo"), impl_name: create_runtime_str!("coretime-rococo"), authoring_version: 1, - spec_version: 1_007_001, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 4b9b180321d..7fa70647992 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("coretime-westend"), impl_name: create_runtime_str!("coretime-westend"), authoring_version: 1, - spec_version: 1_007_001, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index e09ad42ea9f..232a82115a8 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -100,7 +100,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("glutton-westend"), impl_name: create_runtime_str!("glutton-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index 28b8062e0e0..2b8cc32f67c 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-rococo"), impl_name: create_runtime_str!("people-rococo"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index b2b32445613..2dc2d06a66b 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("people-westend"), impl_name: create_runtime_str!("people-westend"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 0, diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs index b69c2341d6b..2b21a12c3ca 100644 --- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs @@ -107,7 +107,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("test-parachain"), impl_name: create_runtime_str!("test-parachain"), authoring_version: 1, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 6, diff --git a/polkadot/node/primitives/src/lib.rs b/polkadot/node/primitives/src/lib.rs index 6e3eefbcbe8..d295c21cce1 100644 --- a/polkadot/node/primitives/src/lib.rs +++ b/polkadot/node/primitives/src/lib.rs @@ -58,7 +58,7 @@ pub use disputes::{ /// relatively rare. /// /// The associated worker binaries should use the same version as the node that spawns them. -pub const NODE_VERSION: &'static str = "1.7.0"; +pub const NODE_VERSION: &'static str = "1.8.0"; // For a 16-ary Merkle Prefix Trie, we can expect at most 16 32-byte hashes per node // plus some overhead: diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 48395f45238..96e8c4e0979 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -149,7 +149,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("rococo"), impl_name: create_runtime_str!("parity-rococo-v2.0"), authoring_version: 0, - spec_version: 1_007_000, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 4ac2202b8fc..b55d68ee0f6 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -150,7 +150,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("westend"), impl_name: create_runtime_str!("parity-westend"), authoring_version: 2, - spec_version: 1_007_001, + spec_version: 1_008_000, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 24, diff --git a/prdoc/pr_1660.prdoc b/prdoc/1.8.0/pr_1660.prdoc similarity index 100% rename from prdoc/pr_1660.prdoc rename to prdoc/1.8.0/pr_1660.prdoc diff --git a/prdoc/pr_2061.prdoc b/prdoc/1.8.0/pr_2061.prdoc similarity index 100% rename from prdoc/pr_2061.prdoc rename to prdoc/1.8.0/pr_2061.prdoc diff --git a/prdoc/pr_2290.prdoc b/prdoc/1.8.0/pr_2290.prdoc similarity index 100% rename from prdoc/pr_2290.prdoc rename to prdoc/1.8.0/pr_2290.prdoc diff --git a/prdoc/pr_2903.prdoc b/prdoc/1.8.0/pr_2903.prdoc similarity index 100% rename from prdoc/pr_2903.prdoc rename to prdoc/1.8.0/pr_2903.prdoc diff --git a/prdoc/pr_2949-async-backing-on-all-testnet-system-chains.prdoc b/prdoc/1.8.0/pr_2949-async-backing-on-all-testnet-system-chains.prdoc similarity index 100% rename from prdoc/pr_2949-async-backing-on-all-testnet-system-chains.prdoc rename to prdoc/1.8.0/pr_2949-async-backing-on-all-testnet-system-chains.prdoc diff --git a/prdoc/pr_3007.prdoc b/prdoc/1.8.0/pr_3007.prdoc similarity index 100% rename from prdoc/pr_3007.prdoc rename to prdoc/1.8.0/pr_3007.prdoc diff --git a/prdoc/pr_3052.prdoc b/prdoc/1.8.0/pr_3052.prdoc similarity index 100% rename from prdoc/pr_3052.prdoc rename to prdoc/1.8.0/pr_3052.prdoc diff --git a/prdoc/pr_3060.prdoc b/prdoc/1.8.0/pr_3060.prdoc similarity index 100% rename from prdoc/pr_3060.prdoc rename to prdoc/1.8.0/pr_3060.prdoc diff --git a/prdoc/pr_3079.prdoc b/prdoc/1.8.0/pr_3079.prdoc similarity index 100% rename from prdoc/pr_3079.prdoc rename to prdoc/1.8.0/pr_3079.prdoc diff --git a/prdoc/pr_3154.prdoc b/prdoc/1.8.0/pr_3154.prdoc similarity index 100% rename from prdoc/pr_3154.prdoc rename to prdoc/1.8.0/pr_3154.prdoc diff --git a/prdoc/pr_3160.prdoc b/prdoc/1.8.0/pr_3160.prdoc similarity index 100% rename from prdoc/pr_3160.prdoc rename to prdoc/1.8.0/pr_3160.prdoc diff --git a/prdoc/pr_3166.prdoc b/prdoc/1.8.0/pr_3166.prdoc similarity index 100% rename from prdoc/pr_3166.prdoc rename to prdoc/1.8.0/pr_3166.prdoc diff --git a/prdoc/pr_3184.prdoc b/prdoc/1.8.0/pr_3184.prdoc similarity index 100% rename from prdoc/pr_3184.prdoc rename to prdoc/1.8.0/pr_3184.prdoc diff --git a/prdoc/pr_3212.prdoc b/prdoc/1.8.0/pr_3212.prdoc similarity index 100% rename from prdoc/pr_3212.prdoc rename to prdoc/1.8.0/pr_3212.prdoc diff --git a/prdoc/pr_3225.prdoc b/prdoc/1.8.0/pr_3225.prdoc similarity index 100% rename from prdoc/pr_3225.prdoc rename to prdoc/1.8.0/pr_3225.prdoc diff --git a/prdoc/pr_3230.prdoc b/prdoc/1.8.0/pr_3230.prdoc similarity index 100% rename from prdoc/pr_3230.prdoc rename to prdoc/1.8.0/pr_3230.prdoc diff --git a/prdoc/pr_3232.prdoc b/prdoc/1.8.0/pr_3232.prdoc similarity index 100% rename from prdoc/pr_3232.prdoc rename to prdoc/1.8.0/pr_3232.prdoc diff --git a/prdoc/pr_3243.prdoc b/prdoc/1.8.0/pr_3243.prdoc similarity index 100% rename from prdoc/pr_3243.prdoc rename to prdoc/1.8.0/pr_3243.prdoc diff --git a/prdoc/pr_3244.prdoc b/prdoc/1.8.0/pr_3244.prdoc similarity index 100% rename from prdoc/pr_3244.prdoc rename to prdoc/1.8.0/pr_3244.prdoc diff --git a/prdoc/pr_3272.prdoc b/prdoc/1.8.0/pr_3272.prdoc similarity index 100% rename from prdoc/pr_3272.prdoc rename to prdoc/1.8.0/pr_3272.prdoc diff --git a/prdoc/pr_3301.prdoc b/prdoc/1.8.0/pr_3301.prdoc similarity index 100% rename from prdoc/pr_3301.prdoc rename to prdoc/1.8.0/pr_3301.prdoc diff --git a/prdoc/pr_3308.prdoc b/prdoc/1.8.0/pr_3308.prdoc similarity index 100% rename from prdoc/pr_3308.prdoc rename to prdoc/1.8.0/pr_3308.prdoc diff --git a/prdoc/pr_3319.prdoc b/prdoc/1.8.0/pr_3319.prdoc similarity index 100% rename from prdoc/pr_3319.prdoc rename to prdoc/1.8.0/pr_3319.prdoc diff --git a/prdoc/pr_3325.prdoc b/prdoc/1.8.0/pr_3325.prdoc similarity index 100% rename from prdoc/pr_3325.prdoc rename to prdoc/1.8.0/pr_3325.prdoc diff --git a/prdoc/pr_3358.prdoc b/prdoc/1.8.0/pr_3358.prdoc similarity index 100% rename from prdoc/pr_3358.prdoc rename to prdoc/1.8.0/pr_3358.prdoc diff --git a/prdoc/pr_3361.prdoc b/prdoc/1.8.0/pr_3361.prdoc similarity index 100% rename from prdoc/pr_3361.prdoc rename to prdoc/1.8.0/pr_3361.prdoc diff --git a/prdoc/pr_3364.prdoc b/prdoc/1.8.0/pr_3364.prdoc similarity index 100% rename from prdoc/pr_3364.prdoc rename to prdoc/1.8.0/pr_3364.prdoc diff --git a/prdoc/pr_3370.prdoc b/prdoc/1.8.0/pr_3370.prdoc similarity index 100% rename from prdoc/pr_3370.prdoc rename to prdoc/1.8.0/pr_3370.prdoc diff --git a/prdoc/pr_3384.prdoc b/prdoc/1.8.0/pr_3384.prdoc similarity index 100% rename from prdoc/pr_3384.prdoc rename to prdoc/1.8.0/pr_3384.prdoc diff --git a/prdoc/pr_3395.prdoc b/prdoc/1.8.0/pr_3395.prdoc similarity index 100% rename from prdoc/pr_3395.prdoc rename to prdoc/1.8.0/pr_3395.prdoc diff --git a/prdoc/pr_3415.prdoc b/prdoc/1.8.0/pr_3415.prdoc similarity index 100% rename from prdoc/pr_3415.prdoc rename to prdoc/1.8.0/pr_3415.prdoc diff --git a/prdoc/pr_3435.prdoc b/prdoc/1.8.0/pr_3435.prdoc similarity index 100% rename from prdoc/pr_3435.prdoc rename to prdoc/1.8.0/pr_3435.prdoc diff --git a/prdoc/1.8.0/pr_3477.prdoc b/prdoc/1.8.0/pr_3477.prdoc new file mode 100644 index 00000000000..26e96d3635b --- /dev/null +++ b/prdoc/1.8.0/pr_3477.prdoc @@ -0,0 +1,11 @@ +title: Allow parachain which acquires multiple coretime cores to make progress + +doc: + - audience: Node Operator + description: | + Adds the needed changes so that parachains which acquire multiple coretime cores can still make progress. + Only one of the cores will be able to be occupied at a time. + Only works if the ElasticScalingMVP node feature is enabled in the runtime and the block author validator is + updated to include this change. + +crates: [ ] -- GitLab