Files
consensus/engine
zeekay 8067e0da05 fix(engine/chain): converge competing siblings — no down-leader halt
When a slot-leader proposer is down, each healthy validator builds its OWN
block at the next height (own clock -> own blkID). The alpha-of-K finality
cert needs alpha votes on ONE block, but the votes split across the competing
siblings, no cert assembles, and the chain HALTS the moment one proposer is
down (observed: devnet stuck at height 36 with 4/5 validators healthy).

Root cause: the VM kept building on the last FINALIZED block, so every node
re-proposed the same height instead of building on a verified-but-unfinalized
sibling. There was no convergence onto one build target.

Fix (matches avalanchego snowman, which steers the VM to its preferred
non-finalized tip via SetPreference after every poll):
- Add ChainConsensus.PreferredBuildTip / Transitive.PreferredBuildTip — the
  DETERMINISTIC build target: descend from the finalized tip through verified,
  non-rejected children, lowest-ID per level, to the deepest verified tip. Every
  node with the same block tree picks the SAME chain.
- followVerifiedBlock steers the inner VM to PreferredBuildTip on adopt, so
  validators build H+1 on top of one verified block at H and CONVERGE; the
  alpha-of-K votes then land on a single block and finalize.

Decomplected from the finality Preference (UNCHANGED — still the cert tip; the
conformance suite pins that contract). Build hint only: finality stays governed
by the alpha-of-K cert on c.ledger, so this cannot affect safety, only liveness.

Tests: TestPreference_ConvergesSiblings_NoDownLeaderHalt (deterministic lowest-ID
build tip across competing siblings, deepest-verified follow, rejected-sibling
skip), TestPreference_NoChildren_ReturnsFinalizedTip (no regression). Full
engine/... suite green; nil-VM path guarded.
2026-06-29 01:10:12 -07:00
..
2025-12-19 08:49:11 -08:00