linera_service/cli/validator_benchmark/config.rs
1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! CLI definition for `linera validator benchmark`.
5
6use linera_base::{crypto::ValidatorPublicKey, identifiers::ChainId};
7
8/// Multi-layer pre-onboarding benchmark for a single candidate validator.
9///
10/// Probes the candidate across read-side primitives (preflight, baseline,
11/// concurrency ramp, bulk download, tip lag) and emits a structured report.
12/// The optional `--deep` layer additionally exercises the write path by
13/// syncing a bounded number of blocks; it has a stateful side effect on the
14/// candidate and is therefore off by default.
15///
16/// PREREQUISITE: the read layers are only meaningful if the candidate already
17/// holds the `--chain` you pass. A not-yet-committee candidate may hold no
18/// blocks; in that case pre-sync it (`linera validator sync`) or pass `--deep`,
19/// which seeds the blocks first (and is run before the read layers). The tool
20/// warns when a chain is not held.
21#[derive(Debug, Clone, clap::Parser, serde::Serialize)]
22pub struct Benchmark {
23 /// Network address of the candidate validator (e.g. `grpcs://host:port`).
24 pub address: String,
25
26 /// Expected public key of the validator (identity verification).
27 #[arg(long)]
28 pub public_key: Option<ValidatorPublicKey>,
29
30 /// Chain to exercise. Repeat for multiple chains. At least one required.
31 #[arg(long, required = true)]
32 pub chain: Vec<ChainId>,
33
34 // --- Layer toggles ---
35 /// Skip L1 preflight (version, network description, RTT).
36 #[arg(long)]
37 pub skip_preflight: bool,
38 /// Skip L3 read latency baseline.
39 #[arg(long)]
40 pub skip_read_baseline: bool,
41 /// Skip L4 read stress (concurrency ramp).
42 #[arg(long)]
43 pub skip_read_stress: bool,
44 /// Skip L5 bulk certificate download.
45 #[arg(long)]
46 pub skip_bulk_download: bool,
47 /// Skip L6 tip-lag snapshot.
48 #[arg(long)]
49 pub skip_tip_lag: bool,
50
51 /// L2 partial sync (seed): sync a bounded run of blocks into the candidate,
52 /// run before the read layers so they exercise real data. Stateful side
53 /// effect on the candidate; off by default.
54 #[arg(long)]
55 pub deep: bool,
56
57 // --- L3 (read latency baseline) ---
58 /// Number of sequential chain-info queries per chain in L3.
59 #[arg(long, default_value_t = 200)]
60 pub baseline_requests: usize,
61
62 // --- L4 (read stress / concurrency ramp) ---
63 /// Concurrency levels for the L4 ramp.
64 #[arg(long, value_delimiter = ',', default_value = "1,2,4,8,16,32,64")]
65 pub stress_levels: Vec<usize>,
66 /// Seconds to sustain each L4 concurrency level.
67 #[arg(long, default_value_t = 30)]
68 pub stress_duration_secs: u64,
69
70 // --- L5 (bulk download) ---
71 /// Number of heights per L5 download batch.
72 #[arg(long, default_value_t = 100)]
73 pub bulk_batch_size: u32,
74 /// Concurrency levels for L5 bulk download.
75 #[arg(long, value_delimiter = ',', default_value = "1,8")]
76 pub bulk_concurrency: Vec<usize>,
77 /// Either `auto` (last batch_size * 100 heights up to the candidate's tip)
78 /// or an explicit `FROM:TO` range.
79 #[arg(long, default_value = "auto")]
80 pub bulk_height_range: String,
81
82 // --- L6 (tip-lag snapshot) ---
83 /// Number of tip-lag samples in L6.
84 #[arg(long, default_value_t = 3)]
85 pub tip_lag_samples: usize,
86 /// Seconds between L6 tip-lag samples.
87 #[arg(long, default_value_t = 120)]
88 pub tip_lag_interval_secs: u64,
89
90 // --- L2 (partial sync / seed, opt-in) ---
91 /// Maximum number of blocks to seed in L2 partial sync (with `--deep`).
92 #[arg(long, default_value_t = 1000)]
93 pub deep_blocks: u32,
94 /// Chain to use for the L2 partial-sync seed (defaults to the first `--chain`).
95 #[arg(long)]
96 pub deep_chain: Option<ChainId>,
97
98 // --- Output ---
99 /// Output spec, repeatable; or comma/+-separated within a single value.
100 /// SPEC: `<format>` (stdout) or `<format>:<path>` (file).
101 /// Formats: `json`, `yaml`, `md`, `brief`. Default if omitted: `md` to stdout.
102 #[arg(long)]
103 pub output: Vec<String>,
104
105 /// Free-form tag carried in the report (e.g. `OVH US-EAST`).
106 #[arg(long, default_value = "unspecified")]
107 pub observer_location: String,
108
109 /// Disable the interactive progress UI (auto-disabled when stderr is not a TTY).
110 #[arg(long)]
111 pub no_progress: bool,
112
113 // --- Robustness ---
114 /// Per-RPC timeout in seconds. A call that exceeds it is recorded as a
115 /// `timeout` error and the run keeps going, so a hung validator never blocks.
116 #[arg(long, default_value_t = 30)]
117 pub rpc_timeout_secs: u64,
118 /// Abort the run if preflight fails (default: continue and report).
119 #[arg(long)]
120 pub abort_on_preflight_fail: bool,
121}