Order chainstate init more logically.

* Order chainstate init more logically - first all of the
  blocktree-related loading, then coinsdb, then
  pcoinsTip/chainActive. Only create objects as needed.

* More clearly document exactly what is and isn't called in
  -reindex and -reindex-chainstate both with comments noting
  calls as no-ops and by adding if guards.

* Move LoadGenesisBlock further down in init. This is a more logical
  location for it, as it is after all of the blockindex-related
  loading and checking, but before any of the UTXO-related loading
  and checking.

* Move all of the VerifyDB()-related stuff into a -reindex +
  -reindex-chainstate if guard. It couldn't do anything useful
  as chainActive.Tip() would be null at this point anyway.
pull/10758/head
Matt Corallo 7 years ago
parent ff3a21919d
commit 138569722c

@ -1391,23 +1391,19 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
delete pblocktree; delete pblocktree;
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState);
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
if (fReindex) { if (fReindex) {
pblocktree->WriteReindexing(true); pblocktree->WriteReindexing(true);
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
if (fPruneMode) if (fPruneMode)
CleanupBlockRevFiles(); CleanupBlockRevFiles();
} else {
// If necessary, upgrade from older database format.
if (!pcoinsdbview->Upgrade()) {
strLoadError = _("Error upgrading chainstate database");
break;
}
} }
if (fRequestShutdown) break; if (fRequestShutdown) break;
// LoadBlockIndex will load fTxIndex from the db, or set it if
// we're reindexing. It will also load fHavePruned if we've
// ever removed a block file from disk.
if (!LoadBlockIndex(chainparams)) { if (!LoadBlockIndex(chainparams)) {
strLoadError = _("Error loading block database"); strLoadError = _("Error loading block database");
break; break;
@ -1418,12 +1414,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0) if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0)
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
// Initialize the block index (no-op if non-empty database was already loaded)
if (!fReindex && !LoadGenesisBlock(chainparams)) {
strLoadError = _("Error initializing block database");
break;
}
// Check for changed -txindex state // Check for changed -txindex state
if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
strLoadError = _("You need to rebuild the database using -reindex-chainstate to change -txindex"); strLoadError = _("You need to rebuild the database using -reindex-chainstate to change -txindex");
@ -1437,10 +1427,34 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
break; break;
} }
// At this point blocktree args are consistent with what's on disk.
// If we're not mid-reindex (based on disk + args), add a genesis block on disk.
// This is called again in ThreadImport in the reindex completes.
if (!fReindex && !LoadGenesisBlock(chainparams)) {
strLoadError = _("Error initializing block database");
break;
}
// At this point we're either in reindex or we've loaded a useful
// block tree into mapBlockIndex!
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState);
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
// If necessary, upgrade from older database format.
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
if (!pcoinsdbview->Upgrade()) {
strLoadError = _("Error upgrading chainstate database");
break;
}
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
if (!ReplayBlocks(chainparams, pcoinsdbview)) { if (!ReplayBlocks(chainparams, pcoinsdbview)) {
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate."); strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
break; break;
} }
// The on-disk coinsdb is now in a good state, create the cache
pcoinsTip = new CCoinsViewCache(pcoinscatcher); pcoinsTip = new CCoinsViewCache(pcoinscatcher);
if (!fReindex && !fReindexChainState) { if (!fReindex && !fReindexChainState) {
@ -1463,28 +1477,30 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
} }
} }
uiInterface.InitMessage(_("Verifying blocks...")); if (!fReindex && !fReindexChainState) {
if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { uiInterface.InitMessage(_("Verifying blocks..."));
LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
MIN_BLOCKS_TO_KEEP); LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks",
} MIN_BLOCKS_TO_KEEP);
}
{ {
LOCK(cs_main); LOCK(cs_main);
CBlockIndex* tip = chainActive.Tip(); CBlockIndex* tip = chainActive.Tip();
RPCNotifyBlockChange(true, tip); RPCNotifyBlockChange(true, tip);
if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) { if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
strLoadError = _("The block database contains a block which appears to be from the future. " strLoadError = _("The block database contains a block which appears to be from the future. "
"This may be due to your computer's date and time being set incorrectly. " "This may be due to your computer's date and time being set incorrectly. "
"Only rebuild the block database if you are sure that your computer's date and time are correct"); "Only rebuild the block database if you are sure that your computer's date and time are correct");
break; break;
}
} }
}
if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL), if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL),
GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
strLoadError = _("Corrupted block database detected"); strLoadError = _("Corrupted block database detected");
break; break;
}
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
LogPrintf("%s\n", e.what()); LogPrintf("%s\n", e.what());

Loading…
Cancel
Save