From 3cb2d626656fc7210ab4000d80b1cd86f9159c8d Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 21 Jan 2022 14:42:39 +0100 Subject: [PATCH] HRMP benchmarks (#3876) * wip template for hrmp benchmarks * add all of the benchmarks, first draft * File was not saved :/ * cargo +nightly fmt * Use configs * add configs * Fix rococo * Final touches * revert fmt changes, one last time * Fix wrappings * Fix a bunch of tests * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=kusama-dev --steps=50 --repeat=20 --pallet=runtime_parachains::hrmp --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/kusama/src/weights/runtime_parachains_hrmp.rs * add to westend * actually use everything * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=runtime_parachains::hrmp --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/westend/src/weights/runtime_parachains_hrmp.rs * Update runtime/parachains/src/hrmp.rs Co-authored-by: Keith Yeung * use real weight in wnd * reorg * minor cleanup * weigh some of the internal stuff as well * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=kusama-dev --steps=50 --repeat=20 --pallet=runtime_parachains::hrmp --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/kusama/src/weights/runtime_parachains_hrmp.rs * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=runtime_parachains::hrmp --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/westend/src/weights/runtime_parachains_hrmp.rs * add files * Master.into() * add validation * fmt * fmt * final fixes * all runtimes build * undo formatting * Update runtime/parachains/src/hrmp.rs Co-authored-by: Zeke Mostov * non-controversial changes * do it the parachain-way: use const instead of type configs for simplicity. * borrow assert_storage_consistency_exhaustive * move assert_storage_consistency_exhaustive to Pallet, so it can be reused for benchmarks as well. * fix typo Co-authored-by: Parity Bot Co-authored-by: Keith Yeung Co-authored-by: Sergey Shulepov Co-authored-by: Zeke Mostov --- polkadot/Cargo.lock | 1 + polkadot/runtime/kusama/src/lib.rs | 3 + polkadot/runtime/kusama/src/weights/mod.rs | 1 + .../src/weights/runtime_parachains_hrmp.rs | 157 +++++ polkadot/runtime/parachains/Cargo.toml | 3 + .../runtime/parachains/src/configuration.rs | 21 +- polkadot/runtime/parachains/src/hrmp.rs | 557 +++++++++++------- .../parachains/src/hrmp/benchmarking.rs | 303 ++++++++++ polkadot/runtime/parachains/src/mock.rs | 5 + polkadot/runtime/parachains/src/paras/mod.rs | 16 + polkadot/runtime/polkadot/src/lib.rs | 1 + polkadot/runtime/polkadot/src/weights/mod.rs | 1 + .../src/weights/runtime_parachains_hrmp.rs | 157 +++++ polkadot/runtime/rococo/src/lib.rs | 3 +- polkadot/runtime/rococo/src/weights/mod.rs | 1 + .../src/weights/runtime_parachains_hrmp.rs | 157 +++++ polkadot/runtime/test-runtime/src/lib.rs | 1 + polkadot/runtime/westend/src/lib.rs | 3 + polkadot/runtime/westend/src/weights/mod.rs | 1 + .../src/weights/runtime_parachains_hrmp.rs | 153 +++++ 20 files changed, 1323 insertions(+), 222 deletions(-) create mode 100644 polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs create mode 100644 polkadot/runtime/parachains/src/hrmp/benchmarking.rs create mode 100644 polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs create mode 100644 polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs create mode 100644 polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock index f47ed54feb..87f8635266 100644 --- a/polkadot/Cargo.lock +++ b/polkadot/Cargo.lock @@ -7031,6 +7031,7 @@ dependencies = [ "sp-staking", "sp-std", "sp-tracing", + "static_assertions", "thousands", "xcm", "xcm-executor", diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index fc6adac249..02d2d18393 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -1230,6 +1230,7 @@ impl parachains_hrmp::Config for Runtime { type Event = Event; type Origin = Origin; type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; } impl parachains_paras_inherent::Config for Runtime { @@ -3297,6 +3298,7 @@ sp_api::impl_runtime_apis! { list_benchmark!(list, extra, runtime_common::slots, Slots); list_benchmark!(list, extra, runtime_common::paras_registrar, Registrar); list_benchmark!(list, extra, runtime_parachains::configuration, Configuration); + list_benchmark!(list, extra, runtime_parachains::hrmp, Hrmp); list_benchmark!(list, extra, runtime_parachains::disputes, ParasDisputes); list_benchmark!(list, extra, runtime_parachains::initializer, Initializer); list_benchmark!(list, extra, runtime_parachains::paras_inherent, ParaInherent); @@ -3377,6 +3379,7 @@ sp_api::impl_runtime_apis! { add_benchmark!(params, batches, runtime_common::slots, Slots); add_benchmark!(params, batches, runtime_common::paras_registrar, Registrar); add_benchmark!(params, batches, runtime_parachains::configuration, Configuration); + add_benchmark!(params, batches, runtime_parachains::hrmp, Hrmp); add_benchmark!(params, batches, runtime_parachains::disputes, ParasDisputes); add_benchmark!(params, batches, runtime_parachains::initializer, Initializer); add_benchmark!(params, batches, runtime_parachains::paras_inherent, ParaInherent); diff --git a/polkadot/runtime/kusama/src/weights/mod.rs b/polkadot/runtime/kusama/src/weights/mod.rs index 93c12c2083..42f406954a 100644 --- a/polkadot/runtime/kusama/src/weights/mod.rs +++ b/polkadot/runtime/kusama/src/weights/mod.rs @@ -47,6 +47,7 @@ pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; pub mod runtime_parachains_configuration; pub mod runtime_parachains_disputes; +pub mod runtime_parachains_hrmp; pub mod runtime_parachains_initializer; pub mod runtime_parachains_paras; pub mod runtime_parachains_paras_inherent; diff --git a/polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000..de6e57873b --- /dev/null +++ b/polkadot/runtime/kusama/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,157 @@ +// Copyright 2017-2021 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 . +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_hrmp.rs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + // Storage: Paras ParaLifecycles (r:2 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_init_open_channel() -> Weight { + (54_952_000 as Weight) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Paras ParaLifecycles (r:1 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_accept_open_channel() -> Weight { + (47_965_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_close_channel() -> Weight { + (44_369_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:127) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:127 w:127) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + // Storage: Hrmp HrmpChannelContents (r:0 w:127) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 17_000 + .saturating_add((15_959_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 17_000 + .saturating_add((16_048_000 as Weight).saturating_mul(e as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(e as Weight))) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(e as Weight))) + } + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + // Storage: Paras ParaLifecycles (r:4 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpChannels (r:0 w:2) + fn force_process_hrmp_open(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 26_000 + .saturating_add((35_598_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((7 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((6 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpChannels (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpCloseChannelRequests (r:0 w:2) + // Storage: Hrmp HrmpChannelContents (r:0 w:2) + fn force_process_hrmp_close(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 15_000 + .saturating_add((20_510_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + (32_749_000 as Weight) + // Standard Error: 0 + .saturating_add((59_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + fn clean_open_channel_requests(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((5_781_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) + } +} diff --git a/polkadot/runtime/parachains/Cargo.toml b/polkadot/runtime/parachains/Cargo.toml index cc308fc64b..6ac657530b 100644 --- a/polkadot/runtime/parachains/Cargo.toml +++ b/polkadot/runtime/parachains/Cargo.toml @@ -43,6 +43,7 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau rand = { version = "0.8.3", default-features = false } rand_chacha = { version = "0.3.1", default-features = false } +static_assertions = { version = "1.1.0", optional = true } polkadot-runtime-metrics = { path = "../metrics", default-features = false} [dev-dependencies] @@ -52,6 +53,7 @@ keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substra frame-support-test = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } test-helpers = { package = "polkadot-primitives-test-helpers", path = "../../primitives/test-helpers"} +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } thousands = "0.2.0" assert_matches = "1" @@ -93,6 +95,7 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "primitives/runtime-benchmarks", + "static_assertions", ] try-runtime = [ "frame-support/try-runtime", diff --git a/polkadot/runtime/parachains/src/configuration.rs b/polkadot/runtime/parachains/src/configuration.rs index cb3abe8033..32a7197578 100644 --- a/polkadot/runtime/parachains/src/configuration.rs +++ b/polkadot/runtime/parachains/src/configuration.rs @@ -319,6 +319,10 @@ pub enum InconsistentError { }, /// `validation_upgrade_delay` is less than or equal 1. ValidationUpgradeDelayIsTooLow { validation_upgrade_delay: BlockNumber }, + /// Maximum number of HRMP outbound channels exceeded. + MaxHrmpOutboundChannelsExceeded, + /// Maximum number of HRMP inbound channels exceeded. + MaxHrmpInboundChannelsExceeded, } impl HostConfiguration @@ -381,6 +385,15 @@ where }) } + if self.hrmp_max_parachain_outbound_channels > crate::hrmp::HRMP_MAX_OUTBOUND_CHANNELS_BOUND + { + return Err(MaxHrmpOutboundChannelsExceeded) + } + + if self.hrmp_max_parachain_inbound_channels > crate::hrmp::HRMP_MAX_INBOUND_CHANNELS_BOUND { + return Err(MaxHrmpInboundChannelsExceeded) + } + Ok(()) } @@ -1608,11 +1621,11 @@ mod tests { hrmp_recipient_deposit: 4905, hrmp_channel_max_capacity: 3921, hrmp_channel_max_total_size: 7687, - hrmp_max_parachain_inbound_channels: 3722, - hrmp_max_parathread_inbound_channels: 1967, + hrmp_max_parachain_inbound_channels: 37, + hrmp_max_parathread_inbound_channels: 19, hrmp_channel_max_message_size: 8192, - hrmp_max_parachain_outbound_channels: 100, - hrmp_max_parathread_outbound_channels: 200, + hrmp_max_parachain_outbound_channels: 10, + hrmp_max_parathread_outbound_channels: 20, hrmp_max_message_num_per_candidate: 20, ump_max_individual_weight: 909, pvf_checking_enabled: true, diff --git a/polkadot/runtime/parachains/src/hrmp.rs b/polkadot/runtime/parachains/src/hrmp.rs index f49826be9d..bba182d4c4 100644 --- a/polkadot/runtime/parachains/src/hrmp.rs +++ b/polkadot/runtime/parachains/src/hrmp.rs @@ -35,6 +35,58 @@ use sp_std::{ pub use pallet::*; +/// Maximum bound that can be set for inbound channels. +/// +/// If inaccurate, the weighing of this pallet might become inaccurate. It is expected form the +/// `configurations` pallet to check these values before setting +pub const HRMP_MAX_INBOUND_CHANNELS_BOUND: u32 = 128; +/// Same as [`HRMP_MAX_INBOUND_CHANNELS_BOUND`], but for outbound channels. +pub const HRMP_MAX_OUTBOUND_CHANNELS_BOUND: u32 = 128; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub trait WeightInfo { + fn hrmp_init_open_channel() -> Weight; + fn hrmp_accept_open_channel() -> Weight; + fn hrmp_close_channel() -> Weight; + fn force_clean_hrmp(i: u32, e: u32) -> Weight; + fn force_process_hrmp_open(c: u32) -> Weight; + fn force_process_hrmp_close(c: u32) -> Weight; + fn hrmp_cancel_open_request(c: u32) -> Weight; + fn clean_open_channel_requests(c: u32) -> Weight; +} + +/// A weight info that is only suitable for testing. +pub struct TestWeightInfo; + +impl WeightInfo for TestWeightInfo { + fn hrmp_accept_open_channel() -> Weight { + Weight::MAX + } + fn force_clean_hrmp(_: u32, _: u32) -> Weight { + Weight::MAX + } + fn force_process_hrmp_close(_: u32) -> Weight { + Weight::MAX + } + fn force_process_hrmp_open(_: u32) -> Weight { + Weight::MAX + } + fn hrmp_cancel_open_request(_: u32) -> Weight { + Weight::MAX + } + fn hrmp_close_channel() -> Weight { + Weight::MAX + } + fn hrmp_init_open_channel() -> Weight { + Weight::MAX + } + fn clean_open_channel_requests(_: u32) -> Weight { + Weight::MAX + } +} + /// A description of a request to open an HRMP channel. #[derive(Encode, Decode, TypeInfo)] pub struct HrmpOpenChannelRequest { @@ -192,10 +244,13 @@ pub mod pallet { /// An interface for reserving deposits for opening channels. /// - /// NOTE that this Currency instance will be charged with the amounts defined in the `Configuration` - /// pallet. Specifically, that means that the `Balance` of the `Currency` implementation should - /// be the same as `Balance` as used in the `Configuration`. + /// NOTE that this Currency instance will be charged with the amounts defined in the + /// `Configuration` pallet. Specifically, that means that the `Balance` of the `Currency` + /// implementation should be the same as `Balance` as used in the `Configuration`. type Currency: ReservableCurrency; + + /// Something that provides the weight of this pallet. + type WeightInfo: WeightInfo; } #[pallet::event] @@ -251,6 +306,8 @@ pub mod pallet { OpenHrmpChannelDoesntExist, /// Cannot cancel an HRMP open channel request because it is already confirmed. OpenHrmpChannelAlreadyConfirmed, + /// The provided witness data is wrong. + WrongWitness, } /// The set of pending HRMP open channel requests. @@ -263,13 +320,16 @@ pub mod pallet { pub type HrmpOpenChannelRequests = StorageMap<_, Twox64Concat, HrmpChannelId, HrmpOpenChannelRequest>; + // NOTE: could become bounded, but we don't have a global maximum for this. + // `HRMP_MAX_INBOUND_CHANNELS_BOUND` are per parachain/parathread, while this storage tracks the + // global state. #[pallet::storage] pub type HrmpOpenChannelRequestsList = StorageValue<_, Vec, ValueQuery>; /// This mapping tracks how many open channel requests are initiated by a given sender para. - /// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has `(X, _)` - /// as the number of `HrmpOpenChannelRequestCount` for `X`. + /// Invariant: `HrmpOpenChannelRequests` should contain the same number of items that has + /// `(X, _)` as the number of `HrmpOpenChannelRequestCount` for `X`. #[pallet::storage] pub type HrmpOpenChannelRequestCount = StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>; @@ -281,8 +341,8 @@ pub mod pallet { pub type HrmpAcceptedChannelRequestCount = StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>; - /// A set of pending HRMP close channel requests that are going to be closed during the session change. - /// Used for checking if a given channel is registered for closure. + /// A set of pending HRMP close channel requests that are going to be closed during the session + /// change. Used for checking if a given channel is registered for closure. /// /// The set is accompanied by a list for iteration. /// @@ -307,17 +367,17 @@ pub mod pallet { #[pallet::storage] pub type HrmpChannels = StorageMap<_, Twox64Concat, HrmpChannelId, HrmpChannel>; - /// Ingress/egress indexes allow to find all the senders and receivers given the opposite - /// side. I.e. + /// Ingress/egress indexes allow to find all the senders and receivers given the opposite side. + /// I.e. /// /// (a) ingress index allows to find all the senders for a given recipient. /// (b) egress index allows to find all the recipients for a given sender. /// /// Invariants: - /// - for each ingress index entry for `P` each item `I` in the index should present in `HrmpChannels` - /// as `(I, P)`. - /// - for each egress index entry for `P` each item `E` in the index should present in `HrmpChannels` - /// as `(P, E)`. + /// - for each ingress index entry for `P` each item `I` in the index should present in + /// `HrmpChannels` as `(I, P)`. + /// - for each egress index entry for `P` each item `E` in the index should present in + /// `HrmpChannels` as `(P, E)`. /// - there should be no other dangling channels in `HrmpChannels`. /// - the vectors are sorted. #[pallet::storage] @@ -341,27 +401,28 @@ pub mod pallet { ValueQuery, >; - /// Maintains a mapping that can be used to answer the question: - /// What paras sent a message at the given block number for a given receiver. - /// Invariants: + /// Maintains a mapping that can be used to answer the question: What paras sent a message at + /// the given block number for a given receiver. Invariants: /// - The inner `Vec` is never empty. /// - The inner `Vec` cannot store two same `ParaId`. - /// - The outer vector is sorted ascending by block number and cannot store two items with the same - /// block number. + /// - The outer vector is sorted ascending by block number and cannot store two items with the + /// same block number. #[pallet::storage] pub type HrmpChannelDigests = StorageMap<_, Twox64Concat, ParaId, Vec<(T::BlockNumber, Vec)>, ValueQuery>; /// Preopen the given HRMP channels. /// - /// The values in the tuple corresponds to `(sender, recipient, max_capacity, max_message_size)`, - /// i.e. similar to `init_open_channel`. In fact, the initialization is performed as if - /// the `init_open_channel` and `accept_open_channel` were called with the respective parameters - /// and the session change take place. + /// The values in the tuple corresponds to + /// `(sender, recipient, max_capacity, max_message_size)`, i.e. similar to `init_open_channel`. + /// In fact, the initialization is performed as if the `init_open_channel` and + /// `accept_open_channel` were called with the respective parameters and the session change take + /// place. /// /// As such, each channel initializer should satisfy the same constraints, namely: /// - /// 1. `max_capacity` and `max_message_size` should be within the limits set by the configuration pallet. + /// 1. `max_capacity` and `max_message_size` should be within the limits set by the + /// configuration pallet. /// 2. `sender` and `recipient` must be valid paras. #[pallet::genesis_config] pub struct GenesisConfig { @@ -394,7 +455,7 @@ pub mod pallet { /// /// The channel can be opened only after the recipient confirms it and only on a session /// change. - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::hrmp_init_open_channel())] pub fn hrmp_init_open_channel( origin: OriginFor, recipient: ParaId, @@ -420,7 +481,7 @@ pub mod pallet { /// Accept a pending open channel request from the given sender. /// /// The channel will be opened only on the next session boundary. - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::hrmp_accept_open_channel())] pub fn hrmp_accept_open_channel(origin: OriginFor, sender: ParaId) -> DispatchResult { let origin = ensure_parachain(::Origin::from(origin))?; Self::accept_open_channel(origin, sender)?; @@ -432,7 +493,7 @@ pub mod pallet { /// recipient in the channel being closed. /// /// The closure can only happen on a session change. - #[pallet::weight(0)] + #[pallet::weight(::WeightInfo::hrmp_close_channel())] pub fn hrmp_close_channel( origin: OriginFor, channel_id: HrmpChannelId, @@ -448,8 +509,15 @@ pub mod pallet { /// you to trigger the cleanup immediately for a specific parachain. /// /// Origin must be Root. - #[pallet::weight(0)] - pub fn force_clean_hrmp(origin: OriginFor, para: ParaId) -> DispatchResult { + /// + /// Number of inbound and outbound channels for `para` must be provided as witness data of weighing. + #[pallet::weight(::WeightInfo::force_clean_hrmp(*_inbound, *_outbound))] + pub fn force_clean_hrmp( + origin: OriginFor, + para: ParaId, + _inbound: u32, + _outbound: u32, + ) -> DispatchResult { ensure_root(origin)?; Self::clean_hrmp_after_outgoing(¶); Ok(()) @@ -459,8 +527,10 @@ pub mod pallet { /// /// If there are pending HRMP open channel requests, you can use this /// function process all of those requests immediately. - #[pallet::weight(0)] - pub fn force_process_hrmp_open(origin: OriginFor) -> DispatchResult { + /// + /// Total number of opening channels must be provided as witness data of weighing. + #[pallet::weight(::WeightInfo::force_process_hrmp_open(*_channels))] + pub fn force_process_hrmp_open(origin: OriginFor, _channels: u32) -> DispatchResult { ensure_root(origin)?; let host_config = configuration::Pallet::::config(); Self::process_hrmp_open_channel_requests(&host_config); @@ -471,24 +541,35 @@ pub mod pallet { /// /// If there are pending HRMP close channel requests, you can use this /// function process all of those requests immediately. - #[pallet::weight(0)] - pub fn force_process_hrmp_close(origin: OriginFor) -> DispatchResult { + /// + /// Total number of closing channels must be provided as witness data of weighing. + #[pallet::weight(::WeightInfo::force_process_hrmp_close(*_channels))] + pub fn force_process_hrmp_close(origin: OriginFor, _channels: u32) -> DispatchResult { ensure_root(origin)?; Self::process_hrmp_close_channel_requests(); Ok(()) } - /// This cancels a pending open channel request. It can be canceled be either of the sender + /// This cancels a pending open channel request. It can be canceled by either of the sender /// or the recipient for that request. The origin must be either of those. /// /// The cancellation happens immediately. It is not possible to cancel the request if it is /// already accepted. - #[pallet::weight(0)] + /// + /// Total number of open requests (i.e. `HrmpOpenChannelRequestsList`) must be provided as + /// witness data. + #[pallet::weight(::WeightInfo::hrmp_cancel_open_request(*open_requests))] pub fn hrmp_cancel_open_request( origin: OriginFor, channel_id: HrmpChannelId, + open_requests: u32, ) -> DispatchResult { let origin = ensure_parachain(::Origin::from(origin))?; + ensure!( + ::HrmpOpenChannelRequestsList::decode_len().unwrap_or_default() + as u32 <= open_requests, + Error::::WrongWitness + ); Self::cancel_open_request(origin, channel_id.clone())?; Self::deposit_event(Event::OpenChannelCanceled(origin, channel_id)); Ok(()) @@ -535,10 +616,16 @@ impl Pallet { pub(crate) fn initializer_on_new_session( notification: &initializer::SessionChangeNotification, outgoing_paras: &[ParaId], - ) { - Self::perform_outgoing_para_cleanup(¬ification.prev_config, outgoing_paras); + ) -> Weight { + let w1 = Self::perform_outgoing_para_cleanup(¬ification.prev_config, outgoing_paras); Self::process_hrmp_open_channel_requests(¬ification.prev_config); Self::process_hrmp_close_channel_requests(); + w1.saturating_add(::WeightInfo::force_process_hrmp_open( + outgoing_paras.len() as u32 + )) + .saturating_add(::WeightInfo::force_process_hrmp_close( + outgoing_paras.len() as u32 + )) } /// Iterate over all paras that were noted for offboarding and remove all the data @@ -546,20 +633,32 @@ impl Pallet { fn perform_outgoing_para_cleanup( config: &HostConfiguration, outgoing: &[ParaId], - ) { - Self::clean_open_channel_requests(config, outgoing); + ) -> Weight { + let mut w = Self::clean_open_channel_requests(config, outgoing); for outgoing_para in outgoing { Self::clean_hrmp_after_outgoing(outgoing_para); + + // we need a few extra bits of data to weigh this -- all of this is read internally + // anyways, so no overhead. + let ingress_count = ::HrmpIngressChannelsIndex::decode_len(outgoing_para) + .unwrap_or_default() as u32; + let egress_count = ::HrmpEgressChannelsIndex::decode_len(outgoing_para) + .unwrap_or_default() as u32; + w = w.saturating_add(::WeightInfo::force_clean_hrmp( + ingress_count, + egress_count, + )); } + w } // Go over the HRMP open channel requests and remove all in which offboarding paras participate. // // This will also perform the refunds for the counterparty if it doesn't offboard. - fn clean_open_channel_requests( + pub(crate) fn clean_open_channel_requests( config: &HostConfiguration, outgoing: &[ParaId], - ) { + ) -> Weight { // First collect all the channel ids of the open requests in which there is at least one // party presents in the outgoing list. // @@ -605,6 +704,8 @@ impl Pallet { Self::decrease_accepted_channel_request_count(req_id.recipient); } } + + ::WeightInfo::clean_open_channel_requests(outgoing.len() as u32) } /// Remove all storage entries associated with the given para. @@ -983,8 +1084,8 @@ impl Pallet { /// Initiate opening a channel from a parachain to a given recipient with given channel /// parameters. /// - /// Basically the same as [`hrmp_init_open_channel`](Pallet::hrmp_init_open_channel) but intendend for calling directly from - /// other pallets rather than dispatched. + /// Basically the same as [`hrmp_init_open_channel`](Pallet::hrmp_init_open_channel) but + /// intended for calling directly from other pallets rather than dispatched. pub fn init_open_channel( origin: ParaId, recipient: ParaId, @@ -1037,6 +1138,8 @@ impl Pallet { config.hrmp_sender_deposit.unique_saturated_into(), )?; + // mutating storage directly now -- shall not bail henceforth. + ::HrmpOpenChannelRequestCount::insert(&origin, open_req_cnt + 1); ::HrmpOpenChannelRequests::insert( &channel_id, @@ -1067,6 +1170,10 @@ impl Pallet { { // this should never happen unless the max downward message size is configured to an // jokingly small number. + log::error!( + target: "runtime::hrmp", + "sending 'init_open_channel::notification_bytes' failed." + ); debug_assert!(false); } @@ -1076,7 +1183,7 @@ impl Pallet { /// Accept a pending open channel request from the given sender. /// /// Basically the same as [`hrmp_accept_open_channel`](Pallet::hrmp_accept_open_channel) but - /// intendend for calling directly from other pallets rather than dispatched. + /// intended for calling directly from other pallets rather than dispatched. pub fn accept_open_channel(origin: ParaId, sender: ParaId) -> DispatchResult { let channel_id = HrmpChannelId { sender, recipient: origin }; let mut channel_req = ::HrmpOpenChannelRequests::get(&channel_id) @@ -1121,6 +1228,10 @@ impl Pallet { { // this should never happen unless the max downward message size is configured to an // jokingly small number. + log::error!( + target: "runtime::hrmp", + "sending 'accept_open_channel::notification_bytes' failed." + ); debug_assert!(false); } @@ -1195,6 +1306,10 @@ impl Pallet { { // this should never happen unless the max downward message size is configured to an // jokingly small number. + log::error!( + target: "runtime::hrmp", + "sending 'close_channel::notification_bytes' failed." + ); debug_assert!(false); } @@ -1262,10 +1377,175 @@ impl Pallet { }); }); } + + #[cfg(any(feature = "runtime-benchmarks", test))] + fn assert_storage_consistency_exhaustive() { + fn assert_is_sorted(slice: &[T], id: &str) { + assert!(slice.windows(2).all(|xs| xs[0] <= xs[1]), "{} supposed to be sorted", id); + } + + let assert_contains_only_onboarded = |paras: Vec, cause: &str| { + for para in paras { + assert!( + crate::paras::Pallet::::is_valid_para(para), + "{}: {:?} para is offboarded", + cause, + para + ); + } + }; + + assert_eq!( + ::HrmpOpenChannelRequests::iter() + .map(|(k, _)| k) + .collect::>(), + ::HrmpOpenChannelRequestsList::get() + .into_iter() + .collect::>(), + ); + + // verify that the set of keys in `HrmpOpenChannelRequestCount` corresponds to the set + // of _senders_ in `HrmpOpenChannelRequests`. + // + // having ensured that, we can go ahead and go over all counts and verify that they match. + assert_eq!( + ::HrmpOpenChannelRequestCount::iter() + .map(|(k, _)| k) + .collect::>(), + ::HrmpOpenChannelRequests::iter() + .map(|(k, _)| k.sender) + .collect::>(), + ); + for (open_channel_initiator, expected_num) in + ::HrmpOpenChannelRequestCount::iter() + { + let actual_num = ::HrmpOpenChannelRequests::iter() + .filter(|(ch, _)| ch.sender == open_channel_initiator) + .count() as u32; + assert_eq!(expected_num, actual_num); + } + + // The same as above, but for accepted channel request count. Note that we are interested + // only in confirmed open requests. + assert_eq!( + ::HrmpAcceptedChannelRequestCount::iter() + .map(|(k, _)| k) + .collect::>(), + ::HrmpOpenChannelRequests::iter() + .filter(|(_, v)| v.confirmed) + .map(|(k, _)| k.recipient) + .collect::>(), + ); + for (channel_recipient, expected_num) in + ::HrmpAcceptedChannelRequestCount::iter() + { + let actual_num = ::HrmpOpenChannelRequests::iter() + .filter(|(ch, v)| ch.recipient == channel_recipient && v.confirmed) + .count() as u32; + assert_eq!(expected_num, actual_num); + } + + assert_eq!( + ::HrmpCloseChannelRequests::iter() + .map(|(k, _)| k) + .collect::>(), + ::HrmpCloseChannelRequestsList::get() + .into_iter() + .collect::>(), + ); + + // A HRMP watermark can be None for an onboarded parachain. However, an offboarded parachain + // cannot have an HRMP watermark: it should've been cleanup. + assert_contains_only_onboarded( + ::HrmpWatermarks::iter().map(|(k, _)| k).collect::>(), + "HRMP watermarks should contain only onboarded paras", + ); + + // An entry in `HrmpChannels` indicates that the channel is open. Only open channels can + // have contents. + for (non_empty_channel, contents) in ::HrmpChannelContents::iter() { + assert!(::HrmpChannels::contains_key(&non_empty_channel)); + + // pedantic check: there should be no empty vectors in storage, those should be modeled + // by a removed kv pair. + assert!(!contents.is_empty()); + } + + // Senders and recipients must be onboarded. Otherwise, all channels associated with them + // are removed. + assert_contains_only_onboarded( + ::HrmpChannels::iter() + .flat_map(|(k, _)| vec![k.sender, k.recipient]) + .collect::>(), + "senders and recipients in all channels should be onboarded", + ); + + // Check the docs for `HrmpIngressChannelsIndex` and `HrmpEgressChannelsIndex` in decl + // storage to get an index what are the channel mappings indexes. + // + // Here, from indexes. + // + // ingress egress + // + // a -> [x, y] x -> [a, b] + // b -> [x, z] y -> [a] + // z -> [b] + // + // we derive a list of channels they represent. + // + // (a, x) (a, x) + // (a, y) (a, y) + // (b, x) (b, x) + // (b, z) (b, z) + // + // and then that we compare that to the channel list in the `HrmpChannels`. + let channel_set_derived_from_ingress = ::HrmpIngressChannelsIndex::iter() + .flat_map(|(p, v)| v.into_iter().map(|i| (i, p)).collect::>()) + .collect::>(); + let channel_set_derived_from_egress = ::HrmpEgressChannelsIndex::iter() + .flat_map(|(p, v)| v.into_iter().map(|e| (p, e)).collect::>()) + .collect::>(); + let channel_set_ground_truth = ::HrmpChannels::iter() + .map(|(k, _)| (k.sender, k.recipient)) + .collect::>(); + assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress); + assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth); + + ::HrmpIngressChannelsIndex::iter() + .map(|(_, v)| v) + .for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex")); + ::HrmpEgressChannelsIndex::iter() + .map(|(_, v)| v) + .for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex")); + + assert_contains_only_onboarded( + ::HrmpChannelDigests::iter().map(|(k, _)| k).collect::>(), + "HRMP channel digests should contain only onboarded paras", + ); + for (_digest_for_para, digest) in ::HrmpChannelDigests::iter() { + // Assert that items are in **strictly** ascending order. The strictness also implies + // there are no duplicates. + assert!(digest.windows(2).all(|xs| xs[0].0 < xs[1].0)); + + for (_, mut senders) in digest { + assert!(!senders.is_empty()); + + // check for duplicates. For that we sort the vector, then perform deduplication. + // if the vector stayed the same, there are no duplicates. + senders.sort(); + let orig_senders = senders.clone(); + senders.dedup(); + assert_eq!( + orig_senders, senders, + "duplicates removed implies existence of duplicates" + ); + } + } + } } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; use crate::mock::{ new_test_ext, Configuration, Event as MockEvent, Hrmp, MockGenesisConfig, Paras, @@ -1273,7 +1553,7 @@ mod tests { }; use frame_support::{assert_noop, assert_ok, traits::Currency as _}; use primitives::v1::BlockNumber; - use std::collections::{BTreeMap, HashSet}; + use std::collections::BTreeMap; fn run_to_block(to: BlockNumber, new_session: Option>) { let config = Configuration::config(); @@ -1317,7 +1597,7 @@ mod tests { } #[derive(Debug)] - struct GenesisConfigBuilder { + pub(super) struct GenesisConfigBuilder { hrmp_channel_max_capacity: u32, hrmp_channel_max_message_size: u32, hrmp_max_parathread_outbound_channels: u32, @@ -1348,7 +1628,7 @@ mod tests { } impl GenesisConfigBuilder { - fn build(self) -> crate::mock::MockGenesisConfig { + pub(super) fn build(self) -> crate::mock::MockGenesisConfig { let mut genesis = default_genesis_config(); let config = &mut genesis.configuration.config; config.hrmp_channel_max_capacity = self.hrmp_channel_max_capacity; @@ -1403,167 +1683,10 @@ mod tests { ::HrmpChannels::get(&HrmpChannelId { sender, recipient }).is_some() } - fn assert_storage_consistency_exhaustive() { - assert_eq!( - ::HrmpOpenChannelRequests::iter() - .map(|(k, _)| k) - .collect::>(), - ::HrmpOpenChannelRequestsList::get() - .into_iter() - .collect::>(), - ); - - // verify that the set of keys in `HrmpOpenChannelRequestCount` corresponds to the set - // of _senders_ in `HrmpOpenChannelRequests`. - // - // having ensured that, we can go ahead and go over all counts and verify that they match. - assert_eq!( - ::HrmpOpenChannelRequestCount::iter() - .map(|(k, _)| k) - .collect::>(), - ::HrmpOpenChannelRequests::iter() - .map(|(k, _)| k.sender) - .collect::>(), - ); - for (open_channel_initiator, expected_num) in - ::HrmpOpenChannelRequestCount::iter() - { - let actual_num = ::HrmpOpenChannelRequests::iter() - .filter(|(ch, _)| ch.sender == open_channel_initiator) - .count() as u32; - assert_eq!(expected_num, actual_num); - } - - // The same as above, but for accepted channel request count. Note that we are interested - // only in confirmed open requests. - assert_eq!( - ::HrmpAcceptedChannelRequestCount::iter() - .map(|(k, _)| k) - .collect::>(), - ::HrmpOpenChannelRequests::iter() - .filter(|(_, v)| v.confirmed) - .map(|(k, _)| k.recipient) - .collect::>(), - ); - for (channel_recipient, expected_num) in - ::HrmpAcceptedChannelRequestCount::iter() - { - let actual_num = ::HrmpOpenChannelRequests::iter() - .filter(|(ch, v)| ch.recipient == channel_recipient && v.confirmed) - .count() as u32; - assert_eq!(expected_num, actual_num); - } - - assert_eq!( - ::HrmpCloseChannelRequests::iter() - .map(|(k, _)| k) - .collect::>(), - ::HrmpCloseChannelRequestsList::get() - .into_iter() - .collect::>(), - ); - - // A HRMP watermark can be None for an onboarded parachain. However, an offboarded parachain - // cannot have an HRMP watermark: it should've been cleanup. - assert_contains_only_onboarded( - ::HrmpWatermarks::iter().map(|(k, _)| k), - "HRMP watermarks should contain only onboarded paras", - ); - - // An entry in `HrmpChannels` indicates that the channel is open. Only open channels can - // have contents. - for (non_empty_channel, contents) in ::HrmpChannelContents::iter() { - assert!(::HrmpChannels::contains_key(&non_empty_channel)); - - // pedantic check: there should be no empty vectors in storage, those should be modeled - // by a removed kv pair. - assert!(!contents.is_empty()); - } - - // Senders and recipients must be onboarded. Otherwise, all channels associated with them - // are removed. - assert_contains_only_onboarded( - ::HrmpChannels::iter().flat_map(|(k, _)| vec![k.sender, k.recipient]), - "senders and recipients in all channels should be onboarded", - ); - - // Check the docs for `HrmpIngressChannelsIndex` and `HrmpEgressChannelsIndex` in decl - // storage to get an index what are the channel mappings indexes. - // - // Here, from indexes. - // - // ingress egress - // - // a -> [x, y] x -> [a, b] - // b -> [x, z] y -> [a] - // z -> [b] - // - // we derive a list of channels they represent. - // - // (a, x) (a, x) - // (a, y) (a, y) - // (b, x) (b, x) - // (b, z) (b, z) - // - // and then that we compare that to the channel list in the `HrmpChannels`. - let channel_set_derived_from_ingress = ::HrmpIngressChannelsIndex::iter() - .flat_map(|(p, v)| v.into_iter().map(|i| (i, p)).collect::>()) - .collect::>(); - let channel_set_derived_from_egress = ::HrmpEgressChannelsIndex::iter() - .flat_map(|(p, v)| v.into_iter().map(|e| (p, e)).collect::>()) - .collect::>(); - let channel_set_ground_truth = ::HrmpChannels::iter() - .map(|(k, _)| (k.sender, k.recipient)) - .collect::>(); - assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress); - assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth); - - ::HrmpIngressChannelsIndex::iter() - .map(|(_, v)| v) - .for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex")); - ::HrmpEgressChannelsIndex::iter() - .map(|(_, v)| v) - .for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex")); - - assert_contains_only_onboarded( - ::HrmpChannelDigests::iter().map(|(k, _)| k), - "HRMP channel digests should contain only onboarded paras", - ); - for (_digest_for_para, digest) in ::HrmpChannelDigests::iter() { - // Assert that items are in **strictly** ascending order. The strictness also implies - // there are no duplicates. - assert!(digest.windows(2).all(|xs| xs[0].0 < xs[1].0)); - - for (_, mut senders) in digest { - assert!(!senders.is_empty()); - - // check for duplicates. For that we sort the vector, then perform deduplication. - // if the vector stayed the same, there are no duplicates. - senders.sort(); - let orig_senders = senders.clone(); - senders.dedup(); - assert_eq!( - orig_senders, senders, - "duplicates removed implies existence of duplicates" - ); - } - } - - fn assert_contains_only_onboarded(iter: impl Iterator, cause: &str) { - for para in iter { - assert!(Paras::is_valid_para(para), "{}: {} para is offboarded", cause, para); - } - } - } - - fn assert_is_sorted(slice: &[T], id: &str) { - assert!(slice.windows(2).all(|xs| xs[0] <= xs[1]), "{} supposed to be sorted", id); - } - #[test] fn empty_state_consistent_state() { new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); }); } @@ -1581,12 +1704,12 @@ mod tests { run_to_block(5, Some(vec![4, 5])); Hrmp::hrmp_init_open_channel(para_a_origin.into(), para_b, 2, 8).unwrap(); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); assert!(System::events().iter().any(|record| record.event == MockEvent::Hrmp(Event::OpenChannelRequested(para_a, para_b, 2, 8)))); Hrmp::hrmp_accept_open_channel(para_b_origin.into(), para_a).unwrap(); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); assert!(System::events().iter().any(|record| record.event == MockEvent::Hrmp(Event::OpenChannelAccepted(para_a, para_b)))); @@ -1594,7 +1717,7 @@ mod tests { // not been created yet. run_to_block(6, None); assert!(!channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); // Now let the session change happen and thus open the channel. run_to_block(8, Some(vec![8])); @@ -1624,12 +1747,12 @@ mod tests { let channel_id = HrmpChannelId { sender: para_a, recipient: para_b }; Hrmp::hrmp_close_channel(para_b_origin.into(), channel_id.clone()).unwrap(); assert!(channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); // After the session change the channel should be closed. run_to_block(8, Some(vec![8])); assert!(!channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); assert!(System::events().iter().any(|record| record.event == MockEvent::Hrmp(Event::ChannelClosed(para_b, channel_id.clone())))); }); @@ -1662,14 +1785,14 @@ mod tests { let config = Configuration::config(); assert!(Hrmp::check_outbound_hrmp(&config, para_a, &msgs).is_ok()); let _ = Hrmp::queue_outbound_hrmp(para_a, msgs); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); // On Block 7: // B receives the message sent by A. B sets the watermark to 6. run_to_block(7, None); assert!(Hrmp::check_hrmp_watermark(para_b, 7, 6).is_ok()); let _ = Hrmp::prune_hrmp(para_b, 6); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); }); } @@ -1732,7 +1855,7 @@ mod tests { run_to_block(7, Some(vec![6, 7])); assert!(!Paras::is_valid_para(para_a)); assert!(!channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); }); } @@ -1791,7 +1914,7 @@ mod tests { ], ); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); }); } @@ -1940,7 +2063,7 @@ mod tests { // The channel should be removed. assert!(!Paras::is_valid_para(para_a)); assert!(!channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); assert_eq!(::Currency::free_balance(¶_a.into_account()), 100); assert_eq!(::Currency::free_balance(¶_b.into_account()), 110); @@ -1978,7 +2101,7 @@ mod tests { // The outcome we expect is `para_b` should receive the refund. assert_eq!(::Currency::free_balance(¶_b.into_account()), 110); assert!(!channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); }); } @@ -2007,7 +2130,7 @@ mod tests { run_to_block(10, Some(vec![10])); assert!(!channel_exists(para_a, para_b)); - assert_storage_consistency_exhaustive(); + Hrmp::assert_storage_consistency_exhaustive(); }); } } diff --git a/polkadot/runtime/parachains/src/hrmp/benchmarking.rs b/polkadot/runtime/parachains/src/hrmp/benchmarking.rs new file mode 100644 index 0000000000..a9ba7031fe --- /dev/null +++ b/polkadot/runtime/parachains/src/hrmp/benchmarking.rs @@ -0,0 +1,303 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +use crate::{ + configuration::Pallet as Configuration, + hrmp::{Pallet as Hrmp, *}, + paras::Pallet as Paras, + shared::Pallet as Shared, +}; +use frame_support::{assert_ok, traits::Currency}; + +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +fn register_parachain_with_balance(id: ParaId, balance: BalanceOf) { + assert_ok!(Paras::::initialize_para_now( + id, + crate::paras::ParaGenesisArgs { + parachain: true, + genesis_head: vec![1].into(), + validation_code: vec![1].into(), + }, + )); + T::Currency::make_free_balance_be(&id.into_account(), balance); +} + +fn assert_last_event(generic_event: ::Event) { + let events = frame_system::Pallet::::events(); + let system_event: ::Event = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +/// Enumerates the phase in the setup process of a channel between two parachains. +enum ParachainSetupStep { + /// A channel open has been requested + Requested, + /// A channel open has been requested and accepted. + Accepted, + /// A channel open has been requested and accepted, and a session has passed and is now open. + Established, + /// A channel open has been requested and accepted, and a session has passed and is now + /// open, and now it has been requested to close down. + CloseRequested, +} + +fn establish_para_connection( + from: u32, + to: u32, + until: ParachainSetupStep, +) -> [(ParaId, crate::Origin); 2] +where + ::Origin: From, +{ + let config = Configuration::::config(); + let deposit: BalanceOf = config.hrmp_sender_deposit.unique_saturated_into(); + let capacity = config.hrmp_channel_max_capacity; + let message_size = config.hrmp_channel_max_message_size; + + let sender: ParaId = from.into(); + let sender_origin: crate::Origin = from.into(); + + let recipient: ParaId = to.into(); + let recipient_origin: crate::Origin = to.into(); + + let output = [(sender, sender_origin.clone()), (recipient, recipient_origin.clone())]; + + // Make both a parachain if they are already not. + if !Paras::::is_parachain(sender) { + register_parachain_with_balance::(sender, deposit); + } + if !Paras::::is_parachain(recipient) { + register_parachain_with_balance::(recipient, deposit); + } + + assert_ok!(Hrmp::::hrmp_init_open_channel( + sender_origin.clone().into(), + recipient, + capacity, + message_size + )); + + if matches!(until, ParachainSetupStep::Requested) { + return output + } + + assert_ok!(Hrmp::::hrmp_accept_open_channel(recipient_origin.into(), sender)); + if matches!(until, ParachainSetupStep::Accepted) { + return output + } + + Hrmp::::process_hrmp_open_channel_requests(&Configuration::::config()); + if matches!(until, ParachainSetupStep::Established) { + return output + } + + let channel_id = HrmpChannelId { sender, recipient }; + assert_ok!(Hrmp::::hrmp_close_channel(sender_origin.clone().into(), channel_id)); + if matches!(until, ParachainSetupStep::CloseRequested) { + // NOTE: this is just for expressiveness, otherwise the if-statement is 100% useless. + return output + } + + output +} + +/// Prefix value for account generation. These numbers are used as seeds to create distinct (para) +/// accounts. +/// +/// To maintain sensibility created accounts should always be unique and never overlap. For example, +/// if for some benchmarking component `c`, accounts are being created `for s in 0..c` with seed +/// `PREFIX_0 + s`, then we must assert that `c <= PREFIX_1`, meaning that it won't overlap with +/// `PREFIX_2`. +/// +/// These values are chosen large enough so that the likelihood of any clash is already very low. +const PREFIX_0: u32 = 10_000; +const PREFIX_1: u32 = PREFIX_0 * 2; +const MAX_UNIQUE_CHANNELS: u32 = 128; + +static_assertions::const_assert!(MAX_UNIQUE_CHANNELS < PREFIX_0); +static_assertions::const_assert!(HRMP_MAX_INBOUND_CHANNELS_BOUND < PREFIX_0); +static_assertions::const_assert!(HRMP_MAX_OUTBOUND_CHANNELS_BOUND < PREFIX_0); + +frame_benchmarking::benchmarks! { + where_clause { where ::Origin: From } + + hrmp_init_open_channel { + let sender_id: ParaId = 1u32.into(); + let sender_origin: crate::Origin = 1u32.into(); + + let recipient_id: ParaId = 2u32.into(); + + // make sure para is registered, and has enough balance. + let deposit: BalanceOf = Configuration::::config().hrmp_sender_deposit.unique_saturated_into(); + register_parachain_with_balance::(sender_id, deposit); + register_parachain_with_balance::(recipient_id, deposit); + + let capacity = Configuration::::config().hrmp_channel_max_capacity; + let message_size = Configuration::::config().hrmp_channel_max_message_size; + }: _(sender_origin, recipient_id, capacity, message_size) + verify { + assert_last_event::( + Event::::OpenChannelRequested(sender_id, recipient_id, capacity, message_size).into() + ); + } + + hrmp_accept_open_channel { + let [(sender, _), (recipient, recipient_origin)] = + establish_para_connection::(1, 2, ParachainSetupStep::Requested); + }: _(recipient_origin, sender) + verify { + assert_last_event::(Event::::OpenChannelAccepted(sender, recipient).into()); + } + + hrmp_close_channel { + let [(sender, sender_origin), (recipient, _)] = + establish_para_connection::(1, 2, ParachainSetupStep::Established); + let channel_id = HrmpChannelId { sender, recipient }; + }: _(sender_origin, channel_id.clone()) + verify { + assert_last_event::(Event::::ChannelClosed(sender, channel_id).into()); + } + + // NOTE: a single parachain should have the maximum number of allowed ingress and egress + // channels. + force_clean_hrmp { + // ingress channels to a single leaving parachain that need to be closed. + let i in 0 .. (HRMP_MAX_INBOUND_CHANNELS_BOUND - 1); + // egress channels to a single leaving parachain that need to be closed. + let e in 0 .. (HRMP_MAX_OUTBOUND_CHANNELS_BOUND - 1); + + // first, update the configs to support this many open channels... + assert_ok!( + Configuration::::set_hrmp_max_parachain_outbound_channels(frame_system::RawOrigin::Root.into(), e + 1) + ); + assert_ok!( + Configuration::::set_hrmp_max_parachain_inbound_channels(frame_system::RawOrigin::Root.into(), i + 1) + ); + // .. and enact it. + Configuration::::initializer_on_new_session(&Shared::::scheduled_session()); + + let config = Configuration::::config(); + let deposit: BalanceOf = config.hrmp_sender_deposit.unique_saturated_into(); + + let para: ParaId = 1u32.into(); + let para_origin: crate::Origin = 1u32.into(); + register_parachain_with_balance::(para, deposit); + T::Currency::make_free_balance_be(¶.into_account(), deposit * 256u32.into()); + + for ingress_para_id in 0..i { + // establish ingress channels to `para`. + let ingress_para_id = ingress_para_id + PREFIX_0; + let _ = establish_para_connection::(ingress_para_id, para.into(), ParachainSetupStep::Established); + } + + // nothing should be left unprocessed. + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default(), 0); + + for egress_para_id in 0..e { + // establish egress channels to `para`. + let egress_para_id = egress_para_id + PREFIX_1; + let _ = establish_para_connection::(para.into(), egress_para_id, ParachainSetupStep::Established); + } + + // nothing should be left unprocessed. + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default(), 0); + + // all in all, we have created this many channels. + assert_eq!(HrmpChannels::::iter().count() as u32, i + e); + }: _(frame_system::Origin::::Root, para, i, e) verify { + // all in all, all of them must be gone by now. + assert_eq!(HrmpChannels::::iter().count() as u32, 0); + // borrow this function from the tests to make sure state is clear, given that we do a lot + // of out-of-ordinary ops here. + Hrmp::::assert_storage_consistency_exhaustive(); + } + + force_process_hrmp_open { + // number of channels that need to be processed. Worse case is an N-M relation: unique + // sender and recipients for all channels. + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Accepted); + } + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + }: _(frame_system::Origin::::Root, c) + verify { + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, 0); + } + + force_process_hrmp_close { + // number of channels that need to be processed. Worse case is an N-M relation: unique + // sender and recipients for all channels. + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::CloseRequested); + } + + assert_eq!(HrmpCloseChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + }: _(frame_system::Origin::::Root, c) + verify { + assert_eq!(HrmpCloseChannelRequestsList::::decode_len().unwrap_or_default() as u32, 0); + } + + hrmp_cancel_open_request { + // number of items already existing in the `HrmpOpenChannelRequestsList`, other than the + // one that we remove. + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested); + } + + let [(sender, sender_origin), (recipient, _)] = + establish_para_connection::(1, 2, ParachainSetupStep::Requested); + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c + 1); + let channel_id = HrmpChannelId { sender, recipient }; + }: _(sender_origin, channel_id, c + 1) + verify { + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + } + + // worse case will be `n` parachain channel requests, where in all of them either the sender or + // the recipient need to be cleaned. This enforces the deposit of at least one to be processed. + // No code path for triggering two deposit process exists. + clean_open_channel_requests { + let c in 0 .. MAX_UNIQUE_CHANNELS; + + for id in 0 .. c { + let _ = establish_para_connection::(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested); + } + + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, c); + let outgoing = (0..c).map(|id| (id + PREFIX_1).into()).collect::>(); + let config = Configuration::::config(); + }: { + Hrmp::::clean_open_channel_requests(&config, &outgoing); + } verify { + assert_eq!(HrmpOpenChannelRequestsList::::decode_len().unwrap_or_default() as u32, 0); + } +} + +frame_benchmarking::impl_benchmark_test_suite!( + Hrmp, + crate::mock::new_test_ext(crate::hrmp::tests::GenesisConfigBuilder::default().build()), + crate::mock::Test +); diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index cfc9808891..05abd0de27 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -236,6 +236,7 @@ impl crate::hrmp::Config for Test { type Event = Event; type Origin = Origin; type Currency = pallet_balances::Pallet; + type WeightInfo = crate::hrmp::TestWeightInfo; } impl crate::disputes::Config for Test { @@ -363,6 +364,7 @@ impl UmpSink for TestUmpSink { let id = sp_io::hashing::blake2_256(actual_msg); return Err((id, weight)) } + PROCESSED.with(|opt_hook| { opt_hook.borrow_mut().push((actual_origin, actual_msg.to_owned())); }); @@ -395,6 +397,9 @@ impl inclusion::RewardValidators for TestRewardValidators { pub fn new_test_ext(state: MockGenesisConfig) -> TestExternalities { use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStorePtr}; use sp_std::sync::Arc; + + sp_tracing::try_init_simple(); + BACKING_REWARDS.with(|r| r.borrow_mut().clear()); AVAILABILITY_REWARDS.with(|r| r.borrow_mut().clear()); diff --git a/polkadot/runtime/parachains/src/paras/mod.rs b/polkadot/runtime/parachains/src/paras/mod.rs index e2727cd3e9..5422cf1724 100644 --- a/polkadot/runtime/parachains/src/paras/mod.rs +++ b/polkadot/runtime/parachains/src/paras/mod.rs @@ -1993,4 +1993,20 @@ impl Pallet { pub fn heads_insert(para_id: &ParaId, head_data: HeadData) { Heads::::insert(para_id, head_data); } + + #[cfg(feature = "runtime-benchmarks")] + pub(crate) fn initialize_para_now(id: ParaId, genesis: ParaGenesisArgs) -> DispatchResult { + // first queue this para actions.. + let _ = Self::schedule_para_initialize(id, genesis)?; + + // .. and immediately apply them. + Self::apply_actions_queue(Self::scheduled_session()); + + // ensure it has become a para. + ensure!( + ParaLifecycles::::get(id) == Some(ParaLifecycle::Parachain), + "Parachain not created properly" + ); + Ok(()) + } } diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs index 1773e0daad..c49a6d46ce 100644 --- a/polkadot/runtime/polkadot/src/lib.rs +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -1218,6 +1218,7 @@ impl parachains_hrmp::Config for Runtime { type Event = Event; type Origin = Origin; type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; } impl parachains_paras_inherent::Config for Runtime { diff --git a/polkadot/runtime/polkadot/src/weights/mod.rs b/polkadot/runtime/polkadot/src/weights/mod.rs index 867877111a..a93100277a 100644 --- a/polkadot/runtime/polkadot/src/weights/mod.rs +++ b/polkadot/runtime/polkadot/src/weights/mod.rs @@ -45,6 +45,7 @@ pub mod runtime_common_crowdloan; pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; pub mod runtime_parachains_configuration; +pub mod runtime_parachains_hrmp; pub mod runtime_parachains_initializer; pub mod runtime_parachains_paras; pub mod runtime_parachains_paras_inherent; diff --git a/polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000..de6e57873b --- /dev/null +++ b/polkadot/runtime/polkadot/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,157 @@ +// Copyright 2017-2021 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 . +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_hrmp.rs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + // Storage: Paras ParaLifecycles (r:2 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_init_open_channel() -> Weight { + (54_952_000 as Weight) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Paras ParaLifecycles (r:1 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_accept_open_channel() -> Weight { + (47_965_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_close_channel() -> Weight { + (44_369_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:127) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:127 w:127) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + // Storage: Hrmp HrmpChannelContents (r:0 w:127) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 17_000 + .saturating_add((15_959_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 17_000 + .saturating_add((16_048_000 as Weight).saturating_mul(e as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(e as Weight))) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(e as Weight))) + } + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + // Storage: Paras ParaLifecycles (r:4 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpChannels (r:0 w:2) + fn force_process_hrmp_open(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 26_000 + .saturating_add((35_598_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((7 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((6 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpChannels (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpCloseChannelRequests (r:0 w:2) + // Storage: Hrmp HrmpChannelContents (r:0 w:2) + fn force_process_hrmp_close(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 15_000 + .saturating_add((20_510_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + (32_749_000 as Weight) + // Standard Error: 0 + .saturating_add((59_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + fn clean_open_channel_requests(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((5_781_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) + } +} diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 89e9b2ce3d..1c15d2c932 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -596,7 +596,7 @@ impl pallet_authorship::Config for Runtime { impl parachains_origin::Config for Runtime {} impl parachains_configuration::Config for Runtime { - type WeightInfo = weights::runtime_parachains_configuration::WeightInfo; + type WeightInfo = parachains_configuration::TestWeightInfo; } impl parachains_shared::Config for Runtime {} @@ -645,6 +645,7 @@ impl parachains_hrmp::Config for Runtime { type Event = Event; type Origin = Origin; type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; } impl parachains_paras_inherent::Config for Runtime { diff --git a/polkadot/runtime/rococo/src/weights/mod.rs b/polkadot/runtime/rococo/src/weights/mod.rs index ccd1e3b0cd..b8931b180a 100644 --- a/polkadot/runtime/rococo/src/weights/mod.rs +++ b/polkadot/runtime/rococo/src/weights/mod.rs @@ -17,5 +17,6 @@ pub mod runtime_parachains_configuration; pub mod runtime_parachains_disputes; +pub mod runtime_parachains_hrmp; pub mod runtime_parachains_paras; pub mod runtime_parachains_paras_inherent; diff --git a/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000..de6e57873b --- /dev/null +++ b/polkadot/runtime/rococo/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,157 @@ +// Copyright 2017-2021 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 . +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=kusama-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/kusama/src/weights/runtime_parachains_hrmp.rs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + // Storage: Paras ParaLifecycles (r:2 w:0) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_init_open_channel() -> Weight { + (54_952_000 as Weight) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Paras ParaLifecycles (r:1 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_accept_open_channel() -> Weight { + (47_965_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_close_channel() -> Weight { + (44_369_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:127) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:127 w:127) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + // Storage: Hrmp HrmpChannelContents (r:0 w:127) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 17_000 + .saturating_add((15_959_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 17_000 + .saturating_add((16_048_000 as Weight).saturating_mul(e as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(e as Weight))) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(e as Weight))) + } + // Storage: Configuration ActiveConfig (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + // Storage: Paras ParaLifecycles (r:4 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpChannels (r:0 w:2) + fn force_process_hrmp_open(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 26_000 + .saturating_add((35_598_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((7 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((6 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpChannels (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpCloseChannelRequests (r:0 w:2) + // Storage: Hrmp HrmpChannelContents (r:0 w:2) + fn force_process_hrmp_close(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 15_000 + .saturating_add((20_510_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + (32_749_000 as Weight) + // Standard Error: 0 + .saturating_add((59_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + fn clean_open_channel_requests(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((5_781_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) + } +} diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index eed721ad88..1e5859cc3f 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -549,6 +549,7 @@ impl parachains_hrmp::Config for Runtime { type Event = Event; type Origin = Origin; type Currency = Balances; + type WeightInfo = parachains_hrmp::TestWeightInfo; } impl parachains_scheduler::Config for Runtime {} diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 051db95a01..d57e17ebb0 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -858,6 +858,7 @@ impl parachains_hrmp::Config for Runtime { type Event = Event; type Origin = Origin; type Currency = Balances; + type WeightInfo = weights::runtime_parachains_hrmp::WeightInfo; } impl parachains_paras_inherent::Config for Runtime { @@ -1479,6 +1480,7 @@ sp_api::impl_runtime_apis! { list_benchmark!(list, extra, runtime_common::paras_registrar, Registrar); list_benchmark!(list, extra, runtime_common::slots, Slots); list_benchmark!(list, extra, runtime_parachains::configuration, Configuration); + list_benchmark!(list, extra, runtime_parachains::hrmp, Hrmp); list_benchmark!(list, extra, runtime_parachains::initializer, Initializer); list_benchmark!(list, extra, runtime_parachains::paras_inherent, ParaInherent); list_benchmark!(list, extra, runtime_parachains::paras, Paras); @@ -1629,6 +1631,7 @@ sp_api::impl_runtime_apis! { add_benchmark!(params, batches, runtime_common::paras_registrar, Registrar); add_benchmark!(params, batches, runtime_common::slots, Slots); add_benchmark!(params, batches, runtime_parachains::configuration, Configuration); + add_benchmark!(params, batches, runtime_parachains::hrmp, Hrmp); add_benchmark!(params, batches, runtime_parachains::initializer, Initializer); add_benchmark!(params, batches, runtime_parachains::paras, Paras); add_benchmark!(params, batches, runtime_parachains::paras_inherent, ParaInherent); diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs index 600233f4cf..69ace0a5a6 100644 --- a/polkadot/runtime/westend/src/weights/mod.rs +++ b/polkadot/runtime/westend/src/weights/mod.rs @@ -36,6 +36,7 @@ pub mod runtime_common_crowdloan; pub mod runtime_common_paras_registrar; pub mod runtime_common_slots; pub mod runtime_parachains_configuration; +pub mod runtime_parachains_hrmp; pub mod runtime_parachains_initializer; pub mod runtime_parachains_paras; pub mod runtime_parachains_paras_inherent; diff --git a/polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs b/polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs new file mode 100644 index 0000000000..72a12c67e8 --- /dev/null +++ b/polkadot/runtime/westend/src/weights/runtime_parachains_hrmp.rs @@ -0,0 +1,153 @@ +// Copyright 2017-2021 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 . +//! Autogenerated weights for `runtime_parachains::hrmp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-11-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 128 + +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --pallet=runtime_parachains::hrmp +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --output=./runtime/westend/src/weights/runtime_parachains_hrmp.rs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for `runtime_parachains::hrmp`. +pub struct WeightInfo(PhantomData); +impl runtime_parachains::hrmp::WeightInfo for WeightInfo { + // Storage: Paras ParaLifecycles (r:2 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_init_open_channel() -> Weight { + (55_142_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Paras ParaLifecycles (r:1 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:1 w:0) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_accept_open_channel() -> Weight { + (47_170_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpChannels (r:1 w:0) + // Storage: Hrmp HrmpCloseChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:1) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + fn hrmp_close_channel() -> Weight { + (43_586_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Hrmp HrmpIngressChannelsIndex (r:128 w:127) + // Storage: Hrmp HrmpEgressChannelsIndex (r:1 w:1) + // Storage: Hrmp HrmpChannels (r:127 w:127) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:0 w:1) + // Storage: Hrmp HrmpChannelContents (r:0 w:127) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:0 w:1) + fn force_clean_hrmp(i: u32, e: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 21_000 + .saturating_add((15_726_000 as Weight).saturating_mul(i as Weight)) + // Standard Error: 21_000 + .saturating_add((15_859_000 as Weight).saturating_mul(e as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(e as Weight))) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(i as Weight))) + .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(e as Weight))) + } + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + // Storage: Paras ParaLifecycles (r:4 w:0) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpAcceptedChannelRequestCount (r:2 w:2) + // Storage: Hrmp HrmpChannels (r:0 w:2) + fn force_process_hrmp_open(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 24_000 + .saturating_add((35_104_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((7 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((6 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpCloseChannelRequestsList (r:1 w:0) + // Storage: Hrmp HrmpChannels (r:2 w:2) + // Storage: Hrmp HrmpEgressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpIngressChannelsIndex (r:2 w:2) + // Storage: Hrmp HrmpCloseChannelRequests (r:0 w:2) + // Storage: Hrmp HrmpChannelContents (r:0 w:2) + fn force_process_hrmp_close(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 14_000 + .saturating_add((20_295_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((5 as Weight).saturating_mul(c as Weight))) + } + // Storage: Hrmp HrmpOpenChannelRequests (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequestCount (r:1 w:1) + fn hrmp_cancel_open_request(c: u32, ) -> Weight { + (32_796_000 as Weight) + // Standard Error: 0 + .saturating_add((58_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Hrmp HrmpOpenChannelRequestsList (r:1 w:1) + // Storage: Hrmp HrmpOpenChannelRequests (r:2 w:2) + fn clean_open_channel_requests(c: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 6_000 + .saturating_add((5_748_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(c as Weight))) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(c as Weight))) + } +}