You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Add CreateUser / DeleteUser to the serviceability executor with cross-language wire-format fixtures and four new PDA helpers (GetUserPDA, GetAccessPassPDA, GetTunnelIdsPDA, GetDzPrefixBlockPDA)
13
19
- SDK (Rust)
14
20
- Add `DZClient::from_context` and `GeoClient::from_context`, which build clients directly from a resolved RFC-20 `CliContext` instead of re-reading `~/.config/doublezero/cli/config.yml` and re-applying moniker conversion. The context already carries the fully resolved ledger RPC/WS URLs and program IDs, so these constructors consume them verbatim, making the context the single source of truth and removing the double-resolution the binary previously incurred. Keypair precedence is preserved exactly (CLI flag > `DOUBLEZERO_KEYPAIR` > stdin > context keypair path > default): the raw `--keypair` flag is passed as the highest-precedence source and the context keypair path is used only as the low-precedence fallback, so the env var still wins. The new constructors and their `doublezero-cli-core` dependency are gated behind a `cli-context` cargo feature so non-CLI SDK consumers (controlplane, telemetry, e2e) keep a dependency-light default build. `DZClient::new` / `GeoClient::new` are unchanged for callers that do not build a `CliContext` (e.g. `controlplane/doublezero-admin`).
21
+
- Drop the pre-submit `simulate_transaction` call in `DZClient::execute_transaction_inner` and submit with `skip_preflight: true`, eliminating the redundant double-simulation (the explicit simulate plus `send_and_confirm_transaction`'s default preflight) on the happy path. Program logs are now recovered from `get_transaction` on the failure path so `SimulationError` / `SimulationTransactionError` and `DoubleZeroError` mapping in CLI output are unchanged. Trade-off: failing transactions now land onchain and burn fees instead of failing for free at simulation ([#3750](https://github.com/malbeclabs/doublezero/pull/3750))
15
22
- CLI
16
23
- Honor the build-configured default environment (`Testnet` by default, `MainnetBeta` under the `default-mainnet-beta` feature) when neither `--env` nor a persisted `config.yml` selects one. The RFC-20 context-build previously fell back to `Environment::default()`, which is always `Devnet` regardless of the build, so a testnet build with no config silently targeted Devnet's ledger URLs and program IDs. The binary now resolves the fallback through the new `doublezero_sdk::default_environment()`, matching the legacy `DZClient::new` defaults (`default_program_id`, `ClientConfig::default`) which already key off the compiled-in environment ([#3810](https://github.com/malbeclabs/doublezero/pull/3810))
17
24
- Construct the serviceability and geolocation SDK clients in the `doublezero` binary via `DZClient::from_context` / `GeoClient::from_context`, replacing the legacy `DZClient::new(Option<String>, ...)` bridge. The binary no longer round-trips the already-resolved `CliContext` values back through the SDK's config-file re-resolution. No user-facing command, flag, or output change.
18
25
- Restore environment-moniker support for the `--program-id` and `--geo-program-id` global flags. The context-build resolved both flags with a raw `parse::<Pubkey>()`, so a moniker (e.g. `--geo-program-id testnet`) failed to parse, was silently dropped, and the binary fell back to the environment default. Both flags now accept monikers in their full (`mainnet-beta`, `testnet`, `devnet`, `local`) and short (`m`, `t`, `d`, `l`) forms, resolving to the matching program ID; a literal pubkey still passes through. A value that is neither a known moniker nor a valid pubkey is now a hard error instead of being silently ignored. `convert_program_moniker` is broadened to cover all four environments (previously only `devnet`/`testnet`), matching `convert_geo_program_moniker`.
19
26
- Treat `--env` as a base that the per-field flags override, rather than being mutually exclusive with them. `--env <name>` resolves the whole network (ledger URL, WS URL, Solana L1 URL, serviceability and geolocation program IDs); `--url`, `--ws`, `--solana-url`, `--program-id`, and `--geo-program-id` each override only their own value on top (precedence: explicit flag > `--env`, per RFC-20 §override hierarchy). Applies to both the global `doublezero` flags and `doublezero config set`. Previously the global flag rejected the combination at the clap layer (`ArgumentConflict`) and `config set` printed `Invalid flag combination` and exited without writing, so `--env local --program-id <X>` was not possible.
20
-
- Tools
21
-
- Add `tools/stress/device-orchestrator/`, the device-stress orchestrator skeleton for the GRE Tunnel Capacity Study (part 2 of #3746). Runs a batched provision-then-reverse-deprovision sweep against a live serviceability program, dumping `orchestrator-config.json` and emitting a JSONL runlog of `submit | confirm | activate | deprovision_*` events. Cooperates with an abort sentinel file: finish the in-flight user, tear down everything created, exit non-zero. The SSH-backed agent runner (`pre_commit_log` / `applied` events) is stubbed behind `pkg/agent.Runner` and lands in part 3 ([#3771](https://github.com/malbeclabs/doublezero/issues/3771)).
22
-
- Add `tools/stress/device-observer/` initial scaffolding plus eAPI device sampler that writes per-tick snapshots of five `show` commands and an `observer-config.json` with the observer PID; collectors for Prometheus scrape, log tailers, and abort decider are stubbed and will be replaced in follow-up PRs.
23
-
- Implement the `tools/stress/device-observer/` Prometheus scraper for the doublezero-agent metrics endpoint. Each tick fetches `--agent-metrics-url`, parses the exposition response, and appends one NDJSON row per metric sample to `observer.agent_metrics.json`. Counter family totals are also exposed via a thread-safe `Scraper.Snapshot()` for downstream consumers. Per-tick HTTP, parse, or write failures log at WARN and the loop continues.
24
-
- E2E/QA
25
-
- Configure the manager and client CLI with `doublezero config set --env local`, keeping per-field overrides for the container-specific ledger URLs and the deployed serviceability program ID (and geolocation program ID on the manager). The override is required because the sentinel multicast-publisher test deploys serviceability at a generated keypair and the compatibility tests clone testnet/mainnet program IDs; for standard stacks the env defaults already match the fixed localnet pubkeys. Exercises the new `--env`-as-base behavior end-to-end.
- Enforce non-zero bandwidth on CYOA/DIA interfaces in `process_create_device_interface` and `process_update_device_interface`. On update the rule fires only when the transaction is changing CYOA, DIA, or bandwidth, so legacy zero-bandwidth CYOA/DIA interfaces already onchain can still be updated for unrelated fields without first being repaired. Enforce `side_a_iface.bandwidth >= link.bandwidth` (and `side_z_iface.bandwidth >= link.bandwidth` for WAN; DZX side Z is external) in `process_create_link`. Enforce the same rule for both side A and side Z in `process_accept_link` (the DZX accept path), so DZX side Z's bandwidth is validated when it is first bound and side A is re-validated in case it was lowered via `process_update_device_interface` between create and accept. All rejections surface as `DoubleZeroError::InvalidBandwidth` (`Custom(31)`).
37
-
- SDK (Rust)
38
-
- Drop the pre-submit `simulate_transaction` call in `DZClient::execute_transaction_inner` and submit with `skip_preflight: true`, eliminating the redundant double-simulation (the explicit simulate plus `send_and_confirm_transaction`'s default preflight) on the happy path. Program logs are now recovered from `get_transaction` on the failure path so `SimulationError` / `SimulationTransactionError` and `DoubleZeroError` mapping in CLI output are unchanged. Trade-off: failing transactions now land onchain and burn fees instead of failing for free at simulation ([#3750](https://github.com/malbeclabs/doublezero/pull/3750))
- e2e/qa: remove client-side capacity pre-filtering from `ValidDevices`, because the QA user pubkey bypasses capacity limits using the serviceability global-config qa-allowlist. Individual device failures no longer fail the test; instead, overall and per-host failure rates are evaluated after all batches and the test only fails if either exceeds `--failure-threshold` (default 10%) or `--per-host-failure-threshold` (default 20%).
42
-
- CLI
43
27
- Add `--solana-url <SOLANA_RPC_URL>` global flag to `doublezero` per RFC-20 §Global flags. Distinct from `--url`, which continues to override the DZ ledger transport; `--solana-url` targets the Solana L1 transport. The flag is parsed and exposed on the binary's `App` struct; per-verb consumption lands when verbs migrate to construct typed Solana L1 clients from `CliContext`.
44
28
- Add `--log-level <LEVEL>` global flag and initialize the `tracing` subscriber at startup. `LEVEL` is one of `off`, `error`, `warn` (default), `info`, `debug`, `trace`. Diagnostic logs go to stderr so `--json` output on stdout remains parseable. Honors the `RUST_LOG` environment variable when set, overriding the CLI-flag level for per-module filtering. Replaces the previous `println!("using keypair: ...")` stdout line with a `tracing::info!` event; the keypair confirmation now appears only at `--log-level info` or higher and no longer pollutes parseable stdout. (Named `--log-level` rather than the RFC-20 §Global-flags suggested `--verbose` / `-v` because the existing `doublezero connect` / `disconnect` subcommands already own a `--verbose` flag with `bool` type; the global flag deviation will be revisited when the daemon-control module crate is carved out.)
45
29
- Build a `CliContext` once at binary startup from `--env`, the per-field global overrides (`--url`, `--ws`, `--solana-url`, `--program-id`, `--geo-program-id`, `--keypair`, `--sock-file`), and the persisted `~/.config/doublezero/cli/config.yml` (overridable via `DOUBLEZERO_CONFIG_FILE`), per RFC-20 (§CliContext). Precedence (highest wins): CLI flag > persisted config > env-derived default. When `--env` is not set and the persisted config has a serviceability program ID, the environment is derived from that program ID via `Environment::from_program_id`; otherwise the binary falls back to `Environment::default()`. The legacy `DZClient` is now constructed from the fully resolved `CliContext` URL, WebSocket, and program-ID values directly, so verbs that migrate to read `CliContext` see the same backend as the legacy bridge. Keypair resolution is intentionally left to `DZClient::new`'s internal `load_keypair` precedence (CLI `--keypair` flag > `DOUBLEZERO_KEYPAIR` env var > stdin > persisted config) so the `DOUBLEZERO_KEYPAIR` env var continues to override the persisted keypair path, as relied on by the e2e contributor-auth negative-authz suite. File reads happen only in the binary; module crates remain forbidden from touching the filesystem (RFC-20 §67).
@@ -69,6 +53,18 @@ All notable changes to this project will be documented in this file.
69
53
- Restore the default value for `doublezero device interface create --bandwidth` so it is optional again. [#3077](https://github.com/malbeclabs/doublezero/pull/3077) dropped `default_value` from the clap attribute on `bandwidth`; because the field is `u64` (not `Option<u64>`), clap then treated omission as a missing required argument, even though the PR description stated `--bandwidth` was now optional ([#3775](https://github.com/malbeclabs/doublezero/pull/3775))
70
54
- Route the `doublezero user get` "no Access Pass found" warning through `tracing::warn!` instead of `eprintln!`, so diagnostics go to the logging facade per RFC-20 §Diagnostic logging and no longer write directly to stderr. No user-facing output, flag, or schema change.
71
55
- Reconcile the RFC-20 docs with the implemented global logging flag: `rfcs/rfc20-cli-standardization.md` and `docs/cli-standard.md` now describe `--log-level <off|error|warn|info|debug|trace>` (default `warn`) instead of the never-implemented repeatable `--log-verbose`. Documentation only; the binary is unchanged.
56
+
- Tools
57
+
- Add `tools/stress/device-orchestrator/`, the device-stress orchestrator skeleton for the GRE Tunnel Capacity Study (part 2 of #3746). Runs a batched provision-then-reverse-deprovision sweep against a live serviceability program, dumping `orchestrator-config.json` and emitting a JSONL runlog of `submit | confirm | activate | deprovision_*` events. Cooperates with an abort sentinel file: finish the in-flight user, tear down everything created, exit non-zero. The SSH-backed agent runner (`pre_commit_log` / `applied` events) is stubbed behind `pkg/agent.Runner` and lands in part 3 ([#3771](https://github.com/malbeclabs/doublezero/issues/3771)).
58
+
- Add `tools/stress/device-observer/` initial scaffolding plus eAPI device sampler that writes per-tick snapshots of five `show` commands and an `observer-config.json` with the observer PID; collectors for Prometheus scrape, log tailers, and abort decider are stubbed and will be replaced in follow-up PRs.
59
+
- Implement the `tools/stress/device-observer/` Prometheus scraper for the doublezero-agent metrics endpoint. Each tick fetches `--agent-metrics-url`, parses the exposition response, and appends one NDJSON row per metric sample to `observer.agent_metrics.json`. Counter family totals are also exposed via a thread-safe `Scraper.Snapshot()` for downstream consumers. Per-tick HTTP, parse, or write failures log at WARN and the loop continues.
60
+
- E2E/QA
61
+
- Configure the manager and client CLI with `doublezero config set --env local`, keeping per-field overrides for the container-specific ledger URLs and the deployed serviceability program ID (and geolocation program ID on the manager). The override is required because the sentinel multicast-publisher test deploys serviceability at a generated keypair and the compatibility tests clone testnet/mainnet program IDs; for standard stacks the env defaults already match the fixed localnet pubkeys. Exercises the new `--env`-as-base behavior end-to-end.
- e2e/qa: remove client-side capacity pre-filtering from `ValidDevices`, because the QA user pubkey bypasses capacity limits using the serviceability global-config qa-allowlist. Individual device failures no longer fail the test; instead, overall and per-host failure rates are evaluated after all batches and the test only fails if either exceeds `--failure-threshold` (default 10%) or `--per-host-failure-threshold` (default 20%).
- Enforce non-zero bandwidth on CYOA/DIA interfaces in `process_create_device_interface` and `process_update_device_interface`. On update the rule fires only when the transaction is changing CYOA, DIA, or bandwidth, so legacy zero-bandwidth CYOA/DIA interfaces already onchain can still be updated for unrelated fields without first being repaired. Enforce `side_a_iface.bandwidth >= link.bandwidth` (and `side_z_iface.bandwidth >= link.bandwidth` for WAN; DZX side Z is external) in `process_create_link`. Enforce the same rule for both side A and side Z in `process_accept_link` (the DZX accept path), so DZX side Z's bandwidth is validated when it is first bound and side A is re-validated in case it was lowered via `process_update_device_interface` between create and accept. All rejections surface as `DoubleZeroError::InvalidBandwidth` (`Custom(31)`).
72
68
- Telemetry
73
69
- Replace the geoprobe `MinCache` best/backup eviction with a guarded-backup pattern: a backup is only collected while `best` is within its final `maxAge/2` ("guard") window, so on `best`'s expiry the promoted value is always a recent-window minimum rather than a stale fallback. A new record low resets `best` and clears `backup`, and expiry now promotes in a loop so a backup that is itself already expired cannot be promoted. `Best` / `BestRttNs` become pure read-through accessors returning the lower of the two non-expired slots without mutating or promoting.
74
70
- Add `ip-mroute`, `ip-mroute-count`, and the four MSDP show-commands (`ip-msdp-summary`, `ip-msdp-pim-sa-cache`, `ip-msdp-sa-cache`, `ip-msdp-sa-cache-rejected`) to the state-ingest server's default state-collect command list. Devices with `--state-collect-enable` will run each command via Arista eAPI and upload signed JSON snapshots to S3; downstream parsing into ClickHouse lands in separate `lake/indexer/pkg/dzingest` PRs (one per kind family).
0 commit comments