refactoring: remove mapBlockIndex global
in lieu of ::BlockIndex().
This commit is contained in:
parent
55d525ab90
commit
682a1d0f20
6 changed files with 48 additions and 39 deletions
11
src/init.cpp
11
src/init.cpp
|
@ -492,7 +492,7 @@ void SetupServerArgs()
|
|||
"and level 4 tries to reconnect the blocks, "
|
||||
"each level includes the checks of the previous levels "
|
||||
"(0-4, default: %u)", DEFAULT_CHECKLEVEL), true, OptionsCategory::DEBUG_TEST);
|
||||
gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, ::ChainActive() and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
|
||||
gArgs.AddArg("-checkblockindex", strprintf("Do a full consistency check for the block tree, setBlockIndexCandidates, ::ChainActive() and mapBlocksUnlinked occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
|
||||
gArgs.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), true, OptionsCategory::DEBUG_TEST);
|
||||
gArgs.AddArg("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED), true, OptionsCategory::DEBUG_TEST);
|
||||
gArgs.AddArg("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used", true, OptionsCategory::DEBUG_TEST);
|
||||
|
@ -1517,7 +1517,8 @@ bool AppInitMain(InitInterfaces& interfaces)
|
|||
|
||||
// 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() && !LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
|
||||
if (!::BlockIndex().empty() &&
|
||||
!LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
|
||||
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
|
||||
}
|
||||
|
||||
|
@ -1538,7 +1539,7 @@ bool AppInitMain(InitInterfaces& interfaces)
|
|||
}
|
||||
|
||||
// At this point we're either in reindex or we've loaded a useful
|
||||
// block tree into mapBlockIndex!
|
||||
// block tree into BlockIndex()!
|
||||
|
||||
pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
|
||||
pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
|
||||
|
@ -1577,7 +1578,7 @@ bool AppInitMain(InitInterfaces& interfaces)
|
|||
if (!fReset) {
|
||||
// Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
|
||||
// It both disconnects blocks based on ::ChainActive(), and drops block data in
|
||||
// mapBlockIndex based on lack of available witness data.
|
||||
// BlockIndex() based on lack of available witness data.
|
||||
uiInterface.InitMessage(_("Rewinding blocks..."));
|
||||
if (!RewindBlockIndex(chainparams)) {
|
||||
strLoadError = _("Unable to rewind the database to a pre-fork state. You will need to redownload the blockchain");
|
||||
|
@ -1749,7 +1750,7 @@ bool AppInitMain(InitInterfaces& interfaces)
|
|||
//// debug print
|
||||
{
|
||||
LOCK(cs_main);
|
||||
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
||||
LogPrintf("block tree size = %u\n", ::BlockIndex().size());
|
||||
chain_active_height = ::ChainActive().Height();
|
||||
}
|
||||
LogPrintf("nBestHeight = %d\n", chain_active_height);
|
||||
|
|
|
@ -1456,7 +1456,7 @@ static UniValue getchaintips(const JSONRPCRequest& request)
|
|||
/*
|
||||
* Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks which do not have another orphan building off of them.
|
||||
* Algorithm:
|
||||
* - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
|
||||
* - Make one pass through g_blockman.m_block_index, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
|
||||
* - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
|
||||
* - add ::ChainActive().Tip()
|
||||
*/
|
||||
|
@ -1464,7 +1464,7 @@ static UniValue getchaintips(const JSONRPCRequest& request)
|
|||
std::set<const CBlockIndex*> setOrphans;
|
||||
std::set<const CBlockIndex*> setPrevs;
|
||||
|
||||
for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
|
||||
for (const std::pair<const uint256, CBlockIndex*>& item : ::BlockIndex())
|
||||
{
|
||||
if (!::ChainActive().Contains(item.second)) {
|
||||
setOrphans.insert(item.second);
|
||||
|
|
|
@ -250,7 +250,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams,
|
|||
|
||||
pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
|
||||
|
||||
// Load mapBlockIndex
|
||||
// Load m_block_index
|
||||
while (pcursor->Valid()) {
|
||||
boost::this_thread::interruption_point();
|
||||
if (ShutdownRequested()) return false;
|
||||
|
|
|
@ -99,7 +99,6 @@ CChain& ChainActive() { return g_chainstate.m_chain; }
|
|||
*/
|
||||
RecursiveMutex cs_main;
|
||||
|
||||
BlockMap& mapBlockIndex = g_blockman.m_block_index;
|
||||
CBlockIndex *pindexBestHeader = nullptr;
|
||||
Mutex g_best_block_mutex;
|
||||
std::condition_variable g_best_block_cv;
|
||||
|
@ -147,6 +146,13 @@ namespace {
|
|||
std::set<int> setDirtyFileInfo;
|
||||
} // anon 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;
|
||||
}
|
||||
|
||||
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
@ -1046,6 +1052,11 @@ bool CChainState::IsInitialBlockDownload() const
|
|||
|
||||
static CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr;
|
||||
|
||||
BlockMap& BlockIndex()
|
||||
{
|
||||
return g_blockman.m_block_index;
|
||||
}
|
||||
|
||||
static void AlertNotify(const std::string& strMessage)
|
||||
{
|
||||
uiInterface.NotifyAlertChanged();
|
||||
|
@ -3117,7 +3128,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
|
|||
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
|
||||
// MapBlockIndex.
|
||||
// g_blockman.m_block_index.
|
||||
CBlockIndex* pcheckpoint = GetLastCheckpoint(params.Checkpoints());
|
||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_CHECKPOINT, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint");
|
||||
|
@ -3715,8 +3726,8 @@ bool BlockManager::LoadBlockIndex(
|
|||
|
||||
// Calculate nChainWork
|
||||
std::vector<std::pair<int, CBlockIndex*> > vSortedByHeight;
|
||||
vSortedByHeight.reserve(mapBlockIndex.size());
|
||||
for (const std::pair<const uint256, CBlockIndex*>& item : mapBlockIndex)
|
||||
vSortedByHeight.reserve(m_block_index.size());
|
||||
for (const std::pair<const uint256, CBlockIndex*>& item : m_block_index)
|
||||
{
|
||||
CBlockIndex* pindex = item.second;
|
||||
vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex));
|
||||
|
@ -3797,7 +3808,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 : mapBlockIndex)
|
||||
for (const std::pair<const uint256, CBlockIndex*>& item : g_blockman.m_block_index)
|
||||
{
|
||||
CBlockIndex* pindex = item.second;
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) {
|
||||
|
@ -3996,16 +4007,16 @@ bool CChainState::ReplayBlocks(const CChainParams& params, CCoinsView* view)
|
|||
const CBlockIndex* pindexNew; // New tip during the interrupted flush.
|
||||
const CBlockIndex* pindexFork = nullptr; // Latest block common to both the old and the new tip.
|
||||
|
||||
if (mapBlockIndex.count(hashHeads[0]) == 0) {
|
||||
if (m_blockman.m_block_index.count(hashHeads[0]) == 0) {
|
||||
return error("ReplayBlocks(): reorganization to unknown block requested");
|
||||
}
|
||||
pindexNew = mapBlockIndex[hashHeads[0]];
|
||||
pindexNew = m_blockman.m_block_index[hashHeads[0]];
|
||||
|
||||
if (!hashHeads[1].IsNull()) { // The old tip is allowed to be 0, indicating it's the first flush.
|
||||
if (mapBlockIndex.count(hashHeads[1]) == 0) {
|
||||
if (m_blockman.m_block_index.count(hashHeads[1]) == 0) {
|
||||
return error("ReplayBlocks(): reorganization from unknown block requested");
|
||||
}
|
||||
pindexOld = mapBlockIndex[hashHeads[1]];
|
||||
pindexOld = m_blockman.m_block_index[hashHeads[1]];
|
||||
pindexFork = LastCommonAncestor(pindexOld, pindexNew);
|
||||
assert(pindexFork != nullptr);
|
||||
}
|
||||
|
@ -4094,7 +4105,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
|
|||
// blocks will be dealt with below (releasing cs_main in between).
|
||||
{
|
||||
LOCK(cs_main);
|
||||
for (const auto& entry : mapBlockIndex) {
|
||||
for (const auto& entry : m_blockman.m_block_index) {
|
||||
if (IsWitnessEnabled(entry.second->pprev, params.GetConsensus()) && !(entry.second->nStatus & BLOCK_OPT_WITNESS) && !m_chain.Contains(entry.second)) {
|
||||
EraseBlockData(entry.second);
|
||||
}
|
||||
|
@ -4234,7 +4245,7 @@ bool LoadBlockIndex(const CChainParams& chainparams)
|
|||
if (!fReindex) {
|
||||
bool ret = LoadBlockIndexDB(chainparams);
|
||||
if (!ret) return false;
|
||||
needs_init = mapBlockIndex.empty();
|
||||
needs_init = g_blockman.m_block_index.empty();
|
||||
}
|
||||
|
||||
if (needs_init) {
|
||||
|
@ -4254,10 +4265,10 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
|
|||
LOCK(cs_main);
|
||||
|
||||
// Check whether we're already initialized by checking for genesis in
|
||||
// mapBlockIndex. Note that we can't use m_chain here, since it is
|
||||
// m_blockman.m_block_index. Note that we can't use m_chain here, since it is
|
||||
// set based on the coins db, not the block index db, which is the only
|
||||
// thing loaded at this point.
|
||||
if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash()))
|
||||
if (m_blockman.m_block_index.count(chainparams.GenesisBlock().GetHash()))
|
||||
return true;
|
||||
|
||||
try {
|
||||
|
@ -4410,20 +4421,20 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
|
|||
LOCK(cs_main);
|
||||
|
||||
// During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
|
||||
// so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
|
||||
// iterating the block tree require that m_chain has been initialized.)
|
||||
// so we have the genesis block in m_blockman.m_block_index but no active chain. (A few of the
|
||||
// tests when iterating the block tree require that m_chain has been initialized.)
|
||||
if (m_chain.Height() < 0) {
|
||||
assert(mapBlockIndex.size() <= 1);
|
||||
assert(m_blockman.m_block_index.size() <= 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build forward-pointing map of the entire block tree.
|
||||
std::multimap<CBlockIndex*,CBlockIndex*> forward;
|
||||
for (const std::pair<const uint256, CBlockIndex*>& entry : mapBlockIndex) {
|
||||
for (const std::pair<const uint256, CBlockIndex*>& entry : m_blockman.m_block_index) {
|
||||
forward.insert(std::make_pair(entry.second->pprev, entry.second));
|
||||
}
|
||||
|
||||
assert(forward.size() == mapBlockIndex.size());
|
||||
assert(forward.size() == m_blockman.m_block_index.size());
|
||||
|
||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(nullptr);
|
||||
CBlockIndex *pindex = rangeGenesis.first->second;
|
||||
|
@ -4477,7 +4488,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
|
|||
assert(pindex->nHeight == nHeight); // nHeight must be consistent.
|
||||
assert(pindex->pprev == nullptr || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
|
||||
assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
|
||||
assert(pindexFirstNotTreeValid == nullptr); // All mapBlockIndex entries must at least be TREE valid
|
||||
assert(pindexFirstNotTreeValid == nullptr); // All m_blockman.m_block_index entries must at least be TREE valid
|
||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == nullptr); // TREE valid implies all parents are TREE valid
|
||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == nullptr); // CHAIN valid implies all parents are CHAIN valid
|
||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == nullptr); // SCRIPTS valid implies all parents are SCRIPTS valid
|
||||
|
@ -4772,10 +4783,10 @@ public:
|
|||
CMainCleanup() {}
|
||||
~CMainCleanup() {
|
||||
// block headers
|
||||
BlockMap::iterator it1 = mapBlockIndex.begin();
|
||||
for (; it1 != mapBlockIndex.end(); it1++)
|
||||
BlockMap::iterator it1 = g_blockman.m_block_index.begin();
|
||||
for (; it1 != g_blockman.m_block_index.end(); it1++)
|
||||
delete (*it1).second;
|
||||
mapBlockIndex.clear();
|
||||
g_blockman.m_block_index.clear();
|
||||
}
|
||||
};
|
||||
static CMainCleanup instance_of_cmaincleanup;
|
||||
|
|
|
@ -144,7 +144,6 @@ extern CCriticalSection cs_main;
|
|||
extern CBlockPolicyEstimator feeEstimator;
|
||||
extern CTxMemPool mempool;
|
||||
typedef std::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap;
|
||||
extern BlockMap& mapBlockIndex GUARDED_BY(cs_main);
|
||||
extern Mutex g_best_block_mutex;
|
||||
extern std::condition_variable g_best_block_cv;
|
||||
extern uint256 g_best_block;
|
||||
|
@ -406,12 +405,7 @@ public:
|
|||
/** Replay blocks that aren't fully applied to the database. */
|
||||
bool ReplayBlocks(const CChainParams& params, CCoinsView* view);
|
||||
|
||||
inline CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
BlockMap::const_iterator it = mapBlockIndex.find(hash);
|
||||
return it == mapBlockIndex.end() ? nullptr : it->second;
|
||||
}
|
||||
CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
||||
/** Find the last common block between the parameter chain and a locator. */
|
||||
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
|
@ -498,7 +492,7 @@ public:
|
|||
|
||||
/**
|
||||
* If a block header hasn't already been seen, call CheckBlockHeader on it, ensure
|
||||
* that it doesn't descend from an invalid block, and then add it to mapBlockIndex.
|
||||
* that it doesn't descend from an invalid block, and then add it to m_block_index.
|
||||
*/
|
||||
bool AcceptBlockHeader(
|
||||
const CBlockHeader& block,
|
||||
|
@ -658,6 +652,9 @@ CChainState& ChainstateActive();
|
|||
/** @returns the most-work chain. */
|
||||
CChain& ChainActive();
|
||||
|
||||
/** @returns the global block index map. */
|
||||
BlockMap& BlockIndex();
|
||||
|
||||
/** Global variable that points to the coins database (protected by cs_main) */
|
||||
extern std::unique_ptr<CCoinsViewDB> pcoinsdbview;
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ static int64_t AddTx(CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64
|
|||
if (blockTime > 0) {
|
||||
auto locked_chain = wallet.chain().lock();
|
||||
LockAssertion lock(::cs_main);
|
||||
auto inserted = mapBlockIndex.emplace(GetRandHash(), new CBlockIndex);
|
||||
auto inserted = ::BlockIndex().emplace(GetRandHash(), new CBlockIndex);
|
||||
assert(inserted.second);
|
||||
const uint256& hash = inserted.first->first;
|
||||
block = inserted.first->second;
|
||||
|
|
Loading…
Reference in a new issue