Skip to main content

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}