When the block index database is non-contiguous due to file corruption (i.e. it contains indexes of height x-1 and x+1, but not x), bitcoind can currently crash with an assert in BuildSkip() / GetAncestor() during BlockManager::LoadBlockIndex():
0bitcoind: chain.cpp:112: const CBlockIndex* CBlockIndex::GetAncestor(int) const: Assertion `pindexWalk->pprev' failed.
This PR changes it such that we instead return an InitError to the user.
I stumbled upon this because I noticed that the file perturbation in feature_init.py wasn’t working as intended, which is fixed in the second commit:
- Opening the file twice in one
withstatement would lead totf_readbeing empty, so the test wouldn’t perturb anything but replace the file with a new one. Fixed by first opening for read, then for write. - We need to restore the previous state after perturbations, so that only the current perturbation is active and not a mix of the current and previous ones.
- I also added
checkblocks=200to the startup parameters so that corruption in earlier blocks ofblk00000.datis detected during init verification and not ignored.
After fixing feature_init.py like that I’d run into the assert mentioned above (so running the testfix from the second commit without the first one is a way to reproduce it).