fix: detect corrupt block index entries during load#276
Open
MorningLightMountain713 wants to merge 1 commit intomasterfrom
Open
fix: detect corrupt block index entries during load#276MorningLightMountain713 wants to merge 1 commit intomasterfrom
MorningLightMountain713 wants to merge 1 commit intomasterfrom
Conversation
A single bit flip in a block index value causes GetBlockHash() to compute a wrong hash. The entry gets inserted into mapBlockIndex under that wrong hash, while child blocks referencing the correct hash via hashPrev create a stub with NULL pprev. BuildSkip then walks into the stub and hits assert(pindexWalk->pprev), crashing fluxd in a loop. The existing consistency check (header.GetHash() != GetBlockHash()) doesn't catch this because both sides derive from the same corrupt data. Add a check comparing the computed hash against the LevelDB key (key.second), which is the authoritative stored hash. Use key.second for insertBlockIndex to ensure the entry goes under the correct hash. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GetBlockHash()to compute a wrong hash, inserting the entry under an incorrect key inmapBlockIndex. Child blocks referencing the correct hash viahashPrevcreate a stub withpprev=NULL.BuildSkipthen walks into the stub, hittingassert(pindexWalk->pprev)atchain.cpp:94, which callsabort()and produces a core dump (SIGABRT). Systemd restarts fluxd, which hits the same corruption and crashes again — resulting in an infinite core dump loop (300+ restarts observed on a production node).header.GetHash() != GetBlockHash()) misses this because both sides derive from the same corrupt data — it compares the computed hash against itself, not the stored LevelDB key.key.second(the LevelDB key), which is the authoritative stored hash. Exit cleanly with a descriptive error instead of core dumping.Test plan
fluxd: chain.cpp:94: CBlockIndex* CBlockIndex::GetAncestor(int): Assertion 'pindexWalk->pprev' failed.(SIGABRT, exit code 134, 300+ restarts)ERROR: LoadBlockIndex(): corrupt block index entry at height 2225820: computed hash ... != stored key ...🤖 Generated with Claude Code