referrerpolicy=no-referrer-when-downgrade

frame_benchmarking_cli/block/
cmd.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Contains the [`BlockCmd`] as entry point for the CLI to execute
19//! the *block* benchmark.
20
21use sc_block_builder::BlockBuilderApi;
22use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams};
23use sc_client_api::{Backend as ClientBackend, BlockBackend, StorageProvider, UsageProvider};
24use sp_api::{ApiExt, ProvideRuntimeApi};
25use sp_blockchain::HeaderBackend;
26use sp_runtime::{traits::Block as BlockT, OpaqueExtrinsic};
27
28use clap::Parser;
29use std::{fmt::Debug, sync::Arc};
30
31use super::bench::{Benchmark, BenchmarkParams};
32
33/// Benchmark the execution time of historic blocks.
34///
35/// This can be used to verify that blocks do not use more weight than they consumed
36/// in their `WeightInfo`. Example:
37///
38/// Let's say you are on a Substrate chain and want to verify that the first 3 blocks
39/// did not use more weight than declared which would otherwise be an issue.
40/// To test this with a dev node, first create one with a temp directory:
41///
42/// $ substrate --dev -d /tmp/my-dev --wasm-execution compiled
43///
44/// And wait some time to let it produce 3 blocks. Then benchmark them with:
45///
46/// $ substrate benchmark-block --from 1 --to 3 --dev -d /tmp/my-dev
47///   --wasm-execution compiled --pruning archive
48///
49/// The output will be similar to this:
50///
51/// Block 1 with 1 tx used 77.34% of its weight ( 5,308,964 of 6,864,645 ns)
52/// Block 2 with 1 tx used 77.99% of its weight ( 5,353,992 of 6,864,645 ns)
53/// Block 3 with 1 tx used 75.91% of its weight ( 5,305,938 of 6,989,645 ns)
54///
55/// The percent number is important and indicates how much weight
56/// was used as compared to the consumed weight.
57/// This number should be below 100% for reference hardware.
58#[derive(Debug, Parser)]
59pub struct BlockCmd {
60	#[allow(missing_docs)]
61	#[clap(flatten)]
62	pub shared_params: SharedParams,
63
64	#[allow(missing_docs)]
65	#[clap(flatten)]
66	pub import_params: ImportParams,
67
68	#[allow(missing_docs)]
69	#[clap(flatten)]
70	pub params: BenchmarkParams,
71
72	/// Enable the Trie cache.
73	///
74	/// This should only be used for performance analysis and not for final results.
75	#[arg(long)]
76	pub enable_trie_cache: bool,
77}
78
79impl BlockCmd {
80	/// Benchmark the execution time of historic blocks and compare it to their consumed weight.
81	///
82	/// Output will be printed to console.
83	pub fn run<Block, BA, C>(&self, client: Arc<C>) -> Result<()>
84	where
85		Block: BlockT<Extrinsic = OpaqueExtrinsic>,
86		BA: ClientBackend<Block>,
87		C: BlockBackend<Block>
88			+ ProvideRuntimeApi<Block>
89			+ StorageProvider<Block, BA>
90			+ UsageProvider<Block>
91			+ HeaderBackend<Block>,
92		C::Api: ApiExt<Block> + BlockBuilderApi<Block>,
93	{
94		// Put everything in the benchmark type to have the generic types handy.
95		Benchmark::new(client, self.params.clone()).run()
96	}
97}
98
99// Boilerplate
100impl CliConfiguration for BlockCmd {
101	fn shared_params(&self) -> &SharedParams {
102		&self.shared_params
103	}
104
105	fn import_params(&self) -> Option<&ImportParams> {
106		Some(&self.import_params)
107	}
108
109	fn trie_cache_maximum_size(&self) -> Result<Option<usize>> {
110		if self.enable_trie_cache {
111			Ok(self.import_params().map(|x| x.trie_cache_maximum_size()).unwrap_or_default())
112		} else {
113			Ok(None)
114		}
115	}
116}