A validator keeps two records of the chain: the consensus ledger (what a quorum
decided) and the VM (what this node executed). Finalization folds the ledger across
blocks the VM never applied, so the ledger legitimately runs ahead. Both accept lanes
— runtime catch-up and bootstrap — gated fetched blocks on the ledger height, so a
node whose ledger led its VM discarded every block in the gap it had just asked for and
counted the batch accepted. It re-asked forever. Found wedged on five live fleets.
Position is now the LOWER of the two heads, in both lanes; a VM naming no block, or one
whose head is unreadable, does not lower it (absence is not a reading of zero). Blocks
between the applied head and the ledger are executed straight onto the VM — the network
settled those heights long ago, so what is missing is execution, not a decision.
Two authorities gate a replay, in order. The ledger's own per-height record first: it
names which block belongs at a height (canonical or envelope), and a block it finalized
differently is refused without consulting anything else. Where the ledger cannot speak —
below its boot seed or pruning window — a verified quorum cert may vouch.
The cert path binds on what the cert SIGNS, never on transport. The outer BlockID is not
in the signed message, so a held cert can be repointed at any block without breaking a
signature; binding on it let any peer apply an arbitrary block to a catching-up
validator's VM (red PoC, refused now). It binds on the signed canonical tuple instead,
verifies at the block's own P-chain epoch (not height 0, which resolves the genesis set
— rejecting every honest cert and admitting a long-range one), cross-checks the set-root,
and requires the irreversible Quasar tier. Replay also refuses a non-contiguous block
before Accept, since proposervm commits its outer envelope before the EVM refuses.
Nothing here decides: no vote, no cert consumed, no ledger movement. A tracked
above-band block returns ErrCatchupDeferred, distinct from a rejection, so a converging
node stops logging its own progress as failure.
Co-authored-by: Hanzo Dev <[email protected]>