mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 16:31:07 +00:00
* Expose 'benchmark extrinsic' command Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Split benchmarking into own mod Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Simplify code Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fixup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Cleanup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Spell Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Revert Cargo.lock updates Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * update lockfile for {"substrate"} * Fix brittle test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Bump spec version to 9270 Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Sleep in test to make it work in CI... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Disable failing test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Revert "Bump spec version to 9270" This reverts commit c1c385d7a4dc849e7f4d4723740aec66c2b7be09. * Delete brittle test, see #5788 Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Disable failing test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Delete more failing tests... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: parity-processbot <>
This commit is contained in:
committed by
GitHub
parent
9b086257e2
commit
340e7be60d
Generated
+175
-176
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@ polkadot-node-core-pvf = { path = "../node/core/pvf", optional = true }
|
||||
polkadot-performance-test = { path = "../node/test/performance-test", optional = true }
|
||||
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||
try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||
|
||||
+34
-10
@@ -15,12 +15,16 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::cli::{Cli, Subcommand};
|
||||
use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE};
|
||||
use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE};
|
||||
use futures::future::TryFutureExt;
|
||||
use log::info;
|
||||
use polkadot_client::benchmarking::{
|
||||
benchmark_inherent_data, ExistentialDepositProvider, RemarkBuilder, TransferKeepAliveBuilder,
|
||||
};
|
||||
use sc_cli::{Role, RuntimeVersion, SubstrateCli};
|
||||
use service::{self, HeaderBackend, IdentifyVariant};
|
||||
use sp_core::crypto::Ss58AddressFormatRegistry;
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
use std::net::ToSocketAddrs;
|
||||
|
||||
pub use crate::{error::Error, service::BlockId};
|
||||
@@ -508,22 +512,42 @@ pub fn run() -> Result<()> {
|
||||
|
||||
unwrap_client!(client, cmd.run(client.clone()).map_err(Error::SubstrateCli))
|
||||
}),
|
||||
BenchmarkCmd::Overhead(cmd) => {
|
||||
// These commands are very similar and can be handled in nearly the same way.
|
||||
BenchmarkCmd::Extrinsic(_) | BenchmarkCmd::Overhead(_) => {
|
||||
ensure_dev(chain_spec).map_err(Error::Other)?;
|
||||
runner.sync_run(|mut config| {
|
||||
use polkadot_client::benchmark_inherent_data;
|
||||
let (client, _, _, _) = service::new_chain_ops(&mut config, None)?;
|
||||
let wrapped = client.clone();
|
||||
|
||||
let header = client.header(BlockId::Number(0_u32.into())).unwrap().unwrap();
|
||||
let inherent_data = benchmark_inherent_data(header)
|
||||
.map_err(|e| format!("generating inherent data: {:?}", e))?;
|
||||
let remark_builder = RemarkBuilder::new(client.clone());
|
||||
|
||||
unwrap_client!(
|
||||
client,
|
||||
cmd.run(config, client.clone(), inherent_data, wrapped)
|
||||
.map_err(Error::SubstrateCli)
|
||||
)
|
||||
match cmd {
|
||||
BenchmarkCmd::Extrinsic(cmd) => {
|
||||
let tka_builder = TransferKeepAliveBuilder::new(
|
||||
client.clone(),
|
||||
Sr25519Keyring::Alice.to_account_id(),
|
||||
client.existential_deposit(),
|
||||
);
|
||||
|
||||
let ext_factory = ExtrinsicFactory(vec![
|
||||
Box::new(remark_builder),
|
||||
Box::new(tka_builder),
|
||||
]);
|
||||
|
||||
unwrap_client!(
|
||||
client,
|
||||
cmd.run(client.clone(), inherent_data, &ext_factory)
|
||||
.map_err(Error::SubstrateCli)
|
||||
)
|
||||
},
|
||||
BenchmarkCmd::Overhead(cmd) => unwrap_client!(
|
||||
client,
|
||||
cmd.run(config, client.clone(), inherent_data, &remark_builder)
|
||||
.map_err(Error::SubstrateCli)
|
||||
),
|
||||
_ => unreachable!("Ensured by the outside match; qed"),
|
||||
}
|
||||
})
|
||||
},
|
||||
BenchmarkCmd::Pallet(cmd) => {
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
// Copyright 2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Code related to benchmarking a [`crate::Client`].
|
||||
|
||||
use polkadot_primitives::v2::{AccountId, Balance};
|
||||
use sp_core::{Pair, H256};
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
use sp_runtime::OpaqueExtrinsic;
|
||||
|
||||
use crate::*;
|
||||
|
||||
/// Generates `System::Remark` extrinsics for the benchmarks.
|
||||
///
|
||||
/// Note: Should only be used for benchmarking.
|
||||
pub struct RemarkBuilder {
|
||||
client: Arc<Client>,
|
||||
}
|
||||
|
||||
impl RemarkBuilder {
|
||||
/// Creates a new [`Self`] from the given client.
|
||||
pub fn new(client: Arc<Client>) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder {
|
||||
fn pallet(&self) -> &str {
|
||||
"system"
|
||||
}
|
||||
|
||||
fn extrinsic(&self) -> &str {
|
||||
"remark"
|
||||
}
|
||||
|
||||
fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
|
||||
with_client! {
|
||||
self.client.as_ref(), client, {
|
||||
use runtime::{Call, SystemCall};
|
||||
|
||||
let call = Call::System(SystemCall::remark { remark: vec![] });
|
||||
let signer = Sr25519Keyring::Bob.pair();
|
||||
|
||||
let period = polkadot_runtime_common::BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
|
||||
let genesis = client.usage_info().chain.best_hash;
|
||||
|
||||
Ok(client.sign_call(call, nonce, 0, period, genesis, signer))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates `Balances::TransferKeepAlive` extrinsics for the benchmarks.
|
||||
///
|
||||
/// Note: Should only be used for benchmarking.
|
||||
pub struct TransferKeepAliveBuilder {
|
||||
client: Arc<Client>,
|
||||
dest: AccountId,
|
||||
value: Balance,
|
||||
}
|
||||
|
||||
impl TransferKeepAliveBuilder {
|
||||
/// Creates a new [`Self`] from the given client and the arguments for the extrinsics.
|
||||
|
||||
pub fn new(client: Arc<Client>, dest: AccountId, value: Balance) -> Self {
|
||||
Self { client, dest, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder {
|
||||
fn pallet(&self) -> &str {
|
||||
"balances"
|
||||
}
|
||||
|
||||
fn extrinsic(&self) -> &str {
|
||||
"transfer_keep_alive"
|
||||
}
|
||||
|
||||
fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
|
||||
with_client! {
|
||||
self.client.as_ref(), client, {
|
||||
use runtime::{Call, BalancesCall};
|
||||
|
||||
let call = Call::Balances(BalancesCall::transfer_keep_alive {
|
||||
dest: self.dest.clone().into(),
|
||||
value: self.value.into(),
|
||||
});
|
||||
let signer = Sr25519Keyring::Bob.pair();
|
||||
|
||||
let period = polkadot_runtime_common::BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
|
||||
let genesis = client.usage_info().chain.best_hash;
|
||||
|
||||
Ok(client.sign_call(call, nonce, 0, period, genesis, signer))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to implement [`frame_benchmarking_cli::ExtrinsicBuilder`].
|
||||
///
|
||||
/// Should only be used for benchmarking since it makes strong assumptions
|
||||
/// about the chain state that these calls will be valid for.
|
||||
trait BenchmarkCallSigner<Call: Encode + Clone, Signer: Pair> {
|
||||
/// Signs a call together with the signed extensions of the specific runtime.
|
||||
///
|
||||
/// Only works if the current block is the genesis block since the
|
||||
/// `CheckMortality` check is mocked by using the genesis block.
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: Signer,
|
||||
) -> OpaqueExtrinsic;
|
||||
}
|
||||
|
||||
#[cfg(feature = "polkadot")]
|
||||
impl BenchmarkCallSigner<polkadot_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<polkadot_runtime::RuntimeApi, PolkadotExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: polkadot_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use polkadot_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
polkadot_runtime_common::claims::PrevalidateAttests::<runtime::Runtime>::new(),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "westend")]
|
||||
impl BenchmarkCallSigner<westend_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<westend_runtime::RuntimeApi, WestendExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: westend_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use westend_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "kusama")]
|
||||
impl BenchmarkCallSigner<kusama_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<kusama_runtime::RuntimeApi, KusamaExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: kusama_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use kusama_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rococo")]
|
||||
impl BenchmarkCallSigner<rococo_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<rococo_runtime::RuntimeApi, RococoExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: rococo_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use rococo_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates inherent data for benchmarking Polkadot, Kusama, Westend and Rococo.
|
||||
///
|
||||
/// Not to be used outside of benchmarking since it returns mocked values.
|
||||
pub fn benchmark_inherent_data(
|
||||
header: polkadot_core_primitives::Header,
|
||||
) -> std::result::Result<sp_inherents::InherentData, sp_inherents::Error> {
|
||||
use sp_inherents::InherentDataProvider;
|
||||
let mut inherent_data = sp_inherents::InherentData::new();
|
||||
|
||||
// Assume that all runtimes have the `timestamp` pallet.
|
||||
let d = std::time::Duration::from_millis(0);
|
||||
let timestamp = sp_timestamp::InherentDataProvider::new(d.into());
|
||||
timestamp.provide_inherent_data(&mut inherent_data)?;
|
||||
|
||||
let para_data = polkadot_primitives::v2::InherentData {
|
||||
bitfields: Vec::new(),
|
||||
backed_candidates: Vec::new(),
|
||||
disputes: Vec::new(),
|
||||
parent_header: header,
|
||||
};
|
||||
|
||||
polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::from_data(para_data)
|
||||
.provide_inherent_data(&mut inherent_data)?;
|
||||
|
||||
Ok(inherent_data)
|
||||
}
|
||||
|
||||
/// Provides the existential deposit that is only needed for benchmarking.
|
||||
pub trait ExistentialDepositProvider {
|
||||
/// Returns the existential deposit.
|
||||
fn existential_deposit(&self) -> Balance;
|
||||
}
|
||||
|
||||
impl ExistentialDepositProvider for Client {
|
||||
fn existential_deposit(&self) -> Balance {
|
||||
with_client! {
|
||||
self,
|
||||
_client,
|
||||
runtime::ExistentialDeposit::get()
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-291
@@ -28,16 +28,16 @@ use sc_executor::NativeElseWasmExecutor;
|
||||
use sp_api::{CallApiAt, Encode, NumberFor, ProvideRuntimeApi};
|
||||
use sp_blockchain::{HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus::BlockStatus;
|
||||
use sp_core::{Pair, H256};
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
use sp_runtime::{
|
||||
generic::{BlockId, SignedBlock},
|
||||
traits::{BlakeTwo256, Block as BlockT},
|
||||
Justifications, OpaqueExtrinsic,
|
||||
Justifications,
|
||||
};
|
||||
use sp_storage::{ChildInfo, StorageData, StorageKey};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub mod benchmarking;
|
||||
|
||||
pub type FullBackend = sc_service::TFullBackend<Block>;
|
||||
|
||||
pub type FullClient<RuntimeApi, ExecutorDispatch> =
|
||||
@@ -243,35 +243,37 @@ pub trait ClientHandle {
|
||||
/// provides the concrete runtime as `runtime`.
|
||||
macro_rules! with_client {
|
||||
{
|
||||
$self:ident,
|
||||
// The client instance that should be unwrapped.
|
||||
$self:expr,
|
||||
// The name that the unwrapped client will have.
|
||||
$client:ident,
|
||||
// NOTE: Using an expression here is fine since blocks are also expressions.
|
||||
$code:expr
|
||||
} => {
|
||||
match $self {
|
||||
#[cfg(feature = "polkadot")]
|
||||
Self::Polkadot($client) => {
|
||||
Client::Polkadot($client) => {
|
||||
#[allow(unused_imports)]
|
||||
use polkadot_runtime as runtime;
|
||||
|
||||
$code
|
||||
},
|
||||
#[cfg(feature = "westend")]
|
||||
Self::Westend($client) => {
|
||||
Client::Westend($client) => {
|
||||
#[allow(unused_imports)]
|
||||
use westend_runtime as runtime;
|
||||
|
||||
$code
|
||||
},
|
||||
#[cfg(feature = "kusama")]
|
||||
Self::Kusama($client) => {
|
||||
Client::Kusama($client) => {
|
||||
#[allow(unused_imports)]
|
||||
use kusama_runtime as runtime;
|
||||
|
||||
$code
|
||||
},
|
||||
#[cfg(feature = "rococo")]
|
||||
Self::Rococo($client) => {
|
||||
Client::Rococo($client) => {
|
||||
#[allow(unused_imports)]
|
||||
use rococo_runtime as runtime;
|
||||
|
||||
@@ -280,6 +282,8 @@ macro_rules! with_client {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make the macro available only within this crate.
|
||||
pub(crate) use with_client;
|
||||
|
||||
/// A client instance of Polkadot.
|
||||
///
|
||||
@@ -603,286 +607,3 @@ impl sp_blockchain::HeaderBackend<Block> for Client {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_benchmarking_cli::ExtrinsicBuilder for Client {
|
||||
fn remark(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
|
||||
with_client! {
|
||||
self, client, {
|
||||
use runtime::{Call, SystemCall};
|
||||
|
||||
let call = Call::System(SystemCall::remark { remark: vec![] });
|
||||
let signer = Sr25519Keyring::Bob.pair();
|
||||
|
||||
let period = polkadot_runtime_common::BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
|
||||
let genesis = self.usage_info().chain.best_hash;
|
||||
|
||||
Ok(client.sign_call(call, nonce, 0, period, genesis, signer))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to implement [`frame_benchmarking_cli::ExtrinsicBuilder`].
|
||||
///
|
||||
/// Should only be used for benchmarking since it makes strong assumptions
|
||||
/// about the chain state that these calls will be valid for.
|
||||
trait BenchmarkCallSigner<Call: Encode + Clone, Signer: Pair> {
|
||||
/// Signs a call together with the signed extensions of the specific runtime.
|
||||
///
|
||||
/// Only works if the current block is the genesis block since the
|
||||
/// `CheckMortality` check is mocked by using the genesis block.
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: Signer,
|
||||
) -> OpaqueExtrinsic;
|
||||
}
|
||||
|
||||
#[cfg(feature = "polkadot")]
|
||||
impl BenchmarkCallSigner<polkadot_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<polkadot_runtime::RuntimeApi, PolkadotExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: polkadot_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use polkadot_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
polkadot_runtime_common::claims::PrevalidateAttests::<runtime::Runtime>::new(),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "westend")]
|
||||
impl BenchmarkCallSigner<westend_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<westend_runtime::RuntimeApi, WestendExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: westend_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use westend_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "kusama")]
|
||||
impl BenchmarkCallSigner<kusama_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<kusama_runtime::RuntimeApi, KusamaExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: kusama_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use kusama_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rococo")]
|
||||
impl BenchmarkCallSigner<rococo_runtime::Call, sp_core::sr25519::Pair>
|
||||
for FullClient<rococo_runtime::RuntimeApi, RococoExecutorDispatch>
|
||||
{
|
||||
fn sign_call(
|
||||
&self,
|
||||
call: rococo_runtime::Call,
|
||||
nonce: u32,
|
||||
current_block: u64,
|
||||
period: u64,
|
||||
genesis: H256,
|
||||
acc: sp_core::sr25519::Pair,
|
||||
) -> OpaqueExtrinsic {
|
||||
use rococo_runtime as runtime;
|
||||
|
||||
let extra: runtime::SignedExtra = (
|
||||
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
|
||||
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
|
||||
frame_system::CheckGenesis::<runtime::Runtime>::new(),
|
||||
frame_system::CheckMortality::<runtime::Runtime>::from(
|
||||
sp_runtime::generic::Era::mortal(period, current_block),
|
||||
),
|
||||
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
|
||||
frame_system::CheckWeight::<runtime::Runtime>::new(),
|
||||
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
|
||||
);
|
||||
|
||||
let payload = runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
runtime::VERSION.spec_version,
|
||||
runtime::VERSION.transaction_version,
|
||||
genesis.clone(),
|
||||
genesis,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
);
|
||||
|
||||
let signature = payload.using_encoded(|p| acc.sign(p));
|
||||
runtime::UncheckedExtrinsic::new_signed(
|
||||
call,
|
||||
sp_runtime::AccountId32::from(acc.public()).into(),
|
||||
polkadot_core_primitives::Signature::Sr25519(signature.clone()),
|
||||
extra,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates inherent data for benchmarking Polkadot, Kusama, Westend and Rococo.
|
||||
///
|
||||
/// Not to be used outside of benchmarking since it returns mocked values.
|
||||
pub fn benchmark_inherent_data(
|
||||
header: polkadot_core_primitives::Header,
|
||||
) -> std::result::Result<sp_inherents::InherentData, sp_inherents::Error> {
|
||||
use sp_inherents::InherentDataProvider;
|
||||
let mut inherent_data = sp_inherents::InherentData::new();
|
||||
|
||||
// Assume that all runtimes have the `timestamp` pallet.
|
||||
let d = std::time::Duration::from_millis(0);
|
||||
let timestamp = sp_timestamp::InherentDataProvider::new(d.into());
|
||||
timestamp.provide_inherent_data(&mut inherent_data)?;
|
||||
|
||||
let para_data = polkadot_primitives::v2::InherentData {
|
||||
bitfields: Vec::new(),
|
||||
backed_candidates: Vec::new(),
|
||||
disputes: Vec::new(),
|
||||
parent_header: header,
|
||||
};
|
||||
|
||||
polkadot_node_core_parachains_inherent::ParachainsInherentDataProvider::from_data(para_data)
|
||||
.provide_inherent_data(&mut inherent_data)?;
|
||||
|
||||
Ok(inherent_data)
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ use runtime_parachains::{
|
||||
};
|
||||
|
||||
pub use frame_system::Call as SystemCall;
|
||||
pub use pallet_balances::Call as BalancesCall;
|
||||
|
||||
/// Constant values used within the runtime.
|
||||
use rococo_runtime_constants::{currency::*, fee::*, time::*};
|
||||
|
||||
@@ -76,6 +76,7 @@ use sp_version::NativeVersion;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
pub use frame_system::Call as SystemCall;
|
||||
pub use pallet_balances::Call as BalancesCall;
|
||||
pub use pallet_election_provider_multi_phase::Call as EPMCall;
|
||||
#[cfg(feature = "std")]
|
||||
pub use pallet_staking::StakerStatus;
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
// Copyright 2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Unix only since it uses signals.
|
||||
#![cfg(unix)]
|
||||
|
||||
use assert_cmd::cargo::cargo_bin;
|
||||
use nix::{
|
||||
sys::signal::{kill, Signal::SIGINT},
|
||||
unistd::Pid,
|
||||
};
|
||||
use std::{
|
||||
path::Path,
|
||||
process::{self, Command},
|
||||
result::Result,
|
||||
time::Duration,
|
||||
};
|
||||
use tempfile::tempdir;
|
||||
|
||||
pub mod common;
|
||||
|
||||
static RUNTIMES: [&'static str; 3] = ["polkadot", "kusama", "westend"];
|
||||
|
||||
/// `benchmark block` works for all dev runtimes using the wasm executor.
|
||||
#[tokio::test]
|
||||
async fn benchmark_block_works() {
|
||||
for runtime in RUNTIMES {
|
||||
let tmp_dir = tempdir().expect("could not create a temp dir");
|
||||
let base_path = tmp_dir.path();
|
||||
let runtime = format!("{}-dev", runtime);
|
||||
|
||||
// Build a chain with a single block.
|
||||
build_chain(&runtime, base_path).await.unwrap();
|
||||
// Benchmark the that one.
|
||||
benchmark_block(&runtime, base_path, 1).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a chain with one block for the given runtime and base path.
|
||||
async fn build_chain(runtime: &str, base_path: &Path) -> Result<(), String> {
|
||||
let mut cmd = Command::new(cargo_bin("polkadot"))
|
||||
.stdout(process::Stdio::piped())
|
||||
.stderr(process::Stdio::piped())
|
||||
.args(["--chain", &runtime, "--force-authoring", "--alice"])
|
||||
.arg("-d")
|
||||
.arg(base_path)
|
||||
.arg("--port")
|
||||
.arg("33034")
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap());
|
||||
|
||||
// Wait for the chain to produce one block.
|
||||
let ok = common::wait_n_finalized_blocks(1, Duration::from_secs(60), &ws_url).await;
|
||||
// Send SIGINT to node.
|
||||
kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap();
|
||||
// Wait for the node to handle it and exit.
|
||||
assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default());
|
||||
|
||||
ok.map_err(|e| format!("Node did not build the chain: {:?}", e))
|
||||
}
|
||||
|
||||
/// Benchmarks the given block with the wasm executor.
|
||||
fn benchmark_block(runtime: &str, base_path: &Path, block: u32) -> Result<(), String> {
|
||||
// Invoke `benchmark block` with all options to make sure that they are valid.
|
||||
let status = Command::new(cargo_bin("polkadot"))
|
||||
.args(["benchmark", "block", "--chain", &runtime])
|
||||
.arg("-d")
|
||||
.arg(base_path)
|
||||
.args(["--from", &block.to_string(), "--to", &block.to_string()])
|
||||
.args(["--repeat", "1"])
|
||||
.args(["--execution", "wasm", "--wasm-execution", "compiled"])
|
||||
.status()
|
||||
.map_err(|e| format!("command failed: {:?}", e))?;
|
||||
|
||||
if !status.success() {
|
||||
return Err("Command failed".into())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
// Copyright 2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use assert_cmd::cargo::cargo_bin;
|
||||
use std::{process::Command, result::Result};
|
||||
use tempfile::tempdir;
|
||||
|
||||
static RUNTIMES: [&'static str; 3] = ["polkadot", "kusama", "westend"];
|
||||
|
||||
/// `benchmark overhead` works for all dev runtimes.
|
||||
#[test]
|
||||
fn benchmark_overhead_works() {
|
||||
for runtime in RUNTIMES {
|
||||
let runtime = format!("{}-dev", runtime);
|
||||
assert!(benchmark_overhead(runtime).is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
/// `benchmark overhead` rejects all non-dev runtimes.
|
||||
#[test]
|
||||
fn benchmark_overhead_rejects_non_dev_runtimes() {
|
||||
for runtime in RUNTIMES {
|
||||
assert!(benchmark_overhead(runtime.into()).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
fn benchmark_overhead(runtime: String) -> Result<(), String> {
|
||||
let tmp_dir = tempdir().expect("could not create a temp dir");
|
||||
let base_path = tmp_dir.path();
|
||||
|
||||
// Invoke `benchmark overhead` with all options to make sure that they are valid.
|
||||
let status = Command::new(cargo_bin("polkadot"))
|
||||
.args(["benchmark", "overhead", "--chain", &runtime])
|
||||
.arg("-d")
|
||||
.arg(base_path)
|
||||
.arg("--weight-path")
|
||||
.arg(base_path)
|
||||
.args(["--warmup", "5", "--repeat", "5"])
|
||||
.args(["--add", "100", "--mul", "1.2", "--metric", "p75"])
|
||||
// Only put 5 extrinsics into the block otherwise it takes forever to build it
|
||||
// especially for a non-release builds.
|
||||
.args(["--max-ext-per-block", "5"])
|
||||
.status()
|
||||
.map_err(|e| format!("command failed: {:?}", e))?;
|
||||
|
||||
if !status.success() {
|
||||
return Err("Command failed".into())
|
||||
}
|
||||
|
||||
// Weight files have been created.
|
||||
assert!(base_path.join("block_weights.rs").exists());
|
||||
assert!(base_path.join("extrinsic_weights.rs").exists());
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user