index: Add chainstate member to BaseIndex

This commit is contained in:
Carl Dong 2020-10-14 16:48:17 -04:00
parent f4a47a1feb
commit db33cde80f
8 changed files with 32 additions and 26 deletions

View file

@ -63,30 +63,31 @@ bool BaseIndex::Init()
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(m_chainstate->m_chain, locator);
}
m_synced = m_best_block_index.load() == ::ChainActive().Tip();
CChain& active_chain = m_chainstate->m_chain;
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 & BLOCK_HAVE_DATA)) {
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
while (block_to_test && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
@ -104,20 +105,20 @@ bool BaseIndex::Init()
return true;
}
static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
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()
@ -140,7 +141,7 @@ void BaseIndex::ThreadSync()
{
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;
@ -203,7 +204,7 @@ bool BaseIndex::Commit()
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;
}
@ -279,7 +280,7 @@ void BaseIndex::ChainStateFlushed(const CBlockLocator& locator)
const CBlockIndex* locator_tip_index;
{
LOCK(cs_main);
locator_tip_index = g_chainman.m_blockman.LookupBlockIndex(locator_tip_hash);
locator_tip_index = m_chainstate->m_blockman.LookupBlockIndex(locator_tip_hash);
}
if (!locator_tip_index) {
@ -320,7 +321,7 @@ bool BaseIndex::BlockUntilSyncedToCurrentChain() const
// 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;
@ -337,8 +338,10 @@ void BaseIndex::Interrupt()
m_interrupt();
}
bool BaseIndex::Start()
bool 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);

View file

@ -12,6 +12,7 @@
#include <validationinterface.h>
class CBlockIndex;
class CChainState;
struct IndexSummary {
std::string name;
@ -75,8 +76,9 @@ private:
/// to a chain reorganization), the index must halt until Commit succeeds or else it could end up
/// getting corrupted.
bool Commit();
protected:
CChainState* m_chainstate{nullptr};
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
void ChainStateFlushed(const CBlockLocator& locator) override;
@ -117,7 +119,7 @@ public:
/// Start initializes the sync state and registers the instance as a
/// ValidationInterface so that it stays in sync with blockchain updates.
[[nodiscard]] bool Start();
[[nodiscard]] bool Start(CChainState& active_chainstate);
/// Stops the instance from staying in sync with blockchain updates.
void Stop();

View file

@ -266,7 +266,7 @@ bool CoinStatsIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* n
{
LOCK(cs_main);
CBlockIndex* iter_tip{g_chainman.m_blockman.LookupBlockIndex(current_tip->GetBlockHash())};
CBlockIndex* iter_tip{m_chainstate->m_blockman.LookupBlockIndex(current_tip->GetBlockHash())};
const auto& consensus_params{Params().GetConsensus()};
do {

View file

@ -204,7 +204,7 @@ bool TxIndex::Init()
// 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;
}

View file

@ -1550,21 +1550,21 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
if (!g_txindex->Start()) {
if (!g_txindex->Start(::ChainstateActive())) {
return false;
}
}
for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
if (!GetBlockFilterIndex(filter_type)->Start()) {
if (!GetBlockFilterIndex(filter_type)->Start(::ChainstateActive())) {
return false;
}
}
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
g_coin_stats_index = std::make_unique<CoinStatsIndex>(/* cache size */ 0, false, fReindex);
if (!g_coin_stats_index->Start()) {
if (!g_coin_stats_index->Start(::ChainstateActive())) {
return false;
}
}

View file

@ -131,7 +131,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// BlockUntilSyncedToCurrentChain should return false before index is started.
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(filter_index.Start());
BOOST_REQUIRE(filter_index.Start(::ChainstateActive()));
// Allow filter index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000;

View file

@ -32,7 +32,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
// is started.
BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(coin_stats_index.Start());
BOOST_REQUIRE(coin_stats_index.Start(::ChainstateActive()));
// Allow the CoinStatsIndex to catch up with the block index that is syncing
// in a background thread.

View file

@ -7,6 +7,7 @@
#include <script/standard.h>
#include <test/util/setup_common.h>
#include <util/time.h>
#include <validation.h>
#include <boost/test/unit_test.hpp>
@ -27,7 +28,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
// BlockUntilSyncedToCurrentChain should return false before txindex is started.
BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain());
BOOST_REQUIRE(txindex.Start());
BOOST_REQUIRE(txindex.Start(::ChainstateActive()));
// Allow tx index to catch up with the block index.
constexpr int64_t timeout_ms = 10 * 1000;