Skip to content

Commit

Permalink
Call RewindBlockIndex even if we're about to run -reindex-chainstate
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
TheBlueMatt committed Jul 27, 2017
1 parent b0f3249 commit ff3a219
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
5 changes: 4 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
17 changes: 13 additions & 4 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit ff3a219

Please sign in to comment.