Skip to content

Commit a709768

Browse files
authored
[subsystem-benchmarks] Add statement-distribution benchmarks (#3863)
Fixes #3748 Adds a subsystem benchmark for statements-distribution subsystem. Results in CI (reference hw): ``` $ cargo bench -p polkadot-statement-distribution --bench statement-distribution-regression-bench --features subsystem-benchmarks [Sent to peers] standart_deviation 0.07% [Received from peers] standart_deviation 0.00% [statement-distribution] standart_deviation 0.97% [test-environment] standart_deviation 1.03% Network usage, KiB total per block Received from peers 1088.0000 108.8000 Sent to peers 1238.1800 123.8180 CPU usage, seconds total per block statement-distribution 0.3897 0.0390 test-environment 0.4715 0.0472 ```
1 parent 70dd67a commit a709768

File tree

22 files changed

+1480
-47
lines changed

22 files changed

+1480
-47
lines changed

.gitlab/pipeline/publish.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ publish-subsystem-benchmarks:
7676
artifacts: true
7777
- job: subsystem-benchmark-approval-voting
7878
artifacts: true
79+
- job: subsystem-benchmark-statement-distribution
80+
artifacts: true
7981
- job: publish-rustdoc
8082
artifacts: false
8183
script:
@@ -119,6 +121,8 @@ trigger_workflow:
119121
artifacts: true
120122
- job: subsystem-benchmark-approval-voting
121123
artifacts: true
124+
- job: subsystem-benchmark-statement-distribution
125+
artifacts: true
122126
script:
123127
- echo "Triggering workflow"
124128
- >

.gitlab/pipeline/test.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,10 @@ subsystem-benchmark-approval-voting:
630630
script:
631631
- cargo bench -p polkadot-node-core-approval-voting --bench approval-voting-regression-bench --features subsystem-benchmarks
632632
allow_failure: true
633+
634+
subsystem-benchmark-statement-distribution:
635+
extends:
636+
- .subsystem-benchmark-template
637+
script:
638+
- cargo bench -p polkadot-statement-distribution --bench statement-distribution-regression-bench --features subsystem-benchmarks
639+
allow_failure: true

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

polkadot/node/network/statement-distribution/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,13 @@ sc-network = { path = "../../../../substrate/client/network" }
4242
futures-timer = "3.0.2"
4343
polkadot-primitives-test-helpers = { path = "../../../primitives/test-helpers" }
4444
rand_chacha = "0.3"
45+
polkadot-subsystem-bench = { path = "../../subsystem-bench" }
46+
47+
[[bench]]
48+
name = "statement-distribution-regression-bench"
49+
path = "benches/statement-distribution-regression-bench.rs"
50+
harness = false
51+
required-features = ["subsystem-benchmarks"]
52+
53+
[features]
54+
subsystem-benchmarks = []
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (C) Parity Technologies (UK) Ltd.
2+
// This file is part of Polkadot.
3+
4+
// Polkadot is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Polkadot is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16+
17+
//! statement-distribution regression tests
18+
//!
19+
//! Statement distribution benchmark based on Kusama parameters and scale.
20+
21+
use polkadot_subsystem_bench::{
22+
configuration::TestConfiguration,
23+
statement::{benchmark_statement_distribution, prepare_test, TestState},
24+
usage::BenchmarkUsage,
25+
utils::save_to_file,
26+
};
27+
use std::io::Write;
28+
29+
const BENCH_COUNT: usize = 50;
30+
31+
fn main() -> Result<(), String> {
32+
let mut messages = vec![];
33+
let mut config = TestConfiguration::default();
34+
config.n_cores = 100;
35+
config.n_validators = 500;
36+
config.num_blocks = 10;
37+
config.connectivity = 100;
38+
config.generate_pov_sizes();
39+
let state = TestState::new(&config);
40+
41+
println!("Benchmarking...");
42+
let usages: Vec<BenchmarkUsage> = (0..BENCH_COUNT)
43+
.map(|n| {
44+
print!("\r[{}{}]", "#".repeat(n), "_".repeat(BENCH_COUNT - n));
45+
std::io::stdout().flush().unwrap();
46+
let (mut env, _cfgs) = prepare_test(&state, false);
47+
env.runtime().block_on(benchmark_statement_distribution(
48+
"statement-distribution",
49+
&mut env,
50+
&state,
51+
))
52+
})
53+
.collect();
54+
println!("\rDone!{}", " ".repeat(BENCH_COUNT));
55+
56+
let average_usage = BenchmarkUsage::average(&usages);
57+
save_to_file(
58+
"charts/statement-distribution-regression-bench.json",
59+
average_usage.to_chart_json().map_err(|e| e.to_string())?,
60+
)
61+
.map_err(|e| e.to_string())?;
62+
println!("{}", average_usage);
63+
64+
// We expect no variance for received and sent
65+
// but use 0.001 because we operate with floats
66+
messages.extend(average_usage.check_network_usage(&[
67+
("Received from peers", 106.4000, 0.001),
68+
("Sent to peers", 127.9100, 0.001),
69+
]));
70+
messages.extend(average_usage.check_cpu_usage(&[("statement-distribution", 0.0390, 0.1)]));
71+
72+
if messages.is_empty() {
73+
Ok(())
74+
} else {
75+
eprintln!("{}", messages.join("\n"));
76+
Err("Regressions found".to_string())
77+
}
78+
}

polkadot/node/network/statement-distribution/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
//! This is responsible for distributing signed statements about candidate
2020
//! validity among validators.
2121
22-
#![deny(unused_crate_dependencies)]
2322
#![warn(missing_docs)]
2423

2524
use error::{log_error, FatalResult};

polkadot/node/subsystem-bench/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ polkadot-primitives = { path = "../../primitives" }
2828
polkadot-node-network-protocol = { path = "../network/protocol" }
2929
polkadot-availability-recovery = { path = "../network/availability-recovery", features = ["subsystem-benchmarks"] }
3030
polkadot-availability-distribution = { path = "../network/availability-distribution" }
31+
polkadot-statement-distribution = { path = "../network/statement-distribution" }
3132
polkadot-node-core-av-store = { path = "../core/av-store" }
3233
polkadot-node-core-chain-api = { path = "../core/chain-api" }
3334
polkadot-availability-bitfield-distribution = { path = "../network/bitfield-distribution" }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
TestConfiguration:
2+
- objective: StatementDistribution
3+
num_blocks: 10
4+
n_cores: 100
5+
n_validators: 500

polkadot/node/subsystem-bench/src/cli/subsystem-bench.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use clap::Parser;
2121
use color_eyre::eyre;
2222
use colored::Colorize;
23-
use polkadot_subsystem_bench::{approval, availability, configuration};
23+
use polkadot_subsystem_bench::{approval, availability, configuration, statement};
2424
use pyroscope::PyroscopeAgent;
2525
use pyroscope_pprofrs::{pprof_backend, PprofConfig};
2626
use serde::{Deserialize, Serialize};
@@ -40,6 +40,8 @@ pub enum TestObjective {
4040
DataAvailabilityWrite,
4141
/// Benchmark the approval-voting and approval-distribution subsystems.
4242
ApprovalVoting(approval::ApprovalsOptions),
43+
// Benchmark the statement-distribution subsystem
44+
StatementDistribution,
4345
}
4446

4547
impl std::fmt::Display for TestObjective {
@@ -51,6 +53,7 @@ impl std::fmt::Display for TestObjective {
5153
Self::DataAvailabilityRead(_) => "DataAvailabilityRead",
5254
Self::DataAvailabilityWrite => "DataAvailabilityWrite",
5355
Self::ApprovalVoting(_) => "ApprovalVoting",
56+
Self::StatementDistribution => "StatementDistribution",
5457
}
5558
)
5659
}
@@ -170,6 +173,15 @@ impl BenchCli {
170173
state,
171174
))
172175
},
176+
TestObjective::StatementDistribution => {
177+
let state = statement::TestState::new(&test_config);
178+
let (mut env, _protocol_config) = statement::prepare_test(&state, true);
179+
env.runtime().block_on(statement::benchmark_statement_distribution(
180+
&benchmark_name,
181+
&mut env,
182+
&state,
183+
))
184+
},
173185
};
174186
println!("{}", usage);
175187
}

