use ChainstateManager to initialize chainstate

This allows us to easily initialize multiple chainstates on startup in future
commits. It retires the g_chainstate global in lieu of g_chainman.
This commit is contained in:
James O'Beirne
2019-12-12 10:48:28 -05:00
committed by James O'Beirne
parent 5b690f0aae
commit 4ae29f5f0c
5 changed files with 162 additions and 119 deletions

View File

@@ -77,20 +77,17 @@ bool CBlockIndexWorkComparator::operator()(const CBlockIndex *pa, const CBlockIn
return false;
}
namespace {
BlockManager g_blockman;
} // anon namespace
ChainstateManager g_chainman;
std::unique_ptr<CChainState> g_chainstate;
CChainState& ChainstateActive() {
assert(g_chainstate);
return *g_chainstate;
CChainState& ChainstateActive()
{
assert(g_chainman.m_active_chainstate);
return *g_chainman.m_active_chainstate;
}
CChain& ChainActive() {
assert(g_chainstate);
return g_chainstate->m_chain;
CChain& ChainActive()
{
return ::ChainstateActive().m_chain;
}
/**
@@ -152,8 +149,8 @@ namespace {
CBlockIndex* LookupBlockIndex(const uint256& hash)
{
AssertLockHeld(cs_main);
BlockMap::const_iterator it = g_blockman.m_block_index.find(hash);
return it == g_blockman.m_block_index.end() ? nullptr : it->second;
BlockMap::const_iterator it = g_chainman.BlockIndex().find(hash);
return it == g_chainman.BlockIndex().end() ? nullptr : it->second;
}
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
@@ -1243,13 +1240,10 @@ void CoinsViews::InitCache()
m_cacheview = MakeUnique<CCoinsViewCache>(&m_catcherview);
}
// NOTE: for now m_blockman is set to a global, but this will be changed
// in a future commit.
CChainState::CChainState(uint256 from_snapshot_blockhash)
: m_blockman(g_blockman),
CChainState::CChainState(BlockManager& blockman, uint256 from_snapshot_blockhash)
: m_blockman(blockman),
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
void CChainState::InitCoinsDB(
size_t cache_size_bytes,
bool in_memory,
@@ -1301,7 +1295,7 @@ static CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr;
BlockMap& BlockIndex()
{
return g_blockman.m_block_index;
return g_chainman.m_blockman.m_block_index;
}
static void AlertNotify(const std::string& strMessage)
@@ -3471,7 +3465,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
if (fCheckpointsEnabled) {
// Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// g_blockman.m_block_index.
// BlockIndex().
CBlockIndex* pcheckpoint = GetLastCheckpoint(params.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
@@ -3679,7 +3673,8 @@ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValid
LOCK(cs_main);
for (const CBlockHeader& header : headers) {
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
bool accepted = g_blockman.AcceptBlockHeader(header, state, chainparams, &pindex);
bool accepted = g_chainman.m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex);
::ChainstateActive().CheckBlockIndex(chainparams.GetConsensus());
if (!accepted) {
@@ -3881,7 +3876,7 @@ void PruneOneBlockFile(const int fileNumber)
{
LOCK(cs_LastBlockFile);
for (const auto& entry : g_blockman.m_block_index) {
for (const auto& entry : g_chainman.BlockIndex()) {
CBlockIndex* pindex = entry.second;
if (pindex->nFile == fileNumber) {
pindex->nStatus &= ~BLOCK_HAVE_DATA;
@@ -3895,12 +3890,12 @@ void PruneOneBlockFile(const int fileNumber)
// to be downloaded again in order to consider its chain, at which
// point it would be considered as a candidate for
// m_blocks_unlinked or setBlockIndexCandidates.
auto range = g_blockman.m_blocks_unlinked.equal_range(pindex->pprev);
auto range = g_chainman.m_blockman.m_blocks_unlinked.equal_range(pindex->pprev);
while (range.first != range.second) {
std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
range.first++;
if (_it->second == pindex) {
g_blockman.m_blocks_unlinked.erase(_it);
g_chainman.m_blockman.m_blocks_unlinked.erase(_it);
}
}
}
@@ -4137,9 +4132,11 @@ void BlockManager::Unload() {
bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
if (!g_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree, ::ChainstateActive().setBlockIndexCandidates))
if (!g_chainman.m_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree,
::ChainstateActive().setBlockIndexCandidates)) {
return false;
}
// Load block file info
pblocktree->ReadLastBlockFile(nLastBlockFile);
@@ -4161,7 +4158,7 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_RE
// Check presence of blk files
LogPrintf("Checking all blk files are present...\n");
std::set<int> setBlkDataFiles;
for (const std::pair<const uint256, CBlockIndex*>& item : g_blockman.m_block_index)
for (const std::pair<const uint256, CBlockIndex*>& item : g_chainman.BlockIndex())
{
CBlockIndex* pindex = item.second;
if (pindex->nStatus & BLOCK_HAVE_DATA) {
@@ -4564,8 +4561,7 @@ void CChainState::UnloadBlockIndex() {
void UnloadBlockIndex()
{
LOCK(cs_main);
::ChainActive().SetTip(nullptr);
g_blockman.Unload();
g_chainman.Unload();
pindexBestInvalid = nullptr;
pindexBestHeader = nullptr;
mempool.clear();
@@ -4578,8 +4574,6 @@ void UnloadBlockIndex()
warningcache[b].clear();
}
fHavePruned = false;
::ChainstateActive().UnloadBlockIndex();
}
bool LoadBlockIndex(const CChainParams& chainparams)
@@ -4589,7 +4583,7 @@ bool LoadBlockIndex(const CChainParams& chainparams)
if (!fReindex) {
bool ret = LoadBlockIndexDB(chainparams);
if (!ret) return false;
needs_init = g_blockman.m_block_index.empty();
needs_init = g_chainman.m_blockman.m_block_index.empty();
}
if (needs_init) {
@@ -5135,10 +5129,10 @@ public:
CMainCleanup() {}
~CMainCleanup() {
// block headers
BlockMap::iterator it1 = g_blockman.m_block_index.begin();
for (; it1 != g_blockman.m_block_index.end(); it1++)
BlockMap::iterator it1 = g_chainman.BlockIndex().begin();
for (; it1 != g_chainman.BlockIndex().end(); it1++)
delete (*it1).second;
g_blockman.m_block_index.clear();
g_chainman.BlockIndex().clear();
}
};
static CMainCleanup instance_of_cmaincleanup;
@@ -5176,7 +5170,7 @@ CChainState& ChainstateManager::InitializeChainstate(const uint256& snapshot_blo
throw std::logic_error("should not be overwriting a chainstate");
}
to_modify.reset(new CChainState(snapshot_blockhash));
to_modify.reset(new CChainState(m_blockman, snapshot_blockhash));
// Snapshot chainstates and initial IBD chaintates always become active.
if (is_snapshot || (!is_snapshot && !m_active_chainstate)) {
@@ -5220,6 +5214,8 @@ void ChainstateManager::Unload()
chainstate->m_chain.SetTip(nullptr);
chainstate->UnloadBlockIndex();
}
m_blockman.Unload();
}
void ChainstateManager::Reset()