From 9b87537d59f5aefd6d3206e1318c045411213c15 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 | 12 +++++++++++- src/validation.cpp | 20 ++++++++++++++++---- src/validation.h | 2 +- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index a179ea5bf73c3..f2a54b1f2cd91 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1636,7 +1636,17 @@ bool AppInitMain() break; } pcoinsTip = new CCoinsViewCache(pcoinscatcher); - LoadChainTip(chainparams); + + // !TODO: after enabling reindex-chainstate + // if (!fReindex && !fReindexChainState) { + if (!fReindex) { + // LoadChainTip sets chainActive based on pcoinsTip's best block + if (!LoadChainTip(chainparams)) { + strLoadError = _("Error initializing block database"); + break; + } + assert(chainActive.Tip() != NULL); + } // Populate list of invalid/fraudulent outpoints that are banned from the chain invalid_out::LoadOutpoints(); diff --git a/src/validation.cpp b/src/validation.cpp index 5e882b3b21ed3..dcee17ea8a0e6 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3517,14 +3517,25 @@ bool static LoadBlockIndexDB(std::string& strError) 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)) { + return false; + } + } // Load pointer to end of best chain BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); - if (it == mapBlockIndex.end()) - return; + if (it == mapBlockIndex.end()) { + return false; + } chainActive.SetTip(it->second); PruneBlockIndexCandidates(); @@ -3535,6 +3546,7 @@ void LoadChainTip(const CChainParams& chainparams) pChainTip->GetBlockHash().GetHex(), pChainTip->nHeight, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pChainTip->GetBlockTime()), Checkpoints::GuessVerificationProgress(pChainTip)); + return true; } CVerifyDB::CVerifyDB() diff --git a/src/validation.h b/src/validation.h index d0ff2c1d9f3f2..d6f37cfc6ffb3 100644 --- a/src/validation.h +++ b/src/validation.h @@ -189,7 +189,7 @@ bool LoadGenesisBlock(); * initializing state if we're running with -reindex. */ bool LoadBlockIndex(std::string& strError); /** Update the chain tip based on database information. */ -void LoadChainTip(const CChainParams& chainparams); +bool LoadChainTip(const CChainParams& chainparams); /** Unload database information */ void UnloadBlockIndex(); /** See whether the protocol update is enforced for connected nodes */