Repository navigation
fix(rpc): bound liveness by the wall clock - #670
MegaRedHand wants to merge 2 commits into
Conversation
🤖 Kimi Code ReviewI'll review this PR focusing on the changes to the validator liveness endpoint and its tests. SummaryThis PR changes the liveness endpoint's epoch validation from using the store's tick-driven epoch ( Issues Found1. Potential panic in
|
| Priority | Item | Action |
|---|---|---|
| High | Test determinism | Refactor wall_epoch() to use shared store; avoid creating multiple stores |
| Medium | Underflow safety | Add saturating_sub or preconditions in tests |
| Medium | Test validity | Add explicit test simulating tick/wall clock divergence |
| Low | Comment precision | Clarify "previous epoch" wording |
The core logic change is correct and addresses a real consensus-layer issue. The test infrastructure needs hardening to be reliable and to actually validate the boundary condition that motivated the fix.
Automated review by Kimi (Moonshot AI) · kimi-k2.6 · custom prompt
🤖 Codex Code ReviewLooks good overall. The change is narrowly scoped to RPC liveness windowing and does not touch fork choice, attestation validation, justification/finalization, STF, XMSS, or SSZ logic.
No obvious security or memory-safety concerns:
Minor note:
If you want, I can also sanity-check the full PR against the base branch with Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
🤖 Claude Code ReviewReview of PR 670: bound liveness by the wall clock The change is small and correct. I only read the diff and the The old check used the store's tick-driven epoch, which lags the real epoch until the slot tick runs. That would refuse a validator client asking for the next epoch just after a boundary. Notes
Otherwise this looks good to merge. Automated review by Claude (Anthropic) · sonnet · custom prompt |
…3-636-638-gloas-live Liveness now bounds its epoch by the wall clock; tmp's get_head_node import is kept next to checkpoint_state.
d973505 to
54adf35
Compare
95524f1 to
f94f514
Compare
…the endpoint a validator client's doppelganger protection calls before signing. A validator is live in an epoch if the head state credits it for that epoch (a non-zero participation byte, covering what blocks have already included) or if this node observed it act in that epoch, which covers what no block has included yet. The observations live in a new ObservedLiveness on the Store, one bitset per epoch for the newest three, because three places write them and all three already hold a Store clone: P2P when it accepts a gossip aggregate (its aggregator and every attester its signature verified) or subnet attestation, the chain actor when it imports a beacon block (its proposer, so range-synced and self-published blocks count), and the RPC for attestations and aggregates submitted through pool/attestations and aggregate_and_proofs, since gossip never delivers a node its own messages. The endpoint answers the store clock's previous, current and next epoch and is a 400 for any other epoch or an unknown index, and a 503 while syncing.
The previous/current/next epoch window used the store's tick-driven clock, which still reads the old epoch until the slot tick runs. A validator client asking for the next epoch right after a boundary got a 400. Use the wall-clock epoch, as the duty endpoints do.
54adf35 to
8b3cbc5
Compare
f94f514 to
71d390f
Compare
Motivation
POST /eth/v1/validator/liveness/{epoch}bounds the epoch by the store's tick-driven clock (get_current_store_epoch). At the first moments of an epoch, before the boundary slot's tick has run, that clock still reads the previous epoch, so a validator client asking for the next epoch right at the boundary (doppelganger protection polls at every epoch start) gets a 400. beacon-APIs bounds it by the current (wall-clock) epoch. Same bug class as the duties fixes in #663, found while auditing for it.Change
node::wall_slot, the clockattestation_dataand the duties endpoints already use.cargo test -p ethlambda-rpc --lib --profile release-fast, clippy and fmt clean.