Call RewindBlockIndex even if we're about to run -reindex-chainstate

RewindBlockIndex works over both chainActive - disconnecting blocks
from the tip that need witness verification - and mapBlockIndex -
requiring redownload of blocks missing witness data.

It should never have been the case that the second half is skipped
if we're about to run -reindex-chainstate.
This commit is contained in:
Matt Corallo 2017-07-06 21:29:46 -04:00
parent b0f32497b8
commit ff3a21919d
2 changed files with 17 additions and 5 deletions

View file

@ -1452,7 +1452,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
assert(chainActive.Tip() != NULL);
}
if (!fReindex && chainActive.Tip() != NULL) {
if (!fReindex) {
// Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
// It both disconnects blocks based on chainActive, and drops block data in
// mapBlockIndex based on lack of available witness data.
uiInterface.InitMessage(_("Rewinding blocks..."));
if (!RewindBlockIndex(chainparams)) {
strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain");

View file

@ -3763,6 +3763,8 @@ bool RewindBlockIndex(const CChainParams& params)
{
LOCK(cs_main);
// Note that during -reindex-chainstate we are called with an empty chainActive!
int nHeight = 1;
while (nHeight <= chainActive.Height()) {
if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus()) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) {
@ -3832,12 +3834,19 @@ bool RewindBlockIndex(const CChainParams& params)
}
}
PruneBlockIndexCandidates();
if (chainActive.Tip() != NULL) {
// We can't prune block index candidates based on our tip if we have
// no tip due to chainActive being empty!
PruneBlockIndexCandidates();
CheckBlockIndex(params.GetConsensus());
CheckBlockIndex(params.GetConsensus());
if (!FlushStateToDisk(params, state, FLUSH_STATE_ALWAYS)) {
return false;
// FlushStateToDisk can possibly read chainActive. Be conservative
// and skip it here, we're about to -reindex-chainstate anyway, so
// it'll get called a bunch real soon.
if (!FlushStateToDisk(params, state, FLUSH_STATE_ALWAYS)) {
return false;
}
}
return true;