From 301c3a4c3dae796c4ec84a9f984461f6d4482ea7 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 27 Mar 2023 14:33:12 +0300 Subject: [PATCH] Run benchmarks for mock runtimes (#1996) * run benchmarks for pallet-bridge-grandpa mock runtime * run benchmarks for pallet-bridge-relayers mock runtime * run benchmarks for pallet-bridge-parachains mock runtime * run benchmarks for pallet-bridge-messages mock runtime * test benchmarks on mockj runtimes from CI * clippy and spelling --- bridges/modules/grandpa/src/benchmarking.rs | 2 + bridges/modules/grandpa/src/mock.rs | 9 +++- bridges/modules/messages/Cargo.toml | 4 +- bridges/modules/messages/src/benchmarking.rs | 4 +- bridges/modules/messages/src/mock.rs | 50 +++++++++++++++++-- .../modules/parachains/src/benchmarking.rs | 4 +- bridges/modules/parachains/src/lib.rs | 10 ++-- bridges/modules/parachains/src/mock.rs | 39 ++++++++++++++- bridges/modules/relayers/src/benchmarking.rs | 2 + bridges/modules/relayers/src/mock.rs | 22 ++++++-- 10 files changed, 129 insertions(+), 17 deletions(-) diff --git a/bridges/modules/grandpa/src/benchmarking.rs b/bridges/modules/grandpa/src/benchmarking.rs index 78c7fc362a281..aa222d6e4de6f 100644 --- a/bridges/modules/grandpa/src/benchmarking.rs +++ b/bridges/modules/grandpa/src/benchmarking.rs @@ -136,4 +136,6 @@ benchmarks_instance_pallet! { // check that the header#0 has been pruned assert!(!>::contains_key(genesis_header.hash())); } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) } diff --git a/bridges/modules/grandpa/src/mock.rs b/bridges/modules/grandpa/src/mock.rs index b10f5d86c3de2..2220ba3f129f5 100644 --- a/bridges/modules/grandpa/src/mock.rs +++ b/bridges/modules/grandpa/src/mock.rs @@ -131,10 +131,17 @@ impl ChainWithGrandpa for TestBridgedChain { const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = 64; } +/// Return test externalities to use in tests. +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_io::TestExternalities::new(Default::default()) +} + +/// Return test within default test externalities context. pub fn run_test(test: impl FnOnce() -> T) -> T { - sp_io::TestExternalities::new(Default::default()).execute_with(test) + new_test_ext().execute_with(test) } +/// Return test header with given number. pub fn test_header(num: TestNumber) -> TestHeader { // We wrap the call to avoid explicit type annotations in our tests bp_test_utils::test_header(num) diff --git a/bridges/modules/messages/Cargo.toml b/bridges/modules/messages/Cargo.toml index afa8b92b22827..4f1e04eecc278 100644 --- a/bridges/modules/messages/Cargo.toml +++ b/bridges/modules/messages/Cargo.toml @@ -27,9 +27,9 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } [dev-dependencies] -sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } bp-test-utils = { path = "../../primitives/test-utils" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } [features] default = ["std"] diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index bc9c1f752574b..aab8855a729a8 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -37,7 +37,7 @@ use sp_std::{ops::RangeInclusive, prelude::*}; const SEED: u32 = 0; /// Pallet we're benchmarking here. -pub struct Pallet, I: 'static>(crate::Pallet); +pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Benchmark-specific message proof parameters. #[derive(Debug)] @@ -437,6 +437,8 @@ benchmarks_instance_pallet! { ); assert!(T::is_message_successfully_dispatched(21)); } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) } fn send_regular_message, I: 'static>() { diff --git a/bridges/modules/messages/src/mock.rs b/bridges/modules/messages/src/mock.rs index 807721ba86674..02940f369e25c 100644 --- a/bridges/modules/messages/src/mock.rs +++ b/bridges/modules/messages/src/mock.rs @@ -170,6 +170,44 @@ impl Config for TestRuntime { type BridgedChainId = TestBridgedChainId; } +#[cfg(feature = "runtime-benchmarks")] +impl crate::benchmarking::Config<()> for TestRuntime { + fn bench_lane_id() -> LaneId { + TEST_LANE_ID + } + + fn prepare_message_proof( + params: crate::benchmarking::MessageProofParams, + ) -> (TestMessagesProof, Weight) { + // in mock run we only care about benchmarks correctness, not the benchmark results + // => ignore size related arguments + let (messages, total_dispatch_weight) = + params.message_nonces.into_iter().map(|n| message(n, REGULAR_PAYLOAD)).fold( + (Vec::new(), Weight::zero()), + |(mut messages, total_dispatch_weight), message| { + let weight = REGULAR_PAYLOAD.declared_weight; + messages.push(message); + (messages, total_dispatch_weight.saturating_add(weight)) + }, + ); + let mut proof: TestMessagesProof = Ok(messages).into(); + proof.result.as_mut().unwrap().get_mut(0).unwrap().1.lane_state = params.outbound_lane_data; + (proof, total_dispatch_weight) + } + + fn prepare_message_delivery_proof( + params: crate::benchmarking::MessageDeliveryProofParams, + ) -> TestMessagesDeliveryProof { + // in mock run we only care about benchmarks correctness, not the benchmark results + // => ignore size related arguments + TestMessagesDeliveryProof(Ok((params.lane, params.inbound_lane_data))) + } + + fn is_relayer_rewarded(_relayer: &AccountId) -> bool { + true + } +} + impl Size for TestPayload { fn size(&self) -> u32 { 16 + self.extra.len() as u32 @@ -439,12 +477,16 @@ pub fn unrewarded_relayer( UnrewardedRelayer { relayer, messages: DeliveredMessages { begin, end } } } -/// Run pallet test. -pub fn run_test(test: impl FnOnce() -> T) -> T { +/// Return test externalities to use in tests. +pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(ENDOWED_ACCOUNT, 1_000_000)] } .assimilate_storage(&mut t) .unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(test) + sp_io::TestExternalities::new(t) +} + +/// Run pallet test. +pub fn run_test(test: impl FnOnce() -> T) -> T { + new_test_ext().execute_with(test) } diff --git a/bridges/modules/parachains/src/benchmarking.rs b/bridges/modules/parachains/src/benchmarking.rs index 83cfba0b8c6b0..59c4642cde999 100644 --- a/bridges/modules/parachains/src/benchmarking.rs +++ b/bridges/modules/parachains/src/benchmarking.rs @@ -28,7 +28,7 @@ use frame_system::RawOrigin; use sp_std::prelude::*; /// Pallet we're benchmarking here. -pub struct Pallet, I: 'static>(crate::Pallet); +pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Trait that must be implemented by runtime to benchmark the parachains finality pallet. pub trait Config: crate::Config { @@ -111,4 +111,6 @@ benchmarks_instance_pallet! { assert!(crate::Pallet::::best_parachain_head(parachain).is_some()); } } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) } diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index e72e2aec8c202..8fe6c4e938391 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -689,7 +689,7 @@ pub fn initialize_for_benchmarks, I: 'static, PC: Parachain::WeightInfo; type DbWeight = ::DbWeight; - fn initialize(state_root: RelayBlockHash) { + pub(crate) fn initialize(state_root: RelayBlockHash) -> RelayBlockHash { pallet_bridge_grandpa::Pallet::::initialize( RuntimeOrigin::root(), bp_header_chain::InitializationData { @@ -738,6 +738,8 @@ mod tests { System::::set_block_number(1); System::::reset_events(); + + test_relay_header(0, state_root).hash() } fn proceed(num: RelayBlockNumber, state_root: RelayBlockHash) -> ParaHash { @@ -759,7 +761,7 @@ mod tests { hash } - fn prepare_parachain_heads_proof( + pub(crate) fn prepare_parachain_heads_proof( heads: Vec<(u32, ParaHead)>, ) -> (RelayBlockHash, ParaHeadsProof, Vec<(ParaId, ParaHash)>) { let mut parachains = Vec::with_capacity(heads.len()); @@ -795,7 +797,7 @@ mod tests { } } - fn head_data(parachain: u32, head_number: u32) -> ParaHead { + pub(crate) fn head_data(parachain: u32, head_number: u32) -> ParaHead { ParaHead( RegularParachainHeader::new( head_number as _, diff --git a/bridges/modules/parachains/src/mock.rs b/bridges/modules/parachains/src/mock.rs index c19ce98eba2fe..90e6d7c558e49 100644 --- a/bridges/modules/parachains/src/mock.rs +++ b/bridges/modules/parachains/src/mock.rs @@ -228,6 +228,36 @@ impl pallet_bridge_parachains::Config for TestRuntime { type MaxParaHeadDataSize = ConstU32; } +#[cfg(feature = "runtime-benchmarks")] +impl pallet_bridge_parachains::benchmarking::Config<()> for TestRuntime { + fn parachains() -> Vec { + vec![ + ParaId(Parachain1::PARACHAIN_ID), + ParaId(Parachain2::PARACHAIN_ID), + ParaId(Parachain3::PARACHAIN_ID), + ] + } + + fn prepare_parachain_heads_proof( + parachains: &[ParaId], + _parachain_head_size: u32, + _proof_size: bp_runtime::StorageProofSize, + ) -> ( + crate::RelayBlockNumber, + crate::RelayBlockHash, + bp_polkadot_core::parachains::ParaHeadsProof, + Vec<(ParaId, bp_polkadot_core::parachains::ParaHash)>, + ) { + // in mock run we only care about benchmarks correctness, not the benchmark results + // => ignore size related arguments + let (state_root, proof, parachains) = crate::tests::prepare_parachain_heads_proof( + parachains.iter().map(|p| (p.0, crate::tests::head_data(p.0, 1))).collect(), + ); + let relay_genesis_hash = crate::tests::initialize(state_root); + (0, relay_genesis_hash, proof, parachains) + } +} + #[derive(Debug)] pub struct TestBridgedChain; @@ -290,14 +320,21 @@ impl ChainWithGrandpa for OtherBridgedChain { const AVERAGE_HEADER_SIZE_IN_JUSTIFICATION: u32 = 64; } +/// Return test externalities to use in tests. +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_io::TestExternalities::new(Default::default()) +} + +/// Run pallet test. pub fn run_test(test: impl FnOnce() -> T) -> T { - sp_io::TestExternalities::new(Default::default()).execute_with(|| { + new_test_ext().execute_with(|| { System::set_block_number(1); System::reset_events(); test() }) } +/// Return test relay chain header with given number. pub fn test_relay_header( num: crate::RelayBlockNumber, state_root: crate::RelayBlockHash, diff --git a/bridges/modules/relayers/src/benchmarking.rs b/bridges/modules/relayers/src/benchmarking.rs index 7dcf77eb958ea..a762a5693c26e 100644 --- a/bridges/modules/relayers/src/benchmarking.rs +++ b/bridges/modules/relayers/src/benchmarking.rs @@ -54,4 +54,6 @@ benchmarks! { // payment logic, so we assume that if call has succeeded, the procedure has // also completed successfully } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) } diff --git a/bridges/modules/relayers/src/mock.rs b/bridges/modules/relayers/src/mock.rs index 5e97e81ae3344..fe8c586eecc59 100644 --- a/bridges/modules/relayers/src/mock.rs +++ b/bridges/modules/relayers/src/mock.rs @@ -99,6 +99,18 @@ impl pallet_bridge_relayers::Config for TestRuntime { type WeightInfo = (); } +#[cfg(feature = "runtime-benchmarks")] +impl pallet_bridge_relayers::benchmarking::Config for TestRuntime { + fn prepare_environment(account_params: RewardsAccountParams, reward: Balance) { + use frame_support::traits::fungible::Mutate; + let rewards_account = + bp_relayers::PayRewardFromAccount::::rewards_account( + account_params, + ); + Balances::mint_into(&rewards_account, reward).unwrap(); + } +} + /// Message lane that we're using in tests. pub const TEST_REWARDS_ACCOUNT_PARAMS: RewardsAccountParams = RewardsAccountParams::new(LaneId([0, 0, 0, 0]), *b"test", RewardsAccountOwner::ThisChain); @@ -127,9 +139,13 @@ impl PaymentProcedure for TestPaymentProcedure { } } +/// Return test externalities to use in tests. +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + sp_io::TestExternalities::new(t) +} + /// Run pallet test. pub fn run_test(test: impl FnOnce() -> T) -> T { - let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(test) + new_test_ext().execute_with(test) }