diff --git a/src/index/base.h b/src/index/base.h --- a/src/index/base.h +++ b/src/index/base.h @@ -12,6 +12,7 @@ #include class CBlockIndex; +class CChainState; struct IndexSummary { std::string name; @@ -77,6 +78,8 @@ bool Commit(); protected: + CChainState *m_chainstate{nullptr}; + void BlockConnected(const std::shared_ptr &block, const CBlockIndex *pindex) override; @@ -121,7 +124,7 @@ /// Start initializes the sync state and registers the instance as a /// ValidationInterface so that it stays in sync with blockchain updates. - void Start(); + void Start(CChainState &active_chainstate); /// Stops the instance from staying in sync with blockchain updates. void Stop(); diff --git a/src/index/base.cpp b/src/index/base.cpp --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -61,34 +61,35 @@ } LOCK(cs_main); + CChain &active_chain = m_chainstate->m_chain; if (locator.IsNull()) { m_best_block_index = nullptr; } else { - m_best_block_index = g_chainman.m_blockman.FindForkInGlobalIndex( - ::ChainActive(), locator); + m_best_block_index = m_chainstate->m_blockman.FindForkInGlobalIndex( + active_chain, locator); } - m_synced = m_best_block_index.load() == ::ChainActive().Tip(); + m_synced = m_best_block_index.load() == active_chain.Tip(); if (!m_synced) { bool prune_violation = false; if (!m_best_block_index) { // index is not built yet // make sure we have all block data back to the genesis - const CBlockIndex *block = ::ChainActive().Tip(); + const CBlockIndex *block = active_chain.Tip(); while (block->pprev && block->pprev->nStatus.hasData()) { block = block->pprev; } - prune_violation = block != ::ChainActive().Genesis(); + prune_violation = block != active_chain.Genesis(); } // in case the index has a best block set and is not fully synced // check if we have the required blocks to continue building the index else { const CBlockIndex *block_to_test = m_best_block_index.load(); - if (!ChainActive().Contains(block_to_test)) { + if (!active_chain.Contains(block_to_test)) { // if the bestblock is not part of the mainchain, find the fork // and make sure we have all data down to the fork - block_to_test = ::ChainActive().FindFork(block_to_test); + block_to_test = active_chain.FindFork(block_to_test); } - const CBlockIndex *block = ::ChainActive().Tip(); + const CBlockIndex *block = active_chain.Tip(); prune_violation = true; // check backwards from the tip if we have all block data until we // reach the indexes bestblock @@ -116,20 +117,21 @@ return true; } -static const CBlockIndex *NextSyncBlock(const CBlockIndex *pindex_prev) +static const CBlockIndex *NextSyncBlock(const CBlockIndex *pindex_prev, + CChain &chain) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); if (!pindex_prev) { - return ::ChainActive().Genesis(); + return chain.Genesis(); } - const CBlockIndex *pindex = ::ChainActive().Next(pindex_prev); + const CBlockIndex *pindex = chain.Next(pindex_prev); if (pindex) { return pindex; } - return ::ChainActive().Next(::ChainActive().FindFork(pindex_prev)); + return chain.Next(chain.FindFork(pindex_prev)); } void BaseIndex::ThreadSync() { @@ -152,7 +154,8 @@ { LOCK(cs_main); - const CBlockIndex *pindex_next = NextSyncBlock(pindex); + const CBlockIndex *pindex_next = + NextSyncBlock(pindex, m_chainstate->m_chain); if (!pindex_next) { m_best_block_index = pindex; m_synced = true; @@ -217,8 +220,8 @@ bool BaseIndex::CommitInternal(CDBBatch &batch) { LOCK(cs_main); - GetDB().WriteBestBlock(batch, - ::ChainActive().GetLocator(m_best_block_index)); + GetDB().WriteBestBlock( + batch, m_chainstate->m_chain.GetLocator(m_best_block_index)); return true; } @@ -299,7 +302,7 @@ { LOCK(cs_main); locator_tip_index = - g_chainman.m_blockman.LookupBlockIndex(locator_tip_hash); + m_chainstate->m_blockman.LookupBlockIndex(locator_tip_hash); } if (!locator_tip_index) { @@ -342,7 +345,7 @@ // Skip the queue-draining stuff if we know we're caught up with // ::ChainActive().Tip(). LOCK(cs_main); - const CBlockIndex *chain_tip = ::ChainActive().Tip(); + const CBlockIndex *chain_tip = m_chainstate->m_chain.Tip(); const CBlockIndex *best_block_index = m_best_block_index.load(); if (best_block_index->GetAncestor(chain_tip->nHeight) == chain_tip) { return true; @@ -359,7 +362,10 @@ m_interrupt(); } -void BaseIndex::Start() { +void BaseIndex::Start(CChainState &active_chainstate) { + assert(std::addressof(::ChainstateActive()) == + std::addressof(active_chainstate)); + m_chainstate = &active_chainstate; // Need to register this ValidationInterface before running Init(), so that // callbacks are not missed if Init sets m_synced to true. RegisterValidationInterface(this); diff --git a/src/index/coinstatsindex.cpp b/src/index/coinstatsindex.cpp --- a/src/index/coinstatsindex.cpp +++ b/src/index/coinstatsindex.cpp @@ -291,7 +291,7 @@ { LOCK(cs_main); - CBlockIndex *iter_tip{g_chainman.m_blockman.LookupBlockIndex( + CBlockIndex *iter_tip{m_chainstate->m_blockman.LookupBlockIndex( current_tip->GetBlockHash())}; const auto &consensus_params{Params().GetConsensus()}; diff --git a/src/index/txindex.cpp b/src/index/txindex.cpp --- a/src/index/txindex.cpp +++ b/src/index/txindex.cpp @@ -209,7 +209,7 @@ // Attempt to migrate txindex from the old database to the new one. Even if // chain_tip is null, the node could be reindexing and we still want to // delete txindex records in the old database. - if (!m_db->MigrateData(*pblocktree, ::ChainActive().GetLocator())) { + if (!m_db->MigrateData(*pblocktree, m_chainstate->m_chain.GetLocator())) { return false; } diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -2865,18 +2865,18 @@ // Step 8: load indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { g_txindex = std::make_unique(nTxIndexCache, false, fReindex); - g_txindex->Start(); + g_txindex->Start(::ChainstateActive()); } for (const auto &filter_type : g_enabled_filter_types) { InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex); - GetBlockFilterIndex(filter_type)->Start(); + GetBlockFilterIndex(filter_type)->Start(::ChainstateActive()); } if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) { g_coin_stats_index = std::make_unique( /* cache size */ 0, false, fReindex); - g_coin_stats_index->Start(); + g_coin_stats_index->Start(::ChainstateActive()); } // Step 9: load wallet for (const auto &client : node.chain_clients) { diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -146,7 +146,7 @@ // started. BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain()); - filter_index.Start(); + filter_index.Start(::ChainstateActive()); // Allow filter index to catch up with the block index. constexpr int64_t timeout_ms = 10 * 1000; diff --git a/src/test/coinstatsindex_tests.cpp b/src/test/coinstatsindex_tests.cpp --- a/src/test/coinstatsindex_tests.cpp +++ b/src/test/coinstatsindex_tests.cpp @@ -30,7 +30,7 @@ // is started. BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain()); - coin_stats_index.Start(); + coin_stats_index.Start(::ChainstateActive()); // Allow the CoinStatsIndex to catch up with the block index that is syncing // in a background thread. diff --git a/src/test/txindex_tests.cpp b/src/test/txindex_tests.cpp --- a/src/test/txindex_tests.cpp +++ b/src/test/txindex_tests.cpp @@ -7,6 +7,7 @@ #include #include