mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 07:58:00 +00:00
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 <kungfukeith11@gmail.com> * 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 <z.mostov@gmail.com> * 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 <admin@parity.io> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Sergey Shulepov <s.pepyakin@gmail.com> Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
This commit is contained in:
Generated
+1
@@ -7031,6 +7031,7 @@ dependencies = [
|
||||
"sp-staking",
|
||||
"sp-std",
|
||||
"sp-tracing",
|
||||
"static_assertions",
|
||||
"thousands",
|
||||
"xcm",
|
||||
"xcm-executor",
|
||||
|
||||
@@ -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<Self>;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
//! 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<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> runtime_parachains::hrmp::WeightInfo for WeightInfo<T> {
|
||||
// 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)))
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -319,6 +319,10 @@ pub enum InconsistentError<BlockNumber> {
|
||||
},
|
||||
/// `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<BlockNumber> HostConfiguration<BlockNumber>
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Self::AccountId>;
|
||||
|
||||
/// 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<T: Config> =
|
||||
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<T: Config> =
|
||||
StorageValue<_, Vec<HrmpChannelId>, 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<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, u32, ValueQuery>;
|
||||
@@ -281,8 +341,8 @@ pub mod pallet {
|
||||
pub type HrmpAcceptedChannelRequestCount<T: Config> =
|
||||
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<T: Config> = 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<ParaId>` is never empty.
|
||||
/// - The inner `Vec<ParaId>` 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<T: Config> =
|
||||
StorageMap<_, Twox64Concat, ParaId, Vec<(T::BlockNumber, Vec<ParaId>)>, 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(<T as Config>::WeightInfo::hrmp_init_open_channel())]
|
||||
pub fn hrmp_init_open_channel(
|
||||
origin: OriginFor<T>,
|
||||
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(<T as Config>::WeightInfo::hrmp_accept_open_channel())]
|
||||
pub fn hrmp_accept_open_channel(origin: OriginFor<T>, sender: ParaId) -> DispatchResult {
|
||||
let origin = ensure_parachain(<T as Config>::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(<T as Config>::WeightInfo::hrmp_close_channel())]
|
||||
pub fn hrmp_close_channel(
|
||||
origin: OriginFor<T>,
|
||||
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<T>, para: ParaId) -> DispatchResult {
|
||||
///
|
||||
/// Number of inbound and outbound channels for `para` must be provided as witness data of weighing.
|
||||
#[pallet::weight(<T as Config>::WeightInfo::force_clean_hrmp(*_inbound, *_outbound))]
|
||||
pub fn force_clean_hrmp(
|
||||
origin: OriginFor<T>,
|
||||
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<T>) -> DispatchResult {
|
||||
///
|
||||
/// Total number of opening channels must be provided as witness data of weighing.
|
||||
#[pallet::weight(<T as Config>::WeightInfo::force_process_hrmp_open(*_channels))]
|
||||
pub fn force_process_hrmp_open(origin: OriginFor<T>, _channels: u32) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
let host_config = configuration::Pallet::<T>::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<T>) -> DispatchResult {
|
||||
///
|
||||
/// Total number of closing channels must be provided as witness data of weighing.
|
||||
#[pallet::weight(<T as Config>::WeightInfo::force_process_hrmp_close(*_channels))]
|
||||
pub fn force_process_hrmp_close(origin: OriginFor<T>, _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(<T as Config>::WeightInfo::hrmp_cancel_open_request(*open_requests))]
|
||||
pub fn hrmp_cancel_open_request(
|
||||
origin: OriginFor<T>,
|
||||
channel_id: HrmpChannelId,
|
||||
open_requests: u32,
|
||||
) -> DispatchResult {
|
||||
let origin = ensure_parachain(<T as Config>::Origin::from(origin))?;
|
||||
ensure!(
|
||||
<Self as Store>::HrmpOpenChannelRequestsList::decode_len().unwrap_or_default()
|
||||
as u32 <= open_requests,
|
||||
Error::<T>::WrongWitness
|
||||
);
|
||||
Self::cancel_open_request(origin, channel_id.clone())?;
|
||||
Self::deposit_event(Event::OpenChannelCanceled(origin, channel_id));
|
||||
Ok(())
|
||||
@@ -535,10 +616,16 @@ impl<T: Config> Pallet<T> {
|
||||
pub(crate) fn initializer_on_new_session(
|
||||
notification: &initializer::SessionChangeNotification<T::BlockNumber>,
|
||||
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(<T as Config>::WeightInfo::force_process_hrmp_open(
|
||||
outgoing_paras.len() as u32
|
||||
))
|
||||
.saturating_add(<T as Config>::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<T: Config> Pallet<T> {
|
||||
fn perform_outgoing_para_cleanup(
|
||||
config: &HostConfiguration<T::BlockNumber>,
|
||||
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 = <Self as Store>::HrmpIngressChannelsIndex::decode_len(outgoing_para)
|
||||
.unwrap_or_default() as u32;
|
||||
let egress_count = <Self as Store>::HrmpEgressChannelsIndex::decode_len(outgoing_para)
|
||||
.unwrap_or_default() as u32;
|
||||
w = w.saturating_add(<T as Config>::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<T::BlockNumber>,
|
||||
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<T: Config> Pallet<T> {
|
||||
Self::decrease_accepted_channel_request_count(req_id.recipient);
|
||||
}
|
||||
}
|
||||
|
||||
<T as Config>::WeightInfo::clean_open_channel_requests(outgoing.len() as u32)
|
||||
}
|
||||
|
||||
/// Remove all storage entries associated with the given para.
|
||||
@@ -983,8 +1084,8 @@ impl<T: Config> Pallet<T> {
|
||||
/// 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<T: Config> Pallet<T> {
|
||||
config.hrmp_sender_deposit.unique_saturated_into(),
|
||||
)?;
|
||||
|
||||
// mutating storage directly now -- shall not bail henceforth.
|
||||
|
||||
<Self as Store>::HrmpOpenChannelRequestCount::insert(&origin, open_req_cnt + 1);
|
||||
<Self as Store>::HrmpOpenChannelRequests::insert(
|
||||
&channel_id,
|
||||
@@ -1067,6 +1170,10 @@ impl<T: Config> Pallet<T> {
|
||||
{
|
||||
// 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<T: Config> Pallet<T> {
|
||||
/// 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 = <Self as Store>::HrmpOpenChannelRequests::get(&channel_id)
|
||||
@@ -1121,6 +1228,10 @@ impl<T: Config> Pallet<T> {
|
||||
{
|
||||
// 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<T: Config> Pallet<T> {
|
||||
{
|
||||
// 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<T: Config> Pallet<T> {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "runtime-benchmarks", test))]
|
||||
fn assert_storage_consistency_exhaustive() {
|
||||
fn assert_is_sorted<T: Ord>(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<ParaId>, cause: &str| {
|
||||
for para in paras {
|
||||
assert!(
|
||||
crate::paras::Pallet::<T>::is_valid_para(para),
|
||||
"{}: {:?} para is offboarded",
|
||||
cause,
|
||||
para
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
<Self as Store>::HrmpOpenChannelRequests::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
<Self as Store>::HrmpOpenChannelRequestsList::get()
|
||||
.into_iter()
|
||||
.collect::<BTreeSet<_>>(),
|
||||
);
|
||||
|
||||
// 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!(
|
||||
<Self as Store>::HrmpOpenChannelRequestCount::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
<Self as Store>::HrmpOpenChannelRequests::iter()
|
||||
.map(|(k, _)| k.sender)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
);
|
||||
for (open_channel_initiator, expected_num) in
|
||||
<Self as Store>::HrmpOpenChannelRequestCount::iter()
|
||||
{
|
||||
let actual_num = <Self as Store>::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!(
|
||||
<Self as Store>::HrmpAcceptedChannelRequestCount::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
<Self as Store>::HrmpOpenChannelRequests::iter()
|
||||
.filter(|(_, v)| v.confirmed)
|
||||
.map(|(k, _)| k.recipient)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
);
|
||||
for (channel_recipient, expected_num) in
|
||||
<Self as Store>::HrmpAcceptedChannelRequestCount::iter()
|
||||
{
|
||||
let actual_num = <Self as Store>::HrmpOpenChannelRequests::iter()
|
||||
.filter(|(ch, v)| ch.recipient == channel_recipient && v.confirmed)
|
||||
.count() as u32;
|
||||
assert_eq!(expected_num, actual_num);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
<Self as Store>::HrmpCloseChannelRequests::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<BTreeSet<_>>(),
|
||||
<Self as Store>::HrmpCloseChannelRequestsList::get()
|
||||
.into_iter()
|
||||
.collect::<BTreeSet<_>>(),
|
||||
);
|
||||
|
||||
// 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(
|
||||
<Self as Store>::HrmpWatermarks::iter().map(|(k, _)| k).collect::<Vec<_>>(),
|
||||
"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 <Self as Store>::HrmpChannelContents::iter() {
|
||||
assert!(<Self as Store>::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(
|
||||
<Self as Store>::HrmpChannels::iter()
|
||||
.flat_map(|(k, _)| vec![k.sender, k.recipient])
|
||||
.collect::<Vec<_>>(),
|
||||
"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 = <Self as Store>::HrmpIngressChannelsIndex::iter()
|
||||
.flat_map(|(p, v)| v.into_iter().map(|i| (i, p)).collect::<Vec<_>>())
|
||||
.collect::<BTreeSet<_>>();
|
||||
let channel_set_derived_from_egress = <Self as Store>::HrmpEgressChannelsIndex::iter()
|
||||
.flat_map(|(p, v)| v.into_iter().map(|e| (p, e)).collect::<Vec<_>>())
|
||||
.collect::<BTreeSet<_>>();
|
||||
let channel_set_ground_truth = <Self as Store>::HrmpChannels::iter()
|
||||
.map(|(k, _)| (k.sender, k.recipient))
|
||||
.collect::<BTreeSet<_>>();
|
||||
assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress);
|
||||
assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth);
|
||||
|
||||
<Self as Store>::HrmpIngressChannelsIndex::iter()
|
||||
.map(|(_, v)| v)
|
||||
.for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex"));
|
||||
<Self as Store>::HrmpEgressChannelsIndex::iter()
|
||||
.map(|(_, v)| v)
|
||||
.for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex"));
|
||||
|
||||
assert_contains_only_onboarded(
|
||||
<Self as Store>::HrmpChannelDigests::iter().map(|(k, _)| k).collect::<Vec<_>>(),
|
||||
"HRMP channel digests should contain only onboarded paras",
|
||||
);
|
||||
for (_digest_for_para, digest) in <Self as Store>::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<Vec<BlockNumber>>) {
|
||||
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 {
|
||||
<Hrmp as Store>::HrmpChannels::get(&HrmpChannelId { sender, recipient }).is_some()
|
||||
}
|
||||
|
||||
fn assert_storage_consistency_exhaustive() {
|
||||
assert_eq!(
|
||||
<Hrmp as Store>::HrmpOpenChannelRequests::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<HashSet<_>>(),
|
||||
<Hrmp as Store>::HrmpOpenChannelRequestsList::get()
|
||||
.into_iter()
|
||||
.collect::<HashSet<_>>(),
|
||||
);
|
||||
|
||||
// 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!(
|
||||
<Hrmp as Store>::HrmpOpenChannelRequestCount::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<HashSet<_>>(),
|
||||
<Hrmp as Store>::HrmpOpenChannelRequests::iter()
|
||||
.map(|(k, _)| k.sender)
|
||||
.collect::<HashSet<_>>(),
|
||||
);
|
||||
for (open_channel_initiator, expected_num) in
|
||||
<Hrmp as Store>::HrmpOpenChannelRequestCount::iter()
|
||||
{
|
||||
let actual_num = <Hrmp as Store>::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!(
|
||||
<Hrmp as Store>::HrmpAcceptedChannelRequestCount::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<HashSet<_>>(),
|
||||
<Hrmp as Store>::HrmpOpenChannelRequests::iter()
|
||||
.filter(|(_, v)| v.confirmed)
|
||||
.map(|(k, _)| k.recipient)
|
||||
.collect::<HashSet<_>>(),
|
||||
);
|
||||
for (channel_recipient, expected_num) in
|
||||
<Hrmp as Store>::HrmpAcceptedChannelRequestCount::iter()
|
||||
{
|
||||
let actual_num = <Hrmp as Store>::HrmpOpenChannelRequests::iter()
|
||||
.filter(|(ch, v)| ch.recipient == channel_recipient && v.confirmed)
|
||||
.count() as u32;
|
||||
assert_eq!(expected_num, actual_num);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
<Hrmp as Store>::HrmpCloseChannelRequests::iter()
|
||||
.map(|(k, _)| k)
|
||||
.collect::<HashSet<_>>(),
|
||||
<Hrmp as Store>::HrmpCloseChannelRequestsList::get()
|
||||
.into_iter()
|
||||
.collect::<HashSet<_>>(),
|
||||
);
|
||||
|
||||
// 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(
|
||||
<Hrmp as Store>::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 <Hrmp as Store>::HrmpChannelContents::iter() {
|
||||
assert!(<Hrmp as Store>::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(
|
||||
<Hrmp as Store>::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 = <Hrmp as Store>::HrmpIngressChannelsIndex::iter()
|
||||
.flat_map(|(p, v)| v.into_iter().map(|i| (i, p)).collect::<Vec<_>>())
|
||||
.collect::<HashSet<_>>();
|
||||
let channel_set_derived_from_egress = <Hrmp as Store>::HrmpEgressChannelsIndex::iter()
|
||||
.flat_map(|(p, v)| v.into_iter().map(|e| (p, e)).collect::<Vec<_>>())
|
||||
.collect::<HashSet<_>>();
|
||||
let channel_set_ground_truth = <Hrmp as Store>::HrmpChannels::iter()
|
||||
.map(|(k, _)| (k.sender, k.recipient))
|
||||
.collect::<HashSet<_>>();
|
||||
assert_eq!(channel_set_derived_from_ingress, channel_set_derived_from_egress);
|
||||
assert_eq!(channel_set_derived_from_egress, channel_set_ground_truth);
|
||||
|
||||
<Hrmp as Store>::HrmpIngressChannelsIndex::iter()
|
||||
.map(|(_, v)| v)
|
||||
.for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex"));
|
||||
<Hrmp as Store>::HrmpEgressChannelsIndex::iter()
|
||||
.map(|(_, v)| v)
|
||||
.for_each(|v| assert_is_sorted(&v, "HrmpIngressChannelsIndex"));
|
||||
|
||||
assert_contains_only_onboarded(
|
||||
<Hrmp as Store>::HrmpChannelDigests::iter().map(|(k, _)| k),
|
||||
"HRMP channel digests should contain only onboarded paras",
|
||||
);
|
||||
for (_digest_for_para, digest) in <Hrmp as Store>::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<Item = ParaId>, cause: &str) {
|
||||
for para in iter {
|
||||
assert!(Paras::is_valid_para(para), "{}: {} para is offboarded", cause, para);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_is_sorted<T: Ord>(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!(<Test as Config>::Currency::free_balance(¶_a.into_account()), 100);
|
||||
assert_eq!(<Test as Config>::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!(<Test as Config>::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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
fn register_parachain_with_balance<T: Config>(id: ParaId, balance: BalanceOf<T>) {
|
||||
assert_ok!(Paras::<T>::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<T: Config>(generic_event: <T as Config>::Event) {
|
||||
let events = frame_system::Pallet::<T>::events();
|
||||
let system_event: <T as frame_system::Config>::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<T: Config>(
|
||||
from: u32,
|
||||
to: u32,
|
||||
until: ParachainSetupStep,
|
||||
) -> [(ParaId, crate::Origin); 2]
|
||||
where
|
||||
<T as frame_system::Config>::Origin: From<crate::Origin>,
|
||||
{
|
||||
let config = Configuration::<T>::config();
|
||||
let deposit: BalanceOf<T> = 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::<T>::is_parachain(sender) {
|
||||
register_parachain_with_balance::<T>(sender, deposit);
|
||||
}
|
||||
if !Paras::<T>::is_parachain(recipient) {
|
||||
register_parachain_with_balance::<T>(recipient, deposit);
|
||||
}
|
||||
|
||||
assert_ok!(Hrmp::<T>::hrmp_init_open_channel(
|
||||
sender_origin.clone().into(),
|
||||
recipient,
|
||||
capacity,
|
||||
message_size
|
||||
));
|
||||
|
||||
if matches!(until, ParachainSetupStep::Requested) {
|
||||
return output
|
||||
}
|
||||
|
||||
assert_ok!(Hrmp::<T>::hrmp_accept_open_channel(recipient_origin.into(), sender));
|
||||
if matches!(until, ParachainSetupStep::Accepted) {
|
||||
return output
|
||||
}
|
||||
|
||||
Hrmp::<T>::process_hrmp_open_channel_requests(&Configuration::<T>::config());
|
||||
if matches!(until, ParachainSetupStep::Established) {
|
||||
return output
|
||||
}
|
||||
|
||||
let channel_id = HrmpChannelId { sender, recipient };
|
||||
assert_ok!(Hrmp::<T>::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 <T as frame_system::Config>::Origin: From<crate::Origin> }
|
||||
|
||||
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<T> = Configuration::<T>::config().hrmp_sender_deposit.unique_saturated_into();
|
||||
register_parachain_with_balance::<T>(sender_id, deposit);
|
||||
register_parachain_with_balance::<T>(recipient_id, deposit);
|
||||
|
||||
let capacity = Configuration::<T>::config().hrmp_channel_max_capacity;
|
||||
let message_size = Configuration::<T>::config().hrmp_channel_max_message_size;
|
||||
}: _(sender_origin, recipient_id, capacity, message_size)
|
||||
verify {
|
||||
assert_last_event::<T>(
|
||||
Event::<T>::OpenChannelRequested(sender_id, recipient_id, capacity, message_size).into()
|
||||
);
|
||||
}
|
||||
|
||||
hrmp_accept_open_channel {
|
||||
let [(sender, _), (recipient, recipient_origin)] =
|
||||
establish_para_connection::<T>(1, 2, ParachainSetupStep::Requested);
|
||||
}: _(recipient_origin, sender)
|
||||
verify {
|
||||
assert_last_event::<T>(Event::<T>::OpenChannelAccepted(sender, recipient).into());
|
||||
}
|
||||
|
||||
hrmp_close_channel {
|
||||
let [(sender, sender_origin), (recipient, _)] =
|
||||
establish_para_connection::<T>(1, 2, ParachainSetupStep::Established);
|
||||
let channel_id = HrmpChannelId { sender, recipient };
|
||||
}: _(sender_origin, channel_id.clone())
|
||||
verify {
|
||||
assert_last_event::<T>(Event::<T>::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::<T>::set_hrmp_max_parachain_outbound_channels(frame_system::RawOrigin::Root.into(), e + 1)
|
||||
);
|
||||
assert_ok!(
|
||||
Configuration::<T>::set_hrmp_max_parachain_inbound_channels(frame_system::RawOrigin::Root.into(), i + 1)
|
||||
);
|
||||
// .. and enact it.
|
||||
Configuration::<T>::initializer_on_new_session(&Shared::<T>::scheduled_session());
|
||||
|
||||
let config = Configuration::<T>::config();
|
||||
let deposit: BalanceOf<T> = config.hrmp_sender_deposit.unique_saturated_into();
|
||||
|
||||
let para: ParaId = 1u32.into();
|
||||
let para_origin: crate::Origin = 1u32.into();
|
||||
register_parachain_with_balance::<T>(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::<T>(ingress_para_id, para.into(), ParachainSetupStep::Established);
|
||||
}
|
||||
|
||||
// nothing should be left unprocessed.
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::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::<T>(para.into(), egress_para_id, ParachainSetupStep::Established);
|
||||
}
|
||||
|
||||
// nothing should be left unprocessed.
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default(), 0);
|
||||
|
||||
// all in all, we have created this many channels.
|
||||
assert_eq!(HrmpChannels::<T>::iter().count() as u32, i + e);
|
||||
}: _(frame_system::Origin::<T>::Root, para, i, e) verify {
|
||||
// all in all, all of them must be gone by now.
|
||||
assert_eq!(HrmpChannels::<T>::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::<T>::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::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Accepted);
|
||||
}
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
|
||||
}: _(frame_system::Origin::<T>::Root, c)
|
||||
verify {
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::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::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::CloseRequested);
|
||||
}
|
||||
|
||||
assert_eq!(HrmpCloseChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
|
||||
}: _(frame_system::Origin::<T>::Root, c)
|
||||
verify {
|
||||
assert_eq!(HrmpCloseChannelRequestsList::<T>::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::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested);
|
||||
}
|
||||
|
||||
let [(sender, sender_origin), (recipient, _)] =
|
||||
establish_para_connection::<T>(1, 2, ParachainSetupStep::Requested);
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::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::<T>::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::<T>(PREFIX_0 + id, PREFIX_1 + id, ParachainSetupStep::Requested);
|
||||
}
|
||||
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::decode_len().unwrap_or_default() as u32, c);
|
||||
let outgoing = (0..c).map(|id| (id + PREFIX_1).into()).collect::<Vec<ParaId>>();
|
||||
let config = Configuration::<T>::config();
|
||||
}: {
|
||||
Hrmp::<T>::clean_open_channel_requests(&config, &outgoing);
|
||||
} verify {
|
||||
assert_eq!(HrmpOpenChannelRequestsList::<T>::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
|
||||
);
|
||||
@@ -236,6 +236,7 @@ impl crate::hrmp::Config for Test {
|
||||
type Event = Event;
|
||||
type Origin = Origin;
|
||||
type Currency = pallet_balances::Pallet<Test>;
|
||||
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());
|
||||
|
||||
|
||||
@@ -1993,4 +1993,20 @@ impl<T: Config> Pallet<T> {
|
||||
pub fn heads_insert(para_id: &ParaId, head_data: HeadData) {
|
||||
Heads::<T>::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::<T>::get(id) == Some(ParaLifecycle::Parachain),
|
||||
"Parachain not created properly"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Self>;
|
||||
}
|
||||
|
||||
impl parachains_paras_inherent::Config for Runtime {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
//! 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<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> runtime_parachains::hrmp::WeightInfo for WeightInfo<T> {
|
||||
// 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)))
|
||||
}
|
||||
}
|
||||
@@ -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<Runtime>;
|
||||
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<Self>;
|
||||
}
|
||||
|
||||
impl parachains_paras_inherent::Config for Runtime {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
//! 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<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> runtime_parachains::hrmp::WeightInfo for WeightInfo<T> {
|
||||
// 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)))
|
||||
}
|
||||
}
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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<Self>;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
//! 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<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> runtime_parachains::hrmp::WeightInfo for WeightInfo<T> {
|
||||
// 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)))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user