Skip to content

Commit

Permalink
Add fixed collator set pallet to glutton runtime
Browse files Browse the repository at this point in the history
Signed-off-by: georgepisaltu <george.pisaltu@parity.io>
  • Loading branch information
georgepisaltu committed Aug 29, 2023
1 parent 70ab64b commit 1cd927b
Show file tree
Hide file tree
Showing 15 changed files with 1,341 additions and 15 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
64 changes: 64 additions & 0 deletions cumulus/pallets/fixed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[package]
authors = ["Parity Technologies <admin@parity.io>"]
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" ]
154 changes: 154 additions & 0 deletions cumulus/pallets/fixed/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -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<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
let events = frame_system::Pallet::<T>::events();
let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
// compare to the last event record
let EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}

fn keys<T: Config + session::Config>(c: u32) -> <T as session::Config>::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<T: Config + session::Config>(c: u32) -> (T::AccountId, <T as session::Config>::Keys) {
(account("candidate", c, 1000), keys::<T>(c))
}

fn register_validators<T: Config + session::Config>(count: u32) -> Vec<T::AccountId> {
let validators = (0..count).map(|c| validator::<T>(c)).collect::<Vec<_>>();

for (who, keys) in validators.clone() {
<session::Pallet<T>>::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::<T>(c);
collators.sort();
let collators: frame_support::BoundedVec<_, T::MaxCollators> =
frame_support::BoundedVec::try_from(collators).unwrap();
<Collators<T>>::put(collators);

let (to_add, keys) = validator::<T>(c);
<session::Pallet<T>>::set_keys(RawOrigin::Signed(to_add.clone()).into(), keys, Vec::new())
.unwrap();

#[extrinsic_call]
_(origin as T::RuntimeOrigin, to_add.clone());

assert_last_event::<T>(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::<T>(c);
collators.sort();
let collators: frame_support::BoundedVec<_, T::MaxCollators> =
frame_support::BoundedVec::try_from(collators).unwrap();
<Collators<T>>::put(collators);
let to_remove = <Collators<T>>::get().first().unwrap().clone();

#[extrinsic_call]
_(origin as T::RuntimeOrigin, to_remove.clone());

assert_last_event::<T>(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<T> = 10u32.into();

frame_system::Pallet::<T>::set_block_number(new_block);

#[block]
{
<Fixed<T> as EventHandler<_, _>>::note_author(author.clone())
}

assert_eq!(frame_system::Pallet::<T>::block_number(), new_block);
}

// worst case for new session.
#[benchmark]
fn new_session(c: Linear<1, { T::MaxCollators::get() }>) {
frame_system::Pallet::<T>::set_block_number(0u32.into());

register_validators::<T>(c);

let collators = <Collators<T>>::get();
let pre_length = collators.len();

#[block]
{
let actual_collators = <Fixed<T> as SessionManager<_>>::new_session(0);
let expected_collators: Vec<T::AccountId> = collators.iter().cloned().collect();
assert_eq!(actual_collators.unwrap(), expected_collators);
}

assert!(<Collators<T>>::get().len() == pre_length);
}

impl_benchmark_test_suite!(Fixed, crate::mock::new_test_ext(), crate::mock::Test,);
}
Loading

0 comments on commit 1cd927b

Please sign in to comment.