diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 1db152e39fd9..3336aea162c5 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1529,11 +1529,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -1561,7 +1558,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 5fb495e4e8cf..aa390833417d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1705,11 +1705,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -1737,7 +1734,10 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 35af034310d9..6cd042047293 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1047,11 +1047,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -1077,7 +1074,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 2c2e01b4d21d..e46afaec44f6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -936,11 +936,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -963,7 +960,10 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs index e9adc4d1eae7..a127ad8450e3 100644 --- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs @@ -1053,11 +1053,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -1068,7 +1065,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs index 3348a635df01..b11e1c6d2a13 100644 --- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs @@ -761,11 +761,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -776,7 +773,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs index e9171c79afae..5ed0bee0bbbc 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs @@ -924,11 +924,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; @@ -944,7 +941,10 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs index 975856b3b6ff..7e6ab4c0346e 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs @@ -916,11 +916,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; @@ -936,7 +933,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs index 75f45297fe2c..107375b1ee8e 100644 --- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs @@ -442,21 +442,20 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; + use sp_core::Get; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; let mut list = Vec::::new(); list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs index ffdd86c500e5..9603f8148a03 100644 --- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs @@ -872,11 +872,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; @@ -892,7 +889,10 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs index ee6b0db55b91..cd10e9f5ebdc 100644 --- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs @@ -870,11 +870,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; @@ -890,7 +887,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 38ddf3bc1991..e8d93aab97d7 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -1103,11 +1103,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench; @@ -1117,7 +1114,9 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index cab4394eb5a8..2c151f007bab 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -2429,11 +2429,8 @@ sp_api::impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; @@ -2446,7 +2443,9 @@ sp_api::impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - return (list, storage_info) + let max_extrinsic_weight = BlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 166f3fc42eef..759b475cda0c 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2574,11 +2574,8 @@ sp_api::impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; use pallet_session_benchmarking::Pallet as SessionBench; @@ -2596,7 +2593,9 @@ sp_api::impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - return (list, storage_info) + let max_extrinsic_weight = BlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/prdoc/pr_4020.prdoc b/prdoc/pr_4020.prdoc new file mode 100644 index 000000000000..da740c47c332 --- /dev/null +++ b/prdoc/pr_4020.prdoc @@ -0,0 +1,65 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "Benchmarking: automatic weight sanity check" + +doc: + - audience: Runtime Dev + description: | + This PR introduces a new sanity weight check after benchmark execution to ensure that the weight of the function/extrinsic does not exceed the block limit. + Maximum extrinsic weight value and `RuntimeDbWeight` should be provided by the runtime API. Maximum weight value is usually `max_extrinsic` from + `RuntimeBlockWeights` for `DispatchClass::Normal` type extrinsics. + + During benchmark execution developers can either choose to throw an error, log a warning, or ignore if the weight exceeds the limit. Default behaviour is + warning. This can be configured by passing an argument to `--sanity-weight-check` flag in the benchmarking CLI. + + Note: This introduces a breaking change for `frame_benchmarking::Benchmark` runtime API. `benchmark_metadata` function now returns new struct `RuntimeBenchmarkInfo` + that encapsulates exhaustive benchmarks related information. To ensure backwards compatibility, `RuntimeBenchmarkInfo` can be created from previous + return type: `(Vec, Vec)`. + + It is strongly recommended to use weight sanity check to ensure your benchmarks are within the weight limit: + + ``` + --- a/path/to/runtime.rs + +++ b/path/to/runtime.rs + @@ -1,3 +1,4 @@ + -fn benchmark_metadata(extra: bool) -> (Vec, Vec) { + +fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + /// ... + +let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + +let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + -(list, storage_info) + +RuntimeBenchmarkInfo {list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } + } + ``` + + If you choose to ignore it, the easiest way to migrate is to change the return type by converting previous tuple to `RuntimeBenchmarkInfo`: + + ``` + --- a/path/to/runtime.rs + +++ b/path/to/runtime.rs + @@ -1,3 +1,4 @@ + -fn benchmark_metadata(extra: bool) -> (Vec, Vec) { + +fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + /// ... + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + + -(list, storage_info) + +(list, storage_info).into() + } + ``` + + Once the node is compiled with `runtime-benchmarks` feature, you can pass the `--sanity-weight-check` flag to the benchmarking CLI or `ombi-bencher`: + + ``` + ./target/release/node benchmark pallet --sanity-weight-check warning ... + frame-omni-bencher v1 benchmark pallet --sanity-weight-check error ... + ``` + +crates: + - name: "frame-benchmarking" + - name: "frame-benchmarking-cli" + - name: "sc-cli" \ No newline at end of file diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 93b134e8165f..3a8fdb319556 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -3580,11 +3580,8 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{baseline, Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; use frame_support::traits::StorageInfoTrait; // Trying to add benchmarks directly to the Session Pallet caused cyclic dependency @@ -3602,8 +3599,10 @@ impl_runtime_apis! { list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); - (list, storage_info) + RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight: Some(max_extrinsic_weight), db_weight: Some(db_weight) } } fn dispatch_benchmark( diff --git a/substrate/client/cli/src/arg_enums.rs b/substrate/client/cli/src/arg_enums.rs index cd245dc01554..ff4f988b7503 100644 --- a/substrate/client/cli/src/arg_enums.rs +++ b/substrate/client/cli/src/arg_enums.rs @@ -65,6 +65,21 @@ impl std::fmt::Display for WasmExecutionMethod { } } +/// How to output the result of the sanity weight check and what to do when it fails. +#[derive(Debug, Clone, Copy, ValueEnum, PartialEq)] +#[value(rename_all = "kebab-case")] +pub enum SanityWeightCheck { + /// Prints the results in the terminal and on failing returns an error. + Error, + /// Prints the results in the terminal. + Warning, + /// Sanity weight check is ignored. + Ignore, +} + +/// The default [`SanityWeightCheck`]. +pub const DEFAULT_SANITY_WEIGHT_CHECK: SanityWeightCheck = SanityWeightCheck::Warning; + /// Converts the execution method and instantiation strategy command line arguments /// into an execution method which can be used internally. pub fn execution_method_from_cli( diff --git a/substrate/client/cli/src/params/shared_params.rs b/substrate/client/cli/src/params/shared_params.rs index e0c52deb44ca..830d2c9504f1 100644 --- a/substrate/client/cli/src/params/shared_params.rs +++ b/substrate/client/cli/src/params/shared_params.rs @@ -16,7 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use crate::arg_enums::TracingReceiver; +use crate::{arg_enums::TracingReceiver, SanityWeightCheck, DEFAULT_SANITY_WEIGHT_CHECK}; use clap::Args; use sc_service::config::BasePath; use std::path::PathBuf; @@ -89,6 +89,19 @@ pub struct SharedParams { /// Receiver to process tracing messages. #[arg(long, value_name = "RECEIVER", value_enum, ignore_case = true, default_value_t = TracingReceiver::Log)] pub tracing_receiver: TracingReceiver, + + /// Sanity weight check for benchmarks. Each extrinsic's weight function is executed + /// in the worst case scenario and compared with the maximum extrinsic weight (the maximum + /// weight that can be put in a single block for an extrinsic with `DispatchClass::Normal`). In + /// other words, each extrinsic is checked whether it will fit in an empty (meaning; empty of + /// `DispatchClass::Normal` extrinsics) block. + #[arg( + long, + value_name = "ERROR-LEVEL", + value_enum, + default_value_t = DEFAULT_SANITY_WEIGHT_CHECK, + )] + pub sanity_weight_check: SanityWeightCheck, } impl SharedParams { diff --git a/substrate/frame/benchmarking/src/utils.rs b/substrate/frame/benchmarking/src/utils.rs index 3a10e43d83b8..882c235106b0 100644 --- a/substrate/frame/benchmarking/src/utils.rs +++ b/substrate/frame/benchmarking/src/utils.rs @@ -18,7 +18,10 @@ //! Interfaces, types and utils for benchmarking a FRAME runtime. use alloc::vec::Vec; use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchErrorWithPostInfo, pallet_prelude::*, traits::StorageInfo}; +use frame_support::{ + dispatch::DispatchErrorWithPostInfo, pallet_prelude::*, traits::StorageInfo, + weights::RuntimeDbWeight, +}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; @@ -229,6 +232,27 @@ pub struct BenchmarkMetadata { pub pov_modes: Vec<(Vec, Vec)>, } +/// Benchmark info provided by the runtime. +#[derive(Encode, Decode, Default, Clone, PartialEq, Debug, TypeInfo)] +pub struct RuntimeBenchmarkInfo { + /// List of all benchmarks available for this runtime. + pub list: Vec, + /// List of all metadata about storage items. + pub storage_info: Vec, + /// Maximum extrinsic weight that can be achieved in `DispatchClass::Normal`. + pub max_extrinsic_weight: Option, + /// Weight of the runtime database. + pub db_weight: Option, +} + +/// Convert a tuple of benchmark lists and storage info into a `RuntimeBenchmarkInfo` struct. +/// For backwards compatibility. +impl From<(Vec, Vec)> for RuntimeBenchmarkInfo { + fn from((list, storage_info): (Vec, Vec)) -> Self { + Self { list, storage_info, max_extrinsic_weight: None, db_weight: None } + } +} + sp_api::decl_runtime_apis! { /// Runtime api for benchmarking a FRAME runtime. #[api_version(2)] @@ -238,7 +262,20 @@ sp_api::decl_runtime_apis! { /// Parameters /// - `extra`: Also list benchmarks marked "extra" which would otherwise not be /// needed for weight calculation. + /// + /// Returns: + /// - `(Vec, Vec);` - list of all benchmarks available for this runtime. + #[changed_in(2)] fn benchmark_metadata(extra: bool) -> (Vec, Vec); + /// Get the benchmark metadata available for this runtime. + /// + /// Parameters + /// - `extra`: Also list benchmarks marked "extra" which would otherwise not be + /// needed for weight calculation. + /// + /// Returns: + /// - `RuntimeBenchmarkInfo` - Complete benchmark metadata available for this runtime. + fn benchmark_metadata(extra: bool) -> RuntimeBenchmarkInfo; /// Dispatch the given benchmark. fn dispatch_benchmark(config: BenchmarkConfig) -> Result, alloc::string::String>; diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs index 0c068fc585ba..ca134f940cd1 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/command.rs @@ -29,15 +29,19 @@ use crate::{ use clap::{error::ErrorKind, CommandFactory}; use codec::{Decode, Encode}; use frame_benchmarking::{ - Analysis, BenchmarkBatch, BenchmarkBatchSplitResults, BenchmarkList, BenchmarkParameter, - BenchmarkResult, BenchmarkSelector, + Analysis, AnalysisChoice, BenchmarkBatch, BenchmarkBatchSplitResults, BenchmarkList, + BenchmarkParameter, BenchmarkResult, BenchmarkSelector, RuntimeBenchmarkInfo, +}; +use frame_support::{ + traits::StorageInfo, + weights::{RuntimeDbWeight, Weight}, }; -use frame_support::traits::StorageInfo; use linked_hash_map::LinkedHashMap; use sc_cli::{execution_method_from_cli, ChainSpec, CliConfiguration, Result, SharedParams}; use sc_client_db::BenchmarkingState; -use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; +use sc_executor::{HeapAllocStrategy, RuntimeVersion, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; use sp_core::{ + blake2_64, offchain::{ testing::{TestOffchainExt, TestTransactionPoolExt}, OffchainDbExt, OffchainWorkerExt, TransactionPoolExt, @@ -60,7 +64,6 @@ use std::{ time, }; -/// Logging target const LOG_TARGET: &'static str = "polkadot_sdk_frame::benchmark::pallet"; type SubstrateAndExtraHF = @@ -252,6 +255,9 @@ impl PalletCmd { }) }); + let (genesis_storage, genesis_changes) = + self.genesis_storage::(&chain_spec)?; + let mut changes = genesis_changes.clone(); if let Some(json_input) = &self.json_input { let raw_data = match std::fs::read(json_input) { Ok(raw_data) => raw_data, @@ -334,20 +340,75 @@ impl PalletCmd { ) .ok_or_else(|| ERROR_API_NOT_FOUND)?; - let (list, storage_info): (Vec, Vec) = - Self::exec_state_machine( - StateMachine::new( - state, - &mut Default::default(), - &executor, - "Benchmark_benchmark_metadata", - &(self.extra).encode(), - &mut Self::build_extensions(executor.clone(), state.recorder()), - &runtime_code, - CallContext::Offchain, - ), - ERROR_API_NOT_FOUND, - )?; + let runtime_version: RuntimeVersion = Self::exec_state_machine( + StateMachine::new( + state, + &mut changes, + &executor, + "Core_version", + &[], + &mut Self::build_extensions(executor.clone()), + &runtime_code, + CallContext::Offchain, + ), + ERROR_RUNTIME_VERSION_NOT_FOUND, + )?; + + // Get the version of `Benchmark` runtime API. + let (_, version) = runtime_version + .apis + .iter() + .find(|(name, _)| name == &blake2_64(b"Benchmark")) + .ok_or("Benchmark API not found in runtime version apis")?; + + let RuntimeBenchmarkInfo { list, storage_info, max_extrinsic_weight, db_weight } = { + if *version == 1 { + // This ensures that we don't run sanity checks on API v1. + let old_benchmark_data: (Vec, Vec) = + Self::exec_state_machine( + StateMachine::new( + state, + &mut changes, + &executor, + "Benchmark_benchmark_metadata", + &(self.extra).encode(), + &mut Self::build_extensions(executor.clone()), + &runtime_code, + CallContext::Offchain, + ), + ERROR_METADATA_NOT_FOUND, + )?; + old_benchmark_data.into() + } else { + Self::exec_state_machine( + StateMachine::new( + state, + &mut changes, + &executor, + "Benchmark_benchmark_metadata", + &(self.extra).encode(), + &mut Self::build_extensions(executor.clone()), + &runtime_code, + CallContext::Offchain, + ), + ERROR_METADATA_NOT_FOUND, + )? + } + }; + + if let Some(json_input) = &self.json_input { + let raw_data = match std::fs::read(json_input) { + Ok(raw_data) => raw_data, + Err(error) => + return Err(format!("Failed to read {:?}: {}", json_input, error).into()), + }; + let batches: Vec = match serde_json::from_slice(&raw_data) { + Ok(batches) => batches, + Err(error) => + return Err(format!("Failed to deserialize {:?}: {}", json_input, error).into()), + }; + return self.output_from_results(&batches, max_extrinsic_weight, db_weight) + } // Use the benchmark list and the user input to determine the set of benchmarks to run. let benchmarks_to_run = self.select_benchmarks_to_run(list)?; @@ -583,7 +644,14 @@ impl PalletCmd { // Combine all of the benchmark results, so that benchmarks of the same pallet/function // are together. let batches = combine_batches(batches, batches_db); - self.output(&batches, &storage_info, &component_ranges, pov_modes) + self.output( + &batches, + &storage_info, + &component_ranges, + pov_modes, + max_extrinsic_weight, + db_weight, + ) } fn select_benchmarks_to_run(&self, list: Vec) -> Result> { @@ -726,6 +794,8 @@ impl PalletCmd { storage_info: &[StorageInfo], component_ranges: &ComponentRangeMap, pov_modes: PovModesMap, + max_extrinsic_weight: Option, + db_weight: Option, ) -> Result<()> { // Jsonify the result and write it to a file or stdout if desired. if !self.jsonify(&batches)? && !self.quiet { @@ -733,16 +803,37 @@ impl PalletCmd { self.print_summary(&batches, &storage_info, pov_modes.clone()) } + // Which analysis function should be used when outputting benchmarks + let analysis_choice: AnalysisChoice = + self.output_analysis.clone().try_into().map_err(writer::io_error)?; + let pov_analysis_choice: AnalysisChoice = + self.output_pov_analysis.clone().try_into().map_err(writer::io_error)?; + + // Organize results by pallet into a JSON map + let all_results = writer::map_results( + &batches, + &storage_info, + &component_ranges, + pov_modes.clone(), + self.default_pov_mode, + &analysis_choice, + &pov_analysis_choice, + self.worst_case_map_values, + self.additional_trie_layers, + )?; + // Create the weights.rs file. if let Some(output_path) = &self.output { - writer::write_results( - &batches, - &storage_info, - &component_ranges, - pov_modes, - self.default_pov_mode, - output_path, - self, + writer::write_results(output_path, self, analysis_choice, &all_results)?; + } + + if let (Some(max_extrinsic_weight), Some(db_weight)) = (max_extrinsic_weight, db_weight) { + // Execute sanity weight check. + writer::sanity_weight_check( + all_results, + max_extrinsic_weight, + db_weight, + self.shared_params.sanity_weight_check, )?; } @@ -750,7 +841,12 @@ impl PalletCmd { } /// Re-analyze a batch historic benchmark timing data. Will not take the PoV into account. - fn output_from_results(&self, batches: &[BenchmarkBatchSplitResults]) -> Result<()> { + fn output_from_results( + &self, + batches: &[BenchmarkBatchSplitResults], + max_extrinsic_weight: Option, + db_weight: Option, + ) -> Result<()> { let mut component_ranges = HashMap::<(String, String), HashMap>::new(); for batch in batches { let range = component_ranges @@ -784,7 +880,14 @@ impl PalletCmd { }) .collect(); - self.output(batches, &[], &component_ranges, Default::default()) + self.output( + batches, + &[], + &component_ranges, + Default::default(), + max_extrinsic_weight, + db_weight, + ) } /// Jsonifies the passed batches and writes them to stdout or into a file. diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs b/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs index 28918dd4e6a3..58340b23a362 100644 --- a/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs +++ b/substrate/utils/frame/benchmarking-cli/src/pallet/writer.rs @@ -25,6 +25,8 @@ use std::{ use inflector::Inflector; use itertools::Itertools; +use log::log; +use sc_cli::SanityWeightCheck; use serde::Serialize; use crate::{ @@ -38,7 +40,10 @@ use crate::{ use frame_benchmarking::{ Analysis, AnalysisChoice, BenchmarkBatchSplitResults, BenchmarkResult, BenchmarkSelector, }; -use frame_support::traits::StorageInfo; +use frame_support::{ + traits::StorageInfo, + weights::{RuntimeDbWeight, Weight}, +}; use sp_core::hexdisplay::HexDisplay; use sp_runtime::traits::Zero; @@ -62,7 +67,7 @@ struct TemplateData { // This was the final data we have about each benchmark. #[derive(Serialize, Default, Debug, Clone, PartialEq)] -struct BenchmarkData { +pub(crate) struct BenchmarkData { name: String, components: Vec, #[serde(serialize_with = "string_serialize")] @@ -119,7 +124,7 @@ struct ComponentSlope { } // Small helper to create an `io::Error` from a string. -fn io_error(s: &str) -> std::io::Error { +pub(crate) fn io_error(s: &str) -> std::io::Error { use std::io::{Error, ErrorKind}; Error::new(ErrorKind::Other, s) } @@ -132,7 +137,7 @@ fn io_error(s: &str) -> std::io::Error { // p1 -> [b1, b2, b3] // p2 -> [b1, b2] // ``` -fn map_results( +pub(crate) fn map_results( batches: &[BenchmarkBatchSplitResults], storage_info: &[StorageInfo], component_ranges: &ComponentRangeMap, @@ -175,6 +180,104 @@ fn map_results( Ok(all_benchmarks) } +// Calculates the total maximum weight of an extrinsic (if present, based on the max. component +// value) and compares it with the max. extrinsic weight allowed in a single block. +// +// `max_extrinsic_weight` & `db_weight` are obtained from the runtime configuration. +pub(crate) fn sanity_weight_check( + all_results: HashMap<(String, String), Vec>, + max_extrinsic_weight: Weight, + db_weight: RuntimeDbWeight, + sanity_weight_check: SanityWeightCheck, +) -> Result<(), std::io::Error> { + let log_level = match sanity_weight_check { + SanityWeightCheck::Error => log::Level::Error, + SanityWeightCheck::Warning => log::Level::Warn, + SanityWeightCheck::Ignore => return Ok(()), + }; + + // Helper function to return max. component value (i.e. max. complexity parameter). + fn max_component(parameter: &ComponentSlope, component_ranges: &Vec) -> u64 { + for component in component_ranges { + if parameter.name == component.name { + return component.max.into() + } + } + 0 + } + + log::info!( + "Starting the Sanity Weight Check:\nMaximum extrinsic weight value: {:?}\nResults:\n", + max_extrinsic_weight + ); + let mut sanity_weight_check_passed = true; + // Loop through all benchmark results. + for ((pallet, _), results) in all_results.iter() { + for result in results { + // Constant `ref_time` & `pov_size`. + let mut total_weight = Weight::from_parts( + result.base_weight.try_into().unwrap(), + result.base_calculated_proof_size.try_into().unwrap(), + ); + // `ref_time` multiplied by complexity parameter. + for component in &result.component_weight { + total_weight.saturating_accrue( + Weight::from_parts(component.slope.try_into().unwrap(), 0) + .saturating_mul(max_component(&component, &result.component_ranges)), + ); + } + // Constant storage reads. + total_weight.saturating_accrue(db_weight.reads(result.base_reads.try_into().unwrap())); + + // Storage reads multiplied by complexity parameter. + for component in &result.component_reads { + total_weight.saturating_accrue( + db_weight + .reads(component.slope.try_into().unwrap()) + .saturating_mul(max_component(&component, &result.component_ranges)), + ); + } + // Constant storage writes. + total_weight + .saturating_accrue(db_weight.writes(result.base_writes.try_into().unwrap())); + + // Storage writes multiplied by complexity parameter. + for component in &result.component_writes { + total_weight.saturating_accrue( + db_weight + .writes(component.slope.try_into().unwrap()) + .saturating_mul(max_component(&component, &result.component_ranges)), + ); + } + // `pov_size` multiplied by complexity parameter. + for component in &result.component_calculated_proof_size { + total_weight.saturating_accrue( + Weight::from_parts(0, component.slope.try_into().unwrap()) + .saturating_mul(max_component(&component, &result.component_ranges)), + ); + } + // Comparing (worst case scenario) the extrinsic weight against the maximum extrinsic + // weight. + if total_weight.any_gt(max_extrinsic_weight) { + sanity_weight_check_passed = false; + log!(log_level, " The following extrinsic exceeds the maximum extrinsic weight: \n - '{pallet}:{}': {:?}\nPercentage of max. extrinsic weight: {:.2}% (ref_time), {:.2}% (proof_size)\n", + result.name, + total_weight, + (total_weight.ref_time() as f64 / max_extrinsic_weight.ref_time() as f64) * 100.0, + (total_weight.proof_size() as f64 / max_extrinsic_weight.proof_size() as f64) * 100.0, + ); + } + } + } + if !sanity_weight_check_passed && sanity_weight_check == SanityWeightCheck::Error { + return Err(io_error(&String::from( + "One or more extrinsics exceed the maximum extrinsic weight", + ))) + } + + Ok(()) +} + // Get an iterator of errors. fn extract_errors(errors: &Option>) -> impl Iterator + '_ { errors @@ -378,13 +481,10 @@ fn get_benchmark_data( /// Create weight file from benchmark data and Handlebars template. pub(crate) fn write_results( - batches: &[BenchmarkBatchSplitResults], - storage_info: &[StorageInfo], - component_ranges: &HashMap<(String, String), Vec>, - pov_modes: PovModesMap, - default_pov_mode: PovEstimationMode, path: &PathBuf, cmd: &PalletCmd, + analysis_choice: AnalysisChoice, + all_results: &HashMap<(String, String), Vec>, ) -> Result<(), sc_cli::Error> { // Use custom template if provided. let template: String = match &cmd.template { @@ -407,12 +507,6 @@ pub(crate) fn write_results( // Full CLI args passed to trigger the benchmark. let args = std::env::args().collect::>(); - // Which analysis function should be used when outputting benchmarks - let analysis_choice: AnalysisChoice = - cmd.output_analysis.clone().try_into().map_err(io_error)?; - let pov_analysis_choice: AnalysisChoice = - cmd.output_pov_analysis.clone().try_into().map_err(io_error)?; - if cmd.additional_trie_layers > 4 { println!( "WARNING: `additional_trie_layers` is unexpectedly large. It assumes {} storage items.", @@ -441,18 +535,6 @@ pub(crate) fn write_results( // Don't HTML escape any characters. handlebars.register_escape_fn(|s| -> String { s.to_string() }); - // Organize results by pallet into a JSON map - let all_results = map_results( - batches, - storage_info, - component_ranges, - pov_modes, - default_pov_mode, - &analysis_choice, - &pov_analysis_choice, - cmd.worst_case_map_values, - cmd.additional_trie_layers, - )?; let mut created_files = Vec::new(); for ((pallet, instance), results) in all_results.iter() { @@ -1248,6 +1330,50 @@ mod test { ); } + #[test] + fn sanity_weight_check_works() { + // Create benchmark results that will fail the sanity weight check. + let mapped_results = map_results( + &[test_data(b"first", b"first", BenchmarkParameter::a, 10, 3)], + &test_storage_info(), + &Default::default(), + Default::default(), + PovEstimationMode::MaxEncodedLen, + &AnalysisChoice::default(), + &AnalysisChoice::MedianSlopes, + 1_000_000, + 0, + ) + .unwrap(); + + // Flag set to `error`. + assert!(sanity_weight_check( + mapped_results.clone(), + Weight::from_parts(20_000, 1_000_000), + RuntimeDbWeight { read: 1000, write: 1000 }, + SanityWeightCheck::Error, + ) + .is_err()); + + // Flag set to `warning`. + assert!(sanity_weight_check( + mapped_results.clone(), + Weight::from_parts(20_000, 1_000_000), + RuntimeDbWeight { read: 1000, write: 1000 }, + SanityWeightCheck::Warning, + ) + .is_ok()); + + // Flag set to `ignore`. + assert!(sanity_weight_check( + mapped_results, + Weight::from_parts(20_000, 1_000_000), + RuntimeDbWeight { read: 1000, write: 1000 }, + SanityWeightCheck::Ignore, + ) + .is_ok()); + } + #[test] fn additional_trie_layers_work() { let mapped_results = map_results( diff --git a/templates/parachain/runtime/src/apis.rs b/templates/parachain/runtime/src/apis.rs index 05a508ca655f..af8f49040dac 100644 --- a/templates/parachain/runtime/src/apis.rs +++ b/templates/parachain/runtime/src/apis.rs @@ -242,21 +242,27 @@ impl_runtime_apis! { #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{Benchmarking, BenchmarkList}; - use polkadot_sdk::frame_support::traits::StorageInfoTrait; + fn benchmark_metadata(extra: bool) -> frame_benchmarking::RuntimeBenchmarkInfo { + use frame_benchmarking::{Benchmarking, BenchmarkList, RuntimeBenchmarkInfo}; + use frame_support::{traits::StorageInfoTrait, dispatch::DispatchClass}; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + use super::configs::RuntimeBlockWeights; use super::*; let mut list = Vec::::new(); list_benchmarks!(list, extra); let storage_info = AllPalletsWithSystem::storage_info(); - (list, storage_info) + let max_extrinsic_weight = RuntimeBlockWeights::get().per_class.get(DispatchClass::Normal).max_extrinsic.unwrap(); + let db_weight: frame_support::weights::RuntimeDbWeight = ::DbWeight::get(); + + RuntimeBenchmarkInfo { + list, + storage_info, + max_extrinsic_weight: Some(max_extrinsic_weight), + db_weight: Some(db_weight), + } } fn dispatch_benchmark(