// Copyright (C) Parity Technologies (UK) Ltd. // This file is part of Pezkuwi. // Pezkuwi 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. // Pezkuwi 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 Pezkuwi. If not, see . //! Code related to benchmarking a node. use pezkuwi_primitives::AccountId; use pezsc_client_api::UsageProvider; use pezsp_keyring::Sr25519Keyring; use pezsp_runtime::OpaqueExtrinsic; use crate::*; macro_rules! identify_chain { ( $chain:expr, $nonce:ident, $current_block:ident, $period:ident, $genesis:ident, $signer:ident, $generic_code:expr $(,)* ) => { match $chain { Chain::Pezkuwi => Err("Pezkuwi runtimes are currently not supported"), Chain::Kusama => Err("Kusama runtimes are currently not supported"), Chain::Pezkuwichain => { #[cfg(feature = "pezkuwichain-native")] { use pezkuwichain_runtime as runtime; let call = $generic_code; Ok(pezkuwichain_sign_call( call, $nonce, $current_block, $period, $genesis, $signer, )) } #[cfg(not(feature = "pezkuwichain-native"))] { Err("`pezkuwichain-native` feature not enabled") } }, Chain::Zagros => { #[cfg(feature = "zagros-native")] { use zagros_runtime as runtime; let call = $generic_code; Ok(zagros_sign_call(call, $nonce, $current_block, $period, $genesis, $signer)) } #[cfg(not(feature = "zagros-native"))] { Err("`zagros-native` feature not enabled") } }, Chain::Unknown => { let _ = $nonce; let _ = $current_block; let _ = $period; let _ = $genesis; let _ = $signer; Err("Unknown chain") }, } }; } /// Generates `Balances::TransferKeepAlive` extrinsics for the benchmarks. /// /// Note: Should only be used for benchmarking. pub struct TransferKeepAliveBuilder { client: Arc, dest: AccountId, chain: Chain, } impl TransferKeepAliveBuilder { /// Creates a new [`Self`] from the given client and the arguments for the extrinsics. pub fn new(client: Arc, dest: AccountId, chain: Chain) -> Self { Self { client, dest, chain } } } impl pezframe_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder { fn pezpallet(&self) -> &str { "balances" } fn extrinsic(&self) -> &str { "transfer_keep_alive" } fn build(&self, nonce: u32) -> std::result::Result { let signer = Sr25519Keyring::Bob.pair(); // We apply the extrinsic directly, so let's take some random period. let period = 128; let genesis = self.client.usage_info().chain.best_hash; let current_block = 0; let _dest = self.dest.clone(); identify_chain! { self.chain, nonce, current_block, period, genesis, signer, { runtime::RuntimeCall::Balances(runtime::BalancesCall::transfer_keep_alive { dest: _dest.into(), value: runtime::ExistentialDeposit::get(), }) }, } } } #[cfg(feature = "zagros-native")] fn zagros_sign_call( call: zagros_runtime::RuntimeCall, nonce: u32, current_block: u64, period: u64, genesis: pezsp_core::H256, acc: pezsp_core::sr25519::Pair, ) -> OpaqueExtrinsic { use codec::Encode; use pezsp_core::Pair; use zagros_runtime as runtime; let tx_ext: runtime::TxExtension = ( pezframe_system::AuthorizeCall::::new(), pezframe_system::CheckNonZeroSender::::new(), pezframe_system::CheckSpecVersion::::new(), pezframe_system::CheckTxVersion::::new(), pezframe_system::CheckGenesis::::new(), pezframe_system::CheckMortality::::from(pezsp_runtime::generic::Era::mortal( period, current_block, )), pezframe_system::CheckNonce::::from(nonce), pezframe_system::CheckWeight::::new(), pezpallet_transaction_payment::ChargeTransactionPayment::::from(0), pezframe_metadata_hash_extension::CheckMetadataHash::::new(false), pezframe_system::WeightReclaim::::new(), ) .into(); let payload = runtime::SignedPayload::from_raw( call.clone(), tx_ext.clone(), ( (), (), runtime::VERSION.spec_version, runtime::VERSION.transaction_version, genesis, genesis, (), (), (), None, (), ), ); let signature = payload.using_encoded(|p| acc.sign(p)); runtime::UncheckedExtrinsic::new_signed( call, pezsp_runtime::AccountId32::from(acc.public()).into(), pezkuwi_core_primitives::Signature::Sr25519(signature), tx_ext, ) .into() } #[cfg(feature = "pezkuwichain-native")] fn pezkuwichain_sign_call( call: pezkuwichain_runtime::RuntimeCall, nonce: u32, current_block: u64, period: u64, genesis: pezsp_core::H256, acc: pezsp_core::sr25519::Pair, ) -> OpaqueExtrinsic { use codec::Encode; use pezkuwichain_runtime as runtime; use pezsp_core::Pair; let tx_ext: runtime::TxExtension = ( pezframe_system::AuthorizeCall::::new(), pezframe_system::CheckNonZeroSender::::new(), pezframe_system::CheckSpecVersion::::new(), pezframe_system::CheckTxVersion::::new(), pezframe_system::CheckGenesis::::new(), pezframe_system::CheckMortality::::from(pezsp_runtime::generic::Era::mortal( period, current_block, )), pezframe_system::CheckNonce::::from(nonce), pezframe_system::CheckWeight::::new(), pezpallet_transaction_payment::ChargeTransactionPayment::::from(0), pezframe_metadata_hash_extension::CheckMetadataHash::::new(false), pezframe_system::WeightReclaim::::new(), ) .into(); let payload = runtime::SignedPayload::from_raw( call.clone(), tx_ext.clone(), ( (), (), runtime::VERSION.spec_version, runtime::VERSION.transaction_version, genesis, genesis, (), (), (), None, (), ), ); let signature = payload.using_encoded(|p| acc.sign(p)); runtime::UncheckedExtrinsic::new_signed( call, pezsp_runtime::AccountId32::from(acc.public()).into(), pezkuwi_core_primitives::Signature::Sr25519(signature), tx_ext, ) .into() } /// Generates inherent data for benchmarking Pezkuwi, Kusama, Zagros and Pezkuwichain. /// /// Not to be used outside of benchmarking since it returns mocked values. pub fn benchmark_inherent_data( header: pezkuwi_core_primitives::Header, ) -> std::result::Result { use pezsp_inherents::InherentDataProvider; let mut inherent_data = pezsp_inherents::InherentData::new(); // Assume that all runtimes have the `timestamp` pezpallet. let d = std::time::Duration::from_millis(0); let timestamp = pezsp_timestamp::InherentDataProvider::new(d.into()); futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data))?; let para_data = pezkuwi_primitives::InherentData { bitfields: Vec::new(), backed_candidates: Vec::new(), disputes: Vec::new(), parent_header: header, }; inherent_data.put_data(pezkuwi_primitives::TEYRCHAINS_INHERENT_IDENTIFIER, ¶_data)?; Ok(inherent_data) }