mirror of
https://github.com/luxfi/consensus.git
synced 2026-09-24 00:26:58 +00:00
buildBlocksLocked previously dropped a rebuild of an already-tracked block with a bare continue, so a peer that missed the first PushQuery was only re-asked on the slower rePollAllPending backoff. avalanchego never silently drops a rebuild — its repoll re-queries the still-processing preferred block until it decides (quiesce at NumProcessing==0). Mirror that on the build path: re-solicit an UNDECIDED OWN proposal's votes (idempotent; own-only; never a gossiped block, which keeps the rePoll cap). Pure liveness retry — finality is still the a-of-K cert, so it can never change WHICH block finalizes. Adds a REAL multi-node consensus simulation: N independent *Runtime engines wired through an in-process gossip bus carrying the production topology (block gossip -> HandleIncomingBlock, signed vote broadcast -> HandleIncomingVote, a-of-K cert -> HandleIncomingCert). Nodes run concurrently; finalization is EMERGENT (no synthetic quorum). Distinct down / wedged-present / forked scenarios + safety (sub-quorum never finalizes, forged/divergent rejected, no double-finalize, single head, sustained two-height liveness). BFT >= avalanche: K=5 alpha=4 f=1, the 4 healthy validators the exact zero-margin quorum. fails-before/passes-after proven: build-path re-solicit (RED: RequestVotes flat), execution-Verify binding (RED: forked block finalizes on all 5), threshold boundary (DownProposer 4->final vs SubQuorum 3->never via the 2/3-by-stake gate). Full engine/chain suite green under -race, 5x no flake. Co-authored-by: Hanzo Dev <[email protected]>