mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
handleVote routes a vote for a block that is no longer pending but IS in
finalizedByCert to attestFinalizedVote, which resolves the signed position through
lookupAcceptedPos. applyBranchFinalization sets finalizedByCert and drops the pending
block; rememberAcceptedPos ran later still, inside promoteQuasar. Between those two
points the tap was OPEN and the position ABSENT, so a vote arriving there took the
finalized path, missed the lookup, and returned in silence.
That vote is not recoverable. Accept votes are solicited once and promoteQuasar does no
retroactive promotion, so losing the 2/3-th one leaves the height Nova-only PERMANENTLY:
settlement never exports it, and FinalityStatus reports Degraded with a responsive stake
below the truth — a fleet with 4 of 5 up and all four voting reads back as 0.6 on a live
consumer surface. The window widens under CPU contention, which is where it surfaced, as
the source of the export-liveness flake fixed in f84579ed.
The write moves to before applyBranchFinalization, so the record exists before anything
can observe the block as finalized, and leaves promoteQuasar with one job. A later
VM.Accept failure cannot make it lie: attestFinalizedVote is reachable only for a block
finalizedByCert actually holds.
TestAcceptedPos_RememberedBeforeFinalityIsVisible pins the ordering without needing a
race — the VM's Accept runs inside the same finalization step, so probing lookupAccepted
Pos from Accept observes exactly the interval that used to be empty. It FAILS with the
write moved back.
Also in this commit, from the same review:
- The no-cert-at-height branch gets its own log at Debug. It was sharing the
"unreadable" line and reporting errNoCertAtHeight in a field named getBlockError,
which is self-contradictory, and firing at Error on what is the ORDINARY case: the
steer target is normally the build tip, which sits above the frontier by definition.
- The FourOfFive gate keeps a direct quasarTip() read. Asserting only at blk's height
let a frontier whose canonical nobody certified pass, and that shape is producible:
SyncQuasarFrontier is a SECOND writer that seeds the frontier from the VM's durable
export record with no Nova-ledger check and accepts an empty canonical. The gate now
asserts chain membership AND no conflicting canonical at blk's height.
- waitForExportFrontier advanced its height cursor while leaving parentID behind on a
failed convergence, so every later iteration built on a stale parent and a real
export stall was reported as unconvergeable noise. It now stops at the first
non-converging height.
- Corrected in the comments: the Nova cert freezes at NovaQuorum(5)=3, and alpha does
not gate cert assembly at all. f84579ed's message said "the bare alpha=4 without 2/3",
which is arithmetically impossible — prodParams5 sets alpha=4 and twoThirdsCount(5)
is also 4 — and sends the next reader down a dead end.
Co-authored-by: Hanzo Dev <[email protected]>