Files
consensus/engine
zeekayandHanzo Dev f7924b475f fix(chain): let the finality walk read blocks back from the VM
The finalized tip is durable and the block tree above it is not, so the two
disagree after every restart: the engine comes back knowing it finalized through
height H and remembering nothing above H, while the VM still holds every block it
ever accepted.

A cert for a block above H then walks down looking for ancestors the node HAS,
finds them missing from the live tree, and returns ErrAncestorNotTracked. The
advice that error carries — fetch and retry — cannot help, because the catch-up
path finalizes contiguously from a per-block cert and no cert was ever assembled
for the interior of the gap. Finality therefore cannot re-cross the seam, and the
gap widens with each restart.

blocksAncestry now resolves a miss through the VM. That is the STRONGER source,
not a weaker one: the VM's chain is what this node actually executed and
committed, where the live tree is populated from gossip. It supplies parent links
only — the cert has already cleared the ⅔-by-stake predicate on its own — and a
block the VM does not hold still misses, so the behind-node defer is preserved.
The live tree keeps priority, since its entry carries this process's own view.

Wired in the constructor once both the consensus core and the VM are set; an
engine with no VM is unchanged.

Tests: finality_seam_test.go — crosses the seam for a run the VM holds and the
tree does not, still fails closed on a block the VM lacks, resolves from the live
tree when there is no VM, and prefers the live entry over a read-back. Negative
control executed: removing the read-back fails the seam test alone.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-13 18:44:15 -07:00
..
2025-12-19 08:49:11 -08:00