mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 12:07:57 +00:00
Add benchmark extrinsic command (#11456)
* Benchmark extrinsic Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Reduce warmup and repeat Running this 1000 times with a full block takes ~33 minutes 🙈. Reducing it to ~3 minutes per default. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make ExistentialDeposit public Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add 'bechmark extrinsic' command Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add --list and cleanup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Unrelated Clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix tests and doc Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Move implementations up + fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Dont use parameter_types macro Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Cache to_lowercase() call The .to_lowercase() on the builder is actually not needes since its already documented to only return lower case. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Spelling Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use correct nightly for fmt... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Rename ED Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix compile Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Subtract block base weight Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fixes Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use tmp folder for test This should already be the case since --dev is passed but somehow not... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
committed by
GitHub
parent
3d95c270e0
commit
1843ae83ba
@@ -0,0 +1,134 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2022 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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, 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,
|
||||
};
|
||||
|
||||
/// Benchmark the execution time of different extrinsics.
|
||||
///
|
||||
/// This is calculated by filling a block with a specific extrinsic and executing the block.
|
||||
/// The result time is then divided by the number of extrinsics in that block.
|
||||
///
|
||||
/// NOTE: The BlockExecutionWeight is ignored in this case since it
|
||||
// is very small compared to the total block execution time.
|
||||
#[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,
|
||||
}
|
||||
|
||||
/// The params for the [`ExtrinsicCmd`].
|
||||
#[derive(Debug, Default, Serialize, Clone, PartialEq, Args)]
|
||||
pub struct ExtrinsicParams {
|
||||
#[clap(flatten)]
|
||||
pub bench: BenchmarkParams,
|
||||
|
||||
/// List all available pallets and extrinsics.
|
||||
///
|
||||
/// The format is CSV with header `pallet, extrinsic`.
|
||||
#[clap(long)]
|
||||
pub list: bool,
|
||||
|
||||
/// Pallet name of the extrinsic to benchmark.
|
||||
#[clap(long, value_name = "PALLET", required_unless_present = "list")]
|
||||
pub pallet: Option<String>,
|
||||
|
||||
/// Extrinsic to benchmark.
|
||||
#[clap(long, value_name = "EXTRINSIC", required_unless_present = "list")]
|
||||
pub extrinsic: Option<String>,
|
||||
}
|
||||
|
||||
impl ExtrinsicCmd {
|
||||
/// Benchmark the execution time of a specific type of extrinsic.
|
||||
///
|
||||
/// The output will be printed to console.
|
||||
pub fn run<Block, BA, C>(
|
||||
&self,
|
||||
client: Arc<C>,
|
||||
inherent_data: sp_inherents::InherentData,
|
||||
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>,
|
||||
{
|
||||
// Short circuit if --list was specified.
|
||||
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);
|
||||
let stats = bench.bench_extrinsic(ext_builder)?;
|
||||
info!(
|
||||
"Executing a {}::{} extrinsic takes[ns]:\n{:?}",
|
||||
ext_builder.pallet(),
|
||||
ext_builder.extrinsic(),
|
||||
stats
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
impl CliConfiguration for ExtrinsicCmd {
|
||||
fn shared_params(&self) -> &SharedParams {
|
||||
&self.shared_params
|
||||
}
|
||||
|
||||
fn import_params(&self) -> Option<&ImportParams> {
|
||||
Some(&self.import_params)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user