polkadot/node/subsystem-bench/src/lib/approval/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::{
3030
mock::{
3131
chain_api::{ChainApiState, MockChainApi},
3232
network_bridge::{MockNetworkBridgeRx, MockNetworkBridgeTx},
33-
runtime_api::MockRuntimeApi,
33+
runtime_api::{MockRuntimeApi, MockRuntimeApiCoreState},
3434
AlwaysSupportsParachains, TestSyncOracle,
3535
},
3636
network::{
@@ -465,8 +465,9 @@ impl ApprovalTestState {
465465
}
466466
}
467467

468+
#[async_trait::async_trait]
468469
impl HandleNetworkMessage for ApprovalTestState {
469-
fn handle(
470+
async fn handle(
470471
&self,
471472
_message: crate::network::NetworkMessage,
472473
_node_sender: &mut futures::channel::mpsc::UnboundedSender<crate::network::NetworkMessage>,
@@ -807,6 +808,7 @@ fn build_overseer(
807808
state.candidate_events_by_block(),
808809
Some(state.babe_epoch.clone()),
809810
1,
811+
MockRuntimeApiCoreState::Occupied,
810812
);
811813
let mock_tx_bridge = MockNetworkBridgeTx::new(
812814
network.clone(),
@@ -915,7 +917,9 @@ pub async fn bench_approvals_run(
915917

916918
// First create the initialization messages that make sure that then node under
917919
// tests receives notifications about the topology used and the connected peers.
918-
let mut initialization_messages = env.network().generate_peer_connected();
920+
let mut initialization_messages = env.network().generate_peer_connected(|e| {
921+
AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NetworkBridgeUpdate(e))
922+
});
919923
initialization_messages.extend(generate_new_session_topology(
920924
&state.test_authorities,
921925
ValidatorIndex(NODE_UNDER_TEST),

0 commit comments

Comments
 (0)