diff --git a/.github/workflows/review-trigger.yml b/.github/workflows/review-trigger.yml index 061cf4ab09ed919f6de0a83f74a22c2062c3a258..7f7d9d362782c9738e108de0f7f949aaab3eb8c6 100644 --- a/.github/workflows/review-trigger.yml +++ b/.github/workflows/review-trigger.yml @@ -21,25 +21,30 @@ jobs: - name: Skip merge queue if: ${{ contains(github.ref, 'gh-readonly-queue') }} run: exit 0 - - name: Get comments + - name: Get PR data id: comments - run: echo "bodies=$(gh pr view ${{ github.event.number }} --repo ${{ github.repository }} --json comments --jq '[.comments[].body]')" >> "$GITHUB_OUTPUT" + run: | + echo "bodies=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '[.comments[].body]')" >> "$GITHUB_OUTPUT" + echo "reviews=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews --jq '[.[].state]')" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ github.token }} - name: Fail when author pushes new code # Require new reviews when the author is pushing and he is not a member if: | + contains(fromJson(steps.comments.outputs.reviews), 'APPROVED') && github.event_name == 'pull_request_target' && github.event.action == 'synchronize' && github.event.sender.login == github.event.pull_request.user.login && + github.event.pull_request.author_association != 'CONTRIBUTOR' && github.event.pull_request.author_association != 'MEMBER' run: | + echo "User's association is ${{ github.event.pull_request.author_association }}" # We get the list of reviewers who approved the PR - REVIEWERS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.number }}/reviews \ + REVIEWERS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews \ --jq '{reviewers: [.[] | select(.state == "APPROVED") | .user.login]}') # We request them to review again - echo $REVIEWERS | gh api --method POST repos/${{ github.repository }}/pulls/${{ github.event.number }}/requested_reviewers --input - + echo $REVIEWERS | gh api --method POST repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/requested_reviewers --input - echo "::error::Project needs to be reviewed again" exit 1 @@ -49,7 +54,7 @@ jobs: # If the previous step failed and github-actions hasn't commented yet we comment instructions if: failure() && !contains(fromJson(steps.comments.outputs.bodies), 'Review required! Latest push from author must always be reviewed') run: | - gh pr comment ${{ github.event.number }} --repo ${{ github.repository }} --body "Review required! Latest push from author must always be reviewed" + gh pr comment ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --body "Review required! Latest push from author must always be reviewed" env: GH_TOKEN: ${{ github.token }} COMMENTS: ${{ steps.comments.outputs.users }} diff --git a/Cargo.lock b/Cargo.lock index 32dee11171fdc57382fbd8c0d64e40a006064c13..ff28d842a23ed38a7723563984ea4e697cb0ed25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -820,6 +820,7 @@ dependencies = [ "assert_matches", "asset-hub-rococo-runtime", "asset-test-utils", + "cumulus-pallet-parachain-system", "emulated-integration-tests-common", "frame-support", "pallet-asset-conversion", @@ -827,11 +828,15 @@ dependencies = [ "pallet-assets", "pallet-balances", "pallet-message-queue", + "pallet-treasury", + "pallet-utility", "pallet-xcm", "parachains-common", "parity-scale-codec", "penpal-runtime", + "polkadot-runtime-common", "rococo-runtime", + "rococo-runtime-constants", "rococo-system-emulated-network", "sp-runtime", "staging-xcm", @@ -2834,6 +2839,36 @@ dependencies = [ "testnet-parachains-constants", ] +[[package]] +name = "collectives-westend-integration-tests" +version = "1.0.0" +dependencies = [ + "assert_matches", + "asset-hub-westend-runtime", + "collectives-westend-runtime", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcmp-queue", + "emulated-integration-tests-common", + "frame-support", + "pallet-asset-rate", + "pallet-assets", + "pallet-balances", + "pallet-message-queue", + "pallet-treasury", + "pallet-utility", + "pallet-xcm", + "parachains-common", + "parity-scale-codec", + "polkadot-runtime-common", + "sp-runtime", + "staging-xcm", + "staging-xcm-executor", + "testnet-parachains-constants", + "westend-runtime", + "westend-runtime-constants", + "westend-system-emulated-network", +] + [[package]] name = "collectives-westend-runtime" version = "3.0.0" diff --git a/Cargo.toml b/Cargo.toml index a020bfa694a237dbef0b2133118cd2ca2ca5a925..ab7b8ee4baf40dd9bd9ec2f1f9993fa5ae618757 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,7 @@ members = [ "cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-westend", "cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo", "cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend", + "cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend", "cumulus/parachains/integration-tests/emulated/tests/people/people-rococo", "cumulus/parachains/integration-tests/emulated/tests/people/people-westend", "cumulus/parachains/pallets/collective-content", diff --git a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs index 379a29d697bcb564b670eadb638f7088f042137a..7a3a936ec972f0a8c99e3b472c7cce9e9914e29c 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/relays/rococo/src/lib.rs @@ -39,6 +39,8 @@ decl_test_relay_chains! { Hrmp: rococo_runtime::Hrmp, Identity: rococo_runtime::Identity, IdentityMigrator: rococo_runtime::IdentityMigrator, + Treasury: rococo_runtime::Treasury, + AssetRate: rococo_runtime::AssetRate, } }, } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml index 64fee0241a4da2d987d4906918677fe1acbd91e3..230f7a9c359b922070f507355a74a708d80096e5 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/Cargo.toml @@ -22,15 +22,20 @@ pallet-assets = { path = "../../../../../../../substrate/frame/assets", default- pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false } pallet-asset-rewards = { path = "../../../../../../../substrate/frame/asset-rewards", default-features = false } pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue", default-features = false } +pallet-treasury = { path = "../../../../../../../substrate/frame/treasury", default-features = false } +pallet-utility = { path = "../../../../../../../substrate/frame/utility", default-features = false } # Polkadot xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false } pallet-xcm = { path = "../../../../../../../polkadot/xcm/pallet-xcm", default-features = false } xcm-executor = { package = "staging-xcm-executor", path = "../../../../../../../polkadot/xcm/xcm-executor", default-features = false } rococo-runtime = { path = "../../../../../../../polkadot/runtime/rococo" } +polkadot-runtime-common = { path = "../../../../../../../polkadot/runtime/common" } +rococo-runtime-constants = { path = "../../../../../../../polkadot/runtime/rococo/constants" } # Cumulus asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" } +cumulus-pallet-parachain-system = { path = "../../../../../../pallets/parachain-system", default-features = false } parachains-common = { path = "../../../../../common" } asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" } penpal-runtime = { path = "../../../../../runtimes/testing/penpal" } diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs index dfe0a7561d509717647744d2ede358a45840b284..89f32ccdfb51c0f85c4b1da18914d30281ad6780 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/mod.rs @@ -20,3 +20,4 @@ mod set_xcm_versions; mod swap; mod teleport; mod treasury_asset_reward_pool; +mod treasury; diff --git a/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs new file mode 100644 index 0000000000000000000000000000000000000000..01bf40ae8fdf2cf87092c83ef604ef25427e2939 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/assets/asset-hub-rococo/src/tests/treasury.rs @@ -0,0 +1,270 @@ +// 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::imports::*; +use emulated_integration_tests_common::accounts::{ALICE, BOB}; +use frame_support::{ + dispatch::RawOrigin, + sp_runtime::traits::Dispatchable, + traits::{ + fungible::Inspect, + fungibles::{Create, Inspect as FungiblesInspect, Mutate}, + }, +}; +use parachains_common::AccountId; +use polkadot_runtime_common::impls::VersionedLocatableAsset; +use rococo_runtime::OriginCaller; +use rococo_runtime_constants::currency::GRAND; +use xcm_executor::traits::ConvertLocation; + +// Fund Treasury account on Asset Hub from Treasury account on Relay Chain with ROCs. +#[test] +fn spend_roc_on_asset_hub() { + // initial treasury balance on Asset Hub in ROCs. + let treasury_balance = 9_000 * GRAND; + // the balance spend on Asset Hub. + let treasury_spend_balance = 1_000 * GRAND; + + let init_alice_balance = AssetHubRococo::execute_with(|| { + <<AssetHubRococo as AssetHubRococoPallet>::Balances as Inspect<_>>::balance( + &AssetHubRococo::account_id_of(ALICE), + ) + }); + + Rococo::execute_with(|| { + type RuntimeEvent = <Rococo as Chain>::RuntimeEvent; + type RuntimeCall = <Rococo as Chain>::RuntimeCall; + type Runtime = <Rococo as Chain>::Runtime; + type Balances = <Rococo as RococoPallet>::Balances; + type Treasury = <Rococo as RococoPallet>::Treasury; + + // Fund Treasury account on Asset Hub with ROCs. + + let root = <Rococo as Chain>::RuntimeOrigin::root(); + let treasury_account = Treasury::account_id(); + + // Mint assets to Treasury account on Relay Chain. + assert_ok!(Balances::force_set_balance( + root.clone(), + treasury_account.clone().into(), + treasury_balance * 2, + )); + + let native_asset = Location::here(); + let asset_hub_location: Location = [Parachain(1000)].into(); + let treasury_location: Location = (Parent, PalletInstance(18)).into(); + + let teleport_call = RuntimeCall::Utility(pallet_utility::Call::<Runtime>::dispatch_as { + as_origin: bx!(OriginCaller::system(RawOrigin::Signed(treasury_account))), + call: bx!(RuntimeCall::XcmPallet(pallet_xcm::Call::<Runtime>::teleport_assets { + dest: bx!(VersionedLocation::V4(asset_hub_location.clone())), + beneficiary: bx!(VersionedLocation::V4(treasury_location)), + assets: bx!(VersionedAssets::V4( + Asset { id: native_asset.clone().into(), fun: treasury_balance.into() }.into() + )), + fee_asset_item: 0, + })), + }); + + // Dispatched from Root to `despatch_as` `Signed(treasury_account)`. + assert_ok!(teleport_call.dispatch(root)); + + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + Rococo::execute_with(|| { + type RuntimeEvent = <Rococo as Chain>::RuntimeEvent; + type RuntimeCall = <Rococo as Chain>::RuntimeCall; + type RuntimeOrigin = <Rococo as Chain>::RuntimeOrigin; + type Runtime = <Rococo as Chain>::Runtime; + type Treasury = <Rococo as RococoPallet>::Treasury; + + // Fund Alice account from Rococo Treasury account on Asset Hub. + + let treasury_origin: RuntimeOrigin = + rococo_runtime::governance::pallet_custom_origins::Origin::Treasurer.into(); + + let alice_location: Location = + [Junction::AccountId32 { network: None, id: Rococo::account_id_of(ALICE).into() }] + .into(); + let asset_hub_location: Location = [Parachain(1000)].into(); + let native_asset = Location::parent(); + + let treasury_spend_call = RuntimeCall::Treasury(pallet_treasury::Call::<Runtime>::spend { + asset_kind: bx!(VersionedLocatableAsset::V4 { + location: asset_hub_location.clone(), + asset_id: native_asset.into(), + }), + amount: treasury_spend_balance, + beneficiary: bx!(VersionedLocation::V4(alice_location)), + valid_from: None, + }); + + assert_ok!(treasury_spend_call.dispatch(treasury_origin)); + + // Claim the spend. + + let bob_signed = RuntimeOrigin::signed(Rococo::account_id_of(BOB)); + assert_ok!(Treasury::payout(bob_signed.clone(), 0)); + + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Treasury(pallet_treasury::Event::AssetSpendApproved { .. }) => {}, + RuntimeEvent::Treasury(pallet_treasury::Event::Paid { .. }) => {}, + ] + ); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent; + type Balances = <AssetHubRococo as AssetHubRococoPallet>::Balances; + + // Ensure that the funds deposited to Alice account. + + let alice_account = AssetHubRococo::account_id_of(ALICE); + assert_eq!( + <Balances as Inspect<_>>::balance(&alice_account), + treasury_spend_balance + init_alice_balance + ); + + // Assert events triggered by xcm pay program: + // 1. treasury asset transferred to spend beneficiary; + // 2. response to Relay Chain Treasury pallet instance sent back; + // 3. XCM program completed; + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::Balances(pallet_balances::Event::Transfer { .. }) => {}, + RuntimeEvent::ParachainSystem(cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {}, + ] + ); + }); +} + +#[test] +fn create_and_claim_treasury_spend_in_usdt() { + const ASSET_ID: u32 = 1984; + const SPEND_AMOUNT: u128 = 1_000_000; + // treasury location from a sibling parachain. + let treasury_location: Location = Location::new(1, PalletInstance(18)); + // treasury account on a sibling parachain. + let treasury_account = + asset_hub_rococo_runtime::xcm_config::LocationToAccountId::convert_location( + &treasury_location, + ) + .unwrap(); + let asset_hub_location = + v3::Location::new(0, v3::Junction::Parachain(AssetHubRococo::para_id().into())); + let root = <Rococo as Chain>::RuntimeOrigin::root(); + // asset kind to be spend from the treasury. + let asset_kind = VersionedLocatableAsset::V3 { + location: asset_hub_location, + asset_id: v3::AssetId::Concrete( + (v3::Junction::PalletInstance(50), v3::Junction::GeneralIndex(ASSET_ID.into())).into(), + ), + }; + // treasury spend beneficiary. + let alice: AccountId = Rococo::account_id_of(ALICE); + let bob: AccountId = Rococo::account_id_of(BOB); + let bob_signed = <Rococo as Chain>::RuntimeOrigin::signed(bob.clone()); + + AssetHubRococo::execute_with(|| { + type Assets = <AssetHubRococo as AssetHubRococoPallet>::Assets; + + // create an asset class and mint some assets to the treasury account. + assert_ok!(<Assets as Create<_>>::create( + ASSET_ID, + treasury_account.clone(), + true, + SPEND_AMOUNT / 2 + )); + assert_ok!(<Assets as Mutate<_>>::mint_into(ASSET_ID, &treasury_account, SPEND_AMOUNT * 4)); + // beneficiary has zero balance. + assert_eq!(<Assets as FungiblesInspect<_>>::balance(ASSET_ID, &alice,), 0u128,); + }); + + Rococo::execute_with(|| { + type RuntimeEvent = <Rococo as Chain>::RuntimeEvent; + type Treasury = <Rococo as RococoPallet>::Treasury; + type AssetRate = <Rococo as RococoPallet>::AssetRate; + + // create a conversion rate from `asset_kind` to the native currency. + assert_ok!(AssetRate::create(root.clone(), Box::new(asset_kind.clone()), 2.into())); + + // create and approve a treasury spend. + assert_ok!(Treasury::spend( + root, + Box::new(asset_kind), + SPEND_AMOUNT, + Box::new(Location::new(0, Into::<[u8; 32]>::into(alice.clone())).into()), + None, + )); + // claim the spend. + assert_ok!(Treasury::payout(bob_signed.clone(), 0)); + + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Treasury(pallet_treasury::Event::Paid { .. }) => {}, + ] + ); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent; + type Assets = <AssetHubRococo as AssetHubRococoPallet>::Assets; + + // assert events triggered by xcm pay program + // 1. treasury asset transferred to spend beneficiary + // 2. response to Relay Chain treasury pallet instance sent back + // 3. XCM program completed + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::Assets(pallet_assets::Event::Transferred { asset_id: id, from, to, amount }) => { + id: id == &ASSET_ID, + from: from == &treasury_account, + to: to == &alice, + amount: amount == &SPEND_AMOUNT, + }, + RuntimeEvent::ParachainSystem(cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {}, + ] + ); + // beneficiary received the assets from the treasury. + assert_eq!(<Assets as FungiblesInspect<_>>::balance(ASSET_ID, &alice,), SPEND_AMOUNT,); + }); + + Rococo::execute_with(|| { + type RuntimeEvent = <Rococo as Chain>::RuntimeEvent; + type Treasury = <Rococo as RococoPallet>::Treasury; + + // check the payment status to ensure the response from the AssetHub was received. + assert_ok!(Treasury::check_status(bob_signed, 0)); + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Treasury(pallet_treasury::Event::SpendProcessed { .. }) => {}, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d1dbef9fc4156c08b2c52f54a3759de763c959e0 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "collectives-westend-integration-tests" +version = "1.0.0" +authors.workspace = true +edition.workspace = true +license = "Apache-2.0" +description = "Collectives Westend runtime integration tests with xcm-emulator" +publish = false + +[lints] +workspace = true + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } +assert_matches = "1.5.0" + +# Substrate +sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false } +frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false } +pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false } +pallet-asset-rate = { path = "../../../../../../../substrate/frame/asset-rate", default-features = false } +pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false } +pallet-treasury = { path = "../../../../../../../substrate/frame/treasury", default-features = false } +pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue", default-features = false } +pallet-utility = { path = "../../../../../../../substrate/frame/utility", default-features = false } + +# Polkadot +polkadot-runtime-common = { path = "../../../../../../../polkadot/runtime/common" } +xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false } +xcm-executor = { package = "staging-xcm-executor", path = "../../../../../../../polkadot/xcm/xcm-executor", default-features = false } +pallet-xcm = { path = "../../../../../../../polkadot/xcm/pallet-xcm", default-features = false } +westend-runtime = { path = "../../../../../../../polkadot/runtime/westend" } +westend-runtime-constants = { path = "../../../../../../../polkadot/runtime/westend/constants" } + +# Cumulus +parachains-common = { path = "../../../../../../parachains/common" } +testnet-parachains-constants = { path = "../../../../../runtimes/constants", features = ["westend"] } +asset-hub-westend-runtime = { path = "../../../../../runtimes/assets/asset-hub-westend" } +collectives-westend-runtime = { path = "../../../../../runtimes/collectives/collectives-westend" } +cumulus-pallet-xcmp-queue = { default-features = false, path = "../../../../../../pallets/xcmp-queue" } +cumulus-pallet-parachain-system = { default-features = false, path = "../../../../../../pallets/parachain-system" } +emulated-integration-tests-common = { path = "../../../common", default-features = false } +westend-system-emulated-network = { path = "../../../networks/westend-system" } diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..97239330216ac8f66a7684811d1de30b13f56f7e --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/lib.rs @@ -0,0 +1,30 @@ +// 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 use xcm::{prelude::*, v3}; + +pub use emulated_integration_tests_common::xcm_emulator::{ + assert_expected_events, bx, Chain, RelayChain as Relay, TestExt, +}; +pub use westend_system_emulated_network::{ + asset_hub_westend_emulated_chain::AssetHubWestendParaPallet as AssetHubWestendPallet, + collectives_westend_emulated_chain::CollectivesWestendParaPallet as CollectivesWestendPallet, + westend_emulated_chain::WestendRelayPallet as WestendPallet, + AssetHubWestendPara as AssetHubWestend, CollectivesWestendPara as CollectivesWestend, + WestendRelay as Westend, +}; + +#[cfg(test)] +mod tests; diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs new file mode 100644 index 0000000000000000000000000000000000000000..bde1220e2495bc544e507be1a8b40d77fcbde894 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/fellowship_treasury.rs @@ -0,0 +1,236 @@ +// 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::*; +use asset_hub_westend_runtime::xcm_config::LocationToAccountId as AssetHubLocationToAccountId; +use emulated_integration_tests_common::accounts::ALICE; +use frame_support::{ + assert_ok, dispatch::RawOrigin, instances::Instance1, sp_runtime::traits::Dispatchable, + traits::fungible::Inspect, +}; +use polkadot_runtime_common::impls::VersionedLocatableAsset; +use westend_runtime::OriginCaller; +use westend_runtime_constants::currency::UNITS; +use xcm_executor::traits::ConvertLocation; + +// Fund Fellowship Treasury from Westend Treasury and spend from Fellowship Treasury. +#[test] +fn fellowship_treasury_spend() { + // initial treasury balance on Asset Hub in WNDs. + let treasury_balance = 20_000_000 * UNITS; + // target fellowship balance on Asset Hub in WNDs. + let fellowship_treasury_balance = 1_000_000 * UNITS; + // fellowship first spend balance in WNDs. + let fellowship_spend_balance = 10_000 * UNITS; + + let init_alice_balance = AssetHubWestend::execute_with(|| { + <<AssetHubWestend as AssetHubWestendPallet>::Balances as Inspect<_>>::balance( + &AssetHubWestend::account_id_of(ALICE), + ) + }); + + Westend::execute_with(|| { + type RuntimeEvent = <Westend as Chain>::RuntimeEvent; + type RuntimeCall = <Westend as Chain>::RuntimeCall; + type Runtime = <Westend as Chain>::Runtime; + type Balances = <Westend as WestendPallet>::Balances; + type Treasury = <Westend as WestendPallet>::Treasury; + + // Fund Treasury account on Asset Hub with WNDs. + + let root = <Westend as Chain>::RuntimeOrigin::root(); + let treasury_account = Treasury::account_id(); + + // Mist assets to Treasury account on Relay Chain. + assert_ok!(Balances::force_set_balance( + root.clone(), + treasury_account.clone().into(), + treasury_balance * 2, + )); + + let native_asset = Location::here(); + let asset_hub_location: Location = [Parachain(1000)].into(); + let treasury_location: Location = (Parent, PalletInstance(37)).into(); + + let teleport_call = RuntimeCall::Utility(pallet_utility::Call::<Runtime>::dispatch_as { + as_origin: bx!(OriginCaller::system(RawOrigin::Signed(treasury_account))), + call: bx!(RuntimeCall::XcmPallet(pallet_xcm::Call::<Runtime>::teleport_assets { + dest: bx!(VersionedLocation::V4(asset_hub_location.clone())), + beneficiary: bx!(VersionedLocation::V4(treasury_location)), + assets: bx!(VersionedAssets::V4( + Asset { id: native_asset.clone().into(), fun: treasury_balance.into() }.into() + )), + fee_asset_item: 0, + })), + }); + + // Dispatched from Root to `dispatch_as` `Signed(treasury_account)`. + assert_ok!(teleport_call.dispatch(root)); + + assert_expected_events!( + Westend, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + Westend::execute_with(|| { + type RuntimeEvent = <Westend as Chain>::RuntimeEvent; + type RuntimeCall = <Westend as Chain>::RuntimeCall; + type RuntimeOrigin = <Westend as Chain>::RuntimeOrigin; + type Runtime = <Westend as Chain>::Runtime; + type Treasury = <Westend as WestendPallet>::Treasury; + + // Fund Fellowship Treasury from Westend Treasury. + + let treasury_origin: RuntimeOrigin = + westend_runtime::governance::pallet_custom_origins::Origin::Treasurer.into(); + let fellowship_treasury_location: Location = + Location::new(1, [Parachain(1001), PalletInstance(65)]); + let asset_hub_location: Location = [Parachain(1000)].into(); + let native_asset = Location::parent(); + + let treasury_spend_call = RuntimeCall::Treasury(pallet_treasury::Call::<Runtime>::spend { + asset_kind: bx!(VersionedLocatableAsset::V4 { + location: asset_hub_location.clone(), + asset_id: native_asset.into(), + }), + amount: fellowship_treasury_balance, + beneficiary: bx!(VersionedLocation::V4(fellowship_treasury_location)), + valid_from: None, + }); + + assert_ok!(treasury_spend_call.dispatch(treasury_origin)); + + // Claim the spend. + + let alice_signed = RuntimeOrigin::signed(Westend::account_id_of(ALICE)); + assert_ok!(Treasury::payout(alice_signed.clone(), 0)); + + assert_expected_events!( + Westend, + vec![ + RuntimeEvent::Treasury(pallet_treasury::Event::AssetSpendApproved { .. }) => {}, + RuntimeEvent::Treasury(pallet_treasury::Event::Paid { .. }) => {}, + ] + ); + }); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent; + type Balances = <AssetHubWestend as AssetHubWestendPallet>::Balances; + + // Ensure that the funds deposited to the Fellowship Treasury account. + + let fellowship_treasury_location: Location = + Location::new(1, [Parachain(1001), PalletInstance(65)]); + let fellowship_treasury_account = + AssetHubLocationToAccountId::convert_location(&fellowship_treasury_location).unwrap(); + + assert_eq!( + <Balances as Inspect<_>>::balance(&fellowship_treasury_account), + fellowship_treasury_balance + ); + + // Assert events triggered by xcm pay program: + // 1. treasury asset transferred to spend beneficiary; + // 2. response to Relay Chain Treasury pallet instance sent back; + // 3. XCM program completed; + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::Balances(pallet_balances::Event::Transfer { .. }) => {}, + RuntimeEvent::ParachainSystem(cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {}, + ] + ); + }); + + CollectivesWestend::execute_with(|| { + type RuntimeEvent = <CollectivesWestend as Chain>::RuntimeEvent; + type RuntimeCall = <CollectivesWestend as Chain>::RuntimeCall; + type RuntimeOrigin = <CollectivesWestend as Chain>::RuntimeOrigin; + type Runtime = <CollectivesWestend as Chain>::Runtime; + type FellowshipTreasury = + <CollectivesWestend as CollectivesWestendPallet>::FellowshipTreasury; + + // Fund Alice account from Fellowship Treasury. + + let fellows_origin: RuntimeOrigin = + collectives_westend_runtime::fellowship::pallet_fellowship_origins::Origin::Fellows + .into(); + let asset_hub_location: Location = (Parent, Parachain(1000)).into(); + let native_asset = Location::parent(); + + let alice_location: Location = [Junction::AccountId32 { + network: None, + id: CollectivesWestend::account_id_of(ALICE).into(), + }] + .into(); + + let fellowship_treasury_spend_call = + RuntimeCall::FellowshipTreasury(pallet_treasury::Call::<Runtime, Instance1>::spend { + asset_kind: bx!(VersionedLocatableAsset::V4 { + location: asset_hub_location, + asset_id: native_asset.into(), + }), + amount: fellowship_spend_balance, + beneficiary: bx!(VersionedLocation::V4(alice_location)), + valid_from: None, + }); + + assert_ok!(fellowship_treasury_spend_call.dispatch(fellows_origin)); + + // Claim the spend. + + let alice_signed = RuntimeOrigin::signed(CollectivesWestend::account_id_of(ALICE)); + assert_ok!(FellowshipTreasury::payout(alice_signed.clone(), 0)); + + assert_expected_events!( + CollectivesWestend, + vec![ + RuntimeEvent::FellowshipTreasury(pallet_treasury::Event::AssetSpendApproved { .. }) => {}, + RuntimeEvent::FellowshipTreasury(pallet_treasury::Event::Paid { .. }) => {}, + ] + ); + }); + + AssetHubWestend::execute_with(|| { + type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent; + type Balances = <AssetHubWestend as AssetHubWestendPallet>::Balances; + + // Ensure that the funds deposited to Alice account. + + let alice_account = AssetHubWestend::account_id_of(ALICE); + assert_eq!( + <Balances as Inspect<_>>::balance(&alice_account), + fellowship_spend_balance + init_alice_balance + ); + + // Assert events triggered by xcm pay program: + // 1. treasury asset transferred to spend beneficiary; + // 2. response to Relay Chain Treasury pallet instance sent back; + // 3. XCM program completed; + assert_expected_events!( + AssetHubWestend, + vec![ + RuntimeEvent::Balances(pallet_balances::Event::Transfer { .. }) => {}, + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true ,.. }) => {}, + ] + ); + }); +} diff --git a/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a9f65df34b647835b4ce5585be6b53b0489de578 --- /dev/null +++ b/cumulus/parachains/integration-tests/emulated/tests/collectives/collectives-westend/src/tests/mod.rs @@ -0,0 +1,16 @@ +// 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. + +mod fellowship_treasury; 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 3816d2ed848ed51740283ffea31e9f7e53c01f1a..94765287637b57d47c588d9a4359666d1b54f509 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/fellowship/mod.rs @@ -21,13 +21,16 @@ mod tracks; use crate::{ weights, xcm_config::{FellowshipAdminBodyId, LocationToAccountId, TreasurerBodyId, UsdtAssetHub}, - AccountId, AssetRate, Balance, Balances, FellowshipReferenda, GovernanceLocation, Preimage, - Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, WestendTreasuryAccount, DAYS, + AccountId, AssetRate, Balance, Balances, FellowshipReferenda, GovernanceLocation, + ParachainInfo, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, + WestendTreasuryAccount, DAYS, }; +use cumulus_primitives_core::ParaId; use frame_support::{ parameter_types, traits::{ - EitherOf, EitherOfDiverse, MapSuccess, NeverEnsureOrigin, OriginTrait, TryWithMorphedArg, + tokens::UnityOrOuterConversion, EitherOf, EitherOfDiverse, FromContains, MapSuccess, + NeverEnsureOrigin, OriginTrait, TryWithMorphedArg, }, PalletId, }; @@ -40,10 +43,10 @@ use pallet_ranked_collective::EnsureOfRank; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use parachains_common::impls::ToParentTreasury; use polkadot_runtime_common::impls::{ - LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, + ContainsParts, LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; use sp_arithmetic::Permill; -use sp_core::{ConstU128, ConstU32}; +use sp_core::{ConstU128, ConstU32, ConstU8}; use sp_runtime::traits::{ConstU16, ConvertToValue, IdentityLookup, Replace, TakeFirst}; use testnet_parachains_constants::westend::{account, currency::GRAND}; use westend_runtime_constants::time::HOURS; @@ -263,6 +266,7 @@ parameter_types! { // The asset's interior location for the paying account. This is the Fellowship Treasury // pallet instance (which sits at index 65). pub FellowshipTreasuryInteriorLocation: InteriorLocation = PalletInstance(65).into(); + pub SelfParaId: ParaId = ParachainInfo::parachain_id(); } #[cfg(feature = "runtime-benchmarks")] @@ -345,7 +349,15 @@ impl pallet_treasury::Config<FellowshipTreasuryInstance> for Runtime { type Paymaster = FellowshipTreasuryPaymaster; #[cfg(feature = "runtime-benchmarks")] type Paymaster = PayWithEnsure<FellowshipTreasuryPaymaster, OpenHrmpChannel<ConstU32<1000>>>; - type BalanceConverter = AssetRate; + type BalanceConverter = UnityOrOuterConversion< + ContainsParts< + FromContains< + xcm_builder::IsSiblingSystemParachain<ParaId, SelfParaId>, + xcm_builder::IsParentsOnly<ConstU8<1>>, + >, + >, + AssetRate, + >; type PayoutPeriod = ConstU32<{ 30 * DAYS }>; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments< diff --git a/docs/contributor/prdoc.md b/docs/contributor/prdoc.md index af0ede5107a6cb1ea31d8b81fe16b06553ef64ac..0c8165af40f4d4f0438ab780c5f87eb5fe2ad62e 100644 --- a/docs/contributor/prdoc.md +++ b/docs/contributor/prdoc.md @@ -1,55 +1,31 @@ # PRDoc -## Intro - -With the merge of [PR #1946](https://github.com/paritytech/polkadot-sdk/pull/1946), a new method for -documenting changes has been introduced: `prdoc`. The [prdoc repository](https://github.com/paritytech/prdoc) -contains more documentation and tooling. - -The current document describes how to quickly get started authoring `PRDoc` files. +A [prdoc](https://github.com/paritytech/prdoc) is like a changelog but for a Pull Request. We use this approach to +record changes on a crate level. This information is then processed by the release team to apply the correct crate +version bumps and to generate the CHANGELOG of the next release. ## Requirements -When creating a PR, the author needs to decides with the `R0` label whether the change (PR) should -appear in the release notes or not. - -Labelling a PR with `R0` means that no `PRDoc` is required. - -A PR without the `R0` label **does** require a valid `PRDoc` file to be introduced in the PR. - -## PRDoc how-to - -A `.prdoc` file is a YAML file with a defined structure (ie JSON Schema). - -For significant changes, a `.prdoc` file is mandatory and the file must meet the following -requirements: -- file named `pr_NNNN.prdoc` where `NNNN` is the PR number. - For convenience, those file can also contain a short description: `pr_NNNN_foobar.prdoc`. -- located under the [`prdoc` folder](https://github.com/paritytech/polkadot-sdk/tree/master/prdoc) of the repository -- compliant with the [JSON schema](https://json-schema.org/) defined in `prdoc/schema_user.json` - -Those requirements can be fulfilled manually without any tooling but a text editor. - -## Tooling - -Users might find the following helpers convenient: -- Setup VSCode to be aware of the prdoc schema: see [using VSCode](https://github.com/paritytech/prdoc#using-vscode) -- Using the `prdoc` cli to: - - generate a `PRDoc` file from a [template defined in the Polkadot SDK - repo](https://github.com/paritytech/polkadot-sdk/blob/master/prdoc/.template.prdoc) simply providing a PR number - - check the validity of one or more `PRDoc` files +When creating a PR, the author needs to decide with the `R0-silent` label whether the PR has to contain a prdoc. The +`R0` label should only be placed for No-OP changes like correcting a typo in a comment or CI stuff. If unsure, ping +the [CODEOWNERS](../../.github/CODEOWNERS) for advice. -## `prdoc` cli usage +## PRDoc How-To -The `prdoc` cli documentation can be found at https://github.com/paritytech/prdoc#prdoc +A `.prdoc` file is a YAML file with a defined structure (ie JSON Schema). Please follow these steps to generate one: -tldr: -- `prdoc generate <NNNN>` -- `prdoc check -n <NNNN>` +1. Install the [`prdoc` CLI](https://github.com/paritytech/prdoc) by running `cargo install prdoc`. +1. Open a Pull Request and get the PR number. +1. Generate the file with `prdoc generate <PR_NUMBER>`. The output filename will be printed. +1. Optional: Install the `prdoc/schema_user.json` schema in your editor, for example +[VsCode](https://github.com/paritytech/prdoc?tab=readme-ov-file#schemas). +1. Edit your `.prdoc` file according to the [Audience](#pick-an-audience) and [SemVer](#record-semver-changes) sections. +1. Check your prdoc with `prdoc check -n <PR_NUMBER>`. This is optional since the CI will also check it. -where <NNNN> is the PR number. +> **Tip:** GitHub CLI and jq can be used to provide the number of your PR to generate the correct file: +> `prdoc generate $(gh pr view --json number | jq '.number') -o prdoc` -## Pick an audience +## Pick An Audience While describing a PR, the author needs to consider which audience(s) need to be addressed. The list of valid audiences is described and documented in the JSON schema as follow: @@ -65,7 +41,41 @@ The list of valid audiences is described and documented in the JSON schema as fo - `Runtime User`: Anyone using the runtime. This can be a token holder or a dev writing a front end for a chain. -## Tips +If you have a change that affects multiple audiences, you can either list them all, or write multiple sections and +re-phrase the changes for each audience. + +## Record SemVer Changes + +All published crates that got modified need to have an entry in the `crates` section of your `PRDoc`. This entry tells +the release team how to bump the crate version prior to the next release. It is very important that this information is +correct, otherwise it could break the code of downstream teams. + +The bump can either be `major`, `minor`, `patch` or `none`. The three first options are defined by +[rust-lang.org](https://doc.rust-lang.org/cargo/reference/semver.html), whereas `None` should be picked if no other +applies. The `None` option is equivalent to the `R0-silent` label, but on a crate level. Experimental and private APIs +are exempt from bumping and can be broken at any time. Please read the [Crate Section](../RELEASE.md) of the RELEASE doc +about them. + +> **Note**: There is currently no CI in place to sanity check this information, but should be added soon. + +### Example + +For example when you modified two crates and record the changes: + +```yaml +crates: +- name: frame-example + bump: major +- name: frame-example-pallet + bump: minor +``` + +It means that downstream code using `frame-example-pallet` is still guaranteed to work as before, while code using +`frame-example` might break. + +### Dependencies -The PRDoc schema is defined in each repo and usually is quite restrictive. -You cannot simply add a new property to a `PRDoc` file unless the Schema allows it. +A crate that depends on another crate will automatically inherit its `major` bumps. This means that you do not need to +bump a crate that had a SemVer breaking change only from re-exporting another crate with a breaking change. +`minor` an `patch` bumps do not need to be inherited, since `cargo` will automatically update them to the latest +compatible version. diff --git a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs b/polkadot/node/core/prospective-parachains/src/fragment_tree/mod.rs similarity index 50% rename from polkadot/node/core/prospective-parachains/src/fragment_tree.rs rename to polkadot/node/core/prospective-parachains/src/fragment_tree/mod.rs index 8061dc82d8358ae9e7c741e3f785634601eb5d03..86814b976d13424281203aa5bca59b0a918b7251 100644 --- a/polkadot/node/core/prospective-parachains/src/fragment_tree.rs +++ b/polkadot/node/core/prospective-parachains/src/fragment_tree/mod.rs @@ -86,6 +86,9 @@ //! will still perform fairly well under these conditions, despite being somewhat wasteful of //! memory. +#[cfg(test)] +mod tests; + use std::{ borrow::Cow, collections::{ @@ -1145,1447 +1148,3 @@ impl FragmentNode { self.children.iter().find(|(_, c)| c == candidate_hash).map(|(p, _)| *p) } } - -#[cfg(test)] -mod tests { - use super::*; - use assert_matches::assert_matches; - use polkadot_node_subsystem_util::inclusion_emulator::InboundHrmpLimitations; - use polkadot_primitives::{BlockNumber, CandidateCommitments, CandidateDescriptor, HeadData}; - use polkadot_primitives_test_helpers as test_helpers; - use rstest::rstest; - use std::iter; - - impl NodePointer { - fn unwrap_idx(self) -> usize { - match self { - NodePointer::Root => panic!("Unexpected root"), - NodePointer::Storage(index) => index, - } - } - } - - fn make_constraints( - min_relay_parent_number: BlockNumber, - valid_watermarks: Vec<BlockNumber>, - required_parent: HeadData, - ) -> Constraints { - Constraints { - min_relay_parent_number, - max_pov_size: 1_000_000, - max_code_size: 1_000_000, - ump_remaining: 10, - ump_remaining_bytes: 1_000, - max_ump_num_per_candidate: 10, - dmp_remaining_messages: [0; 10].into(), - hrmp_inbound: InboundHrmpLimitations { valid_watermarks }, - hrmp_channels_out: HashMap::new(), - max_hrmp_num_per_candidate: 0, - required_parent, - validation_code_hash: Hash::repeat_byte(42).into(), - upgrade_restriction: None, - future_validation_code: None, - } - } - - fn make_committed_candidate( - para_id: ParaId, - relay_parent: Hash, - relay_parent_number: BlockNumber, - parent_head: HeadData, - para_head: HeadData, - hrmp_watermark: BlockNumber, - ) -> (PersistedValidationData, CommittedCandidateReceipt) { - let persisted_validation_data = PersistedValidationData { - parent_head, - relay_parent_number, - relay_parent_storage_root: Hash::repeat_byte(69), - max_pov_size: 1_000_000, - }; - - let candidate = CommittedCandidateReceipt { - descriptor: CandidateDescriptor { - para_id, - relay_parent, - collator: test_helpers::dummy_collator(), - persisted_validation_data_hash: persisted_validation_data.hash(), - pov_hash: Hash::repeat_byte(1), - erasure_root: Hash::repeat_byte(1), - signature: test_helpers::dummy_collator_signature(), - para_head: para_head.hash(), - validation_code_hash: Hash::repeat_byte(42).into(), - }, - commitments: CandidateCommitments { - upward_messages: Default::default(), - horizontal_messages: Default::default(), - new_validation_code: None, - head_data: para_head, - processed_downward_messages: 1, - hrmp_watermark, - }, - }; - - (persisted_validation_data, candidate) - } - - #[test] - fn scope_rejects_ancestors_that_skip_blocks() { - let para_id = ParaId::from(5u32); - let relay_parent = RelayChainBlockInfo { - number: 10, - hash: Hash::repeat_byte(10), - storage_root: Hash::repeat_byte(69), - }; - - let ancestors = vec![RelayChainBlockInfo { - number: 8, - hash: Hash::repeat_byte(8), - storage_root: Hash::repeat_byte(69), - }]; - - let max_depth = 2; - let base_constraints = make_constraints(8, vec![8, 9], vec![1, 2, 3].into()); - let pending_availability = Vec::new(); - - assert_matches!( - Scope::with_ancestors( - para_id, - relay_parent, - base_constraints, - pending_availability, - max_depth, - ancestors - ), - Err(UnexpectedAncestor { number: 8, prev: 10 }) - ); - } - - #[test] - fn scope_rejects_ancestor_for_0_block() { - let para_id = ParaId::from(5u32); - let relay_parent = RelayChainBlockInfo { - number: 0, - hash: Hash::repeat_byte(0), - storage_root: Hash::repeat_byte(69), - }; - - let ancestors = vec![RelayChainBlockInfo { - number: 99999, - hash: Hash::repeat_byte(99), - storage_root: Hash::repeat_byte(69), - }]; - - let max_depth = 2; - let base_constraints = make_constraints(0, vec![], vec![1, 2, 3].into()); - let pending_availability = Vec::new(); - - assert_matches!( - Scope::with_ancestors( - para_id, - relay_parent, - base_constraints, - pending_availability, - max_depth, - ancestors, - ), - Err(UnexpectedAncestor { number: 99999, prev: 0 }) - ); - } - - #[test] - fn scope_only_takes_ancestors_up_to_min() { - let para_id = ParaId::from(5u32); - let relay_parent = RelayChainBlockInfo { - number: 5, - hash: Hash::repeat_byte(0), - storage_root: Hash::repeat_byte(69), - }; - - let ancestors = vec![ - RelayChainBlockInfo { - number: 4, - hash: Hash::repeat_byte(4), - storage_root: Hash::repeat_byte(69), - }, - RelayChainBlockInfo { - number: 3, - hash: Hash::repeat_byte(3), - storage_root: Hash::repeat_byte(69), - }, - RelayChainBlockInfo { - number: 2, - hash: Hash::repeat_byte(2), - storage_root: Hash::repeat_byte(69), - }, - ]; - - let max_depth = 2; - let base_constraints = make_constraints(3, vec![2], vec![1, 2, 3].into()); - let pending_availability = Vec::new(); - - let scope = Scope::with_ancestors( - para_id, - relay_parent, - base_constraints, - pending_availability, - max_depth, - ancestors, - ) - .unwrap(); - - assert_eq!(scope.ancestors.len(), 2); - assert_eq!(scope.ancestors_by_hash.len(), 2); - } - - #[test] - fn storage_add_candidate() { - let mut storage = CandidateStorage::new(); - let relay_parent = Hash::repeat_byte(69); - - let (pvd, candidate) = make_committed_candidate( - ParaId::from(5u32), - relay_parent, - 8, - vec![4, 5, 6].into(), - vec![1, 2, 3].into(), - 7, - ); - - let candidate_hash = candidate.hash(); - let parent_head_hash = pvd.parent_head.hash(); - - storage.add_candidate(candidate, pvd).unwrap(); - assert!(storage.contains(&candidate_hash)); - assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 1); - - assert_eq!(storage.relay_parent_by_candidate_hash(&candidate_hash), Some(relay_parent)); - } - - #[test] - fn storage_retain() { - let mut storage = CandidateStorage::new(); - - let (pvd, candidate) = make_committed_candidate( - ParaId::from(5u32), - Hash::repeat_byte(69), - 8, - vec![4, 5, 6].into(), - vec![1, 2, 3].into(), - 7, - ); - - let candidate_hash = candidate.hash(); - let output_head_hash = candidate.commitments.head_data.hash(); - let parent_head_hash = pvd.parent_head.hash(); - - storage.add_candidate(candidate, pvd).unwrap(); - storage.retain(|_| true); - assert!(storage.contains(&candidate_hash)); - assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 1); - assert!(storage.head_data_by_hash(&output_head_hash).is_some()); - - storage.retain(|_| false); - assert!(!storage.contains(&candidate_hash)); - assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 0); - assert!(storage.head_data_by_hash(&output_head_hash).is_none()); - } - - // [`FragmentTree::populate`] should pick up candidates that build on other candidates. - #[test] - fn populate_works_recursively() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - let relay_parent_b = Hash::repeat_byte(2); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 0, - ); - let candidate_a_hash = candidate_a.hash(); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_b, - 1, - vec![0x0b].into(), - vec![0x0c].into(), - 1, - ); - let candidate_b_hash = candidate_b.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let ancestors = vec![RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }]; - - let relay_parent_b_info = RelayChainBlockInfo { - number: pvd_b.relay_parent_number, - hash: relay_parent_b, - storage_root: pvd_b.relay_parent_storage_root, - }; - - storage.add_candidate(candidate_a, pvd_a).unwrap(); - storage.add_candidate(candidate_b, pvd_b).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_b_info, - base_constraints, - pending_availability, - 4, - ancestors, - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 2); - assert!(candidates.contains(&candidate_a_hash)); - assert!(candidates.contains(&candidate_b_hash)); - - assert_eq!(tree.nodes.len(), 2); - assert_eq!(tree.nodes[0].parent, NodePointer::Root); - assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[0].depth, 0); - - assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); - assert_eq!(tree.nodes[1].candidate_hash, candidate_b_hash); - assert_eq!(tree.nodes[1].depth, 1); - } - - #[test] - fn children_of_root_are_contiguous() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - let relay_parent_b = Hash::repeat_byte(2); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 0, - ); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_b, - 1, - vec![0x0b].into(), - vec![0x0c].into(), - 1, - ); - - let (pvd_a2, candidate_a2) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b, 1].into(), - 0, - ); - let candidate_a2_hash = candidate_a2.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let ancestors = vec![RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }]; - - let relay_parent_b_info = RelayChainBlockInfo { - number: pvd_b.relay_parent_number, - hash: relay_parent_b, - storage_root: pvd_b.relay_parent_storage_root, - }; - - storage.add_candidate(candidate_a, pvd_a).unwrap(); - storage.add_candidate(candidate_b, pvd_b).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_b_info, - base_constraints, - pending_availability, - 4, - ancestors, - ) - .unwrap(); - let mut tree = FragmentTree::populate(scope, &storage); - - storage.add_candidate(candidate_a2, pvd_a2).unwrap(); - tree.add_and_populate(candidate_a2_hash, &storage); - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 3); - - assert_eq!(tree.nodes[0].parent, NodePointer::Root); - assert_eq!(tree.nodes[1].parent, NodePointer::Root); - assert_eq!(tree.nodes[2].parent, NodePointer::Storage(0)); - } - - #[test] - fn add_candidate_child_of_root() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 0, - ); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0c].into(), - 0, - ); - let candidate_b_hash = candidate_b.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - storage.add_candidate(candidate_a, pvd_a).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - 4, - vec![], - ) - .unwrap(); - let mut tree = FragmentTree::populate(scope, &storage); - - storage.add_candidate(candidate_b, pvd_b).unwrap(); - tree.add_and_populate(candidate_b_hash, &storage); - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 2); - - assert_eq!(tree.nodes[0].parent, NodePointer::Root); - assert_eq!(tree.nodes[1].parent, NodePointer::Root); - } - - #[test] - fn add_candidate_child_of_non_root() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 0, - ); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0b].into(), - vec![0x0c].into(), - 0, - ); - let candidate_b_hash = candidate_b.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - storage.add_candidate(candidate_a, pvd_a).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - 4, - vec![], - ) - .unwrap(); - let mut tree = FragmentTree::populate(scope, &storage); - - storage.add_candidate(candidate_b, pvd_b).unwrap(); - tree.add_and_populate(candidate_b_hash, &storage); - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 2); - - assert_eq!(tree.nodes[0].parent, NodePointer::Root); - assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); - } - - #[test] - fn test_find_ancestor_path_and_find_backable_chain_empty_tree() { - let para_id = ParaId::from(5u32); - let relay_parent = Hash::repeat_byte(1); - let required_parent: HeadData = vec![0xff].into(); - let max_depth = 10; - - // Empty tree - let storage = CandidateStorage::new(); - let base_constraints = make_constraints(0, vec![0], required_parent.clone()); - - let relay_parent_info = - RelayChainBlockInfo { number: 0, hash: relay_parent, storage_root: Hash::zero() }; - - let scope = Scope::with_ancestors( - para_id, - relay_parent_info, - base_constraints, - vec![], - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - assert_eq!(tree.candidates().collect::<Vec<_>>().len(), 0); - assert_eq!(tree.nodes.len(), 0); - - assert_eq!(tree.find_ancestor_path(Ancestors::new()).unwrap(), NodePointer::Root); - assert_eq!(tree.find_backable_chain(Ancestors::new(), 2, |_| true), vec![]); - // Invalid candidate. - let ancestors: Ancestors = [CandidateHash::default()].into_iter().collect(); - assert_eq!(tree.find_ancestor_path(ancestors.clone()), Some(NodePointer::Root)); - assert_eq!(tree.find_backable_chain(ancestors, 2, |_| true), vec![]); - } - - #[rstest] - #[case(true, 13)] - #[case(false, 8)] - // The tree with no cycles looks like: - // Make a tree that looks like this (note that there's no cycle): - // +-(root)-+ - // | | - // +----0---+ 7 - // | | - // 1----+ 5 - // | | - // | | - // 2 6 - // | - // 3 - // | - // 4 - // - // The tree with cycles is the same as the first but has a cycle from 4 back to the state - // produced by 0 (It's bounded by the max_depth + 1). - // +-(root)-+ - // | | - // +----0---+ 7 - // | | - // 1----+ 5 - // | | - // | | - // 2 6 - // | - // 3 - // | - // 4---+ - // | | - // 1 5 - // | - // 2 - // | - // 3 - fn test_find_ancestor_path_and_find_backable_chain( - #[case] has_cycle: bool, - #[case] expected_node_count: usize, - ) { - let para_id = ParaId::from(5u32); - let relay_parent = Hash::repeat_byte(1); - let required_parent: HeadData = vec![0xff].into(); - let max_depth = 7; - let relay_parent_number = 0; - let relay_parent_storage_root = Hash::repeat_byte(69); - - let mut candidates = vec![]; - - // Candidate 0 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - required_parent.clone(), - vec![0].into(), - 0, - )); - // Candidate 1 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - vec![0].into(), - vec![1].into(), - 0, - )); - // Candidate 2 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - vec![1].into(), - vec![2].into(), - 0, - )); - // Candidate 3 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - vec![2].into(), - vec![3].into(), - 0, - )); - // Candidate 4 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - vec![3].into(), - vec![4].into(), - 0, - )); - // Candidate 5 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - vec![0].into(), - vec![5].into(), - 0, - )); - // Candidate 6 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - vec![1].into(), - vec![6].into(), - 0, - )); - // Candidate 7 - candidates.push(make_committed_candidate( - para_id, - relay_parent, - 0, - required_parent.clone(), - vec![7].into(), - 0, - )); - - if has_cycle { - candidates[4] = make_committed_candidate( - para_id, - relay_parent, - 0, - vec![3].into(), - vec![0].into(), // put the cycle here back to the output state of 0. - 0, - ); - } - - let base_constraints = make_constraints(0, vec![0], required_parent.clone()); - let mut storage = CandidateStorage::new(); - - let relay_parent_info = RelayChainBlockInfo { - number: relay_parent_number, - hash: relay_parent, - storage_root: relay_parent_storage_root, - }; - - for (pvd, candidate) in candidates.iter() { - storage.add_candidate(candidate.clone(), pvd.clone()).unwrap(); - } - let candidates = - candidates.into_iter().map(|(_pvd, candidate)| candidate).collect::<Vec<_>>(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_info, - base_constraints, - vec![], - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - assert_eq!(tree.candidates().collect::<Vec<_>>().len(), candidates.len()); - assert_eq!(tree.nodes.len(), expected_node_count); - - // Do some common tests on both trees. - { - // No ancestors supplied. - assert_eq!(tree.find_ancestor_path(Ancestors::new()).unwrap(), NodePointer::Root); - assert_eq!( - tree.find_backable_chain(Ancestors::new(), 4, |_| true), - [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - // Ancestor which is not part of the tree. Will be ignored. - let ancestors: Ancestors = [CandidateHash::default()].into_iter().collect(); - assert_eq!(tree.find_ancestor_path(ancestors.clone()).unwrap(), NodePointer::Root); - assert_eq!( - tree.find_backable_chain(ancestors, 4, |_| true), - [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - // A chain fork. - let ancestors: Ancestors = - [(candidates[0].hash()), (candidates[7].hash())].into_iter().collect(); - assert_eq!(tree.find_ancestor_path(ancestors.clone()), None); - assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); - - // Ancestors which are part of the tree but don't form a path. Will be ignored. - let ancestors: Ancestors = - [candidates[1].hash(), candidates[2].hash()].into_iter().collect(); - assert_eq!(tree.find_ancestor_path(ancestors.clone()).unwrap(), NodePointer::Root); - assert_eq!( - tree.find_backable_chain(ancestors, 4, |_| true), - [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - - // Valid ancestors. - let ancestors: Ancestors = [candidates[7].hash()].into_iter().collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[7].hash()); - assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); - - let ancestors: Ancestors = - [candidates[2].hash(), candidates[0].hash(), candidates[1].hash()] - .into_iter() - .collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[2].hash()); - assert_eq!( - tree.find_backable_chain(ancestors.clone(), 2, |_| true), - [3, 4].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - - // Valid ancestors with candidates which have been omitted due to timeouts - let ancestors: Ancestors = - [candidates[0].hash(), candidates[2].hash()].into_iter().collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[0].hash()); - assert_eq!( - tree.find_backable_chain(ancestors, 3, |_| true), - [1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - - let ancestors: Ancestors = - [candidates[0].hash(), candidates[1].hash(), candidates[3].hash()] - .into_iter() - .collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[1].hash()); - if has_cycle { - assert_eq!( - tree.find_backable_chain(ancestors, 2, |_| true), - [2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - } else { - assert_eq!( - tree.find_backable_chain(ancestors, 4, |_| true), - [2, 3, 4].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - } - - let ancestors: Ancestors = - [candidates[1].hash(), candidates[2].hash()].into_iter().collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - assert_eq!(res, NodePointer::Root); - assert_eq!( - tree.find_backable_chain(ancestors, 4, |_| true), - [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - - // Requested count is 0. - assert_eq!(tree.find_backable_chain(Ancestors::new(), 0, |_| true), vec![]); - - let ancestors: Ancestors = - [candidates[2].hash(), candidates[0].hash(), candidates[1].hash()] - .into_iter() - .collect(); - assert_eq!(tree.find_backable_chain(ancestors, 0, |_| true), vec![]); - - let ancestors: Ancestors = - [candidates[2].hash(), candidates[0].hash()].into_iter().collect(); - assert_eq!(tree.find_backable_chain(ancestors, 0, |_| true), vec![]); - } - - // Now do some tests only on the tree with cycles - if has_cycle { - // Exceeds the maximum tree depth. 0-1-2-3-4-1-2-3-4, when the tree stops at - // 0-1-2-3-4-1-2-3. - let ancestors: Ancestors = [ - candidates[0].hash(), - candidates[1].hash(), - candidates[2].hash(), - candidates[3].hash(), - candidates[4].hash(), - ] - .into_iter() - .collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[4].hash()); - assert_eq!( - tree.find_backable_chain(ancestors, 4, |_| true), - [1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - - // 0-1-2. - let ancestors: Ancestors = - [candidates[0].hash(), candidates[1].hash(), candidates[2].hash()] - .into_iter() - .collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[2].hash()); - assert_eq!( - tree.find_backable_chain(ancestors.clone(), 1, |_| true), - [3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - assert_eq!( - tree.find_backable_chain(ancestors, 5, |_| true), - [3, 4, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() - ); - - // 0-1 - let ancestors: Ancestors = - [candidates[0].hash(), candidates[1].hash()].into_iter().collect(); - let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); - let candidate = &tree.nodes[res.unwrap_idx()]; - assert_eq!(candidate.candidate_hash, candidates[1].hash()); - assert_eq!( - tree.find_backable_chain(ancestors, 6, |_| true), - [2, 3, 4, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>(), - ); - - // For 0-1-2-3-4-5, there's more than 1 way of finding this path in - // the tree. `None` should be returned. The runtime should not have accepted this. - let ancestors: Ancestors = [ - candidates[0].hash(), - candidates[1].hash(), - candidates[2].hash(), - candidates[3].hash(), - candidates[4].hash(), - candidates[5].hash(), - ] - .into_iter() - .collect(); - let res = tree.find_ancestor_path(ancestors.clone()); - assert_eq!(res, None); - assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); - } - } - - #[test] - fn graceful_cycle_of_0() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0a].into(), // input same as output - 0, - ); - let candidate_a_hash = candidate_a.hash(); - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - let max_depth = 4; - storage.add_candidate(candidate_a, pvd_a).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 1); - assert_eq!(tree.nodes.len(), max_depth + 1); - - assert_eq!(tree.nodes[0].parent, NodePointer::Root); - assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); - assert_eq!(tree.nodes[2].parent, NodePointer::Storage(1)); - assert_eq!(tree.nodes[3].parent, NodePointer::Storage(2)); - assert_eq!(tree.nodes[4].parent, NodePointer::Storage(3)); - - assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[1].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[2].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[3].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); - - for count in 1..10 { - assert_eq!( - tree.find_backable_chain(Ancestors::new(), count, |_| true), - iter::repeat(candidate_a_hash) - .take(std::cmp::min(count as usize, max_depth + 1)) - .collect::<Vec<_>>() - ); - assert_eq!( - tree.find_backable_chain( - [candidate_a_hash].into_iter().collect(), - count - 1, - |_| true - ), - iter::repeat(candidate_a_hash) - .take(std::cmp::min(count as usize - 1, max_depth)) - .collect::<Vec<_>>() - ); - } - } - - #[test] - fn graceful_cycle_of_1() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), // input same as output - 0, - ); - let candidate_a_hash = candidate_a.hash(); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0b].into(), - vec![0x0a].into(), // input same as output - 0, - ); - let candidate_b_hash = candidate_b.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - let max_depth = 4; - storage.add_candidate(candidate_a, pvd_a).unwrap(); - storage.add_candidate(candidate_b, pvd_b).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 2); - assert_eq!(tree.nodes.len(), max_depth + 1); - - assert_eq!(tree.nodes[0].parent, NodePointer::Root); - assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); - assert_eq!(tree.nodes[2].parent, NodePointer::Storage(1)); - assert_eq!(tree.nodes[3].parent, NodePointer::Storage(2)); - assert_eq!(tree.nodes[4].parent, NodePointer::Storage(3)); - - assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[1].candidate_hash, candidate_b_hash); - assert_eq!(tree.nodes[2].candidate_hash, candidate_a_hash); - assert_eq!(tree.nodes[3].candidate_hash, candidate_b_hash); - assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); - - assert_eq!(tree.find_backable_chain(Ancestors::new(), 1, |_| true), vec![candidate_a_hash],); - assert_eq!( - tree.find_backable_chain(Ancestors::new(), 2, |_| true), - vec![candidate_a_hash, candidate_b_hash], - ); - assert_eq!( - tree.find_backable_chain(Ancestors::new(), 3, |_| true), - vec![candidate_a_hash, candidate_b_hash, candidate_a_hash], - ); - assert_eq!( - tree.find_backable_chain([candidate_a_hash].into_iter().collect(), 2, |_| true), - vec![candidate_b_hash, candidate_a_hash], - ); - - assert_eq!( - tree.find_backable_chain(Ancestors::new(), 6, |_| true), - vec![ - candidate_a_hash, - candidate_b_hash, - candidate_a_hash, - candidate_b_hash, - candidate_a_hash - ], - ); - - for count in 3..7 { - assert_eq!( - tree.find_backable_chain( - [candidate_a_hash, candidate_b_hash].into_iter().collect(), - count, - |_| true - ), - vec![candidate_a_hash, candidate_b_hash, candidate_a_hash], - ); - } - } - - #[test] - fn hypothetical_depths_known_and_unknown() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), // input same as output - 0, - ); - let candidate_a_hash = candidate_a.hash(); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0b].into(), - vec![0x0a].into(), // input same as output - 0, - ); - let candidate_b_hash = candidate_b.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - let max_depth = 4; - storage.add_candidate(candidate_a, pvd_a).unwrap(); - storage.add_candidate(candidate_b, pvd_b).unwrap(); - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 2); - assert_eq!(tree.nodes.len(), max_depth + 1); - - assert_eq!( - tree.hypothetical_depths( - candidate_a_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - false, - ), - vec![0, 2, 4], - ); - - assert_eq!( - tree.hypothetical_depths( - candidate_b_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - false, - ), - vec![1, 3], - ); - - assert_eq!( - tree.hypothetical_depths( - CandidateHash(Hash::repeat_byte(21)), - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - false, - ), - vec![0, 2, 4], - ); - - assert_eq!( - tree.hypothetical_depths( - CandidateHash(Hash::repeat_byte(22)), - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - false, - ), - vec![1, 3] - ); - } - - #[test] - fn hypothetical_depths_stricter_on_complete() { - let storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 1000, // watermark is illegal - ); - - let candidate_a_hash = candidate_a.hash(); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - let max_depth = 4; - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - assert_eq!( - tree.hypothetical_depths( - candidate_a_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - false, - ), - vec![0], - ); - - assert!(tree - .hypothetical_depths( - candidate_a_hash, - HypotheticalCandidate::Complete { - receipt: Cow::Owned(candidate_a), - persisted_validation_data: Cow::Owned(pvd_a), - }, - &storage, - false, - ) - .is_empty()); - } - - #[test] - fn hypothetical_depths_backed_in_path() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 0, - ); - let candidate_a_hash = candidate_a.hash(); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0b].into(), - vec![0x0c].into(), - 0, - ); - let candidate_b_hash = candidate_b.hash(); - - let (pvd_c, candidate_c) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0b].into(), - vec![0x0d].into(), - 0, - ); - - let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); - let pending_availability = Vec::new(); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - - let max_depth = 4; - storage.add_candidate(candidate_a, pvd_a).unwrap(); - storage.add_candidate(candidate_b, pvd_b).unwrap(); - storage.add_candidate(candidate_c, pvd_c).unwrap(); - - // `A` and `B` are backed, `C` is not. - storage.mark_backed(&candidate_a_hash); - storage.mark_backed(&candidate_b_hash); - - let scope = Scope::with_ancestors( - para_id, - relay_parent_a_info, - base_constraints, - pending_availability, - max_depth, - vec![], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 3); - assert_eq!(tree.nodes.len(), 3); - - let candidate_d_hash = CandidateHash(Hash::repeat_byte(0xAA)); - - assert_eq!( - tree.hypothetical_depths( - candidate_d_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - true, - ), - vec![0], - ); - - assert_eq!( - tree.hypothetical_depths( - candidate_d_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0c]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - true, - ), - vec![2], - ); - - assert_eq!( - tree.hypothetical_depths( - candidate_d_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0d]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - true, - ), - Vec::<usize>::new(), - ); - - assert_eq!( - tree.hypothetical_depths( - candidate_d_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0d]).hash(), - relay_parent: relay_parent_a, - }, - &storage, - false, - ), - vec![2], // non-empty if `false`. - ); - } - - #[test] - fn pending_availability_in_scope() { - let mut storage = CandidateStorage::new(); - - let para_id = ParaId::from(5u32); - let relay_parent_a = Hash::repeat_byte(1); - let relay_parent_b = Hash::repeat_byte(2); - let relay_parent_c = Hash::repeat_byte(3); - - let (pvd_a, candidate_a) = make_committed_candidate( - para_id, - relay_parent_a, - 0, - vec![0x0a].into(), - vec![0x0b].into(), - 0, - ); - let candidate_a_hash = candidate_a.hash(); - - let (pvd_b, candidate_b) = make_committed_candidate( - para_id, - relay_parent_b, - 1, - vec![0x0b].into(), - vec![0x0c].into(), - 1, - ); - - // Note that relay parent `a` is not allowed. - let base_constraints = make_constraints(1, vec![], vec![0x0a].into()); - - let relay_parent_a_info = RelayChainBlockInfo { - number: pvd_a.relay_parent_number, - hash: relay_parent_a, - storage_root: pvd_a.relay_parent_storage_root, - }; - let pending_availability = vec![PendingAvailability { - candidate_hash: candidate_a_hash, - relay_parent: relay_parent_a_info, - }]; - - let relay_parent_b_info = RelayChainBlockInfo { - number: pvd_b.relay_parent_number, - hash: relay_parent_b, - storage_root: pvd_b.relay_parent_storage_root, - }; - let relay_parent_c_info = RelayChainBlockInfo { - number: pvd_b.relay_parent_number + 1, - hash: relay_parent_c, - storage_root: Hash::zero(), - }; - - let max_depth = 4; - storage.add_candidate(candidate_a, pvd_a).unwrap(); - storage.add_candidate(candidate_b, pvd_b).unwrap(); - storage.mark_backed(&candidate_a_hash); - - let scope = Scope::with_ancestors( - para_id, - relay_parent_c_info, - base_constraints, - pending_availability, - max_depth, - vec![relay_parent_b_info], - ) - .unwrap(); - let tree = FragmentTree::populate(scope, &storage); - - let candidates: Vec<_> = tree.candidates().collect(); - assert_eq!(candidates.len(), 2); - assert_eq!(tree.nodes.len(), 2); - - let candidate_d_hash = CandidateHash(Hash::repeat_byte(0xAA)); - - assert_eq!( - tree.hypothetical_depths( - candidate_d_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), - relay_parent: relay_parent_c, - }, - &storage, - false, - ), - vec![1], - ); - - assert_eq!( - tree.hypothetical_depths( - candidate_d_hash, - HypotheticalCandidate::Incomplete { - parent_head_data_hash: HeadData::from(vec![0x0c]).hash(), - relay_parent: relay_parent_b, - }, - &storage, - false, - ), - vec![2], - ); - } -} diff --git a/polkadot/node/core/prospective-parachains/src/fragment_tree/tests.rs b/polkadot/node/core/prospective-parachains/src/fragment_tree/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd41be55f7f960367ee0a57ccd4a4c2251b90d13 --- /dev/null +++ b/polkadot/node/core/prospective-parachains/src/fragment_tree/tests.rs @@ -0,0 +1,1451 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. + +use super::*; +use assert_matches::assert_matches; +use polkadot_node_subsystem_util::inclusion_emulator::InboundHrmpLimitations; +use polkadot_primitives::{BlockNumber, CandidateCommitments, CandidateDescriptor, HeadData}; +use polkadot_primitives_test_helpers as test_helpers; +use rstest::rstest; +use std::iter; + +impl NodePointer { + fn unwrap_idx(self) -> usize { + match self { + NodePointer::Root => panic!("Unexpected root"), + NodePointer::Storage(index) => index, + } + } +} + +fn make_constraints( + min_relay_parent_number: BlockNumber, + valid_watermarks: Vec<BlockNumber>, + required_parent: HeadData, +) -> Constraints { + Constraints { + min_relay_parent_number, + max_pov_size: 1_000_000, + max_code_size: 1_000_000, + ump_remaining: 10, + ump_remaining_bytes: 1_000, + max_ump_num_per_candidate: 10, + dmp_remaining_messages: [0; 10].into(), + hrmp_inbound: InboundHrmpLimitations { valid_watermarks }, + hrmp_channels_out: HashMap::new(), + max_hrmp_num_per_candidate: 0, + required_parent, + validation_code_hash: Hash::repeat_byte(42).into(), + upgrade_restriction: None, + future_validation_code: None, + } +} + +fn make_committed_candidate( + para_id: ParaId, + relay_parent: Hash, + relay_parent_number: BlockNumber, + parent_head: HeadData, + para_head: HeadData, + hrmp_watermark: BlockNumber, +) -> (PersistedValidationData, CommittedCandidateReceipt) { + let persisted_validation_data = PersistedValidationData { + parent_head, + relay_parent_number, + relay_parent_storage_root: Hash::repeat_byte(69), + max_pov_size: 1_000_000, + }; + + let candidate = CommittedCandidateReceipt { + descriptor: CandidateDescriptor { + para_id, + relay_parent, + collator: test_helpers::dummy_collator(), + persisted_validation_data_hash: persisted_validation_data.hash(), + pov_hash: Hash::repeat_byte(1), + erasure_root: Hash::repeat_byte(1), + signature: test_helpers::dummy_collator_signature(), + para_head: para_head.hash(), + validation_code_hash: Hash::repeat_byte(42).into(), + }, + commitments: CandidateCommitments { + upward_messages: Default::default(), + horizontal_messages: Default::default(), + new_validation_code: None, + head_data: para_head, + processed_downward_messages: 1, + hrmp_watermark, + }, + }; + + (persisted_validation_data, candidate) +} + +#[test] +fn scope_rejects_ancestors_that_skip_blocks() { + let para_id = ParaId::from(5u32); + let relay_parent = RelayChainBlockInfo { + number: 10, + hash: Hash::repeat_byte(10), + storage_root: Hash::repeat_byte(69), + }; + + let ancestors = vec![RelayChainBlockInfo { + number: 8, + hash: Hash::repeat_byte(8), + storage_root: Hash::repeat_byte(69), + }]; + + let max_depth = 2; + let base_constraints = make_constraints(8, vec![8, 9], vec![1, 2, 3].into()); + let pending_availability = Vec::new(); + + assert_matches!( + Scope::with_ancestors( + para_id, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors + ), + Err(UnexpectedAncestor { number: 8, prev: 10 }) + ); +} + +#[test] +fn scope_rejects_ancestor_for_0_block() { + let para_id = ParaId::from(5u32); + let relay_parent = RelayChainBlockInfo { + number: 0, + hash: Hash::repeat_byte(0), + storage_root: Hash::repeat_byte(69), + }; + + let ancestors = vec![RelayChainBlockInfo { + number: 99999, + hash: Hash::repeat_byte(99), + storage_root: Hash::repeat_byte(69), + }]; + + let max_depth = 2; + let base_constraints = make_constraints(0, vec![], vec![1, 2, 3].into()); + let pending_availability = Vec::new(); + + assert_matches!( + Scope::with_ancestors( + para_id, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors, + ), + Err(UnexpectedAncestor { number: 99999, prev: 0 }) + ); +} + +#[test] +fn scope_only_takes_ancestors_up_to_min() { + let para_id = ParaId::from(5u32); + let relay_parent = RelayChainBlockInfo { + number: 5, + hash: Hash::repeat_byte(0), + storage_root: Hash::repeat_byte(69), + }; + + let ancestors = vec![ + RelayChainBlockInfo { + number: 4, + hash: Hash::repeat_byte(4), + storage_root: Hash::repeat_byte(69), + }, + RelayChainBlockInfo { + number: 3, + hash: Hash::repeat_byte(3), + storage_root: Hash::repeat_byte(69), + }, + RelayChainBlockInfo { + number: 2, + hash: Hash::repeat_byte(2), + storage_root: Hash::repeat_byte(69), + }, + ]; + + let max_depth = 2; + let base_constraints = make_constraints(3, vec![2], vec![1, 2, 3].into()); + let pending_availability = Vec::new(); + + let scope = Scope::with_ancestors( + para_id, + relay_parent, + base_constraints, + pending_availability, + max_depth, + ancestors, + ) + .unwrap(); + + assert_eq!(scope.ancestors.len(), 2); + assert_eq!(scope.ancestors_by_hash.len(), 2); +} + +#[test] +fn storage_add_candidate() { + let mut storage = CandidateStorage::new(); + let relay_parent = Hash::repeat_byte(69); + + let (pvd, candidate) = make_committed_candidate( + ParaId::from(5u32), + relay_parent, + 8, + vec![4, 5, 6].into(), + vec![1, 2, 3].into(), + 7, + ); + + let candidate_hash = candidate.hash(); + let parent_head_hash = pvd.parent_head.hash(); + + storage.add_candidate(candidate, pvd).unwrap(); + assert!(storage.contains(&candidate_hash)); + assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 1); + + assert_eq!(storage.relay_parent_by_candidate_hash(&candidate_hash), Some(relay_parent)); +} + +#[test] +fn storage_retain() { + let mut storage = CandidateStorage::new(); + + let (pvd, candidate) = make_committed_candidate( + ParaId::from(5u32), + Hash::repeat_byte(69), + 8, + vec![4, 5, 6].into(), + vec![1, 2, 3].into(), + 7, + ); + + let candidate_hash = candidate.hash(); + let output_head_hash = candidate.commitments.head_data.hash(); + let parent_head_hash = pvd.parent_head.hash(); + + storage.add_candidate(candidate, pvd).unwrap(); + storage.retain(|_| true); + assert!(storage.contains(&candidate_hash)); + assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 1); + assert!(storage.head_data_by_hash(&output_head_hash).is_some()); + + storage.retain(|_| false); + assert!(!storage.contains(&candidate_hash)); + assert_eq!(storage.iter_para_children(&parent_head_hash).count(), 0); + assert!(storage.head_data_by_hash(&output_head_hash).is_none()); +} + +// [`FragmentTree::populate`] should pick up candidates that build on other candidates. +#[test] +fn populate_works_recursively() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + let relay_parent_b = Hash::repeat_byte(2); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_b, + 1, + vec![0x0b].into(), + vec![0x0c].into(), + 1, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let ancestors = vec![RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }]; + + let relay_parent_b_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number, + hash: relay_parent_b, + storage_root: pvd_b.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_b_info, + base_constraints, + pending_availability, + 4, + ancestors, + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert!(candidates.contains(&candidate_a_hash)); + assert!(candidates.contains(&candidate_b_hash)); + + assert_eq!(tree.nodes.len(), 2); + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[0].depth, 0); + + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + assert_eq!(tree.nodes[1].candidate_hash, candidate_b_hash); + assert_eq!(tree.nodes[1].depth, 1); +} + +#[test] +fn children_of_root_are_contiguous() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + let relay_parent_b = Hash::repeat_byte(2); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_b, + 1, + vec![0x0b].into(), + vec![0x0c].into(), + 1, + ); + + let (pvd_a2, candidate_a2) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b, 1].into(), + 0, + ); + let candidate_a2_hash = candidate_a2.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let ancestors = vec![RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }]; + + let relay_parent_b_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number, + hash: relay_parent_b, + storage_root: pvd_b.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_b_info, + base_constraints, + pending_availability, + 4, + ancestors, + ) + .unwrap(); + let mut tree = FragmentTree::populate(scope, &storage); + + storage.add_candidate(candidate_a2, pvd_a2).unwrap(); + tree.add_and_populate(candidate_a2_hash, &storage); + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 3); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Root); + assert_eq!(tree.nodes[2].parent, NodePointer::Storage(0)); +} + +#[test] +fn add_candidate_child_of_root() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0c].into(), + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + 4, + vec![], + ) + .unwrap(); + let mut tree = FragmentTree::populate(scope, &storage); + + storage.add_candidate(candidate_b, pvd_b).unwrap(); + tree.add_and_populate(candidate_b_hash, &storage); + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Root); +} + +#[test] +fn add_candidate_child_of_non_root() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0c].into(), + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + storage.add_candidate(candidate_a, pvd_a).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + 4, + vec![], + ) + .unwrap(); + let mut tree = FragmentTree::populate(scope, &storage); + + storage.add_candidate(candidate_b, pvd_b).unwrap(); + tree.add_and_populate(candidate_b_hash, &storage); + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); +} + +#[test] +fn test_find_ancestor_path_and_find_backable_chain_empty_tree() { + let para_id = ParaId::from(5u32); + let relay_parent = Hash::repeat_byte(1); + let required_parent: HeadData = vec![0xff].into(); + let max_depth = 10; + + // Empty tree + let storage = CandidateStorage::new(); + let base_constraints = make_constraints(0, vec![0], required_parent.clone()); + + let relay_parent_info = + RelayChainBlockInfo { number: 0, hash: relay_parent, storage_root: Hash::zero() }; + + let scope = Scope::with_ancestors( + para_id, + relay_parent_info, + base_constraints, + vec![], + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + assert_eq!(tree.candidates().collect::<Vec<_>>().len(), 0); + assert_eq!(tree.nodes.len(), 0); + + assert_eq!(tree.find_ancestor_path(Ancestors::new()).unwrap(), NodePointer::Root); + assert_eq!(tree.find_backable_chain(Ancestors::new(), 2, |_| true), vec![]); + // Invalid candidate. + let ancestors: Ancestors = [CandidateHash::default()].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()), Some(NodePointer::Root)); + assert_eq!(tree.find_backable_chain(ancestors, 2, |_| true), vec![]); +} + +#[rstest] +#[case(true, 13)] +#[case(false, 8)] +// The tree with no cycles looks like: +// Make a tree that looks like this (note that there's no cycle): +// +-(root)-+ +// | | +// +----0---+ 7 +// | | +// 1----+ 5 +// | | +// | | +// 2 6 +// | +// 3 +// | +// 4 +// +// The tree with cycles is the same as the first but has a cycle from 4 back to the state +// produced by 0 (It's bounded by the max_depth + 1). +// +-(root)-+ +// | | +// +----0---+ 7 +// | | +// 1----+ 5 +// | | +// | | +// 2 6 +// | +// 3 +// | +// 4---+ +// | | +// 1 5 +// | +// 2 +// | +// 3 +fn test_find_ancestor_path_and_find_backable_chain( + #[case] has_cycle: bool, + #[case] expected_node_count: usize, +) { + let para_id = ParaId::from(5u32); + let relay_parent = Hash::repeat_byte(1); + let required_parent: HeadData = vec![0xff].into(); + let max_depth = 7; + let relay_parent_number = 0; + let relay_parent_storage_root = Hash::repeat_byte(69); + + let mut candidates = vec![]; + + // Candidate 0 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + required_parent.clone(), + vec![0].into(), + 0, + )); + // Candidate 1 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![0].into(), + vec![1].into(), + 0, + )); + // Candidate 2 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![1].into(), + vec![2].into(), + 0, + )); + // Candidate 3 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![2].into(), + vec![3].into(), + 0, + )); + // Candidate 4 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![3].into(), + vec![4].into(), + 0, + )); + // Candidate 5 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![0].into(), + vec![5].into(), + 0, + )); + // Candidate 6 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + vec![1].into(), + vec![6].into(), + 0, + )); + // Candidate 7 + candidates.push(make_committed_candidate( + para_id, + relay_parent, + 0, + required_parent.clone(), + vec![7].into(), + 0, + )); + + if has_cycle { + candidates[4] = make_committed_candidate( + para_id, + relay_parent, + 0, + vec![3].into(), + vec![0].into(), // put the cycle here back to the output state of 0. + 0, + ); + } + + let base_constraints = make_constraints(0, vec![0], required_parent.clone()); + let mut storage = CandidateStorage::new(); + + let relay_parent_info = RelayChainBlockInfo { + number: relay_parent_number, + hash: relay_parent, + storage_root: relay_parent_storage_root, + }; + + for (pvd, candidate) in candidates.iter() { + storage.add_candidate(candidate.clone(), pvd.clone()).unwrap(); + } + let candidates = candidates.into_iter().map(|(_pvd, candidate)| candidate).collect::<Vec<_>>(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_info, + base_constraints, + vec![], + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + assert_eq!(tree.candidates().collect::<Vec<_>>().len(), candidates.len()); + assert_eq!(tree.nodes.len(), expected_node_count); + + // Do some common tests on both trees. + { + // No ancestors supplied. + assert_eq!(tree.find_ancestor_path(Ancestors::new()).unwrap(), NodePointer::Root); + assert_eq!( + tree.find_backable_chain(Ancestors::new(), 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + // Ancestor which is not part of the tree. Will be ignored. + let ancestors: Ancestors = [CandidateHash::default()].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()).unwrap(), NodePointer::Root); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + // A chain fork. + let ancestors: Ancestors = + [(candidates[0].hash()), (candidates[7].hash())].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()), None); + assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); + + // Ancestors which are part of the tree but don't form a path. Will be ignored. + let ancestors: Ancestors = + [candidates[1].hash(), candidates[2].hash()].into_iter().collect(); + assert_eq!(tree.find_ancestor_path(ancestors.clone()).unwrap(), NodePointer::Root); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + + // Valid ancestors. + let ancestors: Ancestors = [candidates[7].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[7].hash()); + assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); + + let ancestors: Ancestors = + [candidates[2].hash(), candidates[0].hash(), candidates[1].hash()] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[2].hash()); + assert_eq!( + tree.find_backable_chain(ancestors.clone(), 2, |_| true), + [3, 4].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + + // Valid ancestors with candidates which have been omitted due to timeouts + let ancestors: Ancestors = + [candidates[0].hash(), candidates[2].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[0].hash()); + assert_eq!( + tree.find_backable_chain(ancestors, 3, |_| true), + [1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + + let ancestors: Ancestors = + [candidates[0].hash(), candidates[1].hash(), candidates[3].hash()] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[1].hash()); + if has_cycle { + assert_eq!( + tree.find_backable_chain(ancestors, 2, |_| true), + [2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + } else { + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [2, 3, 4].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + } + + let ancestors: Ancestors = + [candidates[1].hash(), candidates[2].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + assert_eq!(res, NodePointer::Root); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [0, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + + // Requested count is 0. + assert_eq!(tree.find_backable_chain(Ancestors::new(), 0, |_| true), vec![]); + + let ancestors: Ancestors = + [candidates[2].hash(), candidates[0].hash(), candidates[1].hash()] + .into_iter() + .collect(); + assert_eq!(tree.find_backable_chain(ancestors, 0, |_| true), vec![]); + + let ancestors: Ancestors = + [candidates[2].hash(), candidates[0].hash()].into_iter().collect(); + assert_eq!(tree.find_backable_chain(ancestors, 0, |_| true), vec![]); + } + + // Now do some tests only on the tree with cycles + if has_cycle { + // Exceeds the maximum tree depth. 0-1-2-3-4-1-2-3-4, when the tree stops at + // 0-1-2-3-4-1-2-3. + let ancestors: Ancestors = [ + candidates[0].hash(), + candidates[1].hash(), + candidates[2].hash(), + candidates[3].hash(), + candidates[4].hash(), + ] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[4].hash()); + assert_eq!( + tree.find_backable_chain(ancestors, 4, |_| true), + [1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + + // 0-1-2. + let ancestors: Ancestors = + [candidates[0].hash(), candidates[1].hash(), candidates[2].hash()] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[2].hash()); + assert_eq!( + tree.find_backable_chain(ancestors.clone(), 1, |_| true), + [3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + assert_eq!( + tree.find_backable_chain(ancestors, 5, |_| true), + [3, 4, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>() + ); + + // 0-1 + let ancestors: Ancestors = + [candidates[0].hash(), candidates[1].hash()].into_iter().collect(); + let res = tree.find_ancestor_path(ancestors.clone()).unwrap(); + let candidate = &tree.nodes[res.unwrap_idx()]; + assert_eq!(candidate.candidate_hash, candidates[1].hash()); + assert_eq!( + tree.find_backable_chain(ancestors, 6, |_| true), + [2, 3, 4, 1, 2, 3].into_iter().map(|i| candidates[i].hash()).collect::<Vec<_>>(), + ); + + // For 0-1-2-3-4-5, there's more than 1 way of finding this path in + // the tree. `None` should be returned. The runtime should not have accepted this. + let ancestors: Ancestors = [ + candidates[0].hash(), + candidates[1].hash(), + candidates[2].hash(), + candidates[3].hash(), + candidates[4].hash(), + candidates[5].hash(), + ] + .into_iter() + .collect(); + let res = tree.find_ancestor_path(ancestors.clone()); + assert_eq!(res, None); + assert_eq!(tree.find_backable_chain(ancestors, 1, |_| true), vec![]); + } +} + +#[test] +fn graceful_cycle_of_0() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0a].into(), // input same as output + 0, + ); + let candidate_a_hash = candidate_a.hash(); + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 1); + assert_eq!(tree.nodes.len(), max_depth + 1); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + assert_eq!(tree.nodes[2].parent, NodePointer::Storage(1)); + assert_eq!(tree.nodes[3].parent, NodePointer::Storage(2)); + assert_eq!(tree.nodes[4].parent, NodePointer::Storage(3)); + + assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[1].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[2].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[3].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); + + for count in 1..10 { + assert_eq!( + tree.find_backable_chain(Ancestors::new(), count, |_| true), + iter::repeat(candidate_a_hash) + .take(std::cmp::min(count as usize, max_depth + 1)) + .collect::<Vec<_>>() + ); + assert_eq!( + tree.find_backable_chain([candidate_a_hash].into_iter().collect(), count - 1, |_| true), + iter::repeat(candidate_a_hash) + .take(std::cmp::min(count as usize - 1, max_depth)) + .collect::<Vec<_>>() + ); + } +} + +#[test] +fn graceful_cycle_of_1() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), // input same as output + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0a].into(), // input same as output + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert_eq!(tree.nodes.len(), max_depth + 1); + + assert_eq!(tree.nodes[0].parent, NodePointer::Root); + assert_eq!(tree.nodes[1].parent, NodePointer::Storage(0)); + assert_eq!(tree.nodes[2].parent, NodePointer::Storage(1)); + assert_eq!(tree.nodes[3].parent, NodePointer::Storage(2)); + assert_eq!(tree.nodes[4].parent, NodePointer::Storage(3)); + + assert_eq!(tree.nodes[0].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[1].candidate_hash, candidate_b_hash); + assert_eq!(tree.nodes[2].candidate_hash, candidate_a_hash); + assert_eq!(tree.nodes[3].candidate_hash, candidate_b_hash); + assert_eq!(tree.nodes[4].candidate_hash, candidate_a_hash); + + assert_eq!(tree.find_backable_chain(Ancestors::new(), 1, |_| true), vec![candidate_a_hash],); + assert_eq!( + tree.find_backable_chain(Ancestors::new(), 2, |_| true), + vec![candidate_a_hash, candidate_b_hash], + ); + assert_eq!( + tree.find_backable_chain(Ancestors::new(), 3, |_| true), + vec![candidate_a_hash, candidate_b_hash, candidate_a_hash], + ); + assert_eq!( + tree.find_backable_chain([candidate_a_hash].into_iter().collect(), 2, |_| true), + vec![candidate_b_hash, candidate_a_hash], + ); + + assert_eq!( + tree.find_backable_chain(Ancestors::new(), 6, |_| true), + vec![ + candidate_a_hash, + candidate_b_hash, + candidate_a_hash, + candidate_b_hash, + candidate_a_hash + ], + ); + + for count in 3..7 { + assert_eq!( + tree.find_backable_chain( + [candidate_a_hash, candidate_b_hash].into_iter().collect(), + count, + |_| true + ), + vec![candidate_a_hash, candidate_b_hash, candidate_a_hash], + ); + } +} + +#[test] +fn hypothetical_depths_known_and_unknown() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), // input same as output + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0a].into(), // input same as output + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert_eq!(tree.nodes.len(), max_depth + 1); + + assert_eq!( + tree.hypothetical_depths( + candidate_a_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![0, 2, 4], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_b_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![1, 3], + ); + + assert_eq!( + tree.hypothetical_depths( + CandidateHash(Hash::repeat_byte(21)), + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![0, 2, 4], + ); + + assert_eq!( + tree.hypothetical_depths( + CandidateHash(Hash::repeat_byte(22)), + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![1, 3] + ); +} + +#[test] +fn hypothetical_depths_stricter_on_complete() { + let storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 1000, // watermark is illegal + ); + + let candidate_a_hash = candidate_a.hash(); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + assert_eq!( + tree.hypothetical_depths( + candidate_a_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![0], + ); + + assert!(tree + .hypothetical_depths( + candidate_a_hash, + HypotheticalCandidate::Complete { + receipt: Cow::Owned(candidate_a), + persisted_validation_data: Cow::Owned(pvd_a), + }, + &storage, + false, + ) + .is_empty()); +} + +#[test] +fn hypothetical_depths_backed_in_path() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0c].into(), + 0, + ); + let candidate_b_hash = candidate_b.hash(); + + let (pvd_c, candidate_c) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0b].into(), + vec![0x0d].into(), + 0, + ); + + let base_constraints = make_constraints(0, vec![0], vec![0x0a].into()); + let pending_availability = Vec::new(); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + storage.add_candidate(candidate_c, pvd_c).unwrap(); + + // `A` and `B` are backed, `C` is not. + storage.mark_backed(&candidate_a_hash); + storage.mark_backed(&candidate_b_hash); + + let scope = Scope::with_ancestors( + para_id, + relay_parent_a_info, + base_constraints, + pending_availability, + max_depth, + vec![], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 3); + assert_eq!(tree.nodes.len(), 3); + + let candidate_d_hash = CandidateHash(Hash::repeat_byte(0xAA)); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0a]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + true, + ), + vec![0], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0c]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + true, + ), + vec![2], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0d]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + true, + ), + Vec::<usize>::new(), + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0d]).hash(), + relay_parent: relay_parent_a, + }, + &storage, + false, + ), + vec![2], // non-empty if `false`. + ); +} + +#[test] +fn pending_availability_in_scope() { + let mut storage = CandidateStorage::new(); + + let para_id = ParaId::from(5u32); + let relay_parent_a = Hash::repeat_byte(1); + let relay_parent_b = Hash::repeat_byte(2); + let relay_parent_c = Hash::repeat_byte(3); + + let (pvd_a, candidate_a) = make_committed_candidate( + para_id, + relay_parent_a, + 0, + vec![0x0a].into(), + vec![0x0b].into(), + 0, + ); + let candidate_a_hash = candidate_a.hash(); + + let (pvd_b, candidate_b) = make_committed_candidate( + para_id, + relay_parent_b, + 1, + vec![0x0b].into(), + vec![0x0c].into(), + 1, + ); + + // Note that relay parent `a` is not allowed. + let base_constraints = make_constraints(1, vec![], vec![0x0a].into()); + + let relay_parent_a_info = RelayChainBlockInfo { + number: pvd_a.relay_parent_number, + hash: relay_parent_a, + storage_root: pvd_a.relay_parent_storage_root, + }; + let pending_availability = vec![PendingAvailability { + candidate_hash: candidate_a_hash, + relay_parent: relay_parent_a_info, + }]; + + let relay_parent_b_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number, + hash: relay_parent_b, + storage_root: pvd_b.relay_parent_storage_root, + }; + let relay_parent_c_info = RelayChainBlockInfo { + number: pvd_b.relay_parent_number + 1, + hash: relay_parent_c, + storage_root: Hash::zero(), + }; + + let max_depth = 4; + storage.add_candidate(candidate_a, pvd_a).unwrap(); + storage.add_candidate(candidate_b, pvd_b).unwrap(); + storage.mark_backed(&candidate_a_hash); + + let scope = Scope::with_ancestors( + para_id, + relay_parent_c_info, + base_constraints, + pending_availability, + max_depth, + vec![relay_parent_b_info], + ) + .unwrap(); + let tree = FragmentTree::populate(scope, &storage); + + let candidates: Vec<_> = tree.candidates().collect(); + assert_eq!(candidates.len(), 2); + assert_eq!(tree.nodes.len(), 2); + + let candidate_d_hash = CandidateHash(Hash::repeat_byte(0xAA)); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0b]).hash(), + relay_parent: relay_parent_c, + }, + &storage, + false, + ), + vec![1], + ); + + assert_eq!( + tree.hypothetical_depths( + candidate_d_hash, + HypotheticalCandidate::Incomplete { + parent_head_data_hash: HeadData::from(vec![0x0c]).hash(), + relay_parent: relay_parent_b, + }, + &storage, + false, + ), + vec![2], + ); +} diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs index cc1243790c2e58b23c169de918f28d75397420ba..85531e9c04fc47f83fb007802e30e87799c2150c 100644 --- a/polkadot/runtime/common/src/impls.rs +++ b/polkadot/runtime/common/src/impls.rs @@ -19,7 +19,7 @@ use frame_support::traits::{ fungible::{Balanced, Credit}, tokens::imbalance::ResolveTo, - Imbalance, OnUnbalanced, + Contains, ContainsPair, Imbalance, OnUnbalanced, }; use pallet_treasury::TreasuryAccountId; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; @@ -156,6 +156,26 @@ impl TryConvert<&VersionedLocation, xcm::latest::Location> for VersionedLocation } } +/// Adapter for [`Contains`] trait to match [`VersionedLocatableAsset`] type converted to the latest +/// version of itself where it's location matched by `L` and it's asset id by `A` parameter types. +pub struct ContainsParts<C>(core::marker::PhantomData<C>); +impl<C> Contains<VersionedLocatableAsset> for ContainsParts<C> +where + C: ContainsPair<xcm::latest::Location, xcm::latest::Location>, +{ + fn contains(asset: &VersionedLocatableAsset) -> bool { + use VersionedLocatableAsset::*; + let (location, asset_id) = match asset.clone() { + V3 { location, asset_id } => match (location.try_into(), asset_id.try_into()) { + (Ok(l), Ok(a)) => (l, a), + _ => return false, + }, + V4 { location, asset_id } => (location, asset_id), + }; + C::contains(&location, &asset_id.0) + } +} + #[cfg(feature = "runtime-benchmarks")] pub mod benchmarks { use super::VersionedLocatableAsset; diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 740a6240d39526cec795ba082848a480c8a7e3a3..ba80fa6942c7791e9166281f0bdf2199a41cf10f 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -25,7 +25,10 @@ use beefy_primitives::{ ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, mmr::{BeefyDataProvider, MmrLeafVersion}, }; -use frame_support::dynamic_params::{dynamic_pallet_params, dynamic_params}; +use frame_support::{ + dynamic_params::{dynamic_pallet_params, dynamic_params}, + traits::FromContains, +}; use pallet_nis::WithMaximumOf; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use primitives::{ @@ -40,7 +43,8 @@ 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, VersionedLocationConverter, + ContainsParts, LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, + VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, traits::{Leaser, OnSwap}, @@ -74,10 +78,10 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ - fungible::HoldConsideration, Contains, EitherOf, EitherOfDiverse, EnsureOrigin, - EnsureOriginWithArg, EverythingBut, InstanceFilter, KeyOwnerProofSystem, - LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, StorageMapShim, - WithdrawReasons, + fungible::HoldConsideration, tokens::UnityOrOuterConversion, Contains, EitherOf, + EitherOfDiverse, EnsureOrigin, EnsureOriginWithArg, EverythingBut, InstanceFilter, + KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, + StorageMapShim, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter, WeightToFee as _}, PalletId, @@ -87,7 +91,7 @@ use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use pallet_identity::legacy::IdentityInfo; use pallet_session::historical as session_historical; use pallet_transaction_payment::{FeeDetails, FungibleAdapter, RuntimeDispatchInfo}; -use sp_core::{ConstU128, OpaqueMetadata, H256}; +use sp_core::{ConstU128, ConstU8, OpaqueMetadata, H256}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ @@ -523,7 +527,15 @@ impl pallet_treasury::Config for Runtime { LocatableAssetConverter, VersionedLocationConverter, >; - type BalanceConverter = AssetRate; + type BalanceConverter = UnityOrOuterConversion< + ContainsParts< + FromContains< + xcm_builder::IsChildSystemParachain<ParaId>, + xcm_builder::IsParentsOnly<ConstU8<1>>, + >, + >, + AssetRate, + >; type PayoutPeriod = PayoutSpendPeriod; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = runtime_common::impls::benchmarks::TreasuryArguments; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index a119d78b83ab8a76642d0bc1cf407ec4935ab5dc..a06a1e1f7fc8dfbefee8aae69194265b80fbd8c5 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -31,9 +31,9 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ - fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, EverythingBut, - InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, ProcessMessage, - ProcessMessageError, WithdrawReasons, + fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, Contains, EitherOf, + EitherOfDiverse, EverythingBut, FromContains, InstanceFilter, KeyOwnerProofSystem, + LinearStoragePrice, ProcessMessage, ProcessMessageError, WithdrawReasons, }, weights::{ConstantMultiplier, WeightMeter, WeightToFee as _}, PalletId, @@ -57,7 +57,8 @@ use runtime_common::{ elections::OnChainAccuracy, identity_migrator, impl_runtime_weights, impls::{ - LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, VersionedLocationConverter, + ContainsParts, LocatableAssetConverter, ToAuthor, VersionedLocatableAsset, + VersionedLocationConverter, }, paras_registrar, paras_sudo_wrapper, prod_or_fast, slots, traits::{Leaser, OnSwap}, @@ -80,7 +81,7 @@ use runtime_parachains::{ shared as parachains_shared, }; use scale_info::TypeInfo; -use sp_core::{OpaqueMetadata, RuntimeDebug, H256}; +use sp_core::{ConstU8, OpaqueMetadata, RuntimeDebug, H256}; use sp_runtime::{ create_runtime_str, curve::PiecewiseLinear, @@ -712,7 +713,15 @@ impl pallet_treasury::Config for Runtime { LocatableAssetConverter, VersionedLocationConverter, >; - type BalanceConverter = AssetRate; + type BalanceConverter = UnityOrOuterConversion< + ContainsParts< + FromContains< + xcm_builder::IsChildSystemParachain<ParaId>, + xcm_builder::IsParentsOnly<ConstU8<1>>, + >, + >, + AssetRate, + >; type PayoutPeriod = PayoutSpendPeriod; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = runtime_common::impls::benchmarks::TreasuryArguments; diff --git a/polkadot/xcm/xcm-builder/src/barriers.rs b/polkadot/xcm/xcm-builder/src/barriers.rs index b8923a4d5c6e88d9034536fa4dacf21c47e9108b..c0b328f38e96b23dbadcda4dd8fc1aacf9620d5d 100644 --- a/polkadot/xcm/xcm-builder/src/barriers.rs +++ b/polkadot/xcm/xcm-builder/src/barriers.rs @@ -322,6 +322,29 @@ impl<ParaId: IsSystem + From<u32>> Contains<Location> for IsChildSystemParachain } } +/// Matches if the given location is a system-level sibling parachain. +pub struct IsSiblingSystemParachain<ParaId, SelfParaId>(PhantomData<(ParaId, SelfParaId)>); +impl<ParaId: IsSystem + From<u32> + Eq, SelfParaId: Get<ParaId>> Contains<Location> + for IsSiblingSystemParachain<ParaId, SelfParaId> +{ + fn contains(l: &Location) -> bool { + matches!( + l.unpack(), + (1, [Junction::Parachain(id)]) + if SelfParaId::get() != ParaId::from(*id) && ParaId::from(*id).is_system(), + ) + } +} + +/// Matches if the given location contains only the specified amount of parents and no interior +/// junctions. +pub struct IsParentsOnly<Count>(PhantomData<Count>); +impl<Count: Get<u8>> Contains<Location> for IsParentsOnly<Count> { + fn contains(t: &Location) -> bool { + t.contains_parents_only(Count::get()) + } +} + /// Allows only messages if the generic `ResponseHandler` expects them via `expecting_response`. pub struct AllowKnownQueryResponses<ResponseHandler>(PhantomData<ResponseHandler>); impl<ResponseHandler: OnResponse> ShouldExecute for AllowKnownQueryResponses<ResponseHandler> { diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs index c3400cc72b48e97cb2cdfd85a028b21b7c032963..bd4a4c941c915c8da1f9c05d35444d86ac7668e8 100644 --- a/polkadot/xcm/xcm-builder/src/lib.rs +++ b/polkadot/xcm/xcm-builder/src/lib.rs @@ -37,8 +37,8 @@ mod barriers; pub use barriers::{ AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, DenyReserveTransferToRelayChain, - DenyThenTry, IsChildSystemParachain, RespectSuspension, TakeWeightCredit, TrailingSetTopicAsId, - WithComputedOrigin, + DenyThenTry, IsChildSystemParachain, IsParentsOnly, IsSiblingSystemParachain, + RespectSuspension, TakeWeightCredit, TrailingSetTopicAsId, WithComputedOrigin, }; mod controller; diff --git a/prdoc/pr_3659.prdoc b/prdoc/pr_3659.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..393844d822d864bca595a0257f02989fb4a19ac7 --- /dev/null +++ b/prdoc/pr_3659.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: Unity Balance Conversion for Different IDs of Native Asset + +doc: + - audience: Runtime Dev + description: | + Introduce types to define 1:1 balance conversion for different relative asset ids/locations + of native asset for `ConversionToAssetBalance` trait bounds. + +crates: [ ] \ No newline at end of file diff --git a/prdoc/pr_4151.prdoc b/prdoc/pr_4151.prdoc new file mode 100644 index 0000000000000000000000000000000000000000..70b9f5e60e14c5a0896b60651be89cc40fbe56a5 --- /dev/null +++ b/prdoc/pr_4151.prdoc @@ -0,0 +1,11 @@ +title: "[pallet-broker] Use saturating math in input validation" + +doc: + - audience: Runtime Dev + description: | + Use saturating in the pallet-broker input validation of the `drop_history` extrinsic. This + fixes a safeguard that only expired historic instantaneous pool records get dropped. + +crates: + - name: pallet-broker + bump: patch diff --git a/prdoc/schema_user.json b/prdoc/schema_user.json index 6b44b1b28dfb859dde52e46974a6ef1d06aa3722..1fa4b8d1202c99c1fea077854b6f5efcf58f1ae5 100644 --- a/prdoc/schema_user.json +++ b/prdoc/schema_user.json @@ -200,6 +200,11 @@ "const": "patch", "title": "Patch", "description": "A bump to the third leftmost non-zero digit of the version number." + }, + { + "const": "none", + "title": "None", + "description": "This change requires no SemVer bump (e.g. change was a test)." } ] }, diff --git a/substrate/frame/broker/src/dispatchable_impls.rs b/substrate/frame/broker/src/dispatchable_impls.rs index c2e731462ca58bb042ffe08c3b2c59af2cf3954c..b43911b6bc12d63a2806f3b708e842aee59c9ec0 100644 --- a/substrate/frame/broker/src/dispatchable_impls.rs +++ b/substrate/frame/broker/src/dispatchable_impls.rs @@ -419,7 +419,10 @@ impl<T: Config> Pallet<T> { pub(crate) fn do_drop_history(when: Timeslice) -> DispatchResult { let config = Configuration::<T>::get().ok_or(Error::<T>::Uninitialized)?; let status = Status::<T>::get().ok_or(Error::<T>::Uninitialized)?; - ensure!(status.last_timeslice > when + config.contribution_timeout, Error::<T>::StillValid); + ensure!( + status.last_timeslice > when.saturating_add(config.contribution_timeout), + Error::<T>::StillValid + ); let record = InstaPoolHistory::<T>::take(when).ok_or(Error::<T>::NoHistory)?; if let Some(payout) = record.maybe_payout { let _ = Self::charge(&Self::account_id(), payout); diff --git a/substrate/frame/broker/src/tests.rs b/substrate/frame/broker/src/tests.rs index d738d34450336e8aa8c20eb2c7d232d2c69db592..8ec0c6d158b3bb03a5b1e7b1001f7ded8b7ef79d 100644 --- a/substrate/frame/broker/src/tests.rs +++ b/substrate/frame/broker/src/tests.rs @@ -146,6 +146,7 @@ fn drop_history_works() { advance_to(16); assert_eq!(InstaPoolHistory::<Test>::iter().count(), 6); advance_to(17); + assert_noop!(Broker::do_drop_history(u32::MAX), Error::<Test>::StillValid); assert_noop!(Broker::do_drop_history(region.begin), Error::<Test>::StillValid); advance_to(18); assert_eq!(InstaPoolHistory::<Test>::iter().count(), 6); diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs index 676fd320a17299b2eb2471d485afcd2775168175..952ef180be21860b4a13a26fdf07bf03251f00a2 100644 --- a/substrate/frame/contracts/src/benchmarking/mod.rs +++ b/substrate/frame/contracts/src/benchmarking/mod.rs @@ -623,10 +623,13 @@ mod benchmarks { #[benchmark(pov_mode = Measured)] fn seal_caller(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_caller", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -659,10 +662,13 @@ mod benchmarks { for acc in accounts.iter() { <ContractInfoOf<T>>::insert(acc, info.clone()); } + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -703,19 +709,25 @@ mod benchmarks { for acc in accounts.iter() { <ContractInfoOf<T>>::insert(acc, info.clone()); } + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_own_code_hash(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_own_code_hash", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -732,10 +744,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -754,73 +769,97 @@ mod benchmarks { let mut setup = CallSetup::<T>::new(code); setup.set_origin(Origin::Root); call_builder!(func, setup: setup); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_address(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_address", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_gas_left(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal1", "gas_left", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_balance(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_balance", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_value_transferred(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_value_transferred", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_minimum_balance(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_minimum_balance", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_block_number(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_block_number", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] fn seal_now(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::getter("seal0", "seal_now", r)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -851,10 +890,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -880,10 +922,13 @@ mod benchmarks { }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -944,10 +989,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } #[benchmark(pov_mode = Measured)] @@ -970,10 +1018,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // The same argument as for `seal_return` is true here. @@ -1108,10 +1159,13 @@ mod benchmarks { }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // Overhead of calling the function without any topic. @@ -1140,10 +1194,13 @@ mod benchmarks { }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // Benchmark the overhead that topics generate. @@ -1177,10 +1234,13 @@ mod benchmarks { }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // Benchmark debug_message call with zero input data. @@ -1210,10 +1270,13 @@ mod benchmarks { let mut setup = CallSetup::<T>::new(code); setup.enable_debug_message(); call_builder!(func, setup: setup); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1260,10 +1323,13 @@ mod benchmarks { let mut setup = CallSetup::<T>::new(code); setup.enable_debug_message(); call_builder!(func, setup: setup); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); assert_eq!(setup.debug_message().unwrap().len() as u32, i); Ok(()) } @@ -1324,10 +1390,13 @@ mod benchmarks { ) .map_err(|_| "Failed to write to storage during setup.")?; } + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1366,10 +1435,13 @@ mod benchmarks { false, ) .map_err(|_| "Failed to write to storage during setup.")?; + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1409,10 +1481,13 @@ mod benchmarks { false, ) .map_err(|_| "Failed to write to storage during setup.")?; + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1463,10 +1538,13 @@ mod benchmarks { .map_err(|_| "Failed to write to storage during setup.")?; } <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1504,10 +1582,12 @@ mod benchmarks { ) .map_err(|_| "Failed to write to storage during setup.")?; + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1564,10 +1644,13 @@ mod benchmarks { .map_err(|_| "Failed to write to storage during setup.")?; } <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1613,10 +1696,13 @@ mod benchmarks { ) .map_err(|_| "Failed to write to storage during setup.")?; <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1667,10 +1753,13 @@ mod benchmarks { .map_err(|_| "Failed to write to storage during setup.")?; } <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1708,10 +1797,13 @@ mod benchmarks { ) .map_err(|_| "Failed to write to storage during setup.")?; <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1767,10 +1859,13 @@ mod benchmarks { .map_err(|_| "Failed to write to storage during setup.")?; } <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1816,10 +1911,13 @@ mod benchmarks { ) .map_err(|_| "Failed to write to storage during setup.")?; <ContractInfoOf<T>>::insert(&instance.account_id, info); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -1867,10 +1965,12 @@ mod benchmarks { assert_eq!(T::Currency::total_balance(account), 0u32.into()); } + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); for account in &accounts { assert_eq!(T::Currency::total_balance(account), value); @@ -1947,10 +2047,13 @@ mod benchmarks { let mut setup = CallSetup::<T>::new(code); setup.set_storage_deposit_limit(BalanceOf::<T>::from(u32::MAX.into())); call_builder!(func, setup: setup); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2002,10 +2105,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2057,10 +2163,13 @@ mod benchmarks { let mut setup = CallSetup::<T>::new(code); setup.set_data(vec![42; c as usize]); call_builder!(func, setup: setup); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2165,10 +2274,13 @@ mod benchmarks { return Err("Expected that contract does not exist at this point.".into()); } } + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); for addr in &addresses { ContractInfoOf::<T>::get(&addr).ok_or("Contract should have been instantiated")?; } @@ -2240,10 +2352,13 @@ mod benchmarks { let mut setup = CallSetup::<T>::new(code); setup.set_balance(value + (Pallet::<T>::min_balance() * 2u32.into())); call_builder!(func, setup: setup); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2251,80 +2366,104 @@ mod benchmarks { #[benchmark(pov_mode = Measured)] fn seal_hash_sha2_256(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::hasher("seal_hash_sha2_256", r, 0)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // `n`: Input to hash in bytes #[benchmark(pov_mode = Measured)] fn seal_hash_sha2_256_per_byte(n: Linear<0, { code::max_pages::<T>() * 64 * 1024 }>) { call_builder!(func, WasmModule::hasher("seal_hash_sha2_256", 1, n)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // Only the overhead of calling the function itself with minimal arguments. #[benchmark(pov_mode = Measured)] fn seal_hash_keccak_256(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::hasher("seal_hash_keccak_256", r, 0)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // `n`: Input to hash in bytes #[benchmark(pov_mode = Measured)] fn seal_hash_keccak_256_per_byte(n: Linear<0, { code::max_pages::<T>() * 64 * 1024 }>) { call_builder!(func, WasmModule::hasher("seal_hash_keccak_256", 1, n)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // Only the overhead of calling the function itself with minimal arguments. #[benchmark(pov_mode = Measured)] fn seal_hash_blake2_256(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::hasher("seal_hash_blake2_256", r, 0)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // `n`: Input to hash in bytes #[benchmark(pov_mode = Measured)] fn seal_hash_blake2_256_per_byte(n: Linear<0, { code::max_pages::<T>() * 64 * 1024 }>) { call_builder!(func, WasmModule::hasher("seal_hash_blake2_256", 1, n)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // Only the overhead of calling the function itself with minimal arguments. #[benchmark(pov_mode = Measured)] fn seal_hash_blake2_128(r: Linear<0, API_BENCHMARK_RUNS>) { call_builder!(func, WasmModule::hasher("seal_hash_blake2_128", r, 0)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // `n`: Input to hash in bytes #[benchmark(pov_mode = Measured)] fn seal_hash_blake2_128_per_byte(n: Linear<0, { code::max_pages::<T>() * 64 * 1024 }>) { call_builder!(func, WasmModule::hasher("seal_hash_blake2_128", 1, n)); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // `n`: Message input length to verify in bytes. @@ -2368,10 +2507,13 @@ mod benchmarks { }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2425,10 +2567,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2475,10 +2620,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2515,10 +2663,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2556,10 +2707,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2598,10 +2752,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2656,10 +2813,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2713,10 +2873,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); Ok(()) } @@ -2734,10 +2897,13 @@ mod benchmarks { ..Default::default() }); call_builder!(func, code); + + let res; #[block] { - func.call(); + res = func.call(); } + assert_eq!(res.did_revert(), false); } // We load `i64` values from random linear memory locations and store the loaded diff --git a/substrate/frame/contracts/src/weights.rs b/substrate/frame/contracts/src/weights.rs index ca7f58cf5b0cada995a268cc241b36a0599cb709..b95b1d1a9a2e5ae47ca0d9fe1715031f47e43986 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 32.0.0 -//! DATE: 2024-04-10, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-04-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-anb7yjbi-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` @@ -143,8 +143,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_047_000 picoseconds. - Weight::from_parts(2_116_000, 1627) + // Minimum execution time: 2_149_000 picoseconds. + Weight::from_parts(2_274_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -154,10 +154,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 12_474_000 picoseconds. - Weight::from_parts(12_767_000, 442) - // Standard Error: 1_081 - .saturating_add(Weight::from_parts(1_187_278, 0).saturating_mul(k.into())) + // Minimum execution time: 12_863_000 picoseconds. + Weight::from_parts(13_188_000, 442) + // Standard Error: 1_053 + .saturating_add(Weight::from_parts(1_105_325, 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)) @@ -171,10 +171,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_307_000 picoseconds. - Weight::from_parts(8_939_322, 6149) + // Minimum execution time: 8_432_000 picoseconds. + Weight::from_parts(9_203_290, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_190, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_186, 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())) @@ -187,8 +187,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 16_915_000 picoseconds. - Weight::from_parts(17_638_000, 6450) + // Minimum execution time: 17_177_000 picoseconds. + Weight::from_parts(17_663_000, 6450) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -201,10 +201,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_607_000 picoseconds. - Weight::from_parts(1_979_323, 3635) - // Standard Error: 1_018 - .saturating_add(Weight::from_parts(1_196_162, 0).saturating_mul(k.into())) + // Minimum execution time: 3_636_000 picoseconds. + Weight::from_parts(3_774_000, 3635) + // Standard Error: 542 + .saturating_add(Weight::from_parts(1_260_058, 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()))) @@ -225,10 +225,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `328 + c * (1 ±0)` // Estimated: `6266 + c * (1 ±0)` - // Minimum execution time: 21_056_000 picoseconds. - Weight::from_parts(21_633_895, 6266) + // Minimum execution time: 21_585_000 picoseconds. + Weight::from_parts(22_069_944, 6266) // Standard Error: 1 - .saturating_add(Weight::from_parts(390, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(404, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -239,8 +239,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_860_000 picoseconds. - Weight::from_parts(13_525_000, 6380) + // Minimum execution time: 13_283_000 picoseconds. + Weight::from_parts(14_015_000, 6380) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -254,8 +254,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 46_926_000 picoseconds. - Weight::from_parts(47_828_000, 6292) + // Minimum execution time: 48_022_000 picoseconds. + Weight::from_parts(49_627_000, 6292) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -267,8 +267,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 55_081_000 picoseconds. - Weight::from_parts(56_899_000, 6534) + // Minimum execution time: 58_374_000 picoseconds. + Weight::from_parts(59_615_000, 6534) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -278,8 +278,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `409` // Estimated: `6349` - // Minimum execution time: 12_595_000 picoseconds. - Weight::from_parts(13_059_000, 6349) + // Minimum execution time: 12_559_000 picoseconds. + Weight::from_parts(12_947_000, 6349) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -290,7 +290,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Measured: `142` // Estimated: `1627` // Minimum execution time: 2_480_000 picoseconds. - Weight::from_parts(2_663_000, 1627) + Weight::from_parts(2_680_000, 1627) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -302,8 +302,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 12_115_000 picoseconds. - Weight::from_parts(12_506_000, 3631) + // Minimum execution time: 12_625_000 picoseconds. + Weight::from_parts(13_094_000, 3631) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -313,8 +313,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_757_000 picoseconds. - Weight::from_parts(5_082_000, 3607) + // Minimum execution time: 4_836_000 picoseconds. + Weight::from_parts(5_182_000, 3607) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -325,8 +325,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_017_000 picoseconds. - Weight::from_parts(6_421_000, 3632) + // Minimum execution time: 6_319_000 picoseconds. + Weight::from_parts(6_582_000, 3632) .saturating_add(T::DbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -337,8 +337,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_238_000 picoseconds. - Weight::from_parts(6_587_000, 3607) + // Minimum execution time: 6_532_000 picoseconds. + Weight::from_parts(6_909_000, 3607) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -363,10 +363,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `804 + c * (1 ±0)` // Estimated: `9217 + c * (1 ±0)` - // Minimum execution time: 288_968_000 picoseconds. - Weight::from_parts(267_291_922, 9217) - // Standard Error: 78 - .saturating_add(Weight::from_parts(34_879, 0).saturating_mul(c.into())) + // Minimum execution time: 305_778_000 picoseconds. + Weight::from_parts(282_321_249, 9217) + // Standard Error: 72 + .saturating_add(Weight::from_parts(33_456, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -398,14 +398,14 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `326` // Estimated: `8740` - // Minimum execution time: 3_948_426_000 picoseconds. - Weight::from_parts(440_017_623, 8740) - // Standard Error: 555 - .saturating_add(Weight::from_parts(71_483, 0).saturating_mul(c.into())) - // Standard Error: 66 - .saturating_add(Weight::from_parts(1_831, 0).saturating_mul(i.into())) - // Standard Error: 66 - .saturating_add(Weight::from_parts(1_694, 0).saturating_mul(s.into())) + // Minimum execution time: 3_810_809_000 picoseconds. + Weight::from_parts(739_511_598, 8740) + // Standard Error: 140 + .saturating_add(Weight::from_parts(67_574, 0).saturating_mul(c.into())) + // Standard Error: 16 + .saturating_add(Weight::from_parts(1_488, 0).saturating_mul(i.into())) + // Standard Error: 16 + .saturating_add(Weight::from_parts(1_537, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } @@ -435,12 +435,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `563` // Estimated: `8982` - // Minimum execution time: 2_011_037_000 picoseconds. - Weight::from_parts(2_047_025_000, 8982) - // Standard Error: 28 - .saturating_add(Weight::from_parts(968, 0).saturating_mul(i.into())) - // Standard Error: 28 - .saturating_add(Weight::from_parts(780, 0).saturating_mul(s.into())) + // Minimum execution time: 1_986_789_000 picoseconds. + Weight::from_parts(2_017_466_000, 8982) + // Standard Error: 26 + .saturating_add(Weight::from_parts(827, 0).saturating_mul(i.into())) + // Standard Error: 26 + .saturating_add(Weight::from_parts(781, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -464,8 +464,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `829` // Estimated: `9244` - // Minimum execution time: 202_190_000 picoseconds. - Weight::from_parts(209_378_000, 9244) + // Minimum execution time: 210_724_000 picoseconds. + Weight::from_parts(218_608_000, 9244) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -486,10 +486,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `145` // Estimated: `6085` - // Minimum execution time: 271_161_000 picoseconds. - Weight::from_parts(279_218_977, 6085) - // Standard Error: 80 - .saturating_add(Weight::from_parts(33_973, 0).saturating_mul(c.into())) + // Minimum execution time: 271_259_000 picoseconds. + Weight::from_parts(298_852_854, 6085) + // Standard Error: 65 + .saturating_add(Weight::from_parts(33_547, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -510,10 +510,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `145` // Estimated: `6085` - // Minimum execution time: 273_684_000 picoseconds. - Weight::from_parts(284_348_722, 6085) - // Standard Error: 79 - .saturating_add(Weight::from_parts(34_205, 0).saturating_mul(c.into())) + // Minimum execution time: 278_167_000 picoseconds. + Weight::from_parts(311_888_941, 6085) + // Standard Error: 58 + .saturating_add(Weight::from_parts(33_595, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -531,8 +531,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 45_150_000 picoseconds. - Weight::from_parts(46_780_000, 3780) + // Minimum execution time: 47_403_000 picoseconds. + Weight::from_parts(48_707_000, 3780) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -548,8 +548,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 34_738_000 picoseconds. - Weight::from_parts(35_918_000, 8967) + // Minimum execution time: 35_361_000 picoseconds. + Weight::from_parts(36_714_000, 8967) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -558,10 +558,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_094_000 picoseconds. - Weight::from_parts(10_253_702, 0) - // Standard Error: 223 - .saturating_add(Weight::from_parts(250_757, 0).saturating_mul(r.into())) + // Minimum execution time: 9_340_000 picoseconds. + Weight::from_parts(9_360_237, 0) + // Standard Error: 269 + .saturating_add(Weight::from_parts(249_611, 0).saturating_mul(r.into())) } /// Storage: `Contracts::ContractInfoOf` (r:1600 w:0) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) @@ -570,10 +570,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `509 + r * (77 ±0)` // Estimated: `1467 + r * (2552 ±0)` - // Minimum execution time: 9_102_000 picoseconds. - Weight::from_parts(9_238_000, 1467) - // Standard Error: 6_076 - .saturating_add(Weight::from_parts(3_293_012, 0).saturating_mul(r.into())) + // Minimum execution time: 9_059_000 picoseconds. + Weight::from_parts(9_201_000, 1467) + // Standard Error: 5_643 + .saturating_add(Weight::from_parts(3_343_859, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2552).saturating_mul(r.into())) } @@ -584,10 +584,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `517 + r * (170 ±0)` // Estimated: `1468 + r * (2645 ±0)` - // Minimum execution time: 9_255_000 picoseconds. - Weight::from_parts(9_406_000, 1468) - // Standard Error: 6_826 - .saturating_add(Weight::from_parts(4_205_039, 0).saturating_mul(r.into())) + // Minimum execution time: 9_220_000 picoseconds. + Weight::from_parts(9_399_000, 1468) + // Standard Error: 6_194 + .saturating_add(Weight::from_parts(4_172_011, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2645).saturating_mul(r.into())) } @@ -596,50 +596,50 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_388_000 picoseconds. - Weight::from_parts(9_322_209, 0) - // Standard Error: 269 - .saturating_add(Weight::from_parts(358_189, 0).saturating_mul(r.into())) + // Minimum execution time: 9_707_000 picoseconds. + Weight::from_parts(10_100_456, 0) + // Standard Error: 234 + .saturating_add(Weight::from_parts(338_464, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_origin(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_300_000 picoseconds. - Weight::from_parts(10_268_326, 0) - // Standard Error: 72 - .saturating_add(Weight::from_parts(104_650, 0).saturating_mul(r.into())) + // Minimum execution time: 9_524_000 picoseconds. + Weight::from_parts(10_813_389, 0) + // Standard Error: 76 + .saturating_add(Weight::from_parts(102_535, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_root(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_162_000 picoseconds. - Weight::from_parts(10_059_984, 0) - // Standard Error: 87 - .saturating_add(Weight::from_parts(87_627, 0).saturating_mul(r.into())) + // Minimum execution time: 9_799_000 picoseconds. + Weight::from_parts(10_886_744, 0) + // Standard Error: 75 + .saturating_add(Weight::from_parts(80_901, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_address(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_193_000 picoseconds. - Weight::from_parts(10_160_715, 0) - // Standard Error: 152 - .saturating_add(Weight::from_parts(263_703, 0).saturating_mul(r.into())) + // Minimum execution time: 9_895_000 picoseconds. + Weight::from_parts(10_658_338, 0) + // Standard Error: 189 + .saturating_add(Weight::from_parts(249_694, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_gas_left(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_109_000 picoseconds. - Weight::from_parts(9_766_924, 0) - // Standard Error: 212 - .saturating_add(Weight::from_parts(291_694, 0).saturating_mul(r.into())) + // Minimum execution time: 9_643_000 picoseconds. + Weight::from_parts(10_932_126, 0) + // Standard Error: 153 + .saturating_add(Weight::from_parts(280_924, 0).saturating_mul(r.into())) } /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) @@ -648,10 +648,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `140` // Estimated: `3599` - // Minimum execution time: 9_463_000 picoseconds. - Weight::from_parts(9_541_000, 3599) - // Standard Error: 3_075 - .saturating_add(Weight::from_parts(1_606_043, 0).saturating_mul(r.into())) + // Minimum execution time: 9_548_000 picoseconds. + Weight::from_parts(9_737_000, 3599) + // Standard Error: 971 + .saturating_add(Weight::from_parts(1_704_134, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -659,40 +659,40 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_080_000 picoseconds. - Weight::from_parts(8_121_924, 0) - // Standard Error: 198 - .saturating_add(Weight::from_parts(247_527, 0).saturating_mul(r.into())) + // Minimum execution time: 9_172_000 picoseconds. + Weight::from_parts(18_255_933, 0) + // Standard Error: 540 + .saturating_add(Weight::from_parts(230_929, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_minimum_balance(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_393_000 picoseconds. - Weight::from_parts(9_999_247, 0) - // Standard Error: 169 - .saturating_add(Weight::from_parts(244_563, 0).saturating_mul(r.into())) + // Minimum execution time: 9_232_000 picoseconds. + Weight::from_parts(9_796_584, 0) + // Standard Error: 208 + .saturating_add(Weight::from_parts(239_962, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_block_number(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_236_000 picoseconds. - Weight::from_parts(9_561_435, 0) - // Standard Error: 195 - .saturating_add(Weight::from_parts(239_812, 0).saturating_mul(r.into())) + // Minimum execution time: 9_747_000 picoseconds. + Weight::from_parts(8_733_230, 0) + // Standard Error: 377 + .saturating_add(Weight::from_parts(253_801, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_now(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_259_000 picoseconds. - Weight::from_parts(10_353_960, 0) - // Standard Error: 216 - .saturating_add(Weight::from_parts(243_754, 0).saturating_mul(r.into())) + // Minimum execution time: 9_214_000 picoseconds. + Weight::from_parts(10_194_153, 0) + // Standard Error: 516 + .saturating_add(Weight::from_parts(247_621, 0).saturating_mul(r.into())) } /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) @@ -701,10 +701,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `67` // Estimated: `1552` - // Minimum execution time: 9_145_000 picoseconds. - Weight::from_parts(16_524_937, 1552) - // Standard Error: 438 - .saturating_add(Weight::from_parts(666_821, 0).saturating_mul(r.into())) + // Minimum execution time: 9_022_000 picoseconds. + Weight::from_parts(22_051_160, 1552) + // Standard Error: 697 + .saturating_add(Weight::from_parts(709_612, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -712,10 +712,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_179_000 picoseconds. - Weight::from_parts(8_893_261, 0) - // Standard Error: 215 - .saturating_add(Weight::from_parts(175_586, 0).saturating_mul(r.into())) + // Minimum execution time: 9_135_000 picoseconds. + Weight::from_parts(10_646_215, 0) + // Standard Error: 161 + .saturating_add(Weight::from_parts(170_336, 0).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) @@ -738,10 +738,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `872` // Estimated: `9287` - // Minimum execution time: 259_315_000 picoseconds. - Weight::from_parts(137_461_362, 9287) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_388, 0).saturating_mul(n.into())) + // Minimum execution time: 273_896_000 picoseconds. + Weight::from_parts(148_309_654, 9287) + // Standard Error: 16 + .saturating_add(Weight::from_parts(1_355, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -750,20 +750,20 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_919_000 picoseconds. - Weight::from_parts(9_465_187, 0) - // Standard Error: 32_481 - .saturating_add(Weight::from_parts(992_912, 0).saturating_mul(r.into())) + // Minimum execution time: 8_906_000 picoseconds. + Weight::from_parts(9_264_446, 0) + // Standard Error: 19_760 + .saturating_add(Weight::from_parts(1_256_053, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_return_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_244_000 picoseconds. - Weight::from_parts(10_654_989, 0) + // Minimum execution time: 10_266_000 picoseconds. + Weight::from_parts(10_602_261, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(315, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(318, 0).saturating_mul(n.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) @@ -792,10 +792,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `4805 + r * (2121 ±0)` // Estimated: `13220 + r * (81321 ±0)` - // Minimum execution time: 303_028_000 picoseconds. - Weight::from_parts(323_032_397, 13220) - // Standard Error: 848_406 - .saturating_add(Weight::from_parts(242_988_002, 0).saturating_mul(r.into())) + // Minimum execution time: 295_922_000 picoseconds. + Weight::from_parts(322_472_877, 13220) + // Standard Error: 993_812 + .saturating_add(Weight::from_parts(259_075_422, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().reads((36_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) @@ -809,10 +809,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1561` - // Minimum execution time: 9_227_000 picoseconds. - Weight::from_parts(14_055_283, 1561) - // Standard Error: 758 - .saturating_add(Weight::from_parts(1_104_996, 0).saturating_mul(r.into())) + // Minimum execution time: 9_427_000 picoseconds. + Weight::from_parts(12_996_213, 1561) + // Standard Error: 845 + .saturating_add(Weight::from_parts(1_182_642, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -820,10 +820,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_483_000 picoseconds. - Weight::from_parts(20_453_059, 0) - // Standard Error: 3_271 - .saturating_add(Weight::from_parts(1_713_468, 0).saturating_mul(r.into())) + // Minimum execution time: 9_304_000 picoseconds. + Weight::from_parts(25_678_842, 0) + // Standard Error: 1_855 + .saturating_add(Weight::from_parts(1_814_511, 0).saturating_mul(r.into())) } /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -833,12 +833,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `990 + t * (2475 ±0)` - // Minimum execution time: 23_517_000 picoseconds. - Weight::from_parts(15_543_153, 990) - // Standard Error: 13_814 - .saturating_add(Weight::from_parts(2_357_255, 0).saturating_mul(t.into())) - // Standard Error: 3 - .saturating_add(Weight::from_parts(573, 0).saturating_mul(n.into())) + // Minimum execution time: 23_425_000 picoseconds. + Weight::from_parts(15_229_010, 990) + // Standard Error: 14_380 + .saturating_add(Weight::from_parts(2_545_653, 0).saturating_mul(t.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(594, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(t.into()))) .saturating_add(Weight::from_parts(0, 2475).saturating_mul(t.into())) @@ -848,20 +848,20 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_448_000 picoseconds. - Weight::from_parts(9_845_841, 0) - // Standard Error: 58 - .saturating_add(Weight::from_parts(105_442, 0).saturating_mul(r.into())) + // Minimum execution time: 11_117_000 picoseconds. + Weight::from_parts(12_887_533, 0) + // Standard Error: 83 + .saturating_add(Weight::from_parts(99_373, 0).saturating_mul(r.into())) } /// The range of component `i` is `[0, 1048576]`. fn seal_debug_message_per_byte(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_869_000 picoseconds. - Weight::from_parts(11_024_000, 0) + // Minimum execution time: 10_982_000 picoseconds. + Weight::from_parts(11_176_000, 0) // Standard Error: 8 - .saturating_add(Weight::from_parts(991, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(983, 0).saturating_mul(i.into())) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -870,10 +870,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_119_000 picoseconds. - Weight::from_parts(9_270_000, 105) - // Standard Error: 8_960 - .saturating_add(Weight::from_parts(5_215_976, 0).saturating_mul(r.into())) + // Minimum execution time: 9_150_000 picoseconds. + Weight::from_parts(9_269_000, 105) + // Standard Error: 8_147 + .saturating_add(Weight::from_parts(5_339_554, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) @@ -885,10 +885,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `245` // Estimated: `245` - // Minimum execution time: 17_833_000 picoseconds. - Weight::from_parts(18_940_114, 245) - // Standard Error: 2 - .saturating_add(Weight::from_parts(316, 0).saturating_mul(n.into())) + // Minimum execution time: 19_085_000 picoseconds. + Weight::from_parts(20_007_323, 245) + // Standard Error: 3 + .saturating_add(Weight::from_parts(291, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -899,10 +899,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 18_428_000 picoseconds. - Weight::from_parts(19_372_726, 248) - // Standard Error: 2 - .saturating_add(Weight::from_parts(85, 0).saturating_mul(n.into())) + // Minimum execution time: 19_127_000 picoseconds. + Weight::from_parts(21_152_987, 248) + // Standard Error: 3 + .saturating_add(Weight::from_parts(42, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -914,10 +914,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_335_000 picoseconds. - Weight::from_parts(9_459_000, 105) - // Standard Error: 9_156 - .saturating_add(Weight::from_parts(5_166_621, 0).saturating_mul(r.into())) + // Minimum execution time: 9_264_000 picoseconds. + Weight::from_parts(9_449_000, 105) + // Standard Error: 8_196 + .saturating_add(Weight::from_parts(5_325_578, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) @@ -929,10 +929,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 18_308_000 picoseconds. - Weight::from_parts(19_421_433, 248) + // Minimum execution time: 18_489_000 picoseconds. + Weight::from_parts(19_916_153, 248) // Standard Error: 2 - .saturating_add(Weight::from_parts(83, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(97, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -944,10 +944,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_184_000 picoseconds. - Weight::from_parts(9_245_000, 105) - // Standard Error: 8_442 - .saturating_add(Weight::from_parts(4_543_991, 0).saturating_mul(r.into())) + // Minimum execution time: 9_299_000 picoseconds. + Weight::from_parts(9_464_000, 105) + // Standard Error: 6_827 + .saturating_add(Weight::from_parts(4_720_699, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) } @@ -958,10 +958,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 17_194_000 picoseconds. - Weight::from_parts(19_032_094, 248) + // Minimum execution time: 17_981_000 picoseconds. + Weight::from_parts(19_802_353, 248) // Standard Error: 3 - .saturating_add(Weight::from_parts(590, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(617, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -972,10 +972,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_380_000 picoseconds. - Weight::from_parts(9_501_000, 105) - // Standard Error: 7_029 - .saturating_add(Weight::from_parts(4_406_690, 0).saturating_mul(r.into())) + // Minimum execution time: 9_891_000 picoseconds. + Weight::from_parts(10_046_000, 105) + // Standard Error: 6_993 + .saturating_add(Weight::from_parts(4_601_167, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) } @@ -986,10 +986,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 16_400_000 picoseconds. - Weight::from_parts(17_993_941, 248) + // Minimum execution time: 17_229_000 picoseconds. + Weight::from_parts(18_302_733, 248) // Standard Error: 2 - .saturating_add(Weight::from_parts(68, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(112, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -1000,10 +1000,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_109_000 picoseconds. - Weight::from_parts(9_265_000, 105) - // Standard Error: 8_733 - .saturating_add(Weight::from_parts(5_218_811, 0).saturating_mul(r.into())) + // Minimum execution time: 9_323_000 picoseconds. + Weight::from_parts(9_462_000, 105) + // Standard Error: 8_031 + .saturating_add(Weight::from_parts(5_433_981, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) @@ -1015,10 +1015,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 18_423_000 picoseconds. - Weight::from_parts(20_025_132, 248) + // Minimum execution time: 18_711_000 picoseconds. + Weight::from_parts(20_495_670, 248) // Standard Error: 3 - .saturating_add(Weight::from_parts(628, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(640, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -1030,10 +1030,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `770` // Estimated: `4221 + r * (2475 ±0)` - // Minimum execution time: 9_043_000 picoseconds. - Weight::from_parts(9_176_000, 4221) - // Standard Error: 12_901 - .saturating_add(Weight::from_parts(32_297_438, 0).saturating_mul(r.into())) + // Minimum execution time: 9_226_000 picoseconds. + Weight::from_parts(9_394_000, 4221) + // Standard Error: 14_741 + .saturating_add(Weight::from_parts(34_179_316, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(1_u64)) @@ -1055,10 +1055,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `520 + r * (170 ±0)` // Estimated: `6463 + r * (2646 ±0)` - // Minimum execution time: 9_299_000 picoseconds. - Weight::from_parts(9_427_000, 6463) - // Standard Error: 101_949 - .saturating_add(Weight::from_parts(244_143_691, 0).saturating_mul(r.into())) + // Minimum execution time: 9_455_000 picoseconds. + Weight::from_parts(9_671_000, 6463) + // Standard Error: 126_080 + .saturating_add(Weight::from_parts(244_204_040, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(2_u64)) @@ -1079,11 +1079,11 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { fn seal_delegate_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (527 ±0)` - // Estimated: `6447 + r * (2583 ±3)` - // Minimum execution time: 9_359_000 picoseconds. - Weight::from_parts(9_425_000, 6447) - // Standard Error: 193_938 - .saturating_add(Weight::from_parts(244_904_401, 0).saturating_mul(r.into())) + // Estimated: `6447 + r * (2583 ±10)` + // Minimum execution time: 9_274_000 picoseconds. + Weight::from_parts(9_437_000, 6447) + // Standard Error: 150_832 + .saturating_add(Weight::from_parts(244_196_269, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2583).saturating_mul(r.into())) @@ -1106,12 +1106,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `699 + t * (277 ±0)` // Estimated: `6639 + t * (3458 ±0)` - // Minimum execution time: 214_588_000 picoseconds. - Weight::from_parts(129_214_481, 6639) - // Standard Error: 2_468_090 - .saturating_add(Weight::from_parts(32_514_739, 0).saturating_mul(t.into())) + // Minimum execution time: 214_483_000 picoseconds. + Weight::from_parts(122_634_366, 6639) + // Standard Error: 2_499_235 + .saturating_add(Weight::from_parts(41_326_008, 0).saturating_mul(t.into())) // Standard Error: 3 - .saturating_add(Weight::from_parts(418, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(422, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(7_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1126,10 +1126,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:800 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:802 w:802) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::EventTopics` (r:801 w:801) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `r` is `[1, 800]`. @@ -1137,10 +1137,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `1097 + r * (188 ±0)` // Estimated: `6990 + r * (2664 ±0)` - // Minimum execution time: 352_925_000 picoseconds. - Weight::from_parts(355_487_000, 6990) - // Standard Error: 261_528 - .saturating_add(Weight::from_parts(337_897_187, 0).saturating_mul(r.into())) + // Minimum execution time: 341_569_000 picoseconds. + Weight::from_parts(360_574_000, 6990) + // Standard Error: 259_746 + .saturating_add(Weight::from_parts(337_944_674, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) @@ -1155,10 +1155,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[0, 1]`. @@ -1168,12 +1168,14 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `760 + t * (104 ±0)` // Estimated: `6719 + t * (2549 ±1)` - // Minimum execution time: 1_870_832_000 picoseconds. - Weight::from_parts(949_110_245, 6719) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_084, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(s.into())) + // Minimum execution time: 1_863_119_000 picoseconds. + Weight::from_parts(900_189_174, 6719) + // Standard Error: 13_040_979 + .saturating_add(Weight::from_parts(4_056_063, 0).saturating_mul(t.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_028, 0).saturating_mul(i.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_173, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(T::DbWeight::get().writes(7_u64)) @@ -1185,58 +1187,58 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_142_000 picoseconds. - Weight::from_parts(9_787_220, 0) - // Standard Error: 236 - .saturating_add(Weight::from_parts(267_264, 0).saturating_mul(r.into())) + // Minimum execution time: 9_211_000 picoseconds. + Weight::from_parts(11_696_412, 0) + // Standard Error: 388 + .saturating_add(Weight::from_parts(265_538, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_sha2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_485_000 picoseconds. - Weight::from_parts(1_870_250, 0) + // Minimum execution time: 10_296_000 picoseconds. + Weight::from_parts(572_494, 0) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_073, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_067, 0).saturating_mul(n.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_hash_keccak_256(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_005_000 picoseconds. - Weight::from_parts(8_943_937, 0) - // Standard Error: 1_385 - .saturating_add(Weight::from_parts(665_970, 0).saturating_mul(r.into())) + // Minimum execution time: 9_177_000 picoseconds. + Weight::from_parts(8_620_481, 0) + // Standard Error: 249 + .saturating_add(Weight::from_parts(674_502, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_keccak_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_965_000 picoseconds. - Weight::from_parts(11_749_746, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(3_330, 0).saturating_mul(n.into())) + // Minimum execution time: 11_240_000 picoseconds. + Weight::from_parts(8_696_186, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_328, 0).saturating_mul(n.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_hash_blake2_256(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_400_000 picoseconds. - Weight::from_parts(13_857_546, 0) - // Standard Error: 246 - .saturating_add(Weight::from_parts(326_483, 0).saturating_mul(r.into())) + // Minimum execution time: 9_889_000 picoseconds. + Weight::from_parts(16_103_170, 0) + // Standard Error: 343 + .saturating_add(Weight::from_parts(328_939, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_064_000 picoseconds. - Weight::from_parts(1_885_873, 0) + // Minimum execution time: 10_405_000 picoseconds. + Weight::from_parts(2_264_024, 0) // Standard Error: 0 .saturating_add(Weight::from_parts(1_196, 0).saturating_mul(n.into())) } @@ -1245,60 +1247,60 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_068_000 picoseconds. - Weight::from_parts(17_169_362, 0) - // Standard Error: 1_580 - .saturating_add(Weight::from_parts(330_195, 0).saturating_mul(r.into())) + // Minimum execution time: 9_215_000 picoseconds. + Weight::from_parts(10_505_632, 0) + // Standard Error: 240 + .saturating_add(Weight::from_parts(324_854, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_128_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_169_000 picoseconds. - Weight::from_parts(2_159_277, 0) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_200, 0).saturating_mul(n.into())) + // Minimum execution time: 10_440_000 picoseconds. + Weight::from_parts(2_575_889, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_199, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 125697]`. fn seal_sr25519_verify_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 53_863_000 picoseconds. - Weight::from_parts(54_902_157, 0) - // Standard Error: 9 - .saturating_add(Weight::from_parts(4_588, 0).saturating_mul(n.into())) + // Minimum execution time: 55_119_000 picoseconds. + Weight::from_parts(56_732_248, 0) + // Standard Error: 8 + .saturating_add(Weight::from_parts(4_639, 0).saturating_mul(n.into())) } /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_107_000 picoseconds. - Weight::from_parts(24_115_247, 0) - // Standard Error: 7_427 - .saturating_add(Weight::from_parts(41_116_827, 0).saturating_mul(r.into())) + // Minimum execution time: 9_176_000 picoseconds. + Weight::from_parts(9_861_102, 0) + // Standard Error: 6_029 + .saturating_add(Weight::from_parts(45_948_571, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_404_000 picoseconds. - Weight::from_parts(31_763_334, 0) - // Standard Error: 9_833 - .saturating_add(Weight::from_parts(45_529_880, 0).saturating_mul(r.into())) + // Minimum execution time: 9_293_000 picoseconds. + Weight::from_parts(28_785_765, 0) + // Standard Error: 9_160 + .saturating_add(Weight::from_parts(45_566_150, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_409_000 picoseconds. - Weight::from_parts(15_072_835, 0) - // Standard Error: 4_591 - .saturating_add(Weight::from_parts(11_619_283, 0).saturating_mul(r.into())) + // Minimum execution time: 9_206_000 picoseconds. + Weight::from_parts(12_420_664, 0) + // Standard Error: 3_489 + .saturating_add(Weight::from_parts(11_628_989, 0).saturating_mul(r.into())) } /// Storage: `Contracts::CodeInfoOf` (r:1536 w:1536) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) @@ -1312,11 +1314,11 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (926 ±0)` - // Estimated: `8969 + r * (3047 ±10)` - // Minimum execution time: 9_269_000 picoseconds. - Weight::from_parts(9_372_000, 8969) - // Standard Error: 61_354 - .saturating_add(Weight::from_parts(26_280_409, 0).saturating_mul(r.into())) + // Estimated: `8969 + r * (3047 ±7)` + // Minimum execution time: 9_219_000 picoseconds. + Weight::from_parts(9_385_000, 8969) + // Standard Error: 45_562 + .saturating_add(Weight::from_parts(26_360_661, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 3047).saturating_mul(r.into())) @@ -1328,10 +1330,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `274 + r * (78 ±0)` // Estimated: `1265 + r * (2553 ±0)` - // Minimum execution time: 9_103_000 picoseconds. - Weight::from_parts(14_404_626, 1265) - // Standard Error: 9_343 - .saturating_add(Weight::from_parts(5_154_949, 0).saturating_mul(r.into())) + // Minimum execution time: 9_355_000 picoseconds. + Weight::from_parts(15_071_309, 1265) + // Standard Error: 9_722 + .saturating_add(Weight::from_parts(5_328_717, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2553).saturating_mul(r.into())) @@ -1343,10 +1345,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `275 + r * (78 ±0)` // Estimated: `990 + r * (2568 ±0)` - // Minimum execution time: 9_219_000 picoseconds. - Weight::from_parts(14_085_456, 990) - // Standard Error: 11_206 - .saturating_add(Weight::from_parts(4_422_122, 0).saturating_mul(r.into())) + // Minimum execution time: 8_979_000 picoseconds. + Weight::from_parts(14_362_224, 990) + // Standard Error: 9_137 + .saturating_add(Weight::from_parts(4_488_748, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2568).saturating_mul(r.into())) @@ -1372,10 +1374,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `9282 + r * (3 ±0)` - // Minimum execution time: 269_333_000 picoseconds. - Weight::from_parts(286_922_618, 9282) - // Standard Error: 443 - .saturating_add(Weight::from_parts(168_869, 0).saturating_mul(r.into())) + // Minimum execution time: 269_704_000 picoseconds. + Weight::from_parts(289_916_035, 9282) + // Standard Error: 408 + .saturating_add(Weight::from_parts(166_040, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -1385,10 +1387,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_328_000 picoseconds. - Weight::from_parts(14_019_583, 0) - // Standard Error: 171 - .saturating_add(Weight::from_parts(88_751, 0).saturating_mul(r.into())) + // Minimum execution time: 9_361_000 picoseconds. + Weight::from_parts(11_633_836, 0) + // Standard Error: 86 + .saturating_add(Weight::from_parts(83_083, 0).saturating_mul(r.into())) } /// Storage: `Contracts::Nonce` (r:1 w:0) /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) @@ -1397,10 +1399,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `219` // Estimated: `1704` - // Minimum execution time: 9_267_000 picoseconds. - Weight::from_parts(15_304_284, 1704) - // Standard Error: 1_219 - .saturating_add(Weight::from_parts(74_696, 0).saturating_mul(r.into())) + // Minimum execution time: 9_133_000 picoseconds. + Weight::from_parts(13_259_836, 1704) + // Standard Error: 121 + .saturating_add(Weight::from_parts(76_878, 0).saturating_mul(r.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 5000]`. @@ -1408,10 +1410,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 911_000 picoseconds. - Weight::from_parts(449_666, 0) - // Standard Error: 26 - .saturating_add(Weight::from_parts(14_797, 0).saturating_mul(r.into())) + // Minimum execution time: 851_000 picoseconds. + Weight::from_parts(587_883, 0) + // Standard Error: 16 + .saturating_add(Weight::from_parts(14_912, 0).saturating_mul(r.into())) } } @@ -1423,8 +1425,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `1627` - // Minimum execution time: 2_047_000 picoseconds. - Weight::from_parts(2_116_000, 1627) + // Minimum execution time: 2_149_000 picoseconds. + Weight::from_parts(2_274_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Skipped::Metadata` (r:0 w:0) @@ -1434,10 +1436,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `452 + k * (69 ±0)` // Estimated: `442 + k * (70 ±0)` - // Minimum execution time: 12_474_000 picoseconds. - Weight::from_parts(12_767_000, 442) - // Standard Error: 1_081 - .saturating_add(Weight::from_parts(1_187_278, 0).saturating_mul(k.into())) + // Minimum execution time: 12_863_000 picoseconds. + Weight::from_parts(13_188_000, 442) + // Standard Error: 1_053 + .saturating_add(Weight::from_parts(1_105_325, 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)) @@ -1451,10 +1453,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `211 + c * (1 ±0)` // Estimated: `6149 + c * (1 ±0)` - // Minimum execution time: 8_307_000 picoseconds. - Weight::from_parts(8_939_322, 6149) + // Minimum execution time: 8_432_000 picoseconds. + Weight::from_parts(9_203_290, 6149) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_190, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(1_186, 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())) @@ -1467,8 +1469,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `510` // Estimated: `6450` - // Minimum execution time: 16_915_000 picoseconds. - Weight::from_parts(17_638_000, 6450) + // Minimum execution time: 17_177_000 picoseconds. + Weight::from_parts(17_663_000, 6450) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1481,10 +1483,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `171 + k * (1 ±0)` // Estimated: `3635 + k * (1 ±0)` - // Minimum execution time: 3_607_000 picoseconds. - Weight::from_parts(1_979_323, 3635) - // Standard Error: 1_018 - .saturating_add(Weight::from_parts(1_196_162, 0).saturating_mul(k.into())) + // Minimum execution time: 3_636_000 picoseconds. + Weight::from_parts(3_774_000, 3635) + // Standard Error: 542 + .saturating_add(Weight::from_parts(1_260_058, 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()))) @@ -1505,10 +1507,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `328 + c * (1 ±0)` // Estimated: `6266 + c * (1 ±0)` - // Minimum execution time: 21_056_000 picoseconds. - Weight::from_parts(21_633_895, 6266) + // Minimum execution time: 21_585_000 picoseconds. + Weight::from_parts(22_069_944, 6266) // Standard Error: 1 - .saturating_add(Weight::from_parts(390, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(404, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -1519,8 +1521,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `440` // Estimated: `6380` - // Minimum execution time: 12_860_000 picoseconds. - Weight::from_parts(13_525_000, 6380) + // Minimum execution time: 13_283_000 picoseconds. + Weight::from_parts(14_015_000, 6380) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1534,8 +1536,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `352` // Estimated: `6292` - // Minimum execution time: 46_926_000 picoseconds. - Weight::from_parts(47_828_000, 6292) + // Minimum execution time: 48_022_000 picoseconds. + Weight::from_parts(49_627_000, 6292) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1547,8 +1549,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `594` // Estimated: `6534` - // Minimum execution time: 55_081_000 picoseconds. - Weight::from_parts(56_899_000, 6534) + // Minimum execution time: 58_374_000 picoseconds. + Weight::from_parts(59_615_000, 6534) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1558,8 +1560,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `409` // Estimated: `6349` - // Minimum execution time: 12_595_000 picoseconds. - Weight::from_parts(13_059_000, 6349) + // Minimum execution time: 12_559_000 picoseconds. + Weight::from_parts(12_947_000, 6349) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1570,7 +1572,7 @@ impl WeightInfo for () { // Measured: `142` // Estimated: `1627` // Minimum execution time: 2_480_000 picoseconds. - Weight::from_parts(2_663_000, 1627) + Weight::from_parts(2_680_000, 1627) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1582,8 +1584,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `166` // Estimated: `3631` - // Minimum execution time: 12_115_000 picoseconds. - Weight::from_parts(12_506_000, 3631) + // Minimum execution time: 12_625_000 picoseconds. + Weight::from_parts(13_094_000, 3631) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -1593,8 +1595,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 4_757_000 picoseconds. - Weight::from_parts(5_082_000, 3607) + // Minimum execution time: 4_836_000 picoseconds. + Weight::from_parts(5_182_000, 3607) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -1605,8 +1607,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `167` // Estimated: `3632` - // Minimum execution time: 6_017_000 picoseconds. - Weight::from_parts(6_421_000, 3632) + // Minimum execution time: 6_319_000 picoseconds. + Weight::from_parts(6_582_000, 3632) .saturating_add(RocksDbWeight::get().reads(2_u64)) } /// Storage: UNKNOWN KEY `0x4342193e496fab7ec59d615ed0dc55304e7b9012096b41c4eb3aaf947f6ea429` (r:1 w:0) @@ -1617,8 +1619,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `142` // Estimated: `3607` - // Minimum execution time: 6_238_000 picoseconds. - Weight::from_parts(6_587_000, 3607) + // Minimum execution time: 6_532_000 picoseconds. + Weight::from_parts(6_909_000, 3607) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1643,10 +1645,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `804 + c * (1 ±0)` // Estimated: `9217 + c * (1 ±0)` - // Minimum execution time: 288_968_000 picoseconds. - Weight::from_parts(267_291_922, 9217) - // Standard Error: 78 - .saturating_add(Weight::from_parts(34_879, 0).saturating_mul(c.into())) + // Minimum execution time: 305_778_000 picoseconds. + Weight::from_parts(282_321_249, 9217) + // Standard Error: 72 + .saturating_add(Weight::from_parts(33_456, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(c.into())) @@ -1678,14 +1680,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `326` // Estimated: `8740` - // Minimum execution time: 3_948_426_000 picoseconds. - Weight::from_parts(440_017_623, 8740) - // Standard Error: 555 - .saturating_add(Weight::from_parts(71_483, 0).saturating_mul(c.into())) - // Standard Error: 66 - .saturating_add(Weight::from_parts(1_831, 0).saturating_mul(i.into())) - // Standard Error: 66 - .saturating_add(Weight::from_parts(1_694, 0).saturating_mul(s.into())) + // Minimum execution time: 3_810_809_000 picoseconds. + Weight::from_parts(739_511_598, 8740) + // Standard Error: 140 + .saturating_add(Weight::from_parts(67_574, 0).saturating_mul(c.into())) + // Standard Error: 16 + .saturating_add(Weight::from_parts(1_488, 0).saturating_mul(i.into())) + // Standard Error: 16 + .saturating_add(Weight::from_parts(1_537, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } @@ -1715,12 +1717,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `563` // Estimated: `8982` - // Minimum execution time: 2_011_037_000 picoseconds. - Weight::from_parts(2_047_025_000, 8982) - // Standard Error: 28 - .saturating_add(Weight::from_parts(968, 0).saturating_mul(i.into())) - // Standard Error: 28 - .saturating_add(Weight::from_parts(780, 0).saturating_mul(s.into())) + // Minimum execution time: 1_986_789_000 picoseconds. + Weight::from_parts(2_017_466_000, 8982) + // Standard Error: 26 + .saturating_add(Weight::from_parts(827, 0).saturating_mul(i.into())) + // Standard Error: 26 + .saturating_add(Weight::from_parts(781, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -1744,8 +1746,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `829` // Estimated: `9244` - // Minimum execution time: 202_190_000 picoseconds. - Weight::from_parts(209_378_000, 9244) + // Minimum execution time: 210_724_000 picoseconds. + Weight::from_parts(218_608_000, 9244) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -1766,10 +1768,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `145` // Estimated: `6085` - // Minimum execution time: 271_161_000 picoseconds. - Weight::from_parts(279_218_977, 6085) - // Standard Error: 80 - .saturating_add(Weight::from_parts(33_973, 0).saturating_mul(c.into())) + // Minimum execution time: 271_259_000 picoseconds. + Weight::from_parts(298_852_854, 6085) + // Standard Error: 65 + .saturating_add(Weight::from_parts(33_547, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -1790,10 +1792,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `145` // Estimated: `6085` - // Minimum execution time: 273_684_000 picoseconds. - Weight::from_parts(284_348_722, 6085) - // Standard Error: 79 - .saturating_add(Weight::from_parts(34_205, 0).saturating_mul(c.into())) + // Minimum execution time: 278_167_000 picoseconds. + Weight::from_parts(311_888_941, 6085) + // Standard Error: 58 + .saturating_add(Weight::from_parts(33_595, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -1811,8 +1813,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `315` // Estimated: `3780` - // Minimum execution time: 45_150_000 picoseconds. - Weight::from_parts(46_780_000, 3780) + // Minimum execution time: 47_403_000 picoseconds. + Weight::from_parts(48_707_000, 3780) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -1828,8 +1830,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `552` // Estimated: `8967` - // Minimum execution time: 34_738_000 picoseconds. - Weight::from_parts(35_918_000, 8967) + // Minimum execution time: 35_361_000 picoseconds. + Weight::from_parts(36_714_000, 8967) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1838,10 +1840,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_094_000 picoseconds. - Weight::from_parts(10_253_702, 0) - // Standard Error: 223 - .saturating_add(Weight::from_parts(250_757, 0).saturating_mul(r.into())) + // Minimum execution time: 9_340_000 picoseconds. + Weight::from_parts(9_360_237, 0) + // Standard Error: 269 + .saturating_add(Weight::from_parts(249_611, 0).saturating_mul(r.into())) } /// Storage: `Contracts::ContractInfoOf` (r:1600 w:0) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) @@ -1850,10 +1852,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `509 + r * (77 ±0)` // Estimated: `1467 + r * (2552 ±0)` - // Minimum execution time: 9_102_000 picoseconds. - Weight::from_parts(9_238_000, 1467) - // Standard Error: 6_076 - .saturating_add(Weight::from_parts(3_293_012, 0).saturating_mul(r.into())) + // Minimum execution time: 9_059_000 picoseconds. + Weight::from_parts(9_201_000, 1467) + // Standard Error: 5_643 + .saturating_add(Weight::from_parts(3_343_859, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2552).saturating_mul(r.into())) } @@ -1864,10 +1866,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `517 + r * (170 ±0)` // Estimated: `1468 + r * (2645 ±0)` - // Minimum execution time: 9_255_000 picoseconds. - Weight::from_parts(9_406_000, 1468) - // Standard Error: 6_826 - .saturating_add(Weight::from_parts(4_205_039, 0).saturating_mul(r.into())) + // Minimum execution time: 9_220_000 picoseconds. + Weight::from_parts(9_399_000, 1468) + // Standard Error: 6_194 + .saturating_add(Weight::from_parts(4_172_011, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2645).saturating_mul(r.into())) } @@ -1876,50 +1878,50 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_388_000 picoseconds. - Weight::from_parts(9_322_209, 0) - // Standard Error: 269 - .saturating_add(Weight::from_parts(358_189, 0).saturating_mul(r.into())) + // Minimum execution time: 9_707_000 picoseconds. + Weight::from_parts(10_100_456, 0) + // Standard Error: 234 + .saturating_add(Weight::from_parts(338_464, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_origin(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_300_000 picoseconds. - Weight::from_parts(10_268_326, 0) - // Standard Error: 72 - .saturating_add(Weight::from_parts(104_650, 0).saturating_mul(r.into())) + // Minimum execution time: 9_524_000 picoseconds. + Weight::from_parts(10_813_389, 0) + // Standard Error: 76 + .saturating_add(Weight::from_parts(102_535, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_caller_is_root(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_162_000 picoseconds. - Weight::from_parts(10_059_984, 0) - // Standard Error: 87 - .saturating_add(Weight::from_parts(87_627, 0).saturating_mul(r.into())) + // Minimum execution time: 9_799_000 picoseconds. + Weight::from_parts(10_886_744, 0) + // Standard Error: 75 + .saturating_add(Weight::from_parts(80_901, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_address(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_193_000 picoseconds. - Weight::from_parts(10_160_715, 0) - // Standard Error: 152 - .saturating_add(Weight::from_parts(263_703, 0).saturating_mul(r.into())) + // Minimum execution time: 9_895_000 picoseconds. + Weight::from_parts(10_658_338, 0) + // Standard Error: 189 + .saturating_add(Weight::from_parts(249_694, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_gas_left(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_109_000 picoseconds. - Weight::from_parts(9_766_924, 0) - // Standard Error: 212 - .saturating_add(Weight::from_parts(291_694, 0).saturating_mul(r.into())) + // Minimum execution time: 9_643_000 picoseconds. + Weight::from_parts(10_932_126, 0) + // Standard Error: 153 + .saturating_add(Weight::from_parts(280_924, 0).saturating_mul(r.into())) } /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) @@ -1928,10 +1930,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `140` // Estimated: `3599` - // Minimum execution time: 9_463_000 picoseconds. - Weight::from_parts(9_541_000, 3599) - // Standard Error: 3_075 - .saturating_add(Weight::from_parts(1_606_043, 0).saturating_mul(r.into())) + // Minimum execution time: 9_548_000 picoseconds. + Weight::from_parts(9_737_000, 3599) + // Standard Error: 971 + .saturating_add(Weight::from_parts(1_704_134, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -1939,40 +1941,40 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_080_000 picoseconds. - Weight::from_parts(8_121_924, 0) - // Standard Error: 198 - .saturating_add(Weight::from_parts(247_527, 0).saturating_mul(r.into())) + // Minimum execution time: 9_172_000 picoseconds. + Weight::from_parts(18_255_933, 0) + // Standard Error: 540 + .saturating_add(Weight::from_parts(230_929, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_minimum_balance(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_393_000 picoseconds. - Weight::from_parts(9_999_247, 0) - // Standard Error: 169 - .saturating_add(Weight::from_parts(244_563, 0).saturating_mul(r.into())) + // Minimum execution time: 9_232_000 picoseconds. + Weight::from_parts(9_796_584, 0) + // Standard Error: 208 + .saturating_add(Weight::from_parts(239_962, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_block_number(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_236_000 picoseconds. - Weight::from_parts(9_561_435, 0) - // Standard Error: 195 - .saturating_add(Weight::from_parts(239_812, 0).saturating_mul(r.into())) + // Minimum execution time: 9_747_000 picoseconds. + Weight::from_parts(8_733_230, 0) + // Standard Error: 377 + .saturating_add(Weight::from_parts(253_801, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_now(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_259_000 picoseconds. - Weight::from_parts(10_353_960, 0) - // Standard Error: 216 - .saturating_add(Weight::from_parts(243_754, 0).saturating_mul(r.into())) + // Minimum execution time: 9_214_000 picoseconds. + Weight::from_parts(10_194_153, 0) + // Standard Error: 516 + .saturating_add(Weight::from_parts(247_621, 0).saturating_mul(r.into())) } /// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0) /// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) @@ -1981,10 +1983,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `67` // Estimated: `1552` - // Minimum execution time: 9_145_000 picoseconds. - Weight::from_parts(16_524_937, 1552) - // Standard Error: 438 - .saturating_add(Weight::from_parts(666_821, 0).saturating_mul(r.into())) + // Minimum execution time: 9_022_000 picoseconds. + Weight::from_parts(22_051_160, 1552) + // Standard Error: 697 + .saturating_add(Weight::from_parts(709_612, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -1992,10 +1994,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_179_000 picoseconds. - Weight::from_parts(8_893_261, 0) - // Standard Error: 215 - .saturating_add(Weight::from_parts(175_586, 0).saturating_mul(r.into())) + // Minimum execution time: 9_135_000 picoseconds. + Weight::from_parts(10_646_215, 0) + // Standard Error: 161 + .saturating_add(Weight::from_parts(170_336, 0).saturating_mul(r.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) @@ -2018,10 +2020,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `872` // Estimated: `9287` - // Minimum execution time: 259_315_000 picoseconds. - Weight::from_parts(137_461_362, 9287) - // Standard Error: 18 - .saturating_add(Weight::from_parts(1_388, 0).saturating_mul(n.into())) + // Minimum execution time: 273_896_000 picoseconds. + Weight::from_parts(148_309_654, 9287) + // Standard Error: 16 + .saturating_add(Weight::from_parts(1_355, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -2030,20 +2032,20 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_919_000 picoseconds. - Weight::from_parts(9_465_187, 0) - // Standard Error: 32_481 - .saturating_add(Weight::from_parts(992_912, 0).saturating_mul(r.into())) + // Minimum execution time: 8_906_000 picoseconds. + Weight::from_parts(9_264_446, 0) + // Standard Error: 19_760 + .saturating_add(Weight::from_parts(1_256_053, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_return_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_244_000 picoseconds. - Weight::from_parts(10_654_989, 0) + // Minimum execution time: 10_266_000 picoseconds. + Weight::from_parts(10_602_261, 0) // Standard Error: 0 - .saturating_add(Weight::from_parts(315, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(318, 0).saturating_mul(n.into())) } /// Storage: `Contracts::MigrationInProgress` (r:1 w:0) /// Proof: `Contracts::MigrationInProgress` (`max_values`: Some(1), `max_size`: Some(1026), added: 1521, mode: `Measured`) @@ -2072,10 +2074,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `4805 + r * (2121 ±0)` // Estimated: `13220 + r * (81321 ±0)` - // Minimum execution time: 303_028_000 picoseconds. - Weight::from_parts(323_032_397, 13220) - // Standard Error: 848_406 - .saturating_add(Weight::from_parts(242_988_002, 0).saturating_mul(r.into())) + // Minimum execution time: 295_922_000 picoseconds. + Weight::from_parts(322_472_877, 13220) + // Standard Error: 993_812 + .saturating_add(Weight::from_parts(259_075_422, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().reads((36_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(3_u64)) @@ -2089,10 +2091,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `76` // Estimated: `1561` - // Minimum execution time: 9_227_000 picoseconds. - Weight::from_parts(14_055_283, 1561) - // Standard Error: 758 - .saturating_add(Weight::from_parts(1_104_996, 0).saturating_mul(r.into())) + // Minimum execution time: 9_427_000 picoseconds. + Weight::from_parts(12_996_213, 1561) + // Standard Error: 845 + .saturating_add(Weight::from_parts(1_182_642, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 1600]`. @@ -2100,10 +2102,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_483_000 picoseconds. - Weight::from_parts(20_453_059, 0) - // Standard Error: 3_271 - .saturating_add(Weight::from_parts(1_713_468, 0).saturating_mul(r.into())) + // Minimum execution time: 9_304_000 picoseconds. + Weight::from_parts(25_678_842, 0) + // Standard Error: 1_855 + .saturating_add(Weight::from_parts(1_814_511, 0).saturating_mul(r.into())) } /// Storage: `System::EventTopics` (r:4 w:4) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -2113,12 +2115,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `990 + t * (2475 ±0)` - // Minimum execution time: 23_517_000 picoseconds. - Weight::from_parts(15_543_153, 990) - // Standard Error: 13_814 - .saturating_add(Weight::from_parts(2_357_255, 0).saturating_mul(t.into())) - // Standard Error: 3 - .saturating_add(Weight::from_parts(573, 0).saturating_mul(n.into())) + // Minimum execution time: 23_425_000 picoseconds. + Weight::from_parts(15_229_010, 990) + // Standard Error: 14_380 + .saturating_add(Weight::from_parts(2_545_653, 0).saturating_mul(t.into())) + // Standard Error: 4 + .saturating_add(Weight::from_parts(594, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(t.into()))) .saturating_add(Weight::from_parts(0, 2475).saturating_mul(t.into())) @@ -2128,20 +2130,20 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_448_000 picoseconds. - Weight::from_parts(9_845_841, 0) - // Standard Error: 58 - .saturating_add(Weight::from_parts(105_442, 0).saturating_mul(r.into())) + // Minimum execution time: 11_117_000 picoseconds. + Weight::from_parts(12_887_533, 0) + // Standard Error: 83 + .saturating_add(Weight::from_parts(99_373, 0).saturating_mul(r.into())) } /// The range of component `i` is `[0, 1048576]`. fn seal_debug_message_per_byte(i: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_869_000 picoseconds. - Weight::from_parts(11_024_000, 0) + // Minimum execution time: 10_982_000 picoseconds. + Weight::from_parts(11_176_000, 0) // Standard Error: 8 - .saturating_add(Weight::from_parts(991, 0).saturating_mul(i.into())) + .saturating_add(Weight::from_parts(983, 0).saturating_mul(i.into())) } /// Storage: `Skipped::Metadata` (r:0 w:0) /// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -2150,10 +2152,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_119_000 picoseconds. - Weight::from_parts(9_270_000, 105) - // Standard Error: 8_960 - .saturating_add(Weight::from_parts(5_215_976, 0).saturating_mul(r.into())) + // Minimum execution time: 9_150_000 picoseconds. + Weight::from_parts(9_269_000, 105) + // Standard Error: 8_147 + .saturating_add(Weight::from_parts(5_339_554, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) @@ -2165,10 +2167,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `245` // Estimated: `245` - // Minimum execution time: 17_833_000 picoseconds. - Weight::from_parts(18_940_114, 245) - // Standard Error: 2 - .saturating_add(Weight::from_parts(316, 0).saturating_mul(n.into())) + // Minimum execution time: 19_085_000 picoseconds. + Weight::from_parts(20_007_323, 245) + // Standard Error: 3 + .saturating_add(Weight::from_parts(291, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -2179,10 +2181,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 18_428_000 picoseconds. - Weight::from_parts(19_372_726, 248) - // Standard Error: 2 - .saturating_add(Weight::from_parts(85, 0).saturating_mul(n.into())) + // Minimum execution time: 19_127_000 picoseconds. + Weight::from_parts(21_152_987, 248) + // Standard Error: 3 + .saturating_add(Weight::from_parts(42, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -2194,10 +2196,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_335_000 picoseconds. - Weight::from_parts(9_459_000, 105) - // Standard Error: 9_156 - .saturating_add(Weight::from_parts(5_166_621, 0).saturating_mul(r.into())) + // Minimum execution time: 9_264_000 picoseconds. + Weight::from_parts(9_449_000, 105) + // Standard Error: 8_196 + .saturating_add(Weight::from_parts(5_325_578, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) @@ -2209,10 +2211,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 18_308_000 picoseconds. - Weight::from_parts(19_421_433, 248) + // Minimum execution time: 18_489_000 picoseconds. + Weight::from_parts(19_916_153, 248) // Standard Error: 2 - .saturating_add(Weight::from_parts(83, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(97, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -2224,10 +2226,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_184_000 picoseconds. - Weight::from_parts(9_245_000, 105) - // Standard Error: 8_442 - .saturating_add(Weight::from_parts(4_543_991, 0).saturating_mul(r.into())) + // Minimum execution time: 9_299_000 picoseconds. + Weight::from_parts(9_464_000, 105) + // Standard Error: 6_827 + .saturating_add(Weight::from_parts(4_720_699, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) } @@ -2238,10 +2240,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 17_194_000 picoseconds. - Weight::from_parts(19_032_094, 248) + // Minimum execution time: 17_981_000 picoseconds. + Weight::from_parts(19_802_353, 248) // Standard Error: 3 - .saturating_add(Weight::from_parts(590, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(617, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -2252,10 +2254,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_380_000 picoseconds. - Weight::from_parts(9_501_000, 105) - // Standard Error: 7_029 - .saturating_add(Weight::from_parts(4_406_690, 0).saturating_mul(r.into())) + // Minimum execution time: 9_891_000 picoseconds. + Weight::from_parts(10_046_000, 105) + // Standard Error: 6_993 + .saturating_add(Weight::from_parts(4_601_167, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) } @@ -2266,10 +2268,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 16_400_000 picoseconds. - Weight::from_parts(17_993_941, 248) + // Minimum execution time: 17_229_000 picoseconds. + Weight::from_parts(18_302_733, 248) // Standard Error: 2 - .saturating_add(Weight::from_parts(68, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(112, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) } @@ -2280,10 +2282,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `108 + r * (150 ±0)` // Estimated: `105 + r * (151 ±0)` - // Minimum execution time: 9_109_000 picoseconds. - Weight::from_parts(9_265_000, 105) - // Standard Error: 8_733 - .saturating_add(Weight::from_parts(5_218_811, 0).saturating_mul(r.into())) + // Minimum execution time: 9_323_000 picoseconds. + Weight::from_parts(9_462_000, 105) + // Standard Error: 8_031 + .saturating_add(Weight::from_parts(5_433_981, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 151).saturating_mul(r.into())) @@ -2295,10 +2297,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `248 + n * (1 ±0)` // Estimated: `248 + n * (1 ±0)` - // Minimum execution time: 18_423_000 picoseconds. - Weight::from_parts(20_025_132, 248) + // Minimum execution time: 18_711_000 picoseconds. + Weight::from_parts(20_495_670, 248) // Standard Error: 3 - .saturating_add(Weight::from_parts(628, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(640, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) .saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into())) @@ -2310,10 +2312,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `770` // Estimated: `4221 + r * (2475 ±0)` - // Minimum execution time: 9_043_000 picoseconds. - Weight::from_parts(9_176_000, 4221) - // Standard Error: 12_901 - .saturating_add(Weight::from_parts(32_297_438, 0).saturating_mul(r.into())) + // Minimum execution time: 9_226_000 picoseconds. + Weight::from_parts(9_394_000, 4221) + // Standard Error: 14_741 + .saturating_add(Weight::from_parts(34_179_316, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(1_u64)) @@ -2335,10 +2337,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `520 + r * (170 ±0)` // Estimated: `6463 + r * (2646 ±0)` - // Minimum execution time: 9_299_000 picoseconds. - Weight::from_parts(9_427_000, 6463) - // Standard Error: 101_949 - .saturating_add(Weight::from_parts(244_143_691, 0).saturating_mul(r.into())) + // Minimum execution time: 9_455_000 picoseconds. + Weight::from_parts(9_671_000, 6463) + // Standard Error: 126_080 + .saturating_add(Weight::from_parts(244_204_040, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(2_u64)) @@ -2359,11 +2361,11 @@ impl WeightInfo for () { fn seal_delegate_call(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (527 ±0)` - // Estimated: `6447 + r * (2583 ±3)` - // Minimum execution time: 9_359_000 picoseconds. - Weight::from_parts(9_425_000, 6447) - // Standard Error: 193_938 - .saturating_add(Weight::from_parts(244_904_401, 0).saturating_mul(r.into())) + // Estimated: `6447 + r * (2583 ±10)` + // Minimum execution time: 9_274_000 picoseconds. + Weight::from_parts(9_437_000, 6447) + // Standard Error: 150_832 + .saturating_add(Weight::from_parts(244_196_269, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2583).saturating_mul(r.into())) @@ -2386,12 +2388,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `699 + t * (277 ±0)` // Estimated: `6639 + t * (3458 ±0)` - // Minimum execution time: 214_588_000 picoseconds. - Weight::from_parts(129_214_481, 6639) - // Standard Error: 2_468_090 - .saturating_add(Weight::from_parts(32_514_739, 0).saturating_mul(t.into())) + // Minimum execution time: 214_483_000 picoseconds. + Weight::from_parts(122_634_366, 6639) + // Standard Error: 2_499_235 + .saturating_add(Weight::from_parts(41_326_008, 0).saturating_mul(t.into())) // Standard Error: 3 - .saturating_add(Weight::from_parts(418, 0).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(422, 0).saturating_mul(c.into())) .saturating_add(RocksDbWeight::get().reads(7_u64)) .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -2406,10 +2408,10 @@ impl WeightInfo for () { /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:800 w:801) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:802 w:802) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::EventTopics` (r:801 w:801) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `r` is `[1, 800]`. @@ -2417,10 +2419,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1097 + r * (188 ±0)` // Estimated: `6990 + r * (2664 ±0)` - // Minimum execution time: 352_925_000 picoseconds. - Weight::from_parts(355_487_000, 6990) - // Standard Error: 261_528 - .saturating_add(Weight::from_parts(337_897_187, 0).saturating_mul(r.into())) + // Minimum execution time: 341_569_000 picoseconds. + Weight::from_parts(360_574_000, 6990) + // Standard Error: 259_746 + .saturating_add(Weight::from_parts(337_944_674, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) @@ -2435,10 +2437,10 @@ impl WeightInfo for () { /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) /// Storage: `Contracts::ContractInfoOf` (r:1 w:2) /// Proof: `Contracts::ContractInfoOf` (`max_values`: None, `max_size`: Some(1795), added: 4270, mode: `Measured`) - /// Storage: `Parameters::Parameters` (r:2 w:0) - /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::Account` (r:3 w:3) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `Measured`) /// Storage: `System::EventTopics` (r:2 w:2) /// Proof: `System::EventTopics` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `t` is `[0, 1]`. @@ -2448,12 +2450,14 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `760 + t * (104 ±0)` // Estimated: `6719 + t * (2549 ±1)` - // Minimum execution time: 1_870_832_000 picoseconds. - Weight::from_parts(949_110_245, 6719) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_084, 0).saturating_mul(i.into())) - // Standard Error: 24 - .saturating_add(Weight::from_parts(1_206, 0).saturating_mul(s.into())) + // Minimum execution time: 1_863_119_000 picoseconds. + Weight::from_parts(900_189_174, 6719) + // Standard Error: 13_040_979 + .saturating_add(Weight::from_parts(4_056_063, 0).saturating_mul(t.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_028, 0).saturating_mul(i.into())) + // Standard Error: 20 + .saturating_add(Weight::from_parts(1_173, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(t.into()))) .saturating_add(RocksDbWeight::get().writes(7_u64)) @@ -2465,58 +2469,58 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_142_000 picoseconds. - Weight::from_parts(9_787_220, 0) - // Standard Error: 236 - .saturating_add(Weight::from_parts(267_264, 0).saturating_mul(r.into())) + // Minimum execution time: 9_211_000 picoseconds. + Weight::from_parts(11_696_412, 0) + // Standard Error: 388 + .saturating_add(Weight::from_parts(265_538, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_sha2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_485_000 picoseconds. - Weight::from_parts(1_870_250, 0) + // Minimum execution time: 10_296_000 picoseconds. + Weight::from_parts(572_494, 0) // Standard Error: 1 - .saturating_add(Weight::from_parts(1_073, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(1_067, 0).saturating_mul(n.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_hash_keccak_256(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_005_000 picoseconds. - Weight::from_parts(8_943_937, 0) - // Standard Error: 1_385 - .saturating_add(Weight::from_parts(665_970, 0).saturating_mul(r.into())) + // Minimum execution time: 9_177_000 picoseconds. + Weight::from_parts(8_620_481, 0) + // Standard Error: 249 + .saturating_add(Weight::from_parts(674_502, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_keccak_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_965_000 picoseconds. - Weight::from_parts(11_749_746, 0) - // Standard Error: 6 - .saturating_add(Weight::from_parts(3_330, 0).saturating_mul(n.into())) + // Minimum execution time: 11_240_000 picoseconds. + Weight::from_parts(8_696_186, 0) + // Standard Error: 0 + .saturating_add(Weight::from_parts(3_328, 0).saturating_mul(n.into())) } /// The range of component `r` is `[0, 1600]`. fn seal_hash_blake2_256(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_400_000 picoseconds. - Weight::from_parts(13_857_546, 0) - // Standard Error: 246 - .saturating_add(Weight::from_parts(326_483, 0).saturating_mul(r.into())) + // Minimum execution time: 9_889_000 picoseconds. + Weight::from_parts(16_103_170, 0) + // Standard Error: 343 + .saturating_add(Weight::from_parts(328_939, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_256_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_064_000 picoseconds. - Weight::from_parts(1_885_873, 0) + // Minimum execution time: 10_405_000 picoseconds. + Weight::from_parts(2_264_024, 0) // Standard Error: 0 .saturating_add(Weight::from_parts(1_196, 0).saturating_mul(n.into())) } @@ -2525,60 +2529,60 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_068_000 picoseconds. - Weight::from_parts(17_169_362, 0) - // Standard Error: 1_580 - .saturating_add(Weight::from_parts(330_195, 0).saturating_mul(r.into())) + // Minimum execution time: 9_215_000 picoseconds. + Weight::from_parts(10_505_632, 0) + // Standard Error: 240 + .saturating_add(Weight::from_parts(324_854, 0).saturating_mul(r.into())) } /// The range of component `n` is `[0, 1048576]`. fn seal_hash_blake2_128_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 10_169_000 picoseconds. - Weight::from_parts(2_159_277, 0) - // Standard Error: 0 - .saturating_add(Weight::from_parts(1_200, 0).saturating_mul(n.into())) + // Minimum execution time: 10_440_000 picoseconds. + Weight::from_parts(2_575_889, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_199, 0).saturating_mul(n.into())) } /// The range of component `n` is `[0, 125697]`. fn seal_sr25519_verify_per_byte(n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 53_863_000 picoseconds. - Weight::from_parts(54_902_157, 0) - // Standard Error: 9 - .saturating_add(Weight::from_parts(4_588, 0).saturating_mul(n.into())) + // Minimum execution time: 55_119_000 picoseconds. + Weight::from_parts(56_732_248, 0) + // Standard Error: 8 + .saturating_add(Weight::from_parts(4_639, 0).saturating_mul(n.into())) } /// The range of component `r` is `[0, 160]`. fn seal_sr25519_verify(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_107_000 picoseconds. - Weight::from_parts(24_115_247, 0) - // Standard Error: 7_427 - .saturating_add(Weight::from_parts(41_116_827, 0).saturating_mul(r.into())) + // Minimum execution time: 9_176_000 picoseconds. + Weight::from_parts(9_861_102, 0) + // Standard Error: 6_029 + .saturating_add(Weight::from_parts(45_948_571, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_recover(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_404_000 picoseconds. - Weight::from_parts(31_763_334, 0) - // Standard Error: 9_833 - .saturating_add(Weight::from_parts(45_529_880, 0).saturating_mul(r.into())) + // Minimum execution time: 9_293_000 picoseconds. + Weight::from_parts(28_785_765, 0) + // Standard Error: 9_160 + .saturating_add(Weight::from_parts(45_566_150, 0).saturating_mul(r.into())) } /// The range of component `r` is `[0, 160]`. fn seal_ecdsa_to_eth_address(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_409_000 picoseconds. - Weight::from_parts(15_072_835, 0) - // Standard Error: 4_591 - .saturating_add(Weight::from_parts(11_619_283, 0).saturating_mul(r.into())) + // Minimum execution time: 9_206_000 picoseconds. + Weight::from_parts(12_420_664, 0) + // Standard Error: 3_489 + .saturating_add(Weight::from_parts(11_628_989, 0).saturating_mul(r.into())) } /// Storage: `Contracts::CodeInfoOf` (r:1536 w:1536) /// Proof: `Contracts::CodeInfoOf` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `Measured`) @@ -2592,11 +2596,11 @@ impl WeightInfo for () { fn seal_set_code_hash(r: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + r * (926 ±0)` - // Estimated: `8969 + r * (3047 ±10)` - // Minimum execution time: 9_269_000 picoseconds. - Weight::from_parts(9_372_000, 8969) - // Standard Error: 61_354 - .saturating_add(Weight::from_parts(26_280_409, 0).saturating_mul(r.into())) + // Estimated: `8969 + r * (3047 ±7)` + // Minimum execution time: 9_219_000 picoseconds. + Weight::from_parts(9_385_000, 8969) + // Standard Error: 45_562 + .saturating_add(Weight::from_parts(26_360_661, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((3_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((2_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 3047).saturating_mul(r.into())) @@ -2608,10 +2612,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `274 + r * (78 ±0)` // Estimated: `1265 + r * (2553 ±0)` - // Minimum execution time: 9_103_000 picoseconds. - Weight::from_parts(14_404_626, 1265) - // Standard Error: 9_343 - .saturating_add(Weight::from_parts(5_154_949, 0).saturating_mul(r.into())) + // Minimum execution time: 9_355_000 picoseconds. + Weight::from_parts(15_071_309, 1265) + // Standard Error: 9_722 + .saturating_add(Weight::from_parts(5_328_717, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2553).saturating_mul(r.into())) @@ -2623,10 +2627,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `275 + r * (78 ±0)` // Estimated: `990 + r * (2568 ±0)` - // Minimum execution time: 9_219_000 picoseconds. - Weight::from_parts(14_085_456, 990) - // Standard Error: 11_206 - .saturating_add(Weight::from_parts(4_422_122, 0).saturating_mul(r.into())) + // Minimum execution time: 8_979_000 picoseconds. + Weight::from_parts(14_362_224, 990) + // Standard Error: 9_137 + .saturating_add(Weight::from_parts(4_488_748, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(r.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(r.into()))) .saturating_add(Weight::from_parts(0, 2568).saturating_mul(r.into())) @@ -2652,10 +2656,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `861 + r * (3 ±0)` // Estimated: `9282 + r * (3 ±0)` - // Minimum execution time: 269_333_000 picoseconds. - Weight::from_parts(286_922_618, 9282) - // Standard Error: 443 - .saturating_add(Weight::from_parts(168_869, 0).saturating_mul(r.into())) + // Minimum execution time: 269_704_000 picoseconds. + Weight::from_parts(289_916_035, 9282) + // Standard Error: 408 + .saturating_add(Weight::from_parts(166_040, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 3).saturating_mul(r.into())) @@ -2665,10 +2669,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 9_328_000 picoseconds. - Weight::from_parts(14_019_583, 0) - // Standard Error: 171 - .saturating_add(Weight::from_parts(88_751, 0).saturating_mul(r.into())) + // Minimum execution time: 9_361_000 picoseconds. + Weight::from_parts(11_633_836, 0) + // Standard Error: 86 + .saturating_add(Weight::from_parts(83_083, 0).saturating_mul(r.into())) } /// Storage: `Contracts::Nonce` (r:1 w:0) /// Proof: `Contracts::Nonce` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`) @@ -2677,10 +2681,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `219` // Estimated: `1704` - // Minimum execution time: 9_267_000 picoseconds. - Weight::from_parts(15_304_284, 1704) - // Standard Error: 1_219 - .saturating_add(Weight::from_parts(74_696, 0).saturating_mul(r.into())) + // Minimum execution time: 9_133_000 picoseconds. + Weight::from_parts(13_259_836, 1704) + // Standard Error: 121 + .saturating_add(Weight::from_parts(76_878, 0).saturating_mul(r.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// The range of component `r` is `[0, 5000]`. @@ -2688,9 +2692,9 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 911_000 picoseconds. - Weight::from_parts(449_666, 0) - // Standard Error: 26 - .saturating_add(Weight::from_parts(14_797, 0).saturating_mul(r.into())) + // Minimum execution time: 851_000 picoseconds. + Weight::from_parts(587_883, 0) + // Standard Error: 16 + .saturating_add(Weight::from_parts(14_912, 0).saturating_mul(r.into())) } } diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs index 66777cef7b8e81960c1169c2fb1fd1033e58c4a2..a423656c394f28158da2aedd5d552814ccabb3c5 100644 --- a/substrate/frame/support/src/traits.rs +++ b/substrate/frame/support/src/traits.rs @@ -36,7 +36,7 @@ mod members; pub use members::{AllowAll, DenyAll, Filter}; pub use members::{ AsContains, ChangeMembers, Contains, ContainsLengthBound, ContainsPair, Equals, Everything, - EverythingBut, FromContainsPair, InitializeMembers, InsideBoth, IsInVec, Nothing, + EverythingBut, FromContains, FromContainsPair, InitializeMembers, InsideBoth, IsInVec, Nothing, RankedMembers, RankedMembersSwapHandler, SortedMembers, TheseExcept, }; diff --git a/substrate/frame/support/src/traits/members.rs b/substrate/frame/support/src/traits/members.rs index 3a6e3719593a22c33ad24c24c56f858ea82779ee..53de84ab22455f2d778c1fd64ba94c348c685db0 100644 --- a/substrate/frame/support/src/traits/members.rs +++ b/substrate/frame/support/src/traits/members.rs @@ -66,6 +66,15 @@ impl<A, B, CP: ContainsPair<A, B>> Contains<(A, B)> for FromContainsPair<CP> { } } +/// A [`ContainsPair`] implementation that has a `Contains` implementation for each member of the +/// pair. +pub struct FromContains<CA, CB>(PhantomData<(CA, CB)>); +impl<A, B, CA: Contains<A>, CB: Contains<B>> ContainsPair<A, B> for FromContains<CA, CB> { + fn contains(a: &A, b: &B) -> bool { + CA::contains(a) && CB::contains(b) + } +} + /// A [`Contains`] implementation that contains every value. pub enum Everything {} impl<T> Contains<T> for Everything { diff --git a/substrate/frame/support/src/traits/tokens.rs b/substrate/frame/support/src/traits/tokens.rs index 3635311e64357bbd2e7041d653a4268dfb65a182..8842b20580181f81e4377a0d9f6223e59a6fee6a 100644 --- a/substrate/frame/support/src/traits/tokens.rs +++ b/substrate/frame/support/src/traits/tokens.rs @@ -31,7 +31,7 @@ pub mod pay; pub use misc::{ AssetId, Balance, BalanceStatus, ConversionFromAssetBalance, ConversionToAssetBalance, ConvertRank, DepositConsequence, ExistenceRequirement, Fortitude, GetSalary, Locker, Precision, - Preservation, Provenance, Restriction, UnityAssetBalanceConversion, WithdrawConsequence, - WithdrawReasons, + Preservation, Provenance, Restriction, UnityAssetBalanceConversion, UnityOrOuterConversion, + WithdrawConsequence, WithdrawReasons, }; pub use pay::{Pay, PayFromAccount, PaymentStatus}; diff --git a/substrate/frame/support/src/traits/tokens/misc.rs b/substrate/frame/support/src/traits/tokens/misc.rs index a4dd5e4914283e6da028aac038cecee501a2228f..424acb1d550b15b69582d004e2e466e65e6a9b3f 100644 --- a/substrate/frame/support/src/traits/tokens/misc.rs +++ b/substrate/frame/support/src/traits/tokens/misc.rs @@ -17,6 +17,7 @@ //! Miscellaneous types. +use crate::traits::Contains; use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use sp_arithmetic::traits::{AtLeast32BitUnsigned, Zero}; use sp_core::RuntimeDebug; @@ -299,6 +300,33 @@ where fn ensure_successful(_: AssetId) {} } +/// Implements [`ConversionFromAssetBalance`], allowing for a 1:1 balance conversion of the asset +/// when it meets the conditions specified by `C`. If the conditions are not met, the conversion is +/// delegated to `O`. +pub struct UnityOrOuterConversion<C, O>(core::marker::PhantomData<(C, O)>); +impl<AssetBalance, AssetId, OutBalance, C, O> + ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> for UnityOrOuterConversion<C, O> +where + C: Contains<AssetId>, + O: ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance>, + AssetBalance: Into<OutBalance>, +{ + type Error = O::Error; + fn from_asset_balance( + balance: AssetBalance, + asset_id: AssetId, + ) -> Result<OutBalance, Self::Error> { + if C::contains(&asset_id) { + return Ok(balance.into()); + } + O::from_asset_balance(balance, asset_id) + } + #[cfg(feature = "runtime-benchmarks")] + fn ensure_successful(asset_id: AssetId) { + O::ensure_successful(asset_id) + } +} + /// Trait to handle NFT locking mechanism to ensure interactions with the asset can be implemented /// downstream to extend logic of Uniques/Nfts current functionality. pub trait Locker<CollectionId, ItemId> {