Run NodesReferenceCmd

main

Command repair-proposervm is a fail-closed surgical tool to reconcile a proposervm chain-state DB onto a known-canonical outer block at a single height.

import "github.com/luxfi/node/cmd/repair-proposervm"

Command repair-proposervm is a fail-closed surgical tool to reconcile a proposervm chain-state DB onto a known-canonical outer block at a single height.

The condition it repairs: a node locally accepted a sub-quorum proposervm envelope A while the network finalized the supermajority sibling B, which wraps the IDENTICAL inner EVM block. The two siblings differ ONLY in the proposervm outer envelope; the inner EVM state is byte-identical, so nothing about the EVM diverged. Such a node re-seeds finality from its persisted proposervm lastAccepted=A on restart and then fatals on B's cert as equivocation. This tool swaps the persisted record of height from A to the canonical B, leaving the inner EVM completely untouched (no EVM rollback).

It is NOT a blind hex edit: it opens the exact same typed proposervm state (luxfi/node/vms/proposervm/state) over the exact same nested keyspace luxd uses (chainID -> "vm" -> "proposervm" -> versiondb -> chain/block/height), and writes via the state's own PutBlock / SetBlockIDAtHeight / SetLastAccepted so the on-disk bytes are identical to what luxd itself wrote for B on the canonical node.

proposervm invariant honored: proLastAcceptedHeight must never be < the inner VM's last-accepted height (vm.repairAcceptedChainByHeight). The inner EVM is at height (it accepted the shared inner block under A), so the recovery target is the canonical block AT height (B), never height-1 — keeping outer==inner height.

Modes:

inspect : read-only. Print lastAccepted, height index at H and H-1, and the outer block currently recorded at H. export : read-only. Read the outer block recorded at H and write its raw stateless bytes to --block-file (run against a canonical node's DB). repair : read-write, fail-closed. Parse --block-file (canonical B), assert it is the expected block, assert the DB is in the expected bad state (lastAccepted and heightIndex[H] both == the expected sub-quorum block A, and B's parent == heightIndex[H-1]); then PutBlock(B), SetBlockIDAtHeight(H,B), SetLastAccepted(B), Commit. Idempotent: if already on B, it no-ops.

The DB uses an exclusive LOCK; luxd MUST be stopped on the target before repair.