frame_benchmarking_cli/extrinsic/
cmd.rs1use sc_block_builder::BlockBuilderApi;
19use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams};
20use sc_client_api::UsageProvider;
21use sp_api::{ApiExt, CallApiAt, ProvideRuntimeApi};
22use sp_runtime::{traits::Block as BlockT, DigestItem, OpaqueExtrinsic};
23
24use clap::{Args, Parser};
25use log::info;
26use serde::Serialize;
27use std::{fmt::Debug, sync::Arc};
28
29use super::{
30 bench::{Benchmark, BenchmarkParams},
31 extrinsic_factory::ExtrinsicFactory,
32};
33
34#[derive(Debug, Parser)]
42pub struct ExtrinsicCmd {
43 #[allow(missing_docs)]
44 #[clap(flatten)]
45 pub shared_params: SharedParams,
46
47 #[allow(missing_docs)]
48 #[clap(flatten)]
49 pub import_params: ImportParams,
50
51 #[allow(missing_docs)]
52 #[clap(flatten)]
53 pub params: ExtrinsicParams,
54}
55
56#[derive(Debug, Default, Serialize, Clone, PartialEq, Args)]
58pub struct ExtrinsicParams {
59 #[clap(flatten)]
60 pub bench: BenchmarkParams,
61
62 #[arg(long)]
66 pub list: bool,
67
68 #[arg(long, value_name = "PALLET", required_unless_present = "list")]
70 pub pallet: Option<String>,
71
72 #[arg(long, value_name = "EXTRINSIC", required_unless_present = "list")]
74 pub extrinsic: Option<String>,
75
76 #[arg(long)]
80 pub enable_trie_cache: bool,
81}
82
83impl ExtrinsicCmd {
84 pub fn run<Block, C>(
88 &self,
89 client: Arc<C>,
90 inherent_data: sp_inherents::InherentData,
91 digest_items: Vec<DigestItem>,
92 ext_factory: &ExtrinsicFactory,
93 ) -> Result<()>
94 where
95 Block: BlockT<Extrinsic = OpaqueExtrinsic>,
96 C: ProvideRuntimeApi<Block>
97 + CallApiAt<Block>
98 + UsageProvider<Block>
99 + sp_blockchain::HeaderBackend<Block>,
100 C::Api: ApiExt<Block> + BlockBuilderApi<Block>,
101 {
102 if self.params.list {
104 let list: Vec<String> = ext_factory.0.iter().map(|b| b.name()).collect();
105 info!(
106 "Listing available extrinsics ({}):\npallet, extrinsic\n{}",
107 list.len(),
108 list.join("\n")
109 );
110 return Ok(())
111 }
112
113 let pallet = self.params.pallet.clone().unwrap_or_default();
114 let extrinsic = self.params.extrinsic.clone().unwrap_or_default();
115 let ext_builder = match ext_factory.try_get(&pallet, &extrinsic) {
116 Some(ext_builder) => ext_builder,
117 None =>
118 return Err("Unknown pallet or extrinsic. Use --list for a complete list.".into()),
119 };
120
121 let bench =
122 Benchmark::new(client, self.params.bench.clone(), inherent_data, digest_items, false);
123 let stats = bench.bench_extrinsic(ext_builder)?;
124 info!(
125 "Executing a {}::{} extrinsic takes[ns]:\n{:?}",
126 ext_builder.pallet(),
127 ext_builder.extrinsic(),
128 stats
129 );
130
131 Ok(())
132 }
133}
134
135impl CliConfiguration for ExtrinsicCmd {
137 fn shared_params(&self) -> &SharedParams {
138 &self.shared_params
139 }
140
141 fn import_params(&self) -> Option<&ImportParams> {
142 Some(&self.import_params)
143 }
144
145 fn trie_cache_maximum_size(&self) -> Result<Option<usize>> {
146 if self.params.enable_trie_cache {
147 Ok(self.import_params().map(|x| x.trie_cache_maximum_size()).unwrap_or_default())
148 } else {
149 Ok(None)
150 }
151 }
152}