diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 3ea5f7f44..388f03f8c 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -109,8 +109,10 @@ jobs: - name: Check targets are installed correctly run: rustup target list --installed + # Update to `--profile=production` after uplifting to latest polkadot-sdk (make sure to test it works with + # the specified toolchain first) - name: Install frame-omni bencher tool - run: cargo install frame-omni-bencher --profile=production --locked + run: cargo install frame-omni-bencher --profile=release --locked - name: Execute benchmarking run: | diff --git a/bin/collator/src/benchmarking.rs b/bin/collator/src/benchmarking.rs deleted file mode 100644 index e3c3891c1..000000000 --- a/bin/collator/src/benchmarking.rs +++ /dev/null @@ -1,522 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar 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. - -// Astar 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 Astar. If not, see . - -use crate::parachain::service::ParachainExecutor; -use astar_primitives::{AccountId, Balance, Block}; -use cumulus_primitives_core::PersistedValidationData; -use cumulus_primitives_parachain_inherent::{ParachainInherentData, INHERENT_IDENTIFIER}; -use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder; -use parity_scale_codec::Encode; -use polkadot_runtime_common::BlockHashCount; -use sc_service::TFullClient; -use sp_api::ConstructRuntimeApi; -use sp_core::{Pair, H256}; -use sp_keyring::Sr25519Keyring; -use sp_runtime::OpaqueExtrinsic; -use std::sync::Arc; - -/// Generates `System::Remark` extrinsics for the benchmarks. -/// -/// Note: Should only be used for benchmarking. -pub struct RemarkBuilder -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - client: Arc>, -} - -impl RemarkBuilder -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - /// Creates a new [`Self`] from the given client. - pub fn new(client: Arc>) -> Self { - Self { client } - } -} - -impl frame_benchmarking_cli::ExtrinsicBuilder for RemarkBuilder -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn pallet(&self) -> &str { - "system" - } - - fn extrinsic(&self) -> &str { - "remark" - } - - fn build(&self, nonce: u32) -> std::result::Result { - with_runtime! { - self.client.as_ref(), { - use runtime::{RuntimeCall, SystemCall}; - use sc_client_api::UsageProvider; - - let call = RuntimeCall::System(SystemCall::remark { remark: vec![] }); - let signer = Sr25519Keyring::Bob.pair(); - let period = BlockHashCount::get() - .checked_next_power_of_two() - .map(|c| c / 2) - .unwrap_or(2) as u64; - let genesis = self.client.usage_info().chain.best_hash; - - Ok(self.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 -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - client: Arc>, - dest: AccountId, - value: Balance, -} - -impl TransferKeepAliveBuilder -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - /// Creates a new [`Self`] from the given client. - pub fn new( - client: Arc>, - dest: AccountId, - value: Balance, - ) -> Self { - Self { - client, - dest, - value, - } - } -} - -impl frame_benchmarking_cli::ExtrinsicBuilder for TransferKeepAliveBuilder -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn pallet(&self) -> &str { - "balances" - } - - fn extrinsic(&self) -> &str { - "transfer_keep_alive" - } - - fn build(&self, nonce: u32) -> std::result::Result { - with_runtime! { - self.client.as_ref(), { - use runtime::{RuntimeCall, BalancesCall}; - use sc_client_api::UsageProvider; - - let call = RuntimeCall::Balances(BalancesCall::transfer_keep_alive { - dest: self.dest.clone().into(), - value: self.value.into(), - }); - let signer = Sr25519Keyring::Bob.pair(); - - let period = BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; - let genesis = self.client.usage_info().chain.best_hash; - - Ok(self.client.sign_call(call, nonce, 0, period, genesis, signer)) - } - } - } -} - -/// Helper trait to implement [`frame_benchmarking_cli::ExtrinsicBuilder`]. -/// -/// Should only be used for benchmarking. -trait BenchmarkCallSigner { - /// 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: RuntimeCall, - nonce: u32, - current_block: u64, - period: u64, - genesis: H256, - acc: Signer, - ) -> OpaqueExtrinsic; -} - -impl BenchmarkCallSigner - for TFullClient -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn sign_call( - &self, - call: local_runtime::RuntimeCall, - nonce: u32, - current_block: u64, - period: u64, - genesis: H256, - acc: sp_core::sr25519::Pair, - ) -> OpaqueExtrinsic { - use local_runtime as runtime; - - let extra: runtime::SignedExtra = ( - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from( - sp_runtime::generic::Era::mortal(period, current_block), - ), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - frame_metadata_hash_extension::CheckMetadataHash::::new(false), - ); - - let payload = runtime::SignedPayload::from_raw( - call.clone(), - extra.clone(), - ( - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis.clone(), - genesis, - (), - (), - (), - None, - ), - ); - - let signature = payload.using_encoded(|p| acc.sign(p)); - runtime::UncheckedExtrinsic::new_signed( - call, - sp_runtime::AccountId32::from(acc.public()).into(), - runtime::Signature::Sr25519(signature.clone()), - extra, - ) - .into() - } -} - -impl BenchmarkCallSigner - for TFullClient -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn sign_call( - &self, - call: astar_runtime::RuntimeCall, - nonce: u32, - current_block: u64, - period: u64, - genesis: H256, - acc: sp_core::sr25519::Pair, - ) -> OpaqueExtrinsic { - use astar_runtime as runtime; - - let extra: runtime::SignedExtra = ( - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from( - sp_runtime::generic::Era::mortal(period, current_block), - ), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - frame_metadata_hash_extension::CheckMetadataHash::::new(false), - ); - - let payload = runtime::SignedPayload::from_raw( - call.clone(), - extra.clone(), - ( - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis.clone(), - genesis, - (), - (), - (), - None, - ), - ); - - let signature = payload.using_encoded(|p| acc.sign(p)); - runtime::UncheckedExtrinsic::new_signed( - call, - sp_runtime::AccountId32::from(acc.public()).into(), - runtime::Signature::Sr25519(signature.clone()), - extra, - ) - .into() - } -} - -impl BenchmarkCallSigner - for TFullClient -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn sign_call( - &self, - call: shiden_runtime::RuntimeCall, - nonce: u32, - current_block: u64, - period: u64, - genesis: H256, - acc: sp_core::sr25519::Pair, - ) -> OpaqueExtrinsic { - use shiden_runtime as runtime; - - let extra: runtime::SignedExtra = ( - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from( - sp_runtime::generic::Era::mortal(period, current_block), - ), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - frame_metadata_hash_extension::CheckMetadataHash::::new(false), - ); - - let payload = runtime::SignedPayload::from_raw( - call.clone(), - extra.clone(), - ( - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis.clone(), - genesis, - (), - (), - (), - None, - ), - ); - - let signature = payload.using_encoded(|p| acc.sign(p)); - runtime::UncheckedExtrinsic::new_signed( - call, - sp_runtime::AccountId32::from(acc.public()).into(), - runtime::Signature::Sr25519(signature.clone()), - extra, - ) - .into() - } -} - -impl BenchmarkCallSigner - for TFullClient -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn sign_call( - &self, - call: shibuya_runtime::RuntimeCall, - nonce: u32, - current_block: u64, - period: u64, - genesis: H256, - acc: sp_core::sr25519::Pair, - ) -> OpaqueExtrinsic { - use shibuya_runtime as runtime; - - let extra: runtime::SignedExtra = ( - frame_system::CheckSpecVersion::::new(), - frame_system::CheckTxVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckMortality::::from( - sp_runtime::generic::Era::mortal(period, current_block), - ), - frame_system::CheckNonce::::from(nonce), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(0), - frame_metadata_hash_extension::CheckMetadataHash::::new(false), - ); - - let payload = runtime::SignedPayload::from_raw( - call.clone(), - extra.clone(), - ( - runtime::VERSION.spec_version, - runtime::VERSION.transaction_version, - genesis.clone(), - genesis, - (), - (), - (), - None, - ), - ); - - let signature = payload.using_encoded(|p| acc.sign(p)); - runtime::UncheckedExtrinsic::new_signed( - call, - sp_runtime::AccountId32::from(acc.public()).into(), - runtime::Signature::Sr25519(signature.clone()), - extra, - ) - .into() - } -} - -/// 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 TFullClient -where - RuntimeApi: ConstructRuntimeApi> - + Send - + Sync - + 'static, -{ - fn existential_deposit(&self) -> Balance { - with_runtime! { - self, - runtime::ExistentialDeposit::get() - } - } -} - -/// Generates inherent data for benchmarking local node. -/// -/// Not to be used outside of benchmarking since it returns mocked values. -pub fn local_benchmark_inherent_data( -) -> std::result::Result { - 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()); - futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data))?; - - Ok(inherent_data) -} - -/// Generates inherent data for benchmarking Astar, Shiden and Shibuya. -/// -/// Not to be used outside of benchmarking since it returns mocked values. -pub fn para_benchmark_inherent_data( -) -> std::result::Result { - 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()); - futures::executor::block_on(timestamp.provide_inherent_data(&mut inherent_data))?; - - let sproof_builder = RelayStateSproofBuilder::default(); - let (relay_parent_storage_root, relay_chain_state) = sproof_builder.into_state_root_and_proof(); - // `relay_parent_number` should be bigger than 0 for benchmarking. - // It is mocked value, any number except 0 is valid. - let validation_data = PersistedValidationData { - relay_parent_number: 1, - relay_parent_storage_root, - ..Default::default() - }; - - // Parachain blocks needs to include ParachainInherentData, otherwise block is invalid. - let para_data = ParachainInherentData { - validation_data, - relay_chain_state, - downward_messages: Default::default(), - horizontal_messages: Default::default(), - }; - - inherent_data.put_data(INHERENT_IDENTIFIER, ¶_data)?; - - Ok(inherent_data) -} - -/// Interpret client's native runtime version name (at genesis block). -/// This is valid only for benchmarking, since genesis block is alreways refered to. -macro_rules! with_runtime { - { - $client:expr, - $code:expr - } => { - match $client.runtime_version_at($client.chain_info().genesis_hash).unwrap().spec_name.to_string().as_str() { - "astar" => { - #[allow(unused_imports)] - use astar_runtime as runtime; - $code - }, - "shiden" => { - #[allow(unused_imports)] - use shiden_runtime as runtime; - $code - }, - "shibuya" => { - #[allow(unused_imports)] - use shibuya_runtime as runtime; - $code - }, - _ => { - #[allow(unused_imports)] - use local_runtime as runtime; - $code - } - } - } -} - -use with_runtime; diff --git a/bin/collator/src/command.rs b/bin/collator/src/command.rs index 2ddfca07b..a25570a57 100644 --- a/bin/collator/src/command.rs +++ b/bin/collator/src/command.rs @@ -24,8 +24,6 @@ use crate::{ }; use cumulus_primitives_core::ParaId; use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; -#[cfg(feature = "runtime-benchmarks")] -use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory}; use log::info; use sc_cli::{ ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, @@ -326,8 +324,7 @@ pub fn run() -> Result<()> { Some(Subcommand::Vanity(cmd)) => cmd.run(), #[cfg(feature = "runtime-benchmarks")] Some(Subcommand::Benchmark(cmd)) => { - use crate::benchmarking::*; - use sp_keyring::Sr25519Keyring; + use frame_benchmarking_cli::BenchmarkCmd; use sp_runtime::traits::HashingFor; let runner = cli.create_runner(cmd)?; @@ -394,81 +391,11 @@ pub fn run() -> Result<()> { }) } } - BenchmarkCmd::Overhead(cmd) => { - let chain_name = chain_spec.name().to_string(); - if chain_spec.is_dev() { - runner.sync_run(|config| { - let params = local::new_partial(&config, &rpc_config)?; - let ext_builder = RemarkBuilder::new(params.client.clone()); - let inherent_data = local_benchmark_inherent_data() - .map_err(|e| format!("generating inherent data: {:?}", e))?; - - cmd.run( - chain_name, - params.client, - inherent_data, - Vec::new(), - &ext_builder, - true, - ) - }) - } else { - runner.sync_run(|config| { - let params = parachain::new_partial(&config, &rpc_config)?; - - let ext_builder = RemarkBuilder::new(params.client.clone()); - let inherent_data = para_benchmark_inherent_data() - .map_err(|e| format!("generating inherent data: {:?}", e))?; - - cmd.run( - chain_name, - params.client, - inherent_data, - Vec::new(), - &ext_builder, - true, - ) - }) - } + BenchmarkCmd::Overhead(_) => { + todo!("Overhead benchmarking is not supported. Use 'frame-omni-bencher' tool instead."); } - BenchmarkCmd::Extrinsic(cmd) => { - if chain_spec.is_dev() { - runner.sync_run(|config| { - let params = local::new_partial(&config, &rpc_config)?; - let remark_builder = RemarkBuilder::new(params.client.clone()); - let tka_builder = TransferKeepAliveBuilder::new( - params.client.clone(), - Sr25519Keyring::Alice.to_account_id(), - params.client.existential_deposit(), - ); - let ext_factory = ExtrinsicFactory(vec![ - Box::new(remark_builder), - Box::new(tka_builder), - ]); - let inherent_data = local_benchmark_inherent_data() - .map_err(|e| format!("generating inherent data: {:?}", e))?; - - cmd.run(params.client, inherent_data, Vec::new(), &ext_factory) - }) - } else { - runner.sync_run(|config| { - let params = parachain::new_partial(&config, &rpc_config)?; - let remark_builder = RemarkBuilder::new(params.client.clone()); - let tka_builder = TransferKeepAliveBuilder::new( - params.client.clone(), - Sr25519Keyring::Alice.to_account_id(), - params.client.existential_deposit(), - ); - let ext_factory = ExtrinsicFactory(vec![ - Box::new(remark_builder), - Box::new(tka_builder), - ]); - let inherent_data = para_benchmark_inherent_data() - .map_err(|e| format!("generating inherent data: {:?}", e))?; - - cmd.run(params.client, inherent_data, Vec::new(), &ext_factory) - }) - } + BenchmarkCmd::Extrinsic(_) => { + todo!("Extrinsic benchmarking is not supported."); } BenchmarkCmd::Machine(cmd) => { runner.sync_run(|config| cmd.run(&config, SUBSTRATE_REFERENCE_HARDWARE.clone())) diff --git a/bin/collator/src/lib.rs b/bin/collator/src/lib.rs index d6706cbf8..f5abe7142 100644 --- a/bin/collator/src/lib.rs +++ b/bin/collator/src/lib.rs @@ -26,9 +26,6 @@ pub mod local; /// Parachain node support. pub mod parachain; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - mod cli; mod command; mod evm_tracing_types;