referrerpolicy=no-referrer-when-downgrade

solochain_template_node/
benchmarking.rs

1//! Setup code for [`super::command`] which would otherwise bloat that module.
2//!
3//! Should only be used for benchmarking as it may break in other contexts.
4
5use crate::service::FullClient;
6
7use runtime::{AccountId, Balance, BalancesCall, SystemCall};
8use sc_cli::Result;
9use sc_client_api::BlockBackend;
10use solochain_template_runtime as runtime;
11use sp_core::{Encode, Pair};
12use sp_inherents::{InherentData, InherentDataProvider};
13use sp_keyring::Sr25519Keyring;
14use sp_runtime::{OpaqueExtrinsic, SaturatedConversion};
15
16use std::{sync::Arc, time::Duration};
17
18/// Generates extrinsics for the `benchmark overhead` command.
19///
20/// Note: Should only be used for benchmarking.
21pub struct RemarkBuilder {
22	client: Arc<FullClient>,
23}
24
25impl RemarkBuilder {
26	/// Creates a new [`Self`] from the given client.
27	pub fn new(client: Arc<FullClient>) -> Self {
28		Self { client }
29	}
30}
31
32impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder {
33	fn pallet(&self) -> &str {
34		"system"
35	}
36
37	fn extrinsic(&self) -> &str {
38		"remark"
39	}
40
41	fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
42		let acc = Sr25519Keyring::Bob.pair();
43		let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic(
44			self.client.as_ref(),
45			acc,
46			SystemCall::remark { remark: vec![] }.into(),
47			nonce,
48		)
49		.into();
50
51		Ok(extrinsic)
52	}
53}
54
55/// Generates `Balances::TransferKeepAlive` extrinsics for the benchmarks.
56///
57/// Note: Should only be used for benchmarking.
58pub struct TransferKeepAliveBuilder {
59	client: Arc<FullClient>,
60	dest: AccountId,
61	value: Balance,
62}
63
64impl TransferKeepAliveBuilder {
65	/// Creates a new [`Self`] from the given client.
66	pub fn new(client: Arc<FullClient>, dest: AccountId, value: Balance) -> Self {
67		Self { client, dest, value }
68	}
69}
70
71impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder {
72	fn pallet(&self) -> &str {
73		"balances"
74	}
75
76	fn extrinsic(&self) -> &str {
77		"transfer_keep_alive"
78	}
79
80	fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
81		let acc = Sr25519Keyring::Bob.pair();
82		let extrinsic: OpaqueExtrinsic = create_benchmark_extrinsic(
83			self.client.as_ref(),
84			acc,
85			BalancesCall::transfer_keep_alive { dest: self.dest.clone().into(), value: self.value }
86				.into(),
87			nonce,
88		)
89		.into();
90
91		Ok(extrinsic)
92	}
93}
94
95/// Create a transaction using the given `call`.
96///
97/// Note: Should only be used for benchmarking.
98pub fn create_benchmark_extrinsic(
99	client: &FullClient,
100	sender: sp_core::sr25519::Pair,
101	call: runtime::RuntimeCall,
102	nonce: u32,
103) -> runtime::UncheckedExtrinsic {
104	let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed");
105	let best_hash = client.chain_info().best_hash;
106	let best_block = client.chain_info().best_number;
107
108	let period = runtime::configs::BlockHashCount::get()
109		.checked_next_power_of_two()
110		.map(|c| c / 2)
111		.unwrap_or(2) as u64;
112	let tx_ext: runtime::TxExtension = (
113		frame_system::AuthorizeCall::<runtime::Runtime>::new(),
114		frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
115		frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
116		frame_system::CheckTxVersion::<runtime::Runtime>::new(),
117		frame_system::CheckGenesis::<runtime::Runtime>::new(),
118		frame_system::CheckEra::<runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
119			period,
120			best_block.saturated_into(),
121		)),
122		frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
123		frame_system::CheckWeight::<runtime::Runtime>::new(),
124		pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
125		frame_metadata_hash_extension::CheckMetadataHash::<runtime::Runtime>::new(false),
126		frame_system::WeightReclaim::<runtime::Runtime>::new(),
127	);
128
129	let raw_payload = runtime::SignedPayload::from_raw(
130		call.clone(),
131		tx_ext.clone(),
132		(
133			(),
134			(),
135			runtime::VERSION.spec_version,
136			runtime::VERSION.transaction_version,
137			genesis_hash,
138			best_hash,
139			(),
140			(),
141			(),
142			None,
143			(),
144		),
145	);
146	let signature = raw_payload.using_encoded(|e| sender.sign(e));
147
148	runtime::UncheckedExtrinsic::new_signed(
149		call,
150		sp_runtime::AccountId32::from(sender.public()).into(),
151		runtime::Signature::Sr25519(signature),
152		tx_ext,
153	)
154}
155
156/// Generates inherent data for the `benchmark overhead` command.
157///
158/// Note: Should only be used for benchmarking.
159pub fn inherent_benchmark_data() -> Result<InherentData> {
160	let mut inherent_data = InherentData::new();
161	let d = Duration::from_millis(0);
162	let timestamp = sp_timestamp::InherentDataProvider::new(d.into());
163
164	futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data))
165		.map_err(|e| format!("creating inherent data: {e:?}"))?;
166	Ok(inherent_data)
167}