diff --git a/src/init.cpp b/src/init.cpp index 8772be553..55991ac9b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -974,7 +974,7 @@ bool AppInit2(boost::thread_group& threadGroup) // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). - if (!mapBlockIndex.empty() && chainActive.Genesis() == NULL) + if (!mapBlockIndex.empty() && mapBlockIndex.count(Params().HashGenesisBlock()) == 0) 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) diff --git a/src/main.cpp b/src/main.cpp index 908f4c95b..0612f584a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1968,12 +1968,20 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo // Build list of new blocks to connect. std::vector vpindexToConnect; - vpindexToConnect.reserve(pindexMostWork->nHeight - (pindexFork ? pindexFork->nHeight : -1)); - CBlockIndex *pindexIter = pindexMostWork; - while (pindexIter && pindexIter != pindexFork) { + bool fContinue = true; + int nHeight = pindexFork ? pindexFork->nHeight : -1; + while (fContinue && nHeight != pindexMostWork->nHeight) { + // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need + // a few blocks along the way. + int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); + vpindexToConnect.clear(); + vpindexToConnect.reserve(nTargetHeight - nHeight); + CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); + while (pindexIter && pindexIter->nHeight != nHeight) { vpindexToConnect.push_back(pindexIter); pindexIter = pindexIter->pprev; } + nHeight = nTargetHeight; // Connect new blocks. BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { @@ -1984,6 +1992,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo InvalidChainFound(vpindexToConnect.back()); state = CValidationState(); fInvalidFound = true; + fContinue = false; break; } else { // A system error occurred (disk space, database error, ...). @@ -2001,10 +2010,12 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo assert(!setBlockIndexCandidates.empty()); if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { // We're in a better position than we were. Return temporarily to release the lock. + fContinue = false; break; } } } + } // Callbacks/notifications for a new best chain. if (fInvalidFound)