From d108b65257c552d5ff827bba6019a47cf2a7f6dd Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sun, 1 Aug 2021 20:13:58 +0200 Subject: [PATCH] Refactor Benchmarks for Less Wasm Memory Usage (#9373) * extract repeat out of benchmark * remove r * unused * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * use linked map to keep order * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Delete pallet_balances.rs * Delete out * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * steps and repeat to tuple (current_*, total_*) * idea for list command * fmt * use benchmark list in cli * handle steps in cli * move log update to cli * fmt * remove old todo * line width * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * benchmark metadata function * don't need this warm up * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * fix warnings * fix node-template * fix * fmt * line width * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * improve docs * improve cli * fix format * fix bug? * Revert "fix bug?" This reverts commit 8051bf1bf9bae862ff28dfff386e7045cd3f045e. * skip frame-metadata * extract repeat out of benchmark * remove r * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * use linked map to keep order * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Delete pallet_balances.rs * Delete out * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * steps and repeat to tuple (current_*, total_*) * idea for list command * fmt * use benchmark list in cli * handle steps in cli * move log update to cli * remove old todo * line width * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * benchmark metadata function * don't need this warm up * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_balances --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/balances/src/weights.rs --template=./.maintain/frame-weight-template.hbs * fix warnings * fix node-template * fix * fmt * line width * cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * improve docs * improve cli * fix format * fix bug? * Revert "fix bug?" This reverts commit 8051bf1bf9bae862ff28dfff386e7045cd3f045e. * skip frame-metadata * Update .gitlab-ci.yml * fix import * Update .gitlab-ci.yml Co-authored-by: Parity Benchmarking Bot --- .gitlab-ci.yml | 7 +- Cargo.lock | 2 + bin/node-template/runtime/src/lib.rs | 30 +- bin/node/runtime/src/lib.rs | 63 ++- frame/balances/src/weights.rs | 40 +- frame/benchmarking/src/lib.rs | 373 +++++++------- frame/benchmarking/src/utils.rs | 43 +- frame/staking/src/weights.rs | 524 +++++++++++++++----- utils/frame/benchmarking-cli/Cargo.toml | 2 + utils/frame/benchmarking-cli/src/command.rs | 376 +++++++++----- utils/frame/benchmarking-cli/src/lib.rs | 20 +- utils/frame/benchmarking-cli/src/writer.rs | 2 +- 12 files changed, 1001 insertions(+), 481 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2cef2d8badcc9..f954ac23cba23 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -273,7 +273,7 @@ node-bench-regression-guard: CI_IMAGE: "paritytech/node-bench-regression-guard:latest" before_script: [""] script: - - 'node-bench-regression-guard --reference artifacts/benches/master-* + - 'node-bench-regression-guard --reference artifacts/benches/master-* --compare-with artifacts/benches/$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA' cargo-check-subkey: @@ -343,6 +343,7 @@ unleash-check: - mkdir -p target/unleash - export CARGO_TARGET_DIR=target/unleash - cargo unleash check ${CARGO_UNLEASH_PKG_DEF} + allow_failure: true test-frame-examples-compile-to-wasm: # into one job @@ -578,7 +579,7 @@ build-rust-doc: - buildah push --format=v2s2 "$IMAGE_NAME:latest" after_script: - buildah logout "$IMAGE_NAME" - # pass artifacts to the trigger-simnet job + # pass artifacts to the trigger-simnet job - echo "IMAGE_NAME=${IMAGE_NAME}" | tee -a ./artifacts/$PRODUCT/build.env - IMAGE_TAG="$(cat ./artifacts/$PRODUCT/VERSION)" - echo "IMAGE_TAG=${IMAGE_TAG}" | tee -a ./artifacts/$PRODUCT/build.env @@ -713,7 +714,7 @@ trigger-simnet: - if: $CI_COMMIT_REF_NAME == "master" needs: - job: publish-docker-substrate - # `build.env` brings here `$IMAGE_NAME` and `$IMAGE_TAG` (`$VERSION` here, + # `build.env` brings here `$IMAGE_NAME` and `$IMAGE_TAG` (`$VERSION` here, # i.e. `2643-0.8.29-5f689e0a-6b24dc54`). variables: TRGR_PROJECT: ${CI_PROJECT_NAME} diff --git a/Cargo.lock b/Cargo.lock index 6cfc2d19db81f..3d22e0c0b6bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1800,6 +1800,8 @@ dependencies = [ "frame-benchmarking", "frame-support", "handlebars", + "linked-hash-map", + "log", "parity-scale-codec", "sc-cli", "sc-client-db", diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index f9eaa96153eba..63da72102df3d 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -446,14 +446,30 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + use frame_system_benchmarking::Pallet as SystemBench; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, frame_system, SystemBench::); + list_benchmark!(list, extra, pallet_balances, Balances); + list_benchmark!(list, extra, pallet_timestamp, Timestamp); + list_benchmark!(list, extra, pallet_template, TemplateModule); + + let storage_info = AllPalletsWithSystem::storage_info(); + + return (list, storage_info) + } + fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig - ) -> Result< - (Vec, Vec), - sp_runtime::RuntimeString, - > { + ) -> Result, sp_runtime::RuntimeString> { use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; - use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; impl frame_system_benchmarking::Config for Runtime {} @@ -471,8 +487,6 @@ impl_runtime_apis! { hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), ]; - let storage_info = AllPalletsWithSystem::storage_info(); - let mut batches = Vec::::new(); let params = (&config, &whitelist); @@ -482,7 +496,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_template, TemplateModule); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok((batches, storage_info)) + Ok(batches) } } } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 90bd11d484b26..181f5fd423767 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1534,14 +1534,63 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{list_benchmark, Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + + // Trying to add benchmarks directly to the Session Pallet caused cyclic dependency + // issues. To get around that, we separated the Session benchmarks into its own crate, + // which is why we need these two lines below. + use pallet_session_benchmarking::Pallet as SessionBench; + use pallet_offences_benchmarking::Pallet as OffencesBench; + use frame_system_benchmarking::Pallet as SystemBench; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, pallet_assets, Assets); + list_benchmark!(list, extra, pallet_babe, Babe); + list_benchmark!(list, extra, pallet_balances, Balances); + list_benchmark!(list, extra, pallet_bounties, Bounties); + list_benchmark!(list, extra, pallet_collective, Council); + list_benchmark!(list, extra, pallet_contracts, Contracts); + list_benchmark!(list, extra, pallet_democracy, Democracy); + list_benchmark!(list, extra, pallet_election_provider_multi_phase, ElectionProviderMultiPhase); + list_benchmark!(list, extra, pallet_elections_phragmen, Elections); + list_benchmark!(list, extra, pallet_gilt, Gilt); + list_benchmark!(list, extra, pallet_grandpa, Grandpa); + list_benchmark!(list, extra, pallet_identity, Identity); + list_benchmark!(list, extra, pallet_im_online, ImOnline); + list_benchmark!(list, extra, pallet_indices, Indices); + list_benchmark!(list, extra, pallet_lottery, Lottery); + list_benchmark!(list, extra, pallet_membership, TechnicalMembership); + list_benchmark!(list, extra, pallet_mmr, Mmr); + list_benchmark!(list, extra, pallet_multisig, Multisig); + list_benchmark!(list, extra, pallet_offences, OffencesBench::); + list_benchmark!(list, extra, pallet_proxy, Proxy); + list_benchmark!(list, extra, pallet_scheduler, Scheduler); + list_benchmark!(list, extra, pallet_session, SessionBench::); + list_benchmark!(list, extra, pallet_staking, Staking); + list_benchmark!(list, extra, frame_system, SystemBench::); + list_benchmark!(list, extra, pallet_timestamp, Timestamp); + list_benchmark!(list, extra, pallet_tips, Tips); + list_benchmark!(list, extra, pallet_transaction_storage, TransactionStorage); + list_benchmark!(list, extra, pallet_treasury, Treasury); + list_benchmark!(list, extra, pallet_uniques, Uniques); + list_benchmark!(list, extra, pallet_utility, Utility); + list_benchmark!(list, extra, pallet_vesting, Vesting); + + let storage_info = AllPalletsWithSystem::storage_info(); + + return (list, storage_info) + } + fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig - ) -> Result< - (Vec, Vec), - sp_runtime::RuntimeString, - > { + ) -> Result, sp_runtime::RuntimeString> { use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; - use frame_support::traits::StorageInfoTrait; // Trying to add benchmarks directly to the Session Pallet caused cyclic dependency // issues. To get around that, we separated the Session benchmarks into its own crate, @@ -1569,8 +1618,6 @@ impl_runtime_apis! { hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000").to_vec().into(), ]; - let storage_info = AllPalletsWithSystem::storage_info(); - let mut batches = Vec::::new(); let params = (&config, &whitelist); @@ -1607,7 +1654,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_vesting, Vesting); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } - Ok((batches, storage_info)) + Ok(batches) } } } diff --git a/frame/balances/src/weights.rs b/frame/balances/src/weights.rs index d1e86ce45e4b3..df609b74840d2 100644 --- a/frame/balances/src/weights.rs +++ b/frame/balances/src/weights.rs @@ -17,8 +17,8 @@ //! Autogenerated weights for pallet_balances //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-06-19, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-07-30, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -56,33 +56,39 @@ pub trait WeightInfo { /// Weights for pallet_balances using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + // Storage: System Account (r:1 w:1) fn transfer() -> Weight { - (73_268_000 as Weight) + (78_358_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:1 w:1) fn transfer_keep_alive() -> Weight { - (54_881_000 as Weight) + (59_001_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:1 w:1) fn set_balance_creating() -> Weight { - (29_853_000 as Weight) + (32_698_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:1 w:1) fn set_balance_killing() -> Weight { - (36_007_000 as Weight) + (38_746_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:2 w:2) fn force_transfer() -> Weight { - (72_541_000 as Weight) + (77_622_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } + // Storage: System Account (r:1 w:1) fn transfer_all() -> Weight { - (67_360_000 as Weight) + (72_020_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -90,33 +96,39 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { + // Storage: System Account (r:1 w:1) fn transfer() -> Weight { - (73_268_000 as Weight) + (78_358_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:1 w:1) fn transfer_keep_alive() -> Weight { - (54_881_000 as Weight) + (59_001_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:1 w:1) fn set_balance_creating() -> Weight { - (29_853_000 as Weight) + (32_698_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:1 w:1) fn set_balance_killing() -> Weight { - (36_007_000 as Weight) + (38_746_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: System Account (r:2 w:2) fn force_transfer() -> Weight { - (72_541_000 as Weight) + (77_622_000 as Weight) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } + // Storage: System Account (r:1 w:1) fn transfer_all() -> Weight { - (67_360_000 as Weight) + (72_020_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index a0aa78f722f72..7149ddc82f59d 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -711,8 +711,8 @@ macro_rules! impl_benchmark { extrinsic: &[u8], lowest_range_values: &[u32], highest_range_values: &[u32], - steps: &[u32], - repeat: u32, + steps: (u32, u32), + _repeat: (u32, u32), whitelist: &[$crate::TrackedStorageKey], verify: bool, ) -> Result<$crate::Vec<$crate::BenchmarkResults>, &'static str> { @@ -724,9 +724,6 @@ macro_rules! impl_benchmark { _ => return Err("Could not find extrinsic."), }; let mut results: $crate::Vec<$crate::BenchmarkResults> = $crate::Vec::new(); - if repeat == 0 { - return Ok(results); - } // Add whitelist to DB including whitelisted caller let mut whitelist = whitelist.to_vec(); @@ -737,141 +734,110 @@ macro_rules! impl_benchmark { whitelist.push(whitelisted_caller_key.into()); $crate::benchmarking::set_whitelist(whitelist); - // Warm up the DB - $crate::benchmarking::commit_db(); - $crate::benchmarking::wipe_db(); - let components = < SelectedBenchmark as $crate::BenchmarkingSetup >::components(&selected_benchmark); - let mut progress = $crate::benchmarking::current_time(); - // Default number of steps for a component. - let mut prev_steps = 10; - - let mut repeat_benchmark = | - repeat: u32, + let do_benchmark = | c: &[($crate::BenchmarkParameter, u32)], results: &mut $crate::Vec<$crate::BenchmarkResults>, verify: bool, - step: u32, - num_steps: u32, | -> Result<(), &'static str> { - // Run the benchmark `repeat` times. - for r in 0..repeat { - // Set up the externalities environment for the setup we want to - // benchmark. - let closure_to_benchmark = < - SelectedBenchmark as $crate::BenchmarkingSetup - >::instance(&selected_benchmark, c, verify)?; - - // Set the block number to at least 1 so events are deposited. - if $crate::Zero::is_zero(&frame_system::Pallet::::block_number()) { - frame_system::Pallet::::set_block_number(1u32.into()); - } + // Set up the externalities environment for the setup we want to + // benchmark. + let closure_to_benchmark = < + SelectedBenchmark as $crate::BenchmarkingSetup + >::instance(&selected_benchmark, c, verify)?; - // Commit the externalities to the database, flushing the DB cache. - // This will enable worst case scenario for reading from the database. - $crate::benchmarking::commit_db(); + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Pallet::::block_number()) { + frame_system::Pallet::::set_block_number(1u32.into()); + } - // Reset the read/write counter so we don't count operations in the setup process. - $crate::benchmarking::reset_read_write_count(); + // Commit the externalities to the database, flushing the DB cache. + // This will enable worst case scenario for reading from the database. + $crate::benchmarking::commit_db(); - if verify { - closure_to_benchmark()?; - } else { - // Time the extrinsic logic. - $crate::log::trace!( - target: "benchmark", - "Start Benchmark: {:?}", c - ); - - let start_pov = $crate::benchmarking::proof_size(); - let start_extrinsic = $crate::benchmarking::current_time(); - - closure_to_benchmark()?; - - let finish_extrinsic = $crate::benchmarking::current_time(); - let end_pov = $crate::benchmarking::proof_size(); - - // Calculate the diff caused by the benchmark. - let elapsed_extrinsic = finish_extrinsic.saturating_sub(start_extrinsic); - let diff_pov = match (start_pov, end_pov) { - (Some(start), Some(end)) => end.saturating_sub(start), - _ => Default::default(), - }; - - // Commit the changes to get proper write count - $crate::benchmarking::commit_db(); - $crate::log::trace!( - target: "benchmark", - "End Benchmark: {} ns", elapsed_extrinsic - ); - let read_write_count = $crate::benchmarking::read_write_count(); - $crate::log::trace!( - target: "benchmark", - "Read/Write Count {:?}", read_write_count - ); - - let time = $crate::benchmarking::current_time(); - if time.saturating_sub(progress) > 5000000000 { - progress = $crate::benchmarking::current_time(); - $crate::log::info!( - target: "benchmark", - "Benchmarking {} {}/{}, run {}/{}", - extrinsic, - step, - num_steps, - r, - repeat, - ); - } - - // Time the storage root recalculation. - let start_storage_root = $crate::benchmarking::current_time(); - $crate::storage_root(); - let finish_storage_root = $crate::benchmarking::current_time(); - let elapsed_storage_root = finish_storage_root - start_storage_root; - - // TODO: Fix memory allocation issue then re-enable - // let read_and_written_keys = $crate::benchmarking::get_read_and_written_keys(); - let read_and_written_keys = Default::default(); - - results.push($crate::BenchmarkResults { - components: c.to_vec(), - extrinsic_time: elapsed_extrinsic, - storage_root_time: elapsed_storage_root, - reads: read_write_count.0, - repeat_reads: read_write_count.1, - writes: read_write_count.2, - repeat_writes: read_write_count.3, - proof_size: diff_pov, - keys: read_and_written_keys, - }); - } + // Reset the read/write counter so we don't count operations in the setup process. + $crate::benchmarking::reset_read_write_count(); - // Wipe the DB back to the genesis state. - $crate::benchmarking::wipe_db(); + if verify { + closure_to_benchmark()?; + } else { + // Time the extrinsic logic. + $crate::log::trace!( + target: "benchmark", + "Start Benchmark: {:?}", c + ); + + let start_pov = $crate::benchmarking::proof_size(); + let start_extrinsic = $crate::benchmarking::current_time(); + + closure_to_benchmark()?; + + let finish_extrinsic = $crate::benchmarking::current_time(); + let end_pov = $crate::benchmarking::proof_size(); + + // Calculate the diff caused by the benchmark. + let elapsed_extrinsic = finish_extrinsic.saturating_sub(start_extrinsic); + let diff_pov = match (start_pov, end_pov) { + (Some(start), Some(end)) => end.saturating_sub(start), + _ => Default::default(), + }; + + // Commit the changes to get proper write count + $crate::benchmarking::commit_db(); + $crate::log::trace!( + target: "benchmark", + "End Benchmark: {} ns", elapsed_extrinsic + ); + let read_write_count = $crate::benchmarking::read_write_count(); + $crate::log::trace!( + target: "benchmark", + "Read/Write Count {:?}", read_write_count + ); + + // Time the storage root recalculation. + let start_storage_root = $crate::benchmarking::current_time(); + $crate::storage_root(); + let finish_storage_root = $crate::benchmarking::current_time(); + let elapsed_storage_root = finish_storage_root - start_storage_root; + + let read_and_written_keys = $crate::benchmarking::get_read_and_written_keys(); + + results.push($crate::BenchmarkResults { + components: c.to_vec(), + extrinsic_time: elapsed_extrinsic, + storage_root_time: elapsed_storage_root, + reads: read_write_count.0, + repeat_reads: read_write_count.1, + writes: read_write_count.2, + repeat_writes: read_write_count.3, + proof_size: diff_pov, + keys: read_and_written_keys, + }); } + // Wipe the DB back to the genesis state. + $crate::benchmarking::wipe_db(); + Ok(()) }; + let (current_step, total_steps) = steps; + if components.is_empty() { - if verify { - // If `--verify` is used, run the benchmark once to verify it would complete. - repeat_benchmark(1, Default::default(), &mut $crate::Vec::new(), true, 1, 1)?; + // The CLI could ask to do more steps than is sensible, so we skip those. + if current_step == 0 { + if verify { + // If `--verify` is used, run the benchmark once to verify it would complete. + do_benchmark(Default::default(), &mut $crate::Vec::new(), true)?; + } + do_benchmark(Default::default(), &mut results, false)?; } - repeat_benchmark(repeat, Default::default(), &mut results, false, 1, 1)?; } else { // Select the component we will be benchmarking. Each component will be benchmarked. for (idx, (name, low, high)) in components.iter().enumerate() { - // Get the number of steps for this component. - let steps = steps.get(idx).cloned().unwrap_or(prev_steps); - prev_steps = steps; - - // Skip this loop if steps is zero - if steps == 0 { continue } let lowest = lowest_range_values.get(idx).cloned().unwrap_or(*low); let highest = highest_range_values.get(idx).cloned().unwrap_or(*high); @@ -879,31 +845,34 @@ macro_rules! impl_benchmark { let diff = highest - lowest; // Create up to `STEPS` steps for that component between high and low. - let step_size = (diff / steps).max(1); + let step_size = (diff / total_steps).max(1); let num_of_steps = diff / step_size + 1; - for s in 0..num_of_steps { - // This is the value we will be testing for component `name` - let component_value = lowest + step_size * s; + // The CLI could ask to do more steps than is sensible, so we just skip those. + if current_step >= num_of_steps { + continue; + } - // Select the max value for all the other components. - let c: $crate::Vec<($crate::BenchmarkParameter, u32)> = components.iter() - .enumerate() - .map(|(idx, (n, _, h))| - if n == name { - (*n, component_value) - } else { - (*n, *highest_range_values.get(idx).unwrap_or(h)) - } - ) - .collect(); + // This is the value we will be testing for component `name` + let component_value = lowest + step_size * current_step; + + // Select the max value for all the other components. + let c: $crate::Vec<($crate::BenchmarkParameter, u32)> = components.iter() + .enumerate() + .map(|(idx, (n, _, h))| + if n == name { + (*n, component_value) + } else { + (*n, *highest_range_values.get(idx).unwrap_or(h)) + } + ) + .collect(); - if verify { - // If `--verify` is used, run the benchmark once to verify it would complete. - repeat_benchmark(1, &c, &mut $crate::Vec::new(), true, s, num_of_steps)?; - } - repeat_benchmark(repeat, &c, &mut results, false, s, num_of_steps)?; + if verify { + // If `--verify` is used, run the benchmark once to verify it would complete. + do_benchmark(&c, &mut $crate::Vec::new(), true)?; } + do_benchmark(&c, &mut results, false)?; } } return Ok(results); @@ -1253,8 +1222,8 @@ pub fn show_benchmark_debug_info( benchmark: &[u8], lowest_range_values: &sp_std::prelude::Vec, highest_range_values: &sp_std::prelude::Vec, - steps: &sp_std::prelude::Vec, - repeat: &u32, + steps: &(u32, u32), + repeat: &(u32, u32), verify: &bool, error_message: &str, ) -> sp_runtime::RuntimeString { @@ -1273,8 +1242,8 @@ pub fn show_benchmark_debug_info( .expect("it's all just strings ran through the wasm interface. qed"), lowest_range_values, highest_range_values, - steps, - repeat, + steps.1, + repeat.1, verify, error_message, ) @@ -1359,62 +1328,70 @@ macro_rules! add_benchmark { verify, extra, } = config; - if &pallet[..] == &name_string[..] || &pallet[..] == &b"*"[..] { - if &pallet[..] == &b"*"[..] || &benchmark[..] == &b"*"[..] { - for benchmark in $( $location )*::benchmarks(*extra).into_iter() { - $batches.push($crate::BenchmarkBatch { - pallet: name_string.to_vec(), - instance: instance_string.to_vec(), - benchmark: benchmark.to_vec(), - results: $( $location )*::run_benchmark( - benchmark, - &lowest_range_values[..], - &highest_range_values[..], - &steps[..], - *repeat, - whitelist, - *verify, - ).map_err(|e| { - $crate::show_benchmark_debug_info( - instance_string, - benchmark, - lowest_range_values, - highest_range_values, - steps, - repeat, - verify, - e, - ) - })?, - }); - } - } else { - $batches.push($crate::BenchmarkBatch { - pallet: name_string.to_vec(), - instance: instance_string.to_vec(), - benchmark: benchmark.clone(), - results: $( $location )*::run_benchmark( - &benchmark[..], - &lowest_range_values[..], - &highest_range_values[..], - &steps[..], - *repeat, - whitelist, - *verify, - ).map_err(|e| { - $crate::show_benchmark_debug_info( - instance_string, - benchmark, - lowest_range_values, - highest_range_values, - steps, - repeat, - verify, - e, - ) - })?, - }); - } + if &pallet[..] == &name_string[..] { + $batches.push($crate::BenchmarkBatch { + pallet: name_string.to_vec(), + instance: instance_string.to_vec(), + benchmark: benchmark.clone(), + results: $( $location )*::run_benchmark( + &benchmark[..], + &lowest_range_values[..], + &highest_range_values[..], + *steps, + *repeat, + whitelist, + *verify, + ).map_err(|e| { + $crate::show_benchmark_debug_info( + instance_string, + benchmark, + lowest_range_values, + highest_range_values, + steps, + repeat, + verify, + e, + ) + })? + }); } ) } + +/// This macro allows users to easily generate a list of benchmarks for the pallets configured +/// in the runtime. +/// +/// To use this macro, first create a an object to store the list: +/// +/// ```ignore +/// let mut list = Vec::::new(); +/// ``` +/// +/// Then pass this `list` to the macro, along with the `extra` boolean, the pallet crate, and +/// pallet struct: +/// +/// ```ignore +/// list_benchmark!(list, extra, pallet_balances, Balances); +/// list_benchmark!(list, extra, pallet_session, SessionBench::); +/// list_benchmark!(list, extra, frame_system, SystemBench::); +/// ``` +/// +/// This should match what exists with the `add_benchmark!` macro. + +#[macro_export] +macro_rules! list_benchmark { + ( $list:ident, $extra:ident, $name:path, $( $location:tt )* ) => ( + let pallet_string = stringify!($name).as_bytes(); + let instance_string = stringify!( $( $location )* ).as_bytes(); + let benchmarks = $( $location )*::benchmarks($extra) + .iter() + .map(|b| b.to_vec()) + .collect::>(); + let pallet_benchmarks = BenchmarkList { + pallet: pallet_string.to_vec(), + instance: instance_string.to_vec(), + benchmarks: benchmarks.to_vec(), + }; + $list.push(pallet_benchmarks) + ) +} diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index 33d479a0b54a7..82c6e44796fae 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -103,22 +103,41 @@ pub struct BenchmarkConfig { pub lowest_range_values: Vec, /// An optional manual override to the highest values used in the `steps` range. pub highest_range_values: Vec, - /// The number of samples to take across the range of values for components. - pub steps: Vec, - /// The number of times to repeat a benchmark. - pub repeat: u32, + /// The number of samples to take across the range of values for components. (current_step, + /// total_steps) + pub steps: (u32, u32), + /// The number times to repeat each benchmark to increase accuracy of results. (current_repeat, + /// total_repeat) + pub repeat: (u32, u32), /// Enable an extra benchmark iteration which runs the verification logic for a benchmark. pub verify: bool, - /// Enable benchmarking of "extra" extrinsics, i.e. those that are not directly used in a pallet. + /// Enable benchmarking of "extra" extrinsics, i.e. those that are not directly used in a + /// pallet. pub extra: bool, } +/// A list of benchmarks available for a particular pallet and instance. +/// +/// All `Vec` must be valid utf8 strings. +#[derive(Encode, Decode, Default, Clone, PartialEq, Debug)] +pub struct BenchmarkList { + pub pallet: Vec, + pub instance: Vec, + pub benchmarks: Vec>, +} + sp_api::decl_runtime_apis! { /// Runtime api for benchmarking a FRAME runtime. pub trait Benchmark { + /// Get the benchmark metadata available for this runtime. + /// + /// Parameters + /// - `extra`: Also list benchmarks marked "extra" which would otherwise not be + /// needed for weight calculation. + fn benchmark_metadata(extra: bool) -> (Vec, Vec); + /// Dispatch the given benchmark. - fn dispatch_benchmark(config: BenchmarkConfig) - -> Result<(Vec, Vec), sp_runtime::RuntimeString>; + fn dispatch_benchmark(config: BenchmarkConfig) -> Result, sp_runtime::RuntimeString>; } } @@ -216,16 +235,18 @@ pub trait Benchmarking { /// Parameters /// - `name`: The name of extrinsic function or benchmark you want to benchmark encoded as /// bytes. - /// - `steps`: The number of sample points you want to take across the range of parameters. /// - `lowest_range_values`: The lowest number for each range of parameters. /// - `highest_range_values`: The highest number for each range of parameters. - /// - `repeat`: The number of times you want to repeat a benchmark. + /// - `steps`: The number of sample points you want to take across the range of parameters. + /// (current_step, total_steps) + /// - `repeat`: The total number times to repeat each benchmark to increase accuracy of results. + /// (current_repeat, total_repeats) fn run_benchmark( name: &[u8], lowest_range_values: &[u32], highest_range_values: &[u32], - steps: &[u32], - repeat: u32, + steps: (u32, u32), + repeat: (u32, u32), whitelist: &[TrackedStorageKey], verify: bool, ) -> Result, &'static str>; diff --git a/frame/staking/src/weights.rs b/frame/staking/src/weights.rs index cba4e68b5f61e..fb4ed160d8325 100644 --- a/frame/staking/src/weights.rs +++ b/frame/staking/src/weights.rs @@ -17,8 +17,8 @@ //! Autogenerated weights for pallet_staking //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 -//! DATE: 2021-06-19, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-07-31, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -78,376 +78,664 @@ pub trait WeightInfo { /// Weights for pallet_staking using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Payee (r:0 w:1) fn bond() -> Weight { - (72_617_000 as Weight) + (77_492_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Bonded (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) fn bond_extra() -> Weight { - (55_590_000 as Weight) + (59_476_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Staking Validators (r:1 w:0) fn unbond() -> Weight { - (59_730_000 as Weight) + (63_655_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: System Account (r:1 w:1) fn withdraw_unbonded_update(s: u32, ) -> Weight { - (52_279_000 as Weight) + (54_534_000 as Weight) // Standard Error: 0 - .saturating_add((68_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((24_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking Validators (r:1 w:0) + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking SlashingSpans (r:1 w:0) + // Storage: System Account (r:1 w:1) + // Storage: Staking SpanSlash (r:0 w:2) fn withdraw_unbonded_kill(s: u32, ) -> Weight { - (86_629_000 as Weight) + (89_850_000 as Weight) // Standard Error: 1_000 - .saturating_add((2_379_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((2_396_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } + // Storage: Staking MaxValidatorsCount (r:1 w:0) + // Storage: Staking MinValidatorBond (r:1 w:0) + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Validators (r:1 w:1) + // Storage: Staking CounterForValidators (r:1 w:1) fn validate() -> Weight { - (32_393_000 as Weight) + (36_726_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking Nominators (r:1 w:1) fn kick(k: u32, ) -> Weight { - (36_986_000 as Weight) - // Standard Error: 13_000 - .saturating_add((16_574_000 as Weight).saturating_mul(k as Weight)) + (19_497_000 as Weight) + // Standard Error: 15_000 + .saturating_add((17_057_000 as Weight).saturating_mul(k as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(k as Weight))) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking MinNominatorBond (r:1 w:0) + // Storage: Staking CounterForNominators (r:1 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking Nominators (r:1 w:1) + // Storage: Staking Validators (r:2 w:0) + // Storage: Staking MaxNominatorsCount (r:1 w:0) fn nominate(n: u32, ) -> Weight { - (43_228_000 as Weight) - // Standard Error: 21_000 - .saturating_add((5_119_000 as Weight).saturating_mul(n as Weight)) + (45_146_000 as Weight) + // Standard Error: 13_000 + .saturating_add((5_527_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } + // Storage: Staking Validators (r:1 w:0) + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking Nominators (r:1 w:0) fn chill() -> Weight { - (17_800_000 as Weight) + (18_986_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) } + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking Ledger (r:1 w:0) fn set_payee() -> Weight { - (12_612_000 as Weight) + (13_348_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking Ledger (r:2 w:2) fn set_controller() -> Weight { - (27_503_000 as Weight) + (28_148_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: Staking ValidatorCount (r:0 w:1) fn set_validator_count() -> Weight { - (2_119_000 as Weight) + (2_909_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Staking ForceEra (r:0 w:1) fn force_no_eras() -> Weight { - (2_320_000 as Weight) + (3_163_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Staking ForceEra (r:0 w:1) fn force_new_era() -> Weight { - (2_269_000 as Weight) + (3_141_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Staking ForceEra (r:0 w:1) fn force_new_era_always() -> Weight { - (2_334_000 as Weight) + (3_220_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Staking Invulnerables (r:0 w:1) fn set_invulnerables(v: u32, ) -> Weight { - (2_354_000 as Weight) + (3_569_000 as Weight) // Standard Error: 0 - .saturating_add((5_000 as Weight).saturating_mul(v as Weight)) + .saturating_add((58_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Balances Locks (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking Validators (r:1 w:0) + // Storage: Staking SlashingSpans (r:1 w:0) + // Storage: Staking Ledger (r:0 w:1) + // Storage: Staking SpanSlash (r:0 w:2) fn force_unstake(s: u32, ) -> Weight { - (61_556_000 as Weight) + (65_753_000 as Weight) // Standard Error: 1_000 - .saturating_add((2_377_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((2_420_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } + // Storage: Staking UnappliedSlashes (r:1 w:1) fn cancel_deferred_slash(s: u32, ) -> Weight { - (3_367_105_000 as Weight) - // Standard Error: 222_000 - .saturating_add((19_817_000 as Weight).saturating_mul(s as Weight)) + (3_056_514_000 as Weight) + // Standard Error: 218_000 + .saturating_add((21_159_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } + // Storage: Staking Bonded (r:2 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking ErasRewardPoints (r:1 w:0) + // Storage: Staking ErasValidatorReward (r:1 w:0) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: System Account (r:2 w:2) + // Storage: Staking Payee (r:2 w:0) + // Storage: Staking ErasStakersClipped (r:1 w:0) + // Storage: Staking ErasValidatorPrefs (r:1 w:0) fn payout_stakers_dead_controller(n: u32, ) -> Weight { - (47_229_000 as Weight) - // Standard Error: 53_000 - .saturating_add((48_365_000 as Weight).saturating_mul(n as Weight)) + (121_794_000 as Weight) + // Standard Error: 19_000 + .saturating_add((49_467_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(10 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().writes(2 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight))) } + // Storage: Staking ErasValidatorPrefs (r:1 w:0) + // Storage: Staking Ledger (r:2 w:2) + // Storage: Staking ErasValidatorReward (r:1 w:0) + // Storage: Balances Locks (r:2 w:2) + // Storage: Staking ErasRewardPoints (r:1 w:0) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: System Account (r:2 w:2) + // Storage: Staking ErasStakersClipped (r:1 w:0) + // Storage: Staking Bonded (r:2 w:0) + // Storage: Staking Payee (r:2 w:0) fn payout_stakers_alive_staked(n: u32, ) -> Weight { - (156_788_000 as Weight) - // Standard Error: 20_000 - .saturating_add((61_280_000 as Weight).saturating_mul(n as Weight)) + (147_049_000 as Weight) + // Standard Error: 30_000 + .saturating_add((64_428_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(11 as Weight)) .saturating_add(T::DbWeight::get().reads((5 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().writes(3 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(n as Weight))) } + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Ledger (r:1 w:1) + // Storage: System Account (r:1 w:1) fn rebond(l: u32, ) -> Weight { - (47_815_000 as Weight) + (52_184_000 as Weight) // Standard Error: 1_000 - .saturating_add((65_000 as Weight).saturating_mul(l as Weight)) + .saturating_add((35_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: Staking ErasStakersClipped (r:0 w:2) + // Storage: Staking ErasValidatorReward (r:0 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking ErasValidatorPrefs (r:0 w:2) + // Storage: Staking ErasTotalStake (r:0 w:1) + // Storage: Staking ErasStakers (r:0 w:2) + // Storage: Staking ErasRewardPoints (r:0 w:1) + // Storage: Staking HistoryDepth (r:1 w:1) + // Storage: Staking ErasStartSessionIndex (r:0 w:1) fn set_history_depth(e: u32, ) -> Weight { (0 as Weight) - // Standard Error: 74_000 - .saturating_add((34_945_000 as Weight).saturating_mul(e as Weight)) + // Standard Error: 57_000 + .saturating_add((30_689_000 as Weight).saturating_mul(e as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((7 as Weight).saturating_mul(e as Weight))) } + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking SlashingSpans (r:1 w:1) + // Storage: Staking Validators (r:1 w:1) + // Storage: Staking SpanSlash (r:0 w:1) + // Storage: Staking CounterForValidators (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking Ledger (r:0 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Balances Locks (r:1 w:1) fn reap_stash(s: u32, ) -> Weight { - (73_483_000 as Weight) - // Standard Error: 0 - .saturating_add((2_384_000 as Weight).saturating_mul(s as Weight)) + (75_836_000 as Weight) + // Standard Error: 2_000 + .saturating_add((2_423_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(8 as Weight)) .saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } + // Storage: System BlockWeight (r:1 w:1) + // Storage: Staking ErasStakers (r:0 w:1) + // Storage: Staking ErasStakersClipped (r:0 w:1) + // Storage: Staking Nominators (r:101 w:0) + // Storage: Staking SlashingSpans (r:1 w:0) + // Storage: Staking ErasStartSessionIndex (r:0 w:1) + // Storage: Staking Ledger (r:101 w:0) + // Storage: Staking Validators (r:2 w:0) + // Storage: Staking Bonded (r:101 w:0) + // Storage: Staking CounterForNominators (r:1 w:0) + // Storage: Staking ValidatorCount (r:1 w:0) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: Staking ErasValidatorPrefs (r:0 w:1) + // Storage: Staking CounterForValidators (r:1 w:0) + // Storage: Staking CurrentEra (r:1 w:1) + // Storage: Staking MinimumValidatorCount (r:1 w:0) + // Storage: Staking ErasTotalStake (r:0 w:1) fn new_era(v: u32, n: u32, ) -> Weight { (0 as Weight) - // Standard Error: 846_000 - .saturating_add((305_234_000 as Weight).saturating_mul(v as Weight)) - // Standard Error: 42_000 - .saturating_add((48_280_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 1_492_000 + .saturating_add((299_860_000 as Weight).saturating_mul(v as Weight)) + // Standard Error: 99_000 + .saturating_add((47_937_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(10 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(v as Weight))) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().writes(4 as Weight)) .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } + // Storage: Staking Validators (r:501 w:0) + // Storage: Staking Bonded (r:1500 w:0) + // Storage: Staking Nominators (r:1001 w:0) + // Storage: Staking Ledger (r:1500 w:0) + // Storage: Staking SlashingSpans (r:21 w:0) fn get_npos_voters(v: u32, n: u32, s: u32, ) -> Weight { (0 as Weight) - // Standard Error: 99_000 - .saturating_add((25_735_000 as Weight).saturating_mul(v as Weight)) - // Standard Error: 99_000 - .saturating_add((28_122_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 3_388_000 - .saturating_add((21_500_000 as Weight).saturating_mul(s as Weight)) + // Standard Error: 101_000 + .saturating_add((27_304_000 as Weight).saturating_mul(v as Weight)) + // Standard Error: 101_000 + .saturating_add((29_893_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 3_441_000 + .saturating_add((91_111_000 as Weight).saturating_mul(s as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(v as Weight))) .saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(s as Weight))) } + // Storage: Staking Validators (r:501 w:0) fn get_npos_targets(v: u32, ) -> Weight { (0 as Weight) - // Standard Error: 30_000 - .saturating_add((11_065_000 as Weight).saturating_mul(v as Weight)) + // Standard Error: 32_000 + .saturating_add((11_692_000 as Weight).saturating_mul(v as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(v as Weight))) } + // Storage: Staking MaxNominatorsCount (r:0 w:1) + // Storage: Staking MaxValidatorsCount (r:0 w:1) + // Storage: Staking MinValidatorBond (r:0 w:1) + // Storage: Staking ChillThreshold (r:0 w:1) + // Storage: Staking MinNominatorBond (r:0 w:1) fn set_staking_limits() -> Weight { - (5_028_000 as Weight) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - } + (7_325_000 as Weight) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Staking MinValidatorBond (r:1 w:0) + // Storage: Staking ChillThreshold (r:1 w:0) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Validators (r:1 w:1) + // Storage: Staking CounterForValidators (r:1 w:1) + // Storage: Staking MaxValidatorsCount (r:1 w:0) + // Storage: Staking Ledger (r:1 w:0) fn chill_other() -> Weight { - (35_758_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) + (62_683_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } } // For backwards compatibility and tests impl WeightInfo for () { + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Payee (r:0 w:1) fn bond() -> Weight { - (72_617_000 as Weight) + (77_492_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Bonded (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) fn bond_extra() -> Weight { - (55_590_000 as Weight) + (59_476_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Staking Validators (r:1 w:0) fn unbond() -> Weight { - (59_730_000 as Weight) + (63_655_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: System Account (r:1 w:1) fn withdraw_unbonded_update(s: u32, ) -> Weight { - (52_279_000 as Weight) + (54_534_000 as Weight) // Standard Error: 0 - .saturating_add((68_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((24_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking Validators (r:1 w:0) + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking SlashingSpans (r:1 w:0) + // Storage: System Account (r:1 w:1) + // Storage: Staking SpanSlash (r:0 w:2) fn withdraw_unbonded_kill(s: u32, ) -> Weight { - (86_629_000 as Weight) + (89_850_000 as Weight) // Standard Error: 1_000 - .saturating_add((2_379_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((2_396_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(8 as Weight)) .saturating_add(RocksDbWeight::get().writes(6 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } + // Storage: Staking MaxValidatorsCount (r:1 w:0) + // Storage: Staking MinValidatorBond (r:1 w:0) + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Validators (r:1 w:1) + // Storage: Staking CounterForValidators (r:1 w:1) fn validate() -> Weight { - (32_393_000 as Weight) + (36_726_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking Nominators (r:1 w:1) fn kick(k: u32, ) -> Weight { - (36_986_000 as Weight) - // Standard Error: 13_000 - .saturating_add((16_574_000 as Weight).saturating_mul(k as Weight)) + (19_497_000 as Weight) + // Standard Error: 15_000 + .saturating_add((17_057_000 as Weight).saturating_mul(k as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(k as Weight))) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight))) } + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking MinNominatorBond (r:1 w:0) + // Storage: Staking CounterForNominators (r:1 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking Nominators (r:1 w:1) + // Storage: Staking Validators (r:2 w:0) + // Storage: Staking MaxNominatorsCount (r:1 w:0) fn nominate(n: u32, ) -> Weight { - (43_228_000 as Weight) - // Standard Error: 21_000 - .saturating_add((5_119_000 as Weight).saturating_mul(n as Weight)) + (45_146_000 as Weight) + // Standard Error: 13_000 + .saturating_add((5_527_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(n as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } + // Storage: Staking Validators (r:1 w:0) + // Storage: Staking Ledger (r:1 w:0) + // Storage: Staking Nominators (r:1 w:0) fn chill() -> Weight { - (17_800_000 as Weight) + (18_986_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) } + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking Ledger (r:1 w:0) fn set_payee() -> Weight { - (12_612_000 as Weight) + (13_348_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking Ledger (r:2 w:2) fn set_controller() -> Weight { - (27_503_000 as Weight) + (28_148_000 as Weight) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + // Storage: Staking ValidatorCount (r:0 w:1) fn set_validator_count() -> Weight { - (2_119_000 as Weight) + (2_909_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Staking ForceEra (r:0 w:1) fn force_no_eras() -> Weight { - (2_320_000 as Weight) + (3_163_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Staking ForceEra (r:0 w:1) fn force_new_era() -> Weight { - (2_269_000 as Weight) + (3_141_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Staking ForceEra (r:0 w:1) fn force_new_era_always() -> Weight { - (2_334_000 as Weight) + (3_220_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Staking Invulnerables (r:0 w:1) fn set_invulnerables(v: u32, ) -> Weight { - (2_354_000 as Weight) + (3_569_000 as Weight) // Standard Error: 0 - .saturating_add((5_000 as Weight).saturating_mul(v as Weight)) + .saturating_add((58_000 as Weight).saturating_mul(v as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Balances Locks (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Staking Validators (r:1 w:0) + // Storage: Staking SlashingSpans (r:1 w:0) + // Storage: Staking Ledger (r:0 w:1) + // Storage: Staking SpanSlash (r:0 w:2) fn force_unstake(s: u32, ) -> Weight { - (61_556_000 as Weight) + (65_753_000 as Weight) // Standard Error: 1_000 - .saturating_add((2_377_000 as Weight).saturating_mul(s as Weight)) + .saturating_add((2_420_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(6 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } + // Storage: Staking UnappliedSlashes (r:1 w:1) fn cancel_deferred_slash(s: u32, ) -> Weight { - (3_367_105_000 as Weight) - // Standard Error: 222_000 - .saturating_add((19_817_000 as Weight).saturating_mul(s as Weight)) + (3_056_514_000 as Weight) + // Standard Error: 218_000 + .saturating_add((21_159_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } + // Storage: Staking Bonded (r:2 w:0) + // Storage: Staking Ledger (r:1 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking ErasRewardPoints (r:1 w:0) + // Storage: Staking ErasValidatorReward (r:1 w:0) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: System Account (r:2 w:2) + // Storage: Staking Payee (r:2 w:0) + // Storage: Staking ErasStakersClipped (r:1 w:0) + // Storage: Staking ErasValidatorPrefs (r:1 w:0) fn payout_stakers_dead_controller(n: u32, ) -> Weight { - (47_229_000 as Weight) - // Standard Error: 53_000 - .saturating_add((48_365_000 as Weight).saturating_mul(n as Weight)) + (121_794_000 as Weight) + // Standard Error: 19_000 + .saturating_add((49_467_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(10 as Weight)) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(n as Weight))) } + // Storage: Staking ErasValidatorPrefs (r:1 w:0) + // Storage: Staking Ledger (r:2 w:2) + // Storage: Staking ErasValidatorReward (r:1 w:0) + // Storage: Balances Locks (r:2 w:2) + // Storage: Staking ErasRewardPoints (r:1 w:0) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: System Account (r:2 w:2) + // Storage: Staking ErasStakersClipped (r:1 w:0) + // Storage: Staking Bonded (r:2 w:0) + // Storage: Staking Payee (r:2 w:0) fn payout_stakers_alive_staked(n: u32, ) -> Weight { - (156_788_000 as Weight) - // Standard Error: 20_000 - .saturating_add((61_280_000 as Weight).saturating_mul(n as Weight)) + (147_049_000 as Weight) + // Standard Error: 30_000 + .saturating_add((64_428_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(11 as Weight)) .saturating_add(RocksDbWeight::get().reads((5 as Weight).saturating_mul(n as Weight))) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(n as Weight))) } + // Storage: Balances Locks (r:1 w:1) + // Storage: Staking Ledger (r:1 w:1) + // Storage: System Account (r:1 w:1) fn rebond(l: u32, ) -> Weight { - (47_815_000 as Weight) + (52_184_000 as Weight) // Standard Error: 1_000 - .saturating_add((65_000 as Weight).saturating_mul(l as Weight)) + .saturating_add((35_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + // Storage: Staking ErasStakersClipped (r:0 w:2) + // Storage: Staking ErasValidatorReward (r:0 w:1) + // Storage: Staking CurrentEra (r:1 w:0) + // Storage: Staking ErasValidatorPrefs (r:0 w:2) + // Storage: Staking ErasTotalStake (r:0 w:1) + // Storage: Staking ErasStakers (r:0 w:2) + // Storage: Staking ErasRewardPoints (r:0 w:1) + // Storage: Staking HistoryDepth (r:1 w:1) + // Storage: Staking ErasStartSessionIndex (r:0 w:1) fn set_history_depth(e: u32, ) -> Weight { (0 as Weight) - // Standard Error: 74_000 - .saturating_add((34_945_000 as Weight).saturating_mul(e as Weight)) + // Standard Error: 57_000 + .saturating_add((30_689_000 as Weight).saturating_mul(e as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) .saturating_add(RocksDbWeight::get().writes((7 as Weight).saturating_mul(e as Weight))) } + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking SlashingSpans (r:1 w:1) + // Storage: Staking Validators (r:1 w:1) + // Storage: Staking SpanSlash (r:0 w:1) + // Storage: Staking CounterForValidators (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: Staking Payee (r:0 w:1) + // Storage: Staking Ledger (r:0 w:1) + // Storage: Staking Bonded (r:1 w:1) + // Storage: Balances Locks (r:1 w:1) fn reap_stash(s: u32, ) -> Weight { - (73_483_000 as Weight) - // Standard Error: 0 - .saturating_add((2_384_000 as Weight).saturating_mul(s as Weight)) + (75_836_000 as Weight) + // Standard Error: 2_000 + .saturating_add((2_423_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(8 as Weight)) .saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(s as Weight))) } + // Storage: System BlockWeight (r:1 w:1) + // Storage: Staking ErasStakers (r:0 w:1) + // Storage: Staking ErasStakersClipped (r:0 w:1) + // Storage: Staking Nominators (r:101 w:0) + // Storage: Staking SlashingSpans (r:1 w:0) + // Storage: Staking ErasStartSessionIndex (r:0 w:1) + // Storage: Staking Ledger (r:101 w:0) + // Storage: Staking Validators (r:2 w:0) + // Storage: Staking Bonded (r:101 w:0) + // Storage: Staking CounterForNominators (r:1 w:0) + // Storage: Staking ValidatorCount (r:1 w:0) + // Storage: Staking HistoryDepth (r:1 w:0) + // Storage: Staking ErasValidatorPrefs (r:0 w:1) + // Storage: Staking CounterForValidators (r:1 w:0) + // Storage: Staking CurrentEra (r:1 w:1) + // Storage: Staking MinimumValidatorCount (r:1 w:0) + // Storage: Staking ErasTotalStake (r:0 w:1) fn new_era(v: u32, n: u32, ) -> Weight { (0 as Weight) - // Standard Error: 846_000 - .saturating_add((305_234_000 as Weight).saturating_mul(v as Weight)) - // Standard Error: 42_000 - .saturating_add((48_280_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 1_492_000 + .saturating_add((299_860_000 as Weight).saturating_mul(v as Weight)) + // Standard Error: 99_000 + .saturating_add((47_937_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(10 as Weight)) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(v as Weight))) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(v as Weight))) } + // Storage: Staking Validators (r:501 w:0) + // Storage: Staking Bonded (r:1500 w:0) + // Storage: Staking Nominators (r:1001 w:0) + // Storage: Staking Ledger (r:1500 w:0) + // Storage: Staking SlashingSpans (r:21 w:0) fn get_npos_voters(v: u32, n: u32, s: u32, ) -> Weight { (0 as Weight) - // Standard Error: 99_000 - .saturating_add((25_735_000 as Weight).saturating_mul(v as Weight)) - // Standard Error: 99_000 - .saturating_add((28_122_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 3_388_000 - .saturating_add((21_500_000 as Weight).saturating_mul(s as Weight)) + // Standard Error: 101_000 + .saturating_add((27_304_000 as Weight).saturating_mul(v as Weight)) + // Standard Error: 101_000 + .saturating_add((29_893_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 3_441_000 + .saturating_add((91_111_000 as Weight).saturating_mul(s as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(v as Weight))) .saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(n as Weight))) .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(s as Weight))) } + // Storage: Staking Validators (r:501 w:0) fn get_npos_targets(v: u32, ) -> Weight { (0 as Weight) - // Standard Error: 30_000 - .saturating_add((11_065_000 as Weight).saturating_mul(v as Weight)) + // Standard Error: 32_000 + .saturating_add((11_692_000 as Weight).saturating_mul(v as Weight)) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(v as Weight))) } + // Storage: Staking MaxNominatorsCount (r:0 w:1) + // Storage: Staking MaxValidatorsCount (r:0 w:1) + // Storage: Staking MinValidatorBond (r:0 w:1) + // Storage: Staking ChillThreshold (r:0 w:1) + // Storage: Staking MinNominatorBond (r:0 w:1) fn set_staking_limits() -> Weight { - (5_028_000 as Weight) - .saturating_add(RocksDbWeight::get().writes(4 as Weight)) - } + (7_325_000 as Weight) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + // Storage: Staking MinValidatorBond (r:1 w:0) + // Storage: Staking ChillThreshold (r:1 w:0) + // Storage: Staking Nominators (r:1 w:0) + // Storage: Staking Validators (r:1 w:1) + // Storage: Staking CounterForValidators (r:1 w:1) + // Storage: Staking MaxValidatorsCount (r:1 w:0) + // Storage: Staking Ledger (r:1 w:0) fn chill_other() -> Weight { - (35_758_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + (62_683_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } } diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index 9bae971019779..93616b590f61e 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -30,6 +30,8 @@ chrono = "0.4" serde = "1.0.126" handlebars = "3.5.0" Inflector = "0.11.4" +linked-hash-map = "0.5.4" +log = "0.4.8" [features] default = ["db"] diff --git a/utils/frame/benchmarking-cli/src/command.rs b/utils/frame/benchmarking-cli/src/command.rs index 2ef9f3914a5d7..925cfd07d03e2 100644 --- a/utils/frame/benchmarking-cli/src/command.rs +++ b/utils/frame/benchmarking-cli/src/command.rs @@ -17,8 +17,11 @@ use crate::BenchmarkCmd; use codec::{Decode, Encode}; -use frame_benchmarking::{Analysis, BenchmarkBatch, BenchmarkSelector}; +use frame_benchmarking::{ + Analysis, BenchmarkBatch, BenchmarkList, BenchmarkResults, BenchmarkSelector, +}; use frame_support::traits::StorageInfo; +use linked_hash_map::LinkedHashMap; use sc_cli::{CliConfiguration, ExecutionStrategy, Result, SharedParams}; use sc_client_db::BenchmarkingState; use sc_executor::NativeExecutor; @@ -31,7 +34,43 @@ use sp_externalities::Extensions; use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStorePtr}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sp_state_machine::StateMachine; -use std::{fmt::Debug, sync::Arc}; +use std::{fmt::Debug, sync::Arc, time}; + +// This takes multiple benchmark batches and combines all the results where the pallet, instance, +// and benchmark are the same. +fn combine_batches(batches: Vec) -> Vec { + if batches.is_empty() { + return batches + } + + let mut all_benchmarks = LinkedHashMap::<_, Vec>::new(); + + batches + .into_iter() + .for_each(|BenchmarkBatch { pallet, instance, benchmark, results }| { + // We use this key to uniquely identify a benchmark among batches. + let key = (pallet, instance, benchmark); + + match all_benchmarks.get_mut(&key) { + // We already have this benchmark, so we extend the results. + Some(x) => x.extend(results), + // New benchmark, so we add a new entry with the initial results. + None => { + all_benchmarks.insert(key, results); + }, + } + }); + + all_benchmarks + .into_iter() + .map(|((pallet, instance, benchmark), results)| BenchmarkBatch { + pallet, + instance, + benchmark, + results, + }) + .collect::>() +} impl BenchmarkCmd { /// Runs the command and benchmarks the chain. @@ -63,6 +102,10 @@ impl BenchmarkCmd { let spec = config.chain_spec; let wasm_method = self.wasm_method.into(); let strategy = self.execution.unwrap_or(ExecutionStrategy::Native); + let pallet = self.pallet.clone().unwrap_or_else(|| String::new()); + let pallet = pallet.as_bytes(); + let extrinsic = self.extrinsic.clone().unwrap_or_else(|| String::new()); + let extrinsic = extrinsic.as_bytes(); let genesis_storage = spec.build_storage()?; let mut changes = Default::default(); @@ -74,137 +117,204 @@ impl BenchmarkCmd { 2, // The runtime instances cache size. ); - let mut extensions = Extensions::default(); - extensions.register(KeystoreExt(Arc::new(KeyStore::new()) as SyncCryptoStorePtr)); - let (offchain, _) = TestOffchainExt::new(); - let (pool, _) = TestTransactionPoolExt::new(); - extensions.register(OffchainWorkerExt::new(offchain.clone())); - extensions.register(OffchainDbExt::new(offchain)); - extensions.register(TransactionPoolExt::new(pool)); + let extensions = || -> Extensions { + let mut extensions = Extensions::default(); + extensions.register(KeystoreExt(Arc::new(KeyStore::new()) as SyncCryptoStorePtr)); + let (offchain, _) = TestOffchainExt::new(); + let (pool, _) = TestTransactionPoolExt::new(); + extensions.register(OffchainWorkerExt::new(offchain.clone())); + extensions.register(OffchainDbExt::new(offchain)); + extensions.register(TransactionPoolExt::new(pool)); + return extensions + }; + // Get Benchmark List let result = StateMachine::<_, _, NumberFor, _>::new( &state, None, &mut changes, &executor, - "Benchmark_dispatch_benchmark", - &( - &self.pallet, - &self.extrinsic, - self.lowest_range_values.clone(), - self.highest_range_values.clone(), - self.steps.clone(), - self.repeat, - !self.no_verify, - self.extra, - ) - .encode(), - extensions, + "Benchmark_benchmark_metadata", + &(self.extra).encode(), + extensions(), &sp_state_machine::backend::BackendRuntimeCode::new(&state).runtime_code()?, sp_core::testing::TaskExecutor::new(), ) .execute(strategy.into()) - .map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; - - let results = , Vec), - String, - > as Decode>::decode(&mut &result[..]) - .map_err(|e| format!("Failed to decode benchmark results: {:?}", e))?; - - match results { - Ok((batches, storage_info)) => { - if let Some(output_path) = &self.output { - crate::writer::write_results(&batches, &storage_info, output_path, self)?; - } + .map_err(|e| format!("Error getting benchmark list: {:?}", e))?; - for batch in batches.into_iter() { - // Print benchmark metadata - println!( - "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", - String::from_utf8(batch.pallet).expect("Encoded from String; qed"), - String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), - self.lowest_range_values, - self.highest_range_values, - self.steps, - self.repeat, - ); + let (list, storage_info) = + <(Vec, Vec) as Decode>::decode(&mut &result[..]) + .map_err(|e| format!("Failed to decode benchmark metadata: {:?}", e))?; + + if self.list { + list_benchmark(pallet, extrinsic, list); + return Ok(()) + } - // Skip raw data + analysis if there are no results - if batch.results.is_empty() { - continue + // Use the benchmark list and the user input to determine the set of benchmarks to run. + let mut benchmarks_to_run = Vec::new(); + for item in list { + if pallet == &item.pallet[..] || pallet == &b"*"[..] { + if &pallet[..] == &b"*"[..] || &extrinsic[..] == &b"*"[..] { + for benchmark in item.benchmarks { + benchmarks_to_run.push((item.pallet.clone(), benchmark)); } + } else { + benchmarks_to_run.push((pallet.to_vec(), extrinsic.to_vec())); + } + } + } - if self.raw_data { - // Print the table header - batch.results[0] - .components - .iter() - .for_each(|param| print!("{:?},", param.0)); - - print!("extrinsic_time_ns,storage_root_time_ns,reads,repeat_reads,writes,repeat_writes,proof_size_bytes\n"); - // Print the values - batch.results.iter().for_each(|result| { - let parameters = &result.components; - parameters.iter().for_each(|param| print!("{:?},", param.1)); - // Print extrinsic time and storage root time - print!( - "{:?},{:?},{:?},{:?},{:?},{:?},{:?}\n", - result.extrinsic_time, - result.storage_root_time, - result.reads, - result.repeat_reads, - result.writes, - result.repeat_writes, - result.proof_size, - ); - }); + // Run the benchmarks + let mut batches = Vec::new(); + let mut timer = time::SystemTime::now(); + for (pallet, extrinsic) in benchmarks_to_run { + for s in 0..self.steps { + for r in 0..self.repeat { + // This should run only a single instance of a benchmark for `pallet` and + // `extrinsic`. All loops happen above. + let result = StateMachine::<_, _, NumberFor, _>::new( + &state, + None, + &mut changes, + &executor, + "Benchmark_dispatch_benchmark", + &( + &pallet.clone(), + &extrinsic.clone(), + self.lowest_range_values.clone(), + self.highest_range_values.clone(), + (s, self.steps), + (r, self.repeat), + !self.no_verify, + self.extra, + ) + .encode(), + extensions(), + &sp_state_machine::backend::BackendRuntimeCode::new(&state) + .runtime_code()?, + sp_core::testing::TaskExecutor::new(), + ) + .execute(strategy.into()) + .map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; - println!(); - } + let batch = + , String> as Decode>::decode( + &mut &result[..], + ) + .map_err(|e| format!("Failed to decode benchmark results: {:?}", e))??; - // Conduct analysis. - if !self.no_median_slopes { - println!("Median Slopes Analysis\n========"); - if let Some(analysis) = Analysis::median_slopes( - &batch.results, - BenchmarkSelector::ExtrinsicTime, - ) { - println!("-- Extrinsic Time --\n{}", analysis); - } - if let Some(analysis) = - Analysis::median_slopes(&batch.results, BenchmarkSelector::Reads) - { - println!("Reads = {:?}", analysis); - } - if let Some(analysis) = - Analysis::median_slopes(&batch.results, BenchmarkSelector::Writes) - { - println!("Writes = {:?}", analysis); - } - } - if !self.no_min_squares { - println!("Min Squares Analysis\n========"); - if let Some(analysis) = Analysis::min_squares_iqr( - &batch.results, - BenchmarkSelector::ExtrinsicTime, - ) { - println!("-- Extrinsic Time --\n{}", analysis); - } - if let Some(analysis) = - Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Reads) - { - println!("Reads = {:?}", analysis); - } - if let Some(analysis) = - Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Writes) - { - println!("Writes = {:?}", analysis); + batches.extend(batch); + + // Show progress information + if let Some(elapsed) = timer.elapsed().ok() { + if elapsed >= time::Duration::from_secs(5) { + timer = time::SystemTime::now(); + log::info!( + "Running Benchmark:\t{}\t{}\t{}/{}\t{}/{}", + String::from_utf8(pallet.clone()) + .expect("Encoded from String; qed"), + String::from_utf8(extrinsic.clone()) + .expect("Encoded from String; qed"), + s, + self.steps, + r, + self.repeat, + ); } } } - }, - Err(error) => eprintln!("Error: {}", error), + } + } + + // Combine all of the benchmark results, so that benchmarks of the same pallet/function + // are together. + let batches = combine_batches(batches); + + if let Some(output_path) = &self.output { + crate::writer::write_results(&batches, &storage_info, output_path, self)?; + } + + for batch in batches.into_iter() { + // Print benchmark metadata + println!( + "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", + String::from_utf8(batch.pallet).expect("Encoded from String; qed"), + String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), + self.lowest_range_values, + self.highest_range_values, + self.steps, + self.repeat, + ); + + // Skip raw data + analysis if there are no results + if batch.results.is_empty() { + continue + } + + if self.raw_data { + // Print the table header + batch.results[0].components.iter().for_each(|param| print!("{:?},", param.0)); + + print!("extrinsic_time_ns,storage_root_time_ns,reads,repeat_reads,writes,repeat_writes,proof_size_bytes\n"); + // Print the values + batch.results.iter().for_each(|result| { + let parameters = &result.components; + parameters.iter().for_each(|param| print!("{:?},", param.1)); + // Print extrinsic time and storage root time + print!( + "{:?},{:?},{:?},{:?},{:?},{:?},{:?}\n", + result.extrinsic_time, + result.storage_root_time, + result.reads, + result.repeat_reads, + result.writes, + result.repeat_writes, + result.proof_size, + ); + }); + + println!(); + } + + // Conduct analysis. + if !self.no_median_slopes { + println!("Median Slopes Analysis\n========"); + if let Some(analysis) = + Analysis::median_slopes(&batch.results, BenchmarkSelector::ExtrinsicTime) + { + println!("-- Extrinsic Time --\n{}", analysis); + } + if let Some(analysis) = + Analysis::median_slopes(&batch.results, BenchmarkSelector::Reads) + { + println!("Reads = {:?}", analysis); + } + if let Some(analysis) = + Analysis::median_slopes(&batch.results, BenchmarkSelector::Writes) + { + println!("Writes = {:?}", analysis); + } + } + if !self.no_min_squares { + println!("Min Squares Analysis\n========"); + if let Some(analysis) = + Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::ExtrinsicTime) + { + println!("-- Extrinsic Time --\n{}", analysis); + } + if let Some(analysis) = + Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Reads) + { + println!("Reads = {:?}", analysis); + } + if let Some(analysis) = + Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Writes) + { + println!("Writes = {:?}", analysis); + } + } } Ok(()) @@ -223,3 +333,41 @@ impl CliConfiguration for BenchmarkCmd { }) } } + +/// List the benchmarks available in the runtime, in a CSV friendly format. +/// +/// If `pallet_input` and `extrinsic_input` is empty, we list everything. +/// +/// If `pallet_input` is present, we only list the benchmarks for that pallet. +/// +/// If `extrinsic_input` is `*`, we will hide the individual benchmarks for each pallet, and just +/// show a single line for each available pallet. +fn list_benchmark(pallet_input: &[u8], extrinsic_input: &[u8], list: Vec) { + let filtered_list = list + .into_iter() + .filter(|item| pallet_input.is_empty() || pallet_input == &item.pallet) + .collect::>(); + + if filtered_list.is_empty() { + println!("Pallet not found."); + return + } + + println!("pallet, benchmark"); + for item in filtered_list { + let pallet_string = + String::from_utf8(item.pallet.clone()).expect("Encoded from String; qed"); + + if extrinsic_input == &b"*"[..] { + println!("{}, *", pallet_string) + } else { + for benchmark in item.benchmarks { + println!( + "{}, {}", + pallet_string, + String::from_utf8(benchmark).expect("Encoded from String; qed"), + ); + } + } + } +} diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index 0642ddabc1374..41629a866f726 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -31,16 +31,16 @@ fn parse_pallet_name(pallet: &str) -> String { #[derive(Debug, structopt::StructOpt)] pub struct BenchmarkCmd { /// Select a FRAME Pallet to benchmark, or `*` for all (in which case `extrinsic` must be `*`). - #[structopt(short, long, parse(from_str = parse_pallet_name))] - pub pallet: String, + #[structopt(short, long, parse(from_str = parse_pallet_name), required_unless = "list")] + pub pallet: Option, /// Select an extrinsic inside the pallet to benchmark, or `*` for all. - #[structopt(short, long)] - pub extrinsic: String, + #[structopt(short, long, required_unless = "list")] + pub extrinsic: Option, /// Select how many samples we should take across the variable components. - #[structopt(short, long, use_delimiter = true)] - pub steps: Vec, + #[structopt(short, long, default_value = "1")] + pub steps: u32, /// Indicates lowest values for each of the component ranges. #[structopt(long = "low", use_delimiter = true)] @@ -129,4 +129,12 @@ pub struct BenchmarkCmd { /// Limit the memory the database cache can use. #[structopt(long = "db-cache", value_name = "MiB", default_value = "128")] pub database_cache_size: u32, + + /// List the benchmarks available. + /// + /// * If nothing else is specified, all pallets and benchmarks will be listed. + /// * If the `pallet` argument is passed, then we will only list benchmarks for that pallet. + /// * If the `extrinsic` argument is set to `*`, we will hide the individual benchmarks. + #[structopt(long)] + pub list: bool, } diff --git a/utils/frame/benchmarking-cli/src/writer.rs b/utils/frame/benchmarking-cli/src/writer.rs index 16c93081ac6e1..d80a17e1b2dba 100644 --- a/utils/frame/benchmarking-cli/src/writer.rs +++ b/utils/frame/benchmarking-cli/src/writer.rs @@ -71,7 +71,7 @@ struct BenchmarkData { // This forwards some specific metadata from the `BenchmarkCmd` #[derive(Serialize, Default, Debug, Clone)] struct CmdData { - steps: Vec, + steps: u32, repeat: u32, lowest_range_values: Vec, highest_range_values: Vec,