From b0f32497b873cd1eaf0be86f8e265355aa86174f Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 6 Jul 2017 20:00:11 -0400 Subject: [PATCH] More user-friendly error message if UTXO DB runs ahead of block DB This gives LoadChainTip a return value - allowing it to indicate that the UTXO DB ran ahead of the block DB. This just provides a nicer error message instead of the previous mysterious assert(!setBlockIndexCandidates.empty()) error. This also calls ActivateBestChain in case we just loaded the genesis block in LoadChainTip, avoiding relying on the ActivateBestChain in ThreadImport before continuing init process. --- src/init.cpp | 10 +++++++++- src/validation.cpp | 17 ++++++++++++++--- src/validation.h | 2 +- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b1fe8e7d3c8..8fec69c2b87 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1442,7 +1442,15 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) break; } pcoinsTip = new CCoinsViewCache(pcoinscatcher); - LoadChainTip(chainparams); + + if (!fReindex && !fReindexChainState) { + // LoadChainTip sets chainActive based on pcoinsTip's best block + if (!LoadChainTip(chainparams)) { + strLoadError = _("Error initializing block database"); + break; + } + assert(chainActive.Tip() != NULL); + } if (!fReindex && chainActive.Tip() != NULL) { uiInterface.InitMessage(_("Rewinding blocks...")); diff --git a/src/validation.cpp b/src/validation.cpp index ebbdb7e651d..91982ead90f 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3538,14 +3538,24 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) return true; } -void LoadChainTip(const CChainParams& chainparams) +bool LoadChainTip(const CChainParams& chainparams) { - if (chainActive.Tip() && chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) return; + if (chainActive.Tip() && chainActive.Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) return true; + + if (pcoinsTip->GetBestBlock().IsNull() && mapBlockIndex.size() == 1) { + // In case we just added the genesis block, connect it now, so + // that we always have a chainActive.Tip() when we return. + LogPrintf("%s: Connecting genesis block...\n", __func__); + CValidationState state; + if (!ActivateBestChain(state, chainparams)) { + return false; + } + } // Load pointer to end of best chain BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); if (it == mapBlockIndex.end()) - return; + return false; chainActive.SetTip(it->second); PruneBlockIndexCandidates(); @@ -3554,6 +3564,7 @@ void LoadChainTip(const CChainParams& chainparams) chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), GuessVerificationProgress(chainparams.TxData(), chainActive.Tip())); + return true; } CVerifyDB::CVerifyDB() diff --git a/src/validation.h b/src/validation.h index 3ce5023f0ac..b1d482cbfbd 100644 --- a/src/validation.h +++ b/src/validation.h @@ -262,7 +262,7 @@ bool LoadGenesisBlock(const CChainParams& chainparams); * initializing state if we're running with -reindex. */ bool LoadBlockIndex(const CChainParams& chainparams); /** Update the chain tip based on database information. */ -void LoadChainTip(const CChainParams& chainparams); +bool LoadChainTip(const CChainParams& chainparams); /** Unload database information */ void UnloadBlockIndex(); /** Run an instance of the script checking thread */