This PR attempts to fix an intermittent Init issue encountered during the stress testing of #23289, which relates to the pruning-compatible filter reconstruction logic introduced in #15946.
The problem would occur when the node starts with -txindex=1
but ThreadSync
is interrupted after it sets m_best_block_index
to Genesis, and before it gets do any further work.
In that case, during the next restart of the node, an Init error would be thrown because BaseIndex::Init()
tries to backtrack from the tip to the last block which has been successfully indexed (here: Genesis), but the backtracking logic didn’t work properly in this case:
The loop
while (block_to_test && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA))
checks if a predecessor exists before performing the check block_to_test == block
and then possbily setting prune_violation = false
If block_to_test
and block
are the Genesis block this check will not be reached because block->pprev
does not exist.
To reproduce this bug on regtest:
- start a node with a fresh datadir using
-txindex=1
(or any other index) - stop and restart without any index
- mine a block
- stop and restart again with the index enabled
->InitError
Error: txindex best block of the index goes beyond pruned data. (...)
Fix this by requiring that we have the data for the block of the current iteration block
(instead of requiring it for the predecessor block->pprev
)
That way, the check for block_to_test == block
is also reached when block_to_test
is the Genesis block.
No longer requiring the data of block->pprev
also means that we can now prune up to m_best_block_index
height without requiring a reindex (one block more than before). I added this edge case to feature_blockfilterindex_prune.py
, the new version should fail on master.