From cb6e8cbe507cb551b6e678fea35ef702e7dec3ad Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Tue, 6 Aug 2024 11:01:16 +0200 Subject: [PATCH] collator hardware benchmark (#1315) --- Cargo.lock | 1 + Cargo.toml | 1 + bin/collator/Cargo.toml | 6 +-- bin/collator/src/cli.rs | 10 +++++ bin/collator/src/command.rs | 10 ++++- bin/collator/src/parachain/service.rs | 53 ++++++++++++++++++++++++++- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aacd4cbd09..e9145532e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -682,6 +682,7 @@ dependencies = [ "sc-offchain", "sc-rpc", "sc-service", + "sc-sysinfo", "sc-telemetry", "sc-tracing", "sc-transaction-pool", diff --git a/Cargo.toml b/Cargo.toml index b00ca59d0c..87562d6292 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,6 +134,7 @@ sc-network-sync = { git = "https://github.com/paritytech/polkadot-sdk", branch = sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } sc-rpc = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } sc-service = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } +sc-sysinfo = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } sc-telemetry = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } sc-tracing = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } sc-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } diff --git a/bin/collator/Cargo.toml b/bin/collator/Cargo.toml index 0702b44841..1e876683f6 100644 --- a/bin/collator/Cargo.toml +++ b/bin/collator/Cargo.toml @@ -63,6 +63,7 @@ sc-network-sync = { workspace = true } sc-offchain = { workspace = true } sc-rpc = { workspace = true } sc-service = { workspace = true } +sc-sysinfo = { workspace = true } sc-telemetry = { workspace = true } sc-tracing = { workspace = true } sc-transaction-pool = { workspace = true } @@ -132,7 +133,7 @@ polkadot-service = { workspace = true } # benchmark dependencies frame-benchmarking = { workspace = true, features = ["std"] } -frame-benchmarking-cli = { workspace = true, optional = true } +frame-benchmarking-cli = { workspace = true } polkadot-runtime-common = { workspace = true, features = ["std"], optional = true } # try-runtime @@ -157,7 +158,6 @@ substrate-build-script-utils = { workspace = true } [features] default = ["sc-cli", "polkadot-cli", "sc-service", "sc-service/rocksdb"] runtime-benchmarks = [ - "frame-benchmarking-cli", "local-runtime/runtime-benchmarks", "shibuya-runtime/runtime-benchmarks", "shiden-runtime/runtime-benchmarks", @@ -168,7 +168,7 @@ runtime-benchmarks = [ "polkadot-runtime-common", "astar-primitives/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", - "frame-benchmarking-cli?/runtime-benchmarks", + "frame-benchmarking-cli/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", "pallet-evm/runtime-benchmarks", diff --git a/bin/collator/src/cli.rs b/bin/collator/src/cli.rs index aa2dd9a29a..50b318c93c 100644 --- a/bin/collator/src/cli.rs +++ b/bin/collator/src/cli.rs @@ -53,6 +53,16 @@ pub struct Cli { /// Proposer's soft deadline in percents of block size #[clap(long, default_value = "50")] pub proposer_soft_deadline_percent: u8, + + /// Disable automatic hardware benchmarks. + /// + /// By default these benchmarks are automatically ran at startup and measure + /// the CPU speed, the memory bandwidth and the disk speed. + /// + /// The results are then printed out in the logs, and also sent as part of + /// telemetry, if telemetry is enabled. + #[arg(long)] + pub no_hardware_benchmarks: bool, } /// Possible subcommands of the main binary. diff --git a/bin/collator/src/command.rs b/bin/collator/src/command.rs index 6aefb516f8..ebda5c802f 100644 --- a/bin/collator/src/command.rs +++ b/bin/collator/src/command.rs @@ -835,12 +835,20 @@ pub fn run() -> Result<()> { } ); + let hwbench = (!cli.no_hardware_benchmarks) + .then_some(config.database.path().map(|database_path| { + let _ = std::fs::create_dir_all(database_path); + sc_sysinfo::gather_hwbench(Some(database_path)) + })) + .flatten(); + let additional_config = AdditionalConfig { #[cfg(feature = "evm-tracing")] evm_tracing_config: evm_tracing_config, enable_evm_rpc: cli.enable_evm_rpc, proposer_block_size_limit: cli.proposer_block_size_limit, - proposer_soft_deadline_percent: cli.proposer_soft_deadline_percent + proposer_soft_deadline_percent: cli.proposer_soft_deadline_percent, + hwbench, }; if config.chain_spec.is_astar() { diff --git a/bin/collator/src/parachain/service.rs b/bin/collator/src/parachain/service.rs index c88243cb2c..14547ea4bc 100644 --- a/bin/collator/src/parachain/service.rs +++ b/bin/collator/src/parachain/service.rs @@ -278,6 +278,7 @@ async fn build_relay_chain_interface( telemetry_worker_handle: Option, task_manager: &mut TaskManager, collator_options: CollatorOptions, + hwbench: Option, ) -> RelayChainResult<( Arc<(dyn RelayChainInterface + 'static)>, Option, @@ -293,7 +294,7 @@ async fn build_relay_chain_interface( parachain_config, telemetry_worker_handle, task_manager, - None, + hwbench, ) } } @@ -394,6 +395,7 @@ where telemetry_worker_handle, &mut task_manager, collator_options.clone(), + additional_config.hwbench.clone(), ) .await .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; @@ -531,6 +533,22 @@ where telemetry: telemetry.as_mut(), })?; + if let Some(hwbench) = additional_config.hwbench.clone() { + sc_sysinfo::print_hwbench(&hwbench); + if is_authority { + warn_if_slow_hardware(&hwbench); + } + + if let Some(ref mut telemetry) = telemetry { + let telemetry_handle = telemetry.handle(); + task_manager.spawn_handle().spawn( + "telemetry_hwbench", + None, + sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), + ); + } + } + let announce_block = { let sync_service = sync_service.clone(); Arc::new(move |hash, data| sync_service.announce_block(hash, data)) @@ -596,6 +614,9 @@ pub struct AdditionalConfig { /// Soft deadline limit used by `Proposer` pub proposer_soft_deadline_percent: u8, + + /// Hardware benchmarks score + pub hwbench: Option, } /// Start a node with the given parachain `Configuration` and relay chain `Configuration`. @@ -697,6 +718,7 @@ where telemetry_worker_handle, &mut task_manager, collator_options.clone(), + additional_config.hwbench.clone(), ) .await .map_err(|e| sc_service::Error::Application(Box::new(e) as Box<_>))?; @@ -866,6 +888,22 @@ where telemetry: telemetry.as_mut(), })?; + if let Some(hwbench) = additional_config.hwbench.clone() { + sc_sysinfo::print_hwbench(&hwbench); + if is_authority { + warn_if_slow_hardware(&hwbench); + } + + if let Some(ref mut telemetry) = telemetry { + let telemetry_handle = telemetry.handle(); + task_manager.spawn_handle().spawn( + "telemetry_hwbench", + None, + sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), + ); + } + } + let announce_block = { let sync_service = sync_service.clone(); Arc::new(move |hash, data| sync_service.announce_block(hash, data)) @@ -1374,3 +1412,16 @@ pub async fn start_shibuya_node( ) .await } + +/// Checks that the hardware meets the requirements and print a warning otherwise. +fn warn_if_slow_hardware(hwbench: &sc_sysinfo::HwBench) { + // Polkadot para-chains should generally use these requirements to ensure that the relay-chain + // will not take longer than expected to import its blocks. + if let Err(err) = frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE.check_hardware(hwbench) { + log::warn!( + "⚠️ The hardware does not meet the minimal requirements {} for role 'Authority' find out more at:\n\ + https://wiki.polkadot.network/docs/maintain-guides-how-to-validate-polkadot#reference-hardware", + err + ); + } +}