1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider};
use sc_cli::{CliConfiguration, ImportParams, Result, SharedParams};
use sc_client_api::Backend as ClientBackend;
use sp_api::{ApiExt, ProvideRuntimeApi};
use sp_runtime::{traits::Block as BlockT, DigestItem, OpaqueExtrinsic};
use clap::{Args, Parser};
use log::info;
use serde::Serialize;
use std::{fmt::Debug, sync::Arc};
use super::{
bench::{Benchmark, BenchmarkParams},
extrinsic_factory::ExtrinsicFactory,
};
#[derive(Debug, Parser)]
pub struct ExtrinsicCmd {
#[allow(missing_docs)]
#[clap(flatten)]
pub shared_params: SharedParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub import_params: ImportParams,
#[allow(missing_docs)]
#[clap(flatten)]
pub params: ExtrinsicParams,
}
#[derive(Debug, Default, Serialize, Clone, PartialEq, Args)]
pub struct ExtrinsicParams {
#[clap(flatten)]
pub bench: BenchmarkParams,
#[clap(long)]
pub list: bool,
#[clap(long, value_name = "PALLET", required_unless_present = "list")]
pub pallet: Option<String>,
#[clap(long, value_name = "EXTRINSIC", required_unless_present = "list")]
pub extrinsic: Option<String>,
}
impl ExtrinsicCmd {
pub fn run<Block, BA, C>(
&self,
client: Arc<C>,
inherent_data: sp_inherents::InherentData,
digest_items: Vec<DigestItem>,
ext_factory: &ExtrinsicFactory,
) -> Result<()>
where
Block: BlockT<Extrinsic = OpaqueExtrinsic>,
BA: ClientBackend<Block>,
C: BlockBuilderProvider<BA, Block, C> + ProvideRuntimeApi<Block>,
C::Api: ApiExt<Block, StateBackend = BA::State> + BlockBuilderApi<Block>,
{
if self.params.list {
let list: Vec<String> = ext_factory.0.iter().map(|b| b.name()).collect();
info!(
"Listing available extrinsics ({}):\npallet, extrinsic\n{}",
list.len(),
list.join("\n")
);
return Ok(())
}
let pallet = self.params.pallet.clone().unwrap_or_default();
let extrinsic = self.params.extrinsic.clone().unwrap_or_default();
let ext_builder = match ext_factory.try_get(&pallet, &extrinsic) {
Some(ext_builder) => ext_builder,
None =>
return Err("Unknown pallet or extrinsic. Use --list for a complete list.".into()),
};
let bench = Benchmark::new(client, self.params.bench.clone(), inherent_data, digest_items);
let stats = bench.bench_extrinsic(ext_builder)?;
info!(
"Executing a {}::{} extrinsic takes[ns]:\n{:?}",
ext_builder.pallet(),
ext_builder.extrinsic(),
stats
);
Ok(())
}
}
impl CliConfiguration for ExtrinsicCmd {
fn shared_params(&self) -> &SharedParams {
&self.shared_params
}
fn import_params(&self) -> Option<&ImportParams> {
Some(&self.import_params)
}
}