diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -2492,7 +2492,7 @@ // ReplayBlocks is a no-op if we cleared the coinsviewdb with // -reindex or -reindex-chainstate - if (!ReplayBlocks(params, &::ChainstateActive().CoinsDB())) { + if (!::ChainstateActive().ReplayBlocks(params)) { strLoadError = _("Unable to replay blocks. You will need to rebuild " "the database using -reindex-chainstate.") @@ -2508,9 +2508,9 @@ fReset || fReindexChainState || ::ChainstateActive().CoinsTip().GetBestBlock().IsNull(); if (!is_coinsview_empty) { - // LoadChainTip sets ::ChainActive() based on CoinsTip()'s + // LoadChainTip initializes the chain based on CoinsTip()'s // best block - if (!LoadChainTip(config)) { + if (!::ChainstateActive().LoadChainTip(chainparams)) { strLoadError = _("Error initializing block database").translated; break; diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -337,11 +337,6 @@ bool LoadBlockIndex(const Consensus::Params ¶ms) EXCLUSIVE_LOCKS_REQUIRED(cs_main); -/** - * Update the chain tip based on database information. - */ -bool LoadChainTip(const Config &config) EXCLUSIVE_LOCKS_REQUIRED(cs_main); - /** * Unload database information. */ @@ -661,9 +656,6 @@ int nCheckDepth); }; -/** Replay blocks that aren't fully applied to the database. */ -bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view); - CBlockIndex *LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main); @@ -931,6 +923,9 @@ * we avoid holding cs_main for an extended period of time; the length of * this call may be quite long during reindexing or a substantial reorg. * + * May not be called with cs_main held. May not be called in a + * validationinterface callback. + * * @returns true unless a system error occurred */ bool ActivateBestChain( @@ -1000,7 +995,8 @@ void UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren) EXCLUSIVE_LOCKS_REQUIRED(cs_main); - bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view); + /** Replay blocks that aren't fully applied to the database. */ + bool ReplayBlocks(const Consensus::Params ¶ms); bool LoadGenesisBlock(const CChainParams &chainparams); void PruneBlockIndexCandidates(); @@ -1021,6 +1017,11 @@ */ void CheckBlockIndex(const Consensus::Params &consensusParams); + /** Update the chain tip based on database information, i.e. CoinsTip()'s + * best block. */ + bool LoadChainTip(const CChainParams &chainparams) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + private: bool ActivateBestChainStep(const Config &config, BlockValidationState &state, diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4625,14 +4625,14 @@ return true; } -bool LoadChainTip(const Config &config) { +bool CChainState::LoadChainTip(const CChainParams &chainparams) { AssertLockHeld(cs_main); - const CCoinsViewCache &coins_cache = ::ChainstateActive().CoinsTip(); + const CCoinsViewCache &coins_cache = CoinsTip(); // Never called when the coins view is empty assert(!coins_cache.GetBestBlock().IsNull()); + const CBlockIndex *tip = m_chain.Tip(); - if (::ChainActive().Tip() && - ::ChainActive().Tip()->GetBlockHash() == coins_cache.GetBestBlock()) { + if (tip && tip->GetBlockHash() == coins_cache.GetBestBlock()) { return true; } @@ -4641,17 +4641,15 @@ if (!pindex) { return false; } - ::ChainActive().SetTip(pindex); - - ::ChainstateActive().PruneBlockIndexCandidates(); + m_chain.SetTip(pindex); + PruneBlockIndexCandidates(); + tip = m_chain.Tip(); LogPrintf( "Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n", - ::ChainActive().Tip()->GetBlockHash().ToString(), - ::ChainActive().Height(), - FormatISO8601DateTime(::ChainActive().Tip()->GetBlockTime()), - GuessVerificationProgress(config.GetChainParams().TxData(), - ::ChainActive().Tip())); + tip->GetBlockHash().ToString(), m_chain.Height(), + FormatISO8601DateTime(tip->GetBlockTime()), + GuessVerificationProgress(chainparams.TxData(), tip)); return true; } @@ -4861,18 +4859,17 @@ return true; } -bool CChainState::ReplayBlocks(const Consensus::Params ¶ms, - CCoinsView *view) { +bool CChainState::ReplayBlocks(const Consensus::Params ¶ms) { LOCK(cs_main); - CCoinsViewCache cache(view); + CCoinsView &db = this->CoinsDB(); + CCoinsViewCache cache(&db); - std::vector hashHeads = view->GetHeadBlocks(); + std::vector hashHeads = db.GetHeadBlocks(); if (hashHeads.empty()) { // We're already in a consistent state. return true; } - if (hashHeads.size() != 2) { return error("ReplayBlocks(): unknown inconsistent state"); } @@ -4960,10 +4957,6 @@ return true; } -bool ReplayBlocks(const Consensus::Params ¶ms, CCoinsView *view) { - return ::ChainstateActive().ReplayBlocks(params, view); -} - // May NOT be used after any connections are up as much of the peer-processing // logic assumes a consistent block index state void CChainState::UnloadBlockIndex() {