Skip to content

Commit

Permalink
feat(ismp-grandpa): add benchmarking support (#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvaincormier authored Dec 18, 2024
1 parent 46da0fb commit 0382d9f
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 10 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

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

13 changes: 12 additions & 1 deletion modules/ismp/clients/grandpa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ keywords = ["substrate", "polkadot-sdk", "ISMP", "interoperability", "GRANDPA"]
readme = "./README.md"

[dependencies]
anyhow = { workspace = true }
codec = { workspace = true, features = ["derive"] }
primitive-types = { workspace = true }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
merkle-mountain-range = { workspace = true }
finality-grandpa = { version = "0.16.0", features = ["derive-codec"], default-features = false }
frame-benchmarking = { workspace = true, optional = true }
sp-std = { workspace = true }

# polytope labs
ismp = { workspace = true }
grandpa-verifier-primitives = { workspace = true }
grandpa-verifier-primitives = { workspace = true }
grandpa-verifier = { workspace = true }
pallet-ismp = { workspace = true }

Expand All @@ -40,6 +43,7 @@ substrate-state-machine = { workspace = true }
[features]
default = ["std"]
std = [
"sp-std/std",
"codec/std",
"frame-support/std",
"frame-system/std",
Expand All @@ -60,3 +64,10 @@ std = [
"finality-grandpa/std",
]
try-runtime = []

runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-ismp/runtime-benchmarks",
]
83 changes: 83 additions & 0 deletions modules/ismp/clients/grandpa/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#![cfg(feature = "runtime-benchmarks")]
use super::*;
use frame_benchmarking::v2::*;
use frame_support::pallet_prelude::Weight;
use frame_system::RawOrigin;
use sp_std::prelude::*;

/// Benchmarks for the ISMP GRANDPA pallet operations
#[benchmarks]
mod benchmarks {
use super::*;

/// Benchmark for add_state_machines extrinsic
/// The benchmark creates n state machines and measures the time to add them
/// to the whitelist.
///
/// Parameters:
/// - `n`: Number of state machines to add in a single call
#[benchmark]
fn add_state_machines(n: Linear<1, 100>) -> Result<(), BenchmarkError> {
let caller: T::AccountId = whitelisted_caller();

let state_machines: Vec<AddStateMachine> = (0..n)
.map(|i| {
let id = [i as u8, 0, 0, 0]; // Create unique 4-byte identifier
AddStateMachine {
state_machine: StateMachine::Substrate(id),
slot_duration: 6000u64,
}
})
.collect();

#[extrinsic_call]
_(RawOrigin::Root, state_machines);

// Verify operation was successful
assert!(SupportedStateMachines::<T>::iter().count() == n as usize);
Ok(())
}

/// Benchmark for remove_state_machines extrinsic
/// The benchmark first adds n state machines, then measures the time to remove them
/// from the whitelist.
///
/// Parameters:
/// - `n`: Number of state machines to remove in a single call
#[benchmark]
fn remove_state_machines(n: Linear<1, 100>) -> Result<(), BenchmarkError> {
let caller: T::AccountId = whitelisted_caller();

// Setup: First add state machines that we'll remove
let setup_machines: Vec<AddStateMachine> = (0..n)
.map(|i| {
let id = [i as u8, 0, 0, 0]; // Create unique 4-byte identifier
AddStateMachine {
state_machine: StateMachine::Substrate(id),
slot_duration: 6000u64,
}
})
.collect();

// Add the machines using root origin
Pallet::<T>::add_state_machines(
RawOrigin::Root.into(),
setup_machines.clone(),
)?;

// Create removal list
let remove_machines: Vec<StateMachine> =
setup_machines.into_iter().map(|m| m.state_machine).collect();

// Verify initial state
assert!(SupportedStateMachines::<T>::iter().count() == n as usize);

#[extrinsic_call]
_(RawOrigin::Root, remove_machines);

// Verify all machines were removed
assert!(SupportedStateMachines::<T>::iter().count() == 0);
Ok(())
}
}

19 changes: 17 additions & 2 deletions modules/ismp/clients/grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;

#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;

pub mod consensus;
pub mod messages;

use alloc::vec::Vec;
use frame_support::pallet_prelude::Weight;
use ismp::host::StateMachine;
pub use pallet::*;
pub trait WeightInfo {
/// Weight for adding state machines, scaled by the number of machines
/// * n: The number of machines being added
fn add_state_machines(n: u32) -> Weight;

/// Weight for removing state machines, scaled by the number of machines
/// * n: The number of machines being removed
fn remove_state_machines(n: u32) -> Weight;
}

pub mod weights;
#[frame_support::pallet]
pub mod pallet {
use super::*;
Expand All @@ -41,6 +55,7 @@ pub mod pallet {

/// IsmpHost implementation
type IsmpHost: IsmpHost + Default;
type WeightInfo: WeightInfo;
}

/// Events emitted by this pallet
Expand Down Expand Up @@ -69,7 +84,7 @@ pub mod pallet {
impl<T: Config> Pallet<T> {
/// Add some a state machine to the list of supported state machines
#[pallet::call_index(0)]
#[pallet::weight(T::DbWeight::get().writes(new_state_machines.len() as u64))]
#[pallet::weight(T::WeightInfo::add_state_machines(new_state_machines.len() as u32))]
pub fn add_state_machines(
origin: OriginFor<T>,
new_state_machines: Vec<AddStateMachine>,
Expand All @@ -89,7 +104,7 @@ pub mod pallet {

/// Remove a state machine from the list of supported state machines
#[pallet::call_index(1)]
#[pallet::weight(T::DbWeight::get().writes(state_machines.len() as u64))]
#[pallet::weight(T::WeightInfo::remove_state_machines(state_machines.len() as u32))]
pub fn remove_state_machines(
origin: OriginFor<T>,
state_machines: Vec<StateMachine>,
Expand Down
49 changes: 49 additions & 0 deletions modules/ismp/clients/grandpa/src/weights.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// This file is part of Hyperbridge.

// Copyright (C) Polytope Labs Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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.

#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]

use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use sp_std::marker::PhantomData;

/// Weights for ismp_grandpa
pub struct WeightInfo<T>(PhantomData<T>);

/// Weight functions for ismp-parachain pallet extrinsics.
impl<T: frame_system::Config> crate::WeightInfo for WeightInfo<T> {
/// Weight for adding state machines, scaled by the number of machines.
/// Values based on measured benchmarks:
/// - Base Weight: 5.525 µs
/// - Additional Weight per item: 1.458 µs
/// - DB Weight: n writes
fn add_state_machines(n: u32) -> Weight {
Weight::from_parts(5_525, 0)
.saturating_add(Weight::from_parts(1_458, 0).saturating_mul(n as u64))
.saturating_add(T::DbWeight::get().writes(n as u64))
}

/// Weight for removing state machines, scaled by the number of machines.
/// Values based on measured benchmarks:
/// - Base Weight: 4.914 µs
/// - Additional Weight per item: 1.419 µs
/// - DB Weight: n writes
fn remove_state_machines(n: u32) -> Weight {
Weight::from_parts(4_914, 0)
.saturating_add(Weight::from_parts(1_419, 0).saturating_mul(n as u64))
.saturating_add(T::DbWeight::get().writes(n as u64))
}
}
8 changes: 8 additions & 0 deletions modules/ismp/clients/parachain/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ sp-inherents = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-consensus-aura = { workspace = true }
frame-benchmarking = { workspace = true, optional = true }

# cumulus
cumulus-pallet-parachain-system = { workspace = true, default-features = false }
Expand Down Expand Up @@ -63,3 +64,10 @@ try-runtime = [
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]

runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-ismp/runtime-benchmarks",
]
3 changes: 2 additions & 1 deletion parachain/runtimes/gargantua/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ runtime-benchmarks = [
"pallet-message-queue/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-sudo/runtime-benchmarks",
"parachains-common/runtime-benchmarks"
"parachains-common/runtime-benchmarks",
"ismp-grandpa/runtime-benchmarks",
]

try-runtime = [
Expand Down
6 changes: 4 additions & 2 deletions parachain/runtimes/gargantua/src/ismp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl pallet_state_coprocessor::Config for Runtime {
type Mmr = Mmr;
}


pub struct Coprocessor;

impl Get<Option<StateMachine>> for Coprocessor {
Expand Down Expand Up @@ -107,8 +108,9 @@ impl pallet_ismp::Config for Runtime {
}

impl ismp_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type IsmpHost = Ismp;
type RuntimeEvent = RuntimeEvent;
type IsmpHost = pallet_ismp::Pallet<Runtime>;
type WeightInfo = ismp_grandpa::weights::WeightInfo<Runtime>;
}

impl pallet_token_governor::Config for Runtime {
Expand Down
2 changes: 2 additions & 0 deletions parachain/runtimes/gargantua/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,8 @@ mod benches {
[pallet_collective, TechnicalCollective]
[cumulus_pallet_parachain_system, ParachainSystem]
[pallet_session, SessionBench::<Runtime>]
[ismp_grandpa, IsmpGrandpa]

);
}

Expand Down
11 changes: 7 additions & 4 deletions parachain/runtimes/nexus/src/ismp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ impl Get<Option<StateMachine>> for Coprocessor {
}
}

impl ismp_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type IsmpHost = pallet_ismp::Pallet<Runtime>;
type WeightInfo = ismp_grandpa::weights::WeightInfo<Runtime>;
}

impl pallet_ismp::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type AdminOrigin = EnsureRoot<AccountId>;
Expand All @@ -108,10 +114,7 @@ impl pallet_ismp::Config for Runtime {
type WeightProvider = ();
}

impl ismp_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type IsmpHost = Ismp;
}


impl pallet_ismp_relayer::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
Expand Down

0 comments on commit 0382d9f

Please sign in to comment.