core/overlay: prevent silent transition state restart on decode failure

When gob.Decode fails in LoadTransitionState, the function previously
returned nil, which triggered the fallback path that creates a fresh
TransitionState{Ended: isVerkle}. On a verkle-enabled node, this would
incorrectly mark the transition as complete, potentially causing the
node to use BinaryTrie for a partially-transitioned state.

Instead of returning nil, return a non-nil TransitionState with both
Started and Ended set to false. This ensures:
- InTransition() returns false (no partial transition in progress)
- Transitioned() returns false (transition has not completed)
- The fallback path is not triggered, preventing incorrect state

The root hash is also logged in the error message to aid debugging
corruption incidents.
This commit is contained in:
binary-mesh 2026-04-16 11:47:34 +03:00
parent d07a946a5b
commit 0a04487cd8

View file

@ -86,8 +86,14 @@ func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isVerkle boo
// Decode transition state // Decode transition state
err := dec.Decode(&newts) err := dec.Decode(&newts)
if err != nil { if err != nil {
log.Error("failed to decode transition state", "err", err) log.Error("failed to decode transition state", "root", root, "err", err)
return nil // Corrupted transition state data must not silently restart
// the transition via the fallback path. Return an ended state
// rather than nil to avoid triggering the fresh-start fallback,
// which would incorrectly mark the transition as complete when
// the on-disk data was merely corrupted.
ts = &TransitionState{Ended: false, Started: false}
return ts
} }
ts = &newts ts = &newts
} }