diff --git a/Cargo.lock b/Cargo.lock index c755be63042b..65300886a350 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5865,9 +5865,12 @@ dependencies = [ name = "glutton-runtime" version = "1.0.0" dependencies = [ + "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", + "cumulus-pallet-session-benchmarking", "cumulus-pallet-xcm", "cumulus-primitives-core", + "cumulus-primitives-timestamp", "frame-benchmarking", "frame-executive", "frame-support", @@ -5875,14 +5878,20 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", + "pallet-aura", + "pallet-authorship", + "pallet-fixed", "pallet-glutton", + "pallet-session", "pallet-sudo", + "pallet-timestamp", "parachain-info", "parachains-common", "parity-scale-codec", "scale-info", "sp-api", "sp-block-builder", + "sp-consensus-aura", "sp-core", "sp-inherents", "sp-offchain", @@ -9836,6 +9845,30 @@ dependencies = [ "substrate-test-utils", ] +[[package]] +name = "pallet-fixed" +version = "1.0.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-aura", + "pallet-authorship", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "rand 0.8.5", + "scale-info", + "sp-consensus-aura", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", +] + [[package]] name = "pallet-glutton" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index ab10fe5bb759..af133f687cc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ members = [ "cumulus/pallets/aura-ext", "cumulus/pallets/collator-selection", "cumulus/pallets/dmp-queue", + "cumulus/pallets/fixed", "cumulus/pallets/parachain-system", "cumulus/pallets/parachain-system/proc-macro", "cumulus/pallets/session-benchmarking", diff --git a/cumulus/pallets/fixed/Cargo.toml b/cumulus/pallets/fixed/Cargo.toml new file mode 100644 index 000000000000..55f07240695a --- /dev/null +++ b/cumulus/pallets/fixed/Cargo.toml @@ -0,0 +1,64 @@ +[package] +authors = ["Parity Technologies "] +description = "Simple pallet to select collators for a parachain." +edition = "2021" +homepage = "https://substrate.io" +license = "Apache-2.0" +name = "pallet-fixed" +readme = "README.md" +repository = "https://github.com/paritytech/cumulus/" +version = "1.0.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +log = { version = "0.4.20", default-features = false } +codec = { default-features = false, features = ["derive"], package = "parity-scale-codec", version = "3.0.0" } +rand = { version = "0.8.5", features = ["std_rng"], default-features = false } +scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } + +sp-std = { path = "../../../substrate/primitives/std", default-features = false} +sp-runtime = { path = "../../../substrate/primitives/runtime", default-features = false} +sp-staking = { path = "../../../substrate/primitives/staking", default-features = false} +frame-support = { path = "../../../substrate/frame/support", default-features = false} +frame-system = { path = "../../../substrate/frame/system", default-features = false} +pallet-authorship = { path = "../../../substrate/frame/authorship", default-features = false} +pallet-session = { path = "../../../substrate/frame/session", default-features = false} + +frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true} + +[dev-dependencies] +sp-core = { path = "../../../substrate/primitives/core" } +sp-io = { path = "../../../substrate/primitives/io" } +sp-tracing = { path = "../../../substrate/primitives/tracing" } +sp-runtime = { path = "../../../substrate/primitives/runtime" } +pallet-timestamp = { path = "../../../substrate/frame/timestamp" } +sp-consensus-aura = { path = "../../../substrate/primitives/consensus/aura" } +pallet-aura = { path = "../../../substrate/frame/aura" } + +[features] +default = ["std"] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] +std = [ + "codec/std", + "log/std", + "scale-info/std", + "rand/std", + "sp-runtime/std", + "sp-staking/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", + "pallet-authorship/std", + "pallet-session/std", +] + +try-runtime = [ "frame-support/try-runtime" ] + +experimental = [ "pallet-aura/experimental" ] diff --git a/cumulus/pallets/fixed/src/benchmarking.rs b/cumulus/pallets/fixed/src/benchmarking.rs new file mode 100644 index 000000000000..87daa73307fe --- /dev/null +++ b/cumulus/pallets/fixed/src/benchmarking.rs @@ -0,0 +1,154 @@ +// Copyright (C) 2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Benchmarking setup for pallet-collator-selection + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +#[allow(unused)] +use crate::Pallet as Fixed; +use codec::Decode; +use frame_benchmarking::{account, impl_benchmark_test_suite, v2::*, BenchmarkError}; +use frame_support::traits::{EnsureOrigin, Get}; +use frame_system::{pallet_prelude::BlockNumberFor, EventRecord, RawOrigin}; +use pallet_authorship::EventHandler; +use pallet_session::{self as session, SessionManager}; +use sp_std::prelude::*; + +const SEED: u32 = 0; + +fn assert_last_event(generic_event: ::RuntimeEvent) { + let events = frame_system::Pallet::::events(); + let system_event: ::RuntimeEvent = generic_event.into(); + // compare to the last event record + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +fn keys(c: u32) -> ::Keys { + use rand::{RngCore, SeedableRng}; + + let keys = { + let mut keys = [0u8; 128]; + + if c > 0 { + let mut rng = rand::rngs::StdRng::seed_from_u64(c as u64); + rng.fill_bytes(&mut keys); + } + + keys + }; + + Decode::decode(&mut &keys[..]).unwrap() +} + +fn validator(c: u32) -> (T::AccountId, ::Keys) { + (account("candidate", c, 1000), keys::(c)) +} + +fn register_validators(count: u32) -> Vec { + let validators = (0..count).map(|c| validator::(c)).collect::>(); + + for (who, keys) in validators.clone() { + >::set_keys(RawOrigin::Signed(who).into(), keys, Vec::new()).unwrap(); + } + + validators.into_iter().map(|(who, _)| who).collect() +} + +#[benchmarks(where T: pallet_authorship::Config + session::Config)] +mod benchmarks { + use super::*; + + #[benchmark] + fn add_collator(c: Linear<1, { T::MaxCollators::get() - 1 }>) -> Result<(), BenchmarkError> { + let origin = + T::UpdateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + let mut collators = register_validators::(c); + collators.sort(); + let collators: frame_support::BoundedVec<_, T::MaxCollators> = + frame_support::BoundedVec::try_from(collators).unwrap(); + >::put(collators); + + let (to_add, keys) = validator::(c); + >::set_keys(RawOrigin::Signed(to_add.clone()).into(), keys, Vec::new()) + .unwrap(); + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, to_add.clone()); + + assert_last_event::(Event::CollatorAdded { account_id: to_add }.into()); + Ok(()) + } + + #[benchmark] + fn remove_collator(c: Linear<1, { T::MaxCollators::get() }>) -> Result<(), BenchmarkError> { + let origin = + T::UpdateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let mut collators = register_validators::(c); + collators.sort(); + let collators: frame_support::BoundedVec<_, T::MaxCollators> = + frame_support::BoundedVec::try_from(collators).unwrap(); + >::put(collators); + let to_remove = >::get().first().unwrap().clone(); + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, to_remove.clone()); + + assert_last_event::(Event::CollatorRemoved { account_id: to_remove }.into()); + Ok(()) + } + + // worse case is paying a non-existing candidate account. + #[benchmark] + fn note_author() { + let author: T::AccountId = account("author", 0, SEED); + let new_block: BlockNumberFor = 10u32.into(); + + frame_system::Pallet::::set_block_number(new_block); + + #[block] + { + as EventHandler<_, _>>::note_author(author.clone()) + } + + assert_eq!(frame_system::Pallet::::block_number(), new_block); + } + + // worst case for new session. + #[benchmark] + fn new_session(c: Linear<1, { T::MaxCollators::get() }>) { + frame_system::Pallet::::set_block_number(0u32.into()); + + register_validators::(c); + + let collators = >::get(); + let pre_length = collators.len(); + + #[block] + { + let actual_collators = as SessionManager<_>>::new_session(0); + let expected_collators: Vec = collators.iter().cloned().collect(); + assert_eq!(actual_collators.unwrap(), expected_collators); + } + + assert!(>::get().len() == pre_length); + } + + impl_benchmark_test_suite!(Fixed, crate::mock::new_test_ext(), crate::mock::Test,); +} diff --git a/cumulus/pallets/fixed/src/lib.rs b/cumulus/pallets/fixed/src/lib.rs new file mode 100644 index 000000000000..bf01defaaee8 --- /dev/null +++ b/cumulus/pallets/fixed/src/lib.rs @@ -0,0 +1,255 @@ +// Copyright (C) 2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Fixed pallet. +//! +//! A pallet to manage a fixed set of collators in a parachain. +//! +//! ## Overview +//! +//! The Fixed pallet manages the collators of a parachain. **Collation is _not_ a +//! secure activity** and this pallet does not implement any game-theoretic mechanisms to meet BFT +//! safety assumptions of the chosen set. There are no rewards and no balances. +//! +//! The pallet starts with a genesis config of a set of collators. Then, +//! through root privileges, collators can be added or removed from the set. +//! +//! Note: Eventually the Pot distribution may be modified as discussed in +//! [this issue](https://github.com/paritytech/statemint/issues/21#issuecomment-810481073). + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +pub mod weights; + +#[frame_support::pallet] +pub mod pallet { + pub use crate::weights::WeightInfo; + use frame_support::{ + pallet_prelude::*, + traits::{EnsureOrigin, ValidatorRegistration}, + BoundedVec, DefaultNoBound, + }; + use frame_system::pallet_prelude::*; + use pallet_session::SessionManager; + use sp_runtime::traits::Convert; + use sp_staking::SessionIndex; + use sp_std::vec::Vec; + + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + + /// A convertor from collators id. Since this pallet does not have stash/controller, this is + /// just identity. + pub struct IdentityCollator; + impl sp_runtime::traits::Convert> for IdentityCollator { + fn convert(t: T) -> Option { + Some(t) + } + } + + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config { + /// Overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Origin that can dictate updating parameters of this pallet. + type UpdateOrigin: EnsureOrigin; + + /// Maximum number of collators. + type MaxCollators: Get; + + /// A stable ID for a validator. + type ValidatorId: Member + Parameter; + + /// A conversion from account ID to validator ID. + /// + /// Its cost must be at most one storage read. + type ValidatorIdOf: Convert>; + + /// Validate a user is registered + type ValidatorRegistration: ValidatorRegistration; + + // /// The weight information of this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + /// The collator list. + #[pallet::storage] + #[pallet::getter(fn collators)] + pub type Collators = + StorageValue<_, BoundedVec, ValueQuery>; + + /// Last block authored by collator. Probably useless since we don't do + /// rewards but may be useful for UX? + #[pallet::storage] + #[pallet::getter(fn last_authored_block)] + pub type LastAuthoredBlock = + StorageMap<_, Twox64Concat, T::AccountId, BlockNumberFor, ValueQuery>; + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + pub collators: Vec, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + let duplicate_collators = + self.collators.iter().collect::>(); + assert!( + duplicate_collators.len() == self.collators.len(), + "duplicate collators in genesis." + ); + + let mut bounded_collators = + BoundedVec::<_, T::MaxCollators>::try_from(self.collators.clone()) + .expect("genesis collators are more than T::MaxCollators"); + + bounded_collators.sort(); + >::put(bounded_collators); + } + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// A new collator was added. + CollatorAdded { account_id: T::AccountId }, + /// An collator was removed. + CollatorRemoved { account_id: T::AccountId }, + } + + #[pallet::error] + pub enum Error { + /// Account is already a collator. + AlreadyCollator, + /// Account is not a collator. + NotCollator, + /// The collator list is saturated. + TooManyCollators, + /// Account has no associated validator ID. + NoAssociatedValidatorId, + /// Validator ID is not yet registered. + ValidatorNotRegistered, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + assert!(T::MaxCollators::get() > 0, "chain must have at least one collator"); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::add_collator( + T::MaxCollators::get().saturating_sub(1), + ))] + pub fn add_collator(origin: OriginFor, who: T::AccountId) -> DispatchResult { + T::UpdateOrigin::ensure_origin(origin)?; + + let validator_key = T::ValidatorIdOf::convert(who.clone()) + .ok_or(Error::::NoAssociatedValidatorId)?; + ensure!( + T::ValidatorRegistration::is_registered(&validator_key), + Error::::ValidatorNotRegistered + ); + + >::try_mutate(|collators| -> DispatchResult { + match collators.binary_search(&who) { + Ok(_) => return Err(Error::::AlreadyCollator)?, + Err(pos) => collators + .try_insert(pos, who.clone()) + .map_err(|_| Error::::TooManyCollators)?, + } + Ok(()) + })?; + + Self::deposit_event(Event::CollatorAdded { account_id: who }); + + Ok(()) + } + + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::remove_collator(T::MaxCollators::get()))] + pub fn remove_collator(origin: OriginFor, who: T::AccountId) -> DispatchResult { + T::UpdateOrigin::ensure_origin(origin)?; + + >::try_mutate(|collators| -> DispatchResult { + let pos = collators.binary_search(&who).map_err(|_| Error::::NotCollator)?; + collators.remove(pos); + Ok(()) + })?; + + Self::deposit_event(Event::CollatorRemoved { account_id: who }); + Ok(()) + } + } + + /// Keep track of number of authored blocks per authority. + impl + pallet_authorship::EventHandler> for Pallet + { + fn note_author(author: T::AccountId) { + >::insert(author, frame_system::Pallet::::block_number()); + + // frame_system::Pallet::::register_extra_weight_unchecked( + // T::WeightInfo::note_author(), + // DispatchClass::Mandatory, + // ); + } + } + + /// Play the role of the session manager. + impl SessionManager for Pallet { + fn new_session(index: SessionIndex) -> Option> { + log::info!( + "assembling new collators for new session {} at #{:?}", + index, + >::block_number(), + ); + + let collators = >::get().iter().cloned().collect(); + + // frame_system::Pallet::::register_extra_weight_unchecked( + // T::WeightInfo::new_session(something), + // DispatchClass::Mandatory, + // ); + Some(collators) + } + fn start_session(_: SessionIndex) { + // we don't care. + } + fn end_session(_: SessionIndex) { + // we don't care. + } + } +} diff --git a/cumulus/pallets/fixed/src/mock.rs b/cumulus/pallets/fixed/src/mock.rs new file mode 100644 index 000000000000..883d2d1afd26 --- /dev/null +++ b/cumulus/pallets/fixed/src/mock.rs @@ -0,0 +1,208 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # Preimage test environment. + +use super::*; + +use crate as fixed; +use frame_support::{ + ord_parameter_types, parameter_types, + traits::{ConstBool, ConstU32, ConstU64, FindAuthor, ValidatorRegistration}, +}; +use frame_system as system; +use frame_system::EnsureSignedBy; +use sp_core::H256; +use sp_runtime::{ + testing::UintAuthorityId, + traits::{BlakeTwo256, IdentityLookup, OpaqueKeys}, + BuildStorage, RuntimeAppPublic, +}; + +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Timestamp: pallet_timestamp, + Session: pallet_session, + Aura: pallet_aura, + Fixed: fixed, + Authorship: pallet_authorship, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} + +impl system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +pub struct Author4; +impl FindAuthor for Author4 { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(4) + } +} + +impl pallet_authorship::Config for Test { + type FindAuthor = Author4; + type EventHandler = Fixed; +} + +impl pallet_timestamp::Config for Test { + type Moment = u64; + type OnTimestampSet = Aura; + type MinimumPeriod = ConstU64<1>; + type WeightInfo = (); +} + +impl pallet_aura::Config for Test { + type AuthorityId = sp_consensus_aura::sr25519::AuthorityId; + type MaxAuthorities = ConstU32<100_000>; + type DisabledValidators = (); + type AllowMultipleBlocksPerSlot = ConstBool; +} + +sp_runtime::impl_opaque_keys! { + pub struct MockSessionKeys { + // a key for aura authoring + pub aura: UintAuthorityId, + } +} + +impl From for MockSessionKeys { + fn from(aura: sp_runtime::testing::UintAuthorityId) -> Self { + Self { aura } + } +} + +parameter_types! { + pub static SessionHandlerCollators: Vec = Vec::new(); + pub static SessionChangeBlock: u64 = 0; +} + +pub struct TestSessionHandler; +impl pallet_session::SessionHandler for TestSessionHandler { + const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[UintAuthorityId::ID]; + fn on_genesis_session(keys: &[(u64, Ks)]) { + SessionHandlerCollators::set(keys.iter().map(|(a, _)| *a).collect::>()) + } + fn on_new_session(_: bool, keys: &[(u64, Ks)], _: &[(u64, Ks)]) { + SessionChangeBlock::set(System::block_number()); + dbg!(keys.len()); + SessionHandlerCollators::set(keys.iter().map(|(a, _)| *a).collect::>()) + } + fn on_before_session_ending() {} + fn on_disabled(_: u32) {} +} + +parameter_types! { + pub const Offset: u64 = 0; + pub const Period: u64 = 10; +} + +impl pallet_session::Config for Test { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = ::AccountId; + // we don't have stash and controller, thus we don't need the convert as well. + type ValidatorIdOf = IdentityCollator; + type ShouldEndSession = pallet_session::PeriodicSessions; + type NextSessionRotation = pallet_session::PeriodicSessions; + type SessionManager = Fixed; + type SessionHandler = TestSessionHandler; + type Keys = MockSessionKeys; + type WeightInfo = (); +} + +ord_parameter_types! { + pub const RootAccount: u64 = 777; +} + +pub struct IsRegistered; +impl ValidatorRegistration for IsRegistered { + fn is_registered(id: &u64) -> bool { + *id != 42u64 + } +} + +impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = EnsureSignedBy; + type MaxCollators = ConstU32<20>; + type ValidatorId = ::AccountId; + type ValidatorIdOf = IdentityCollator; + type ValidatorRegistration = IsRegistered; + type WeightInfo = (); +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_tracing::try_init_simple(); + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let collators = vec![2, 1]; // unsorted + + let accounts = vec![1, 2, 3, 4, 5]; + let keys = accounts + .into_iter() + .map(|i| (i, i, MockSessionKeys { aura: UintAuthorityId(i) })) + .collect::>(); + + let fixed_collators = fixed::GenesisConfig:: { collators }; + let session = pallet_session::GenesisConfig:: { keys }; + + // fixed collator selection must be initialized before session. + fixed_collators.assimilate_storage(&mut t).unwrap(); + session.assimilate_storage(&mut t).unwrap(); + + t.into() +} + +pub fn initialize_to_block(n: u64) { + for i in System::block_number() + 1..=n { + System::set_block_number(i); + >::on_initialize(i); + } +} diff --git a/cumulus/pallets/fixed/src/tests.rs b/cumulus/pallets/fixed/src/tests.rs new file mode 100644 index 000000000000..f87fee2d871c --- /dev/null +++ b/cumulus/pallets/fixed/src/tests.rs @@ -0,0 +1,31 @@ +// Copyright (C) 2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate as fixed; +use crate::{mock::*, Error}; +use frame_support::{assert_ok, traits::OnInitialize}; +use sp_runtime::{testing::UintAuthorityId, traits::BadOrigin, BuildStorage}; + +#[test] +#[should_panic = "duplicate collators in genesis."] +fn cannot_set_genesis_value_twice() { + sp_tracing::try_init_simple(); + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let collators = vec![1, 1]; + + let fixed_collators = fixed::GenesisConfig:: { collators }; + // collator selection must be initialized before session. + fixed_collators.assimilate_storage(&mut t).unwrap(); +} diff --git a/cumulus/pallets/fixed/src/weights.rs b/cumulus/pallets/fixed/src/weights.rs new file mode 100644 index 000000000000..6fba930adf2e --- /dev/null +++ b/cumulus/pallets/fixed/src/weights.rs @@ -0,0 +1,151 @@ +// This file is part of Substrate. + +// Copyright (C) 2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; +use sp_std::marker::PhantomData; + +// The weight info trait for `pallet_collator_selection`. +pub trait WeightInfo { + fn add_collator(_c: u32) -> Weight; + fn remove_collator(_c: u32) -> Weight; + fn note_author() -> Weight; + fn new_session(_c: u32, _r: u32) -> Weight; +} + +/// Weights for pallet_collator_selection using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn note_author() -> Weight { + Weight::from_parts(71_461_000_u64, 0) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + fn new_session(r: u32, c: u32) -> Weight { + Weight::from_parts(0_u64, 0) + // Standard Error: 1_010_000 + .saturating_add(Weight::from_parts(109_961_000_u64, 0).saturating_mul(r as u64)) + // Standard Error: 1_010_000 + .saturating_add(Weight::from_parts(151_952_000_u64, 0).saturating_mul(c as u64)) + .saturating_add(T::DbWeight::get().reads(1_u64.saturating_mul(r as u64))) + .saturating_add(T::DbWeight::get().reads(2_u64.saturating_mul(c as u64))) + .saturating_add(T::DbWeight::get().writes(2_u64.saturating_mul(r as u64))) + .saturating_add(T::DbWeight::get().writes(2_u64.saturating_mul(c as u64))) + } + /// Storage: Session NextKeys (r:1 w:0) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: CollatorSelection collators (r:1 w:1) + /// Proof: CollatorSelection collators (max_values: Some(1), max_size: Some(641), added: + /// 1136, mode: MaxEncodedLen) Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, + /// mode: MaxEncodedLen) Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: + /// MaxEncodedLen) The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_collator(c: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) + } + /// Storage: CollatorSelection collators (r:1 w:1) + /// Proof: CollatorSelection collators (max_values: Some(1), max_size: Some(3202), added: + /// 3697, mode: MaxEncodedLen) The range of component `b` is `[1, 100]`. + fn remove_collator(b: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `119 + b * (32 ±0)` + // Estimated: `4687` + // Minimum execution time: 183_054_000 picoseconds. + Weight::from_parts(197_205_427, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 13_533 + .saturating_add(Weight::from_parts(376_231, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: Session NextKeys (r:1 w:0) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: CollatorSelection collators (r:1 w:1) + /// Proof: CollatorSelection collators (max_values: Some(1), max_size: Some(641), added: + /// 1136, mode: MaxEncodedLen) Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, + /// mode: MaxEncodedLen) Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: + /// MaxEncodedLen) The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_collator(c: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(4)) + .saturating_add(RocksDbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) + } + /// Storage: CollatorSelection collators (r:1 w:1) + /// Proof: CollatorSelection collators (max_values: Some(1), max_size: Some(3202), added: + /// 3697, mode: MaxEncodedLen) The range of component `b` is `[1, 100]`. + fn remove_collator(c: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `119 + b * (32 ±0)` + // Estimated: `4687` + // Minimum execution time: 183_054_000 picoseconds. + Weight::from_parts(197_205_427, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 13_533 + .saturating_add(Weight::from_parts(376_231, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn note_author() -> Weight { + Weight::from_parts(71_461_000_u64, 0) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + fn new_session(r: u32, c: u32) -> Weight { + Weight::from_parts(0_u64, 0) + // Standard Error: 1_010_000 + .saturating_add(Weight::from_parts(109_961_000_u64, 0).saturating_mul(r as u64)) + // Standard Error: 1_010_000 + .saturating_add(Weight::from_parts(151_952_000_u64, 0).saturating_mul(c as u64)) + .saturating_add(RocksDbWeight::get().reads(1_u64.saturating_mul(r as u64))) + .saturating_add(RocksDbWeight::get().reads(2_u64.saturating_mul(c as u64))) + .saturating_add(RocksDbWeight::get().writes(2_u64.saturating_mul(r as u64))) + .saturating_add(RocksDbWeight::get().writes(2_u64.saturating_mul(c as u64))) + } +} diff --git a/cumulus/parachains/runtimes/glutton/glutton-kusama/Cargo.toml b/cumulus/parachains/runtimes/glutton/glutton-kusama/Cargo.toml index 43bf468c7954..b7a0f5bf121a 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-kusama/Cargo.toml +++ b/cumulus/parachains/runtimes/glutton/glutton-kusama/Cargo.toml @@ -16,10 +16,15 @@ frame-system = { path = "../../../../../substrate/frame/system", default-feature frame-system-rpc-runtime-api = { path = "../../../../../substrate/frame/system/rpc/runtime-api", default-features = false} frame-system-benchmarking = { path = "../../../../../substrate/frame/system/benchmarking", default-features = false, optional = true} frame-try-runtime = { path = "../../../../../substrate/frame/try-runtime", default-features = false, optional = true} +pallet-aura = { path = "../../../../../substrate/frame/aura", default-features = false} +pallet-authorship = { path = "../../../../../substrate/frame/authorship", default-features = false} pallet-glutton = { path = "../../../../../substrate/frame/glutton", default-features = false, optional = true} +pallet-session = { path = "../../../../../substrate/frame/session", default-features = false } pallet-sudo = { path = "../../../../../substrate/frame/sudo", default-features = false, optional = true} +pallet-timestamp = { path = "../../../../../substrate/frame/timestamp", default-features = false } sp-api = { path = "../../../../../substrate/primitives/api", default-features = false} sp-block-builder = { path = "../../../../../substrate/primitives/block-builder", default-features = false} +sp-consensus-aura = { path = "../../../../../substrate/primitives/consensus/aura", default-features = false } sp-core = { path = "../../../../../substrate/primitives/core", default-features = false} sp-inherents = { path = "../../../../../substrate/primitives/inherents", default-features = false} sp-offchain = { path = "../../../../../substrate/primitives/offchain", default-features = false} @@ -36,9 +41,13 @@ xcm-builder = { path = "../../../../../polkadot/xcm/xcm-builder", default-featur xcm-executor = { path = "../../../../../polkadot/xcm/xcm-executor", default-features = false} # Cumulus +cumulus-pallet-aura-ext = { path = "../../../../pallets/aura-ext", default-features = false } cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook",] } +cumulus-pallet-session-benchmarking = {path = "../../../../pallets/session-benchmarking", default-features = false, version = "3.0.0"} cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false } cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false } +cumulus-primitives-timestamp = { path = "../../../../primitives/timestamp", default-features = false } +pallet-fixed = { path = "../../../../pallets/fixed", default-features = false } parachain-info = { path = "../../../pallets/parachain-info", default-features = false } parachains-common = { path = "../../../common", default-features = false } @@ -49,29 +58,40 @@ substrate-wasm-builder = { path = "../../../../../substrate/utils/wasm-builder" default = [ "std" ] runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", + "cumulus-pallet-session-benchmarking/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-fixed/runtime-benchmarks", "pallet-glutton/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", "xcm-builder/runtime-benchmarks", ] std = [ "codec/std", + "cumulus-pallet-aura-ext/std", "cumulus-pallet-parachain-system/std", "cumulus-pallet-xcm/std", "cumulus-primitives-core/std", + "cumulus-primitives-timestamp/std", "frame-executive/std", "frame-support/std", "frame-system-rpc-runtime-api/std", "frame-system/std", + "pallet-aura/std", + "pallet-authorship/std", + "pallet-fixed/std", "pallet-glutton/std", + "pallet-session/std", "pallet-sudo/std", + "pallet-timestamp/std", "parachain-info/std", "parachains-common/std", "scale-info/std", "sp-api/std", "sp-block-builder/std", + "sp-consensus-aura/std", "sp-core/std", "sp-inherents/std", "sp-offchain/std", @@ -85,8 +105,14 @@ std = [ "xcm/std", ] try-runtime = [ + "cumulus-pallet-aura-ext/try-runtime", "frame-executive/try-runtime", "frame-try-runtime/try-runtime", + "pallet-aura/try-runtime", + "pallet-authorship/try-runtime", + "pallet-fixed/try-runtime", "pallet-glutton/try-runtime", + "pallet-session/try-runtime", "pallet-sudo/try-runtime", + "pallet-timestamp/try-runtime", ] diff --git a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/lib.rs index cd9d31a4d989..c2085c264bd5 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/lib.rs @@ -48,9 +48,10 @@ pub mod xcm_config; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use sp_api::impl_runtime_apis; -use sp_core::OpaqueMetadata; +pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ - create_runtime_str, generic, + create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, @@ -64,24 +65,32 @@ pub use frame_support::{ construct_runtime, dispatch::DispatchClass, parameter_types, - traits::{Everything, IsInVec, Randomness}, + traits::{ + ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Everything, IsInVec, Randomness, + }, weights::{ constants::{ BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND, }, IdentityFee, Weight, }, - StorageValue, + PalletId, StorageValue, }; use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, }; -use parachains_common::{AccountId, Signature}; +use parachains_common::{AccountId, Signature, HOURS, SLOT_DURATION}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } +} + #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("glutton"), @@ -184,6 +193,62 @@ impl cumulus_pallet_parachain_system::Config for Runtime { impl parachain_info::Config for Runtime {} +impl cumulus_pallet_aura_ext::Config for Runtime {} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = Aura; + type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; + type WeightInfo = weights::pallet_timestamp::WeightInfo; +} + +impl pallet_authorship::Config for Runtime { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type EventHandler = (Fixed,); +} + +pub const PERIOD: u32 = 6 * HOURS; +pub const OFFSET: u32 = 0; + +impl pallet_session::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_fixed::IdentityCollator; + // TODO: decide how often the session should end, collators aren't changing + // often but there may be additions by the root user which need to come in + // at some point so we must have new sessions. + type ShouldEndSession = pallet_session::PeriodicSessions, ConstU32>; + type NextSessionRotation = pallet_session::PeriodicSessions, ConstU32>; + type SessionManager = Fixed; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; + type WeightInfo = weights::pallet_session::WeightInfo; +} + +impl pallet_aura::Config for Runtime { + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = ConstU32<100_000>; + type AllowMultipleBlocksPerSlot = ConstBool; +} + +parameter_types! { + // Symbolic, could be removed. + pub const SessionLength: BlockNumber = 6 * HOURS; +} + +pub type FixedUpdateOrigin = EnsureRoot; + +impl pallet_fixed::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = FixedUpdateOrigin; + type MaxCollators = ConstU32<100>; + type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_fixed::IdentityCollator; + type ValidatorRegistration = Session; + type WeightInfo = weights::pallet_fixed::WeightInfo; +} + impl pallet_glutton::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_glutton::WeightInfo; @@ -204,12 +269,20 @@ construct_runtime! { Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, } = 1, ParachainInfo: parachain_info::{Pallet, Storage, Config} = 2, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent} = 3, // DMP handler. CumulusXcm: cumulus_pallet_xcm::{Pallet, Call, Storage, Event, Origin} = 10, + // Collator support + Authorship: pallet_authorship::{Pallet, Storage} = 20, + Fixed: pallet_fixed::{Pallet, Call, Storage, Event, Config} = 21, + Session: pallet_session::{Pallet, Call, Storage, Event, Config} = 22, + Aura: pallet_aura::{Pallet, Storage, Config} = 23, + AuraExt: cumulus_pallet_aura_ext::{Pallet, Storage, Config} = 24, + // The main stage. - Glutton: pallet_glutton::{Pallet, Call, Storage, Event, Config} = 20, + Glutton: pallet_glutton::{Pallet, Call, Storage, Event, Config} = 30, // Sudo. Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, @@ -263,6 +336,8 @@ mod benches { define_benchmarks!( [frame_system, SystemBench::] [pallet_glutton, Glutton] + [pallet_session, SessionBench::] + [pallet_fixed, Fixed] ); } @@ -295,6 +370,16 @@ impl_runtime_apis! { } } + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + } + + fn authorities() -> Vec { + Aura::authorities().into_inner() + } + } + impl sp_block_builder::BlockBuilder for Runtime { fn apply_extrinsic( extrinsic: ::Extrinsic, @@ -332,12 +417,14 @@ impl_runtime_apis! { } impl sp_session::SessionKeys for Runtime { - fn decode_session_keys(_: Vec) -> Option, sp_core::crypto::KeyTypeId)>> { - Some(Vec::new()) + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) } - fn generate_session_keys(_: Option>) -> Vec { - Vec::new() + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) } } @@ -362,6 +449,7 @@ impl_runtime_apis! { use frame_benchmarking::{Benchmarking, BenchmarkList}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -378,6 +466,8 @@ impl_runtime_apis! { use sp_storage::TrackedStorageKey; use frame_system_benchmarking::Pallet as SystemBench; + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + impl cumulus_pallet_session_benchmarking::Config for Runtime {} impl frame_system_benchmarking::Config for Runtime { fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); @@ -402,5 +492,5 @@ impl_runtime_apis! { cumulus_pallet_parachain_system::register_validate_block! { Runtime = Runtime, - BlockExecutor = Executive, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, } diff --git a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/mod.rs b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/mod.rs index 234ce34bf420..82b82c82a90b 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/mod.rs @@ -1 +1,4 @@ +pub mod pallet_fixed; pub mod pallet_glutton; +pub mod pallet_session; +pub mod pallet_timestamp; diff --git a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_fixed.rs b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_fixed.rs new file mode 100644 index 000000000000..b7c3f7b79ff7 --- /dev/null +++ b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_fixed.rs @@ -0,0 +1,108 @@ +// Copyright Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_session` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-kusama-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot-parachain +// benchmark +// pallet +// --chain=asset-hub-kusama-dev +// --wasm-execution=compiled +// --pallet=pallet_session +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json +// --header=./file_header.txt +// --output=./parachains/runtimes/assets/asset-hub-kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_session`. +pub struct WeightInfo(PhantomData); +impl pallet_fixed::WeightInfo for WeightInfo { + fn note_author() -> Weight { + Weight::from_parts(71_461_000_u64, 0) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + fn new_session(r: u32, c: u32) -> Weight { + Weight::from_parts(0_u64, 0) + // Standard Error: 1_010_000 + .saturating_add(Weight::from_parts(109_961_000_u64, 0).saturating_mul(r as u64)) + // Standard Error: 1_010_000 + .saturating_add(Weight::from_parts(151_952_000_u64, 0).saturating_mul(c as u64)) + .saturating_add(T::DbWeight::get().reads(1_u64.saturating_mul(r as u64))) + .saturating_add(T::DbWeight::get().reads(2_u64.saturating_mul(c as u64))) + .saturating_add(T::DbWeight::get().writes(2_u64.saturating_mul(r as u64))) + .saturating_add(T::DbWeight::get().writes(2_u64.saturating_mul(c as u64))) + } + /// Storage: Session NextKeys (r:1 w:0) + /// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured) + /// Storage: CollatorSelection collators (r:1 w:1) + /// Proof: CollatorSelection collators (max_values: Some(1), max_size: Some(641), added: + /// 1136, mode: MaxEncodedLen) Storage: CollatorSelection Candidates (r:1 w:1) + /// Proof: CollatorSelection Candidates (max_values: Some(1), max_size: Some(4802), added: 5297, + /// mode: MaxEncodedLen) Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: + /// MaxEncodedLen) The range of component `b` is `[1, 19]`. + /// The range of component `c` is `[1, 99]`. + fn add_collator(c: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `757 + b * (32 ±0) + c * (53 ±0)` + // Estimated: `6287 + b * (37 ±0) + c * (53 ±0)` + // Minimum execution time: 52_720_000 picoseconds. + Weight::from_parts(56_102_459, 0) + .saturating_add(Weight::from_parts(0, 6287)) + // Standard Error: 12_957 + // Standard Error: 2_456 + .saturating_add(Weight::from_parts(128_528, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 53).saturating_mul(c.into())) + } + /// Storage: CollatorSelection collators (r:1 w:1) + /// Proof: CollatorSelection collators (max_values: Some(1), max_size: Some(3202), added: + /// 3697, mode: MaxEncodedLen) The range of component `b` is `[1, 100]`. + fn remove_collator(b: u32) -> Weight { + // Proof Size summary in bytes: + // Measured: `119 + b * (32 ±0)` + // Estimated: `4687` + // Minimum execution time: 183_054_000 picoseconds. + Weight::from_parts(197_205_427, 0) + .saturating_add(Weight::from_parts(0, 4687)) + // Standard Error: 13_533 + .saturating_add(Weight::from_parts(376_231, 0).saturating_mul(b.into())) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_session.rs b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_session.rs new file mode 100644 index 000000000000..c5064adf8b03 --- /dev/null +++ b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_session.rs @@ -0,0 +1,81 @@ +// Copyright Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_session` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-kusama-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot-parachain +// benchmark +// pallet +// --chain=asset-hub-kusama-dev +// --wasm-execution=compiled +// --pallet=pallet_session +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json +// --header=./file_header.txt +// --output=./parachains/runtimes/assets/asset-hub-kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_session`. +pub struct WeightInfo(PhantomData); +impl pallet_session::WeightInfo for WeightInfo { + /// Storage: `Session::NextKeys` (r:1 w:1) + /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::KeyOwner` (r:1 w:1) + /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn set_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `270` + // Estimated: `3735` + // Minimum execution time: 16_932_000 picoseconds. + Weight::from_parts(17_357_000, 0) + .saturating_add(Weight::from_parts(0, 3735)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `Session::NextKeys` (r:1 w:1) + /// Proof: `Session::NextKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Session::KeyOwner` (r:0 w:1) + /// Proof: `Session::KeyOwner` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn purge_keys() -> Weight { + // Proof Size summary in bytes: + // Measured: `242` + // Estimated: `3707` + // Minimum execution time: 12_157_000 picoseconds. + Weight::from_parts(12_770_000, 0) + .saturating_add(Weight::from_parts(0, 3707)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} diff --git a/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_timestamp.rs b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_timestamp.rs new file mode 100644 index 000000000000..8edae065f1b9 --- /dev/null +++ b/cumulus/parachains/runtimes/glutton/glutton-kusama/src/weights/pallet_timestamp.rs @@ -0,0 +1,75 @@ +// Copyright Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Autogenerated weights for `pallet_timestamp` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-kusama-dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot-parachain +// benchmark +// pallet +// --chain=asset-hub-kusama-dev +// --wasm-execution=compiled +// --pallet=pallet_timestamp +// --no-storage-info +// --no-median-slopes +// --no-min-squares +// --extrinsic=* +// --steps=50 +// --repeat=20 +// --json +// --header=./file_header.txt +// --output=./parachains/runtimes/assets/asset-hub-kusama/src/weights/ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_timestamp`. +pub struct WeightInfo(PhantomData); +impl pallet_timestamp::WeightInfo for WeightInfo { + /// Storage: `Timestamp::Now` (r:1 w:1) + /// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Aura::CurrentSlot` (r:1 w:0) + /// Proof: `Aura::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + fn set() -> Weight { + // Proof Size summary in bytes: + // Measured: `86` + // Estimated: `1493` + // Minimum execution time: 9_313_000 picoseconds. + Weight::from_parts(9_775_000, 0) + .saturating_add(Weight::from_parts(0, 1493)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + fn on_finalize() -> Weight { + // Proof Size summary in bytes: + // Measured: `57` + // Estimated: `0` + // Minimum execution time: 3_322_000 picoseconds. + Weight::from_parts(3_577_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/cumulus/polkadot-parachain/src/chain_spec/glutton.rs b/cumulus/polkadot-parachain/src/chain_spec/glutton.rs index 5ea51c3a9181..9a296ff8faf2 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/glutton.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/glutton.rs @@ -16,9 +16,12 @@ use crate::chain_spec::{get_account_id_from_seed, Extensions}; use cumulus_primitives_core::ParaId; +use parachains_common::{AccountId, AuraId}; use sc_service::ChainType; use sp_core::sr25519; +use super::get_collator_keys_from_seed; + /// Specialized `ChainSpec` for the Glutton parachain runtime. pub type GluttonChainSpec = sc_service::GenericChainSpec; @@ -30,7 +33,15 @@ pub fn glutton_development_config(para_id: ParaId) -> GluttonChainSpec { // ID "glutton_dev", ChainType::Local, - move || glutton_genesis(para_id), + move || { + glutton_genesis( + para_id, + vec![( + get_account_id_from_seed::("Alice"), + get_collator_keys_from_seed::("Alice"), + )], + ) + }, Vec::new(), None, None, @@ -47,7 +58,21 @@ pub fn glutton_local_config(para_id: ParaId) -> GluttonChainSpec { // ID "glutton_local", ChainType::Local, - move || glutton_genesis(para_id), + move || { + glutton_genesis( + para_id, + vec![ + ( + get_account_id_from_seed::("Alice"), + get_collator_keys_from_seed::("Alice"), + ), + ( + get_account_id_from_seed::("Bob"), + get_collator_keys_from_seed::("Bob"), + ), + ], + ) + }, Vec::new(), None, None, @@ -67,7 +92,7 @@ pub fn glutton_config(para_id: ParaId) -> GluttonChainSpec { // ID format!("glutton-kusama-{}", para_id).as_str(), ChainType::Live, - move || glutton_genesis(para_id), + move || glutton_genesis(para_id, vec![]), Vec::new(), None, // Protocol ID @@ -78,7 +103,10 @@ pub fn glutton_config(para_id: ParaId) -> GluttonChainSpec { ) } -fn glutton_genesis(parachain_id: ParaId) -> glutton_runtime::RuntimeGenesisConfig { +fn glutton_genesis( + parachain_id: ParaId, + collators: Vec<(AccountId, AuraId)>, +) -> glutton_runtime::RuntimeGenesisConfig { glutton_runtime::RuntimeGenesisConfig { system: glutton_runtime::SystemConfig { code: glutton_runtime::WASM_BINARY @@ -94,6 +122,24 @@ fn glutton_genesis(parachain_id: ParaId) -> glutton_runtime::RuntimeGenesisConfi trash_data_count: Default::default(), ..Default::default() }, + fixed: glutton_runtime::FixedConfig { + collators: collators.iter().cloned().map(|(acc, _)| acc).collect(), + ..Default::default() + }, + session: glutton_runtime::SessionConfig { + keys: collators + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + glutton_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + aura: Default::default(), + aura_ext: Default::default(), sudo: glutton_runtime::SudoConfig { key: Some(get_account_id_from_seed::("Alice")), },