failover: initial MVP with tower file steaming - #11290
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Safety-critical configuration mismatches are currently accepted during HELLO validation.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds failover wire-protocol definitions, HELLO validation, and a session state machine.
Changes:
- Defines failover messages, roles, events, and session states.
- Implements HELLO checks and state transitions.
- Adds unit tests and build integration.
- Critical: HELLO validation must reject mismatched
cfg_hashvalues and test this case.
File summaries
| File | Description |
|---|---|
src/discof/failover/test_failover_proto.c |
Tests HELLO validation and session behavior. |
src/discof/failover/Local.mk |
Registers sources and tests. |
src/discof/failover/fd_failover_proto.h |
Defines protocol layouts and APIs; lacks a configuration-mismatch outcome. |
src/discof/failover/fd_failover_proto.c |
Implements validation and transitions but does not compare cfg_hash. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| uchar role; /* FD_FAILOVER_ROLE_* role */ | ||
| ulong boot_id; /* random value per boot to distinguish restarts */ | ||
| uchar commit[ 20 ]; /* FD commit hash */ | ||
| ulong cfg_hash; /* config hash to ensure matching safety-critical config */ |
Performance Measurements ⏳
|
There was a problem hiding this comment.
🟡 Changes recommended
Safety checks and readiness are ineffective, several advertised handoff settings are unused, and the listener permits connection-starvation attacks.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 62/69 changed files
- Comments generated: 6
- Review effort level: Balanced
| # Local listener address used when dial_peer is false. | ||
| bind_address = "0.0.0.0" | ||
| bind_port = 9700 |
| tile->admin.failover_peer_silence_intervals = config->firedancer.failover.peer_silence_intervals; | ||
| tile->admin.failover_retry_backoff_min_millis = config->firedancer.failover.retry_backoff_min_millis; | ||
| tile->admin.failover_retry_backoff_max_millis = config->firedancer.failover.retry_backoff_max_millis; | ||
| tile->admin.failover_cfg_hash = 0UL; |
| /* Status flag bits */ | ||
| #define FD_FAILOVER_FLAG_VOTE_ROOTED (1) | ||
| #define FD_FAILOVER_FLAG_IS_LEADER (2) | ||
| #define FD_FAILOVER_FLAG_CAUGHT_UP (4) |
| # Pair credentials and the two local identity keypairs. | ||
| pair_secret_path = "" | ||
| junk_identity_path = "" | ||
| staked_identity_path = "" |
| # Permit a request initiated by the standby to trigger a handoff. | ||
| accept_peer_requests = false |
| min_slots_to_leader = 150 | ||
| deadline_slots = 64 | ||
| catchup_gap_slots = 8 |
7a7ab27 to
1a9197b
Compare
┌─ ⚡ PERF · 1a9197b vs main@b523cfd ─────────────────────────────────
│ SUITE BASELINE NEW Δ
│ replay tps, mainnet 29,804 tps 29,660 tps · -0.49%
│ bench tps, localnet 128,645 tps 128,644 tps · 0.00%
│ snapshot load, testnet 9.21 s 9.18 s · -0.31%
│ mem total, mainnet 171.43 GiB 171.43 GiB · 0.00%
│ mem total, testnet 102.31 GiB 102.31 GiB · 0.00%
+│ clean compile, firedancer 237.7 cpu·s 228.9 cpu·s ▼ -3.67%
│ binary size, firedancer 85.78 MB 86.06 MB · +0.33%
├─────────────────────────────────────────────────────────────────────
@@ 0 REGRESSIONS · 0 WARNINGS · 1 IMPROVED · 6 NOISE @@
└───────────────────────────────────────────────────────────────────── |
There was a problem hiding this comment.
🟡 Changes recommended
Failover roles become stale after identity switches, readiness cannot succeed, and configuration compatibility hashing is disabled.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (3)
src/discof/admin/fd_admin_tile.c:956
failover_local_statusinitializesflagsto zero, and there is no production path that setsFD_FAILOVER_FLAG_CAUGHT_UP. Consequently both endpoints always advertise the standby as not caught up, so this branch makesreadypermanently false even for a healthy synchronized pair. Derive and publish the caught-up flag from the configured catch-up criteria before using it in readiness.
src/app/firedancer/config/default.toml:1887- These settings are documented as operative handoff thresholds, but
min_slots_to_leader,deadline_slots, andcatchup_gap_slotsare only parsed and copied into topology fields; no runtime code reads them. Changing them therefore has no effect. Implement their checks or mark/remove them until supported so operators are not given ineffective safety controls.
# Handoff and channel parameter thresholds.
status_interval_millis = 800
min_slots_to_leader = 150
deadline_slots = 64
catchup_gap_slots = 8
src/app/firedancer/topology.c:1466
- This hard-codes the safety configuration hash to zero on every node, so the HELLO
cfg_hashcomparison can never detect mismatched failover thresholds or protocol-critical settings. Compute a canonical hash of the safety-critical configuration and pass that value into the admin tile.
tile->admin.failover_cfg_hash = 0UL;
- Files reviewed: 62/69 changed files
- Comments generated: 1
- Review effort level: Balanced
| ctx->failover_role = is_staked ? FD_FAILOVER_ROLE_ACTIVE : FD_FAILOVER_ROLE_STANDBY; | ||
| ctx->failover_hello.role = (uchar)ctx->failover_role; |
https://jumptrading.slack.com/archives/C0B5SNLSA12/p1787855643080949