Merge a55904a80c into merged_master (Bitcoin PR bitcoin/bitcoin#21866)

Paying the piper for some lazy use of globals, including ones I added
in 8e770d3f21

Had to add another couple methods to interfaces::Chain
This commit is contained in:
Andrew Poelstra 2021-07-29 13:18:11 +00:00
commit 34da23bd1a
41 changed files with 270 additions and 365 deletions

View file

@ -107,21 +107,6 @@ bool CBlockIndexWorkComparator::operator()(const CBlockIndex *pa, const CBlockIn
return false;
}
ChainstateManager g_chainman;
CChainState& ChainstateActive()
{
LOCK(::cs_main);
assert(g_chainman.m_active_chainstate);
return *g_chainman.m_active_chainstate;
}
CChain& ChainActive()
{
LOCK(::cs_main);
return ::ChainstateActive().m_chain;
}
/**
* Mutex to guard access to validation specific variables, such as reading
* or changing the chainstate.
@ -167,7 +152,6 @@ void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash) const
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.BlockIndex()) == std::addressof(m_block_index));
BlockMap::const_iterator it = m_block_index.find(hash);
return it == m_block_index.end() ? nullptr : it->second;
}
@ -176,7 +160,6 @@ CBlockIndex* BlockManager::FindForkInGlobalIndex(const CChain& chain, const CBlo
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
// Find the latest block common to locator and chain - we expect that
// locator.vHave is sorted descending by height.
for (const uint256& hash : locator.vHave) {
@ -204,7 +187,6 @@ bool CheckFinalTx(const CBlockIndex* active_chain_tip, const CTransaction &tx, i
{
AssertLockHeld(cs_main);
assert(active_chain_tip); // TODO: Make active_chain_tip a reference
assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*active_chain_tip));
// By convention a negative value for flags indicates that the
// current network-enforced consensus rules should be used. In
@ -243,7 +225,6 @@ bool TestLockPointValidity(CChain& active_chain, const LockPoints* lp)
if (lp->maxInputBlock) {
// Check whether ::ChainActive() is an extension of the block at which the LockPoints
// calculation was valid. If not LockPoints are no longer valid
assert(std::addressof(::ChainActive()) == std::addressof(active_chain));
if (!active_chain.Contains(lp->maxInputBlock)) {
return false;
}
@ -343,7 +324,6 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz
std::vector<COutPoint> vNoSpendsRemaining;
pool.TrimToSize(limit, &vNoSpendsRemaining);
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(coins_cache));
for (const COutPoint& removed : vNoSpendsRemaining)
coins_cache.Uncache(removed);
}
@ -351,7 +331,6 @@ static void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache, siz
static bool IsCurrentForFeeEstimation(CChainState& active_chainstate) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (active_chainstate.IsInitialBlockDownload())
return false;
if (active_chainstate.m_chain.Tip()->GetBlockTime() < count_seconds(GetTime<std::chrono::seconds>() - MAX_FEE_ESTIMATION_TIP_AGE))
@ -378,7 +357,6 @@ static void UpdateMempoolForReorg(CChainState& active_chainstate, CTxMemPool& me
{
AssertLockHeld(cs_main);
AssertLockHeld(mempool.cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
std::vector<uint256> vHashUpdate;
// disconnectpool's insertion_order index sorts the entries from
// oldest to newest, but the oldest entry will be the last tx from the
@ -449,7 +427,6 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, TxValidationS
assert(txFrom->vout.size() > txin.prevout.n);
assert(txFrom->vout[txin.prevout.n] == coin.out);
} else {
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(coins_tip));
const Coin& coinFromUTXOSet = coins_tip.AccessCoin(txin.prevout);
assert(!coinFromUTXOSet.IsSpent());
assert(coinFromUTXOSet.out == coin.out);
@ -470,7 +447,6 @@ public:
m_limit_ancestor_size(gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000),
m_limit_descendants(gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)),
m_limit_descendant_size(gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000) {
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
}
// We put the arguments we're handed into a struct, so we can pass them
@ -618,7 +594,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// And now do PAK checks. Filtered by next blocks' enforced list
if (chainparams.GetEnforcePak()) {
if (!IsPAKValidTx(tx, GetActivePAKList(::ChainActive().Tip(), chainparams.GetConsensus()), chainparams.ParentGenesisBlockHash(), chainparams.GetConsensus().pegged_asset)) {
if (!IsPAKValidTx(tx, GetActivePAKList(m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus()), chainparams.ParentGenesisBlockHash(), chainparams.GetConsensus().pegged_asset)) {
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "invalid-pegout-proof");
}
}
@ -633,7 +609,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Only accept nLockTime-using transactions that can be mined in the next
// block; we don't want our mempool filled up with transactions that can't
// be mined yet.
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
if (!CheckFinalTx(m_active_chainstate.m_chain.Tip(), tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-final");
@ -702,9 +677,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
// Used when checking peg-ins
std::vector<std::pair<CScript, CScript>> fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), chainparams.GetConsensus(), true /* nextblock_validation */);
std::vector<std::pair<CScript, CScript>> fedpegscripts = GetValidFedpegScripts(m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus(), true /* nextblock_validation */);
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
const CCoinsViewCache& coins_cache = m_active_chainstate.CoinsTip();
// do all inputs exist?
for (unsigned int i = 0; i < tx.vin.size(); i++) {
@ -764,11 +738,9 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// be mined yet.
// Pass in m_view which has all of the relevant inputs cached. Note that, since m_view's
// backend was removed, it no longer pulls coins from the mempool.
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
if (!CheckSequenceLocks(m_active_chainstate.m_chain.Tip(), m_view, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_active_chainstate.m_blockman));
CAmountMap fee_map;
if (!Consensus::CheckTxInputs(tx, state, m_view, m_active_chainstate.m_blockman.GetSpendHeight(m_view), fee_map, setPeginsSpent, NULL, true, true, fedpegscripts)) {
return false; // state filled in by CheckTxInputs
@ -776,7 +748,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Check for non-standard pay-to-script-hash in inputs
const auto& params = args.m_chainparams.GetConsensus();
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
auto taproot_state = VersionBitsState(m_active_chainstate.m_chain.Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
@ -810,7 +781,6 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
}
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
entry.reset(new CTxMemPoolEntry(ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(),
fSpendsCoinbase, nSigOpsCost, lp, setPeginsSpent));
unsigned int nSize = entry->GetTxSize();
@ -1025,7 +995,7 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws, Prec
// Temporarily add additional script flags based on the activation of
// Dynamic Federations. This can be included in the
// STANDARD_LOCKTIME_VERIFY_FLAGS in a release post-activation.
if (IsDynaFedEnabled(::ChainActive().Tip(), args.m_chainparams.GetConsensus())) {
if (IsDynaFedEnabled(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus())) {
scriptVerifyFlags |= SCRIPT_SIGHASH_RANGEPROOF;
}
@ -1070,9 +1040,7 @@ bool MemPoolAccept::ConsensusScriptChecks(const ATMPArgs& args, Workspace& ws, P
// There is a similar check in CreateNewBlock() to prevent creating
// invalid blocks (using TestBlockValidity), however allowing such
// transactions into the mempool can be exploited as a DoS attack.
assert(std::addressof(::ChainActive()) == std::addressof(m_active_chainstate.m_chain));
unsigned int currentBlockScriptVerifyFlags = GetBlockScriptFlags(m_active_chainstate.m_chain.Tip(), chainparams.GetConsensus());
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
if (!CheckInputsFromMempoolAndCache(tx, state, m_view, m_pool, currentBlockScriptVerifyFlags, txdata, m_active_chainstate.CoinsTip())) {
return error("%s: BUG! PLEASE REPORT THIS! CheckInputScripts failed against latest-block but not STANDARD flags %s, %s",
__func__, hash.ToString(), state.ToString());
@ -1113,7 +1081,6 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
// - it's not being re-added during a reorg which bypasses typical mempool fee limits
// - the node is not behind
// - the transaction is not dependent on any other transactions in the mempool
assert(std::addressof(::ChainstateActive()) == std::addressof(m_active_chainstate));
bool validForFeeEstimation = !fReplacementTransaction && !bypass_limits && IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
// Store transaction in memory
@ -1121,7 +1088,6 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
// trim mempool and check if tx was trimmed
if (!bypass_limits) {
assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(m_active_chainstate.CoinsTip()));
LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
if (!m_pool.exists(hash))
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
@ -1224,7 +1190,6 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
MemPoolAccept::ATMPArgs args { chainparams, nAcceptTime, bypass_limits, coins_to_uncache,
test_accept, /* m_allow_bip125_replacement */ true };
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
const MempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptSingleTransaction(tx, args);
if (result.m_result_type != MempoolAcceptResult::ResultType::VALID) {
// Remove coins that were not present in the coins cache before calling
@ -1244,7 +1209,6 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, CTxMemPool& pool, const CTransactionRef& tx,
bool bypass_limits, bool test_accept)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
return AcceptToMemoryPoolWithTime(Params(), pool, active_chainstate, tx, GetTime(), bypass_limits, test_accept);
}
@ -1260,7 +1224,6 @@ PackageMempoolAcceptResult ProcessNewPackage(CChainState& active_chainstate, CTx
const CChainParams& chainparams = Params();
MemPoolAccept::ATMPArgs args { chainparams, GetTime(), /* bypass_limits */ false, coins_to_uncache,
test_accept, /* m_allow_bip125_replacement */ false };
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
const PackageMempoolAcceptResult result = MemPoolAccept(pool, active_chainstate).AcceptMultipleTransactions(package, args);
// Uncache coins pertaining to transactions that were not submitted to the mempool.
@ -1399,7 +1362,6 @@ static void AlertNotify(const std::string& strMessage)
void CChainState::CheckForkWarningConditions()
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
// Before we get past initial download, we cannot reliably alert about forks
// (we assume we don't get stuck on a fork before finishing our initial sync)
@ -1418,7 +1380,6 @@ void CChainState::CheckForkWarningConditions()
// Called both upon regular invalid block discovery *and* InvalidateBlock
void CChainState::InvalidChainFound(CBlockIndex* pindexNew)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
pindexBestInvalid = pindexNew;
if (pindexBestHeader != nullptr && pindexBestHeader->GetAncestor(pindexNew->nHeight) == pindexNew) {
@ -1488,7 +1449,6 @@ bool CScriptCheck::operator()() {
int BlockManager::GetSpendHeight(const CCoinsViewCache& inputs)
{
AssertLockHeld(cs_main);
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
CBlockIndex* pindexPrev = LookupBlockIndex(inputs.GetBestBlock());
return pindexPrev->nHeight + 1;
}
@ -2479,7 +2439,6 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
}
bilingual_str warning_messages;
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (!active_chainstate.IsInitialBlockDownload()) {
const CBlockIndex* pindex = pindexNew;
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
@ -2495,7 +2454,6 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
}
}
}
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
LogPrintf("%s: new best=%s height=%d version=0x%08x tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
(unsigned long)pindexNew->nChainTx,
@ -2788,7 +2746,6 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
{
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
const CBlockIndex* pindexOldTip = m_chain.Tip();
const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork);
@ -2888,7 +2845,6 @@ static bool NotifyHeaderTip(CChainState& chainstate) LOCKS_EXCLUDED(cs_main) {
if (pindexHeader != pindexHeaderOld) {
fNotify = true;
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
fInitialBlockDownload = chainstate.IsInitialBlockDownload();
pindexHeaderOld = pindexHeader;
}
@ -3099,7 +3055,6 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
// transactions back to the mempool if disconnecting was successful,
// and we're not doing a very deep invalidation (in which case
// keeping the mempool up to date is probably futile anyway).
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
UpdateMempoolForReorg(*this, m_mempool, disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
if (!ret) return false;
assert(invalid_walk_tip->pprev == m_chain.Tip());
@ -3536,7 +3491,6 @@ CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints))
{
const uint256& hash = i.second;
assert(std::addressof(g_chainman.m_blockman) == std::addressof(*this));
CBlockIndex* pindex = LookupBlockIndex(hash);
if (pindex) {
return pindex;
@ -3569,7 +3523,6 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
// Don't accept any forks from the main chain prior to last checkpoint.
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
// BlockIndex().
assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman));
CBlockIndex* pcheckpoint = blockman.GetLastCheckpoint(params.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
@ -3796,7 +3749,6 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
// Exposed wrapper for AcceptBlockHeader
bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(ActiveChainstate()));
AssertLockNotHeld(cs_main);
{
LOCK(cs_main);
@ -3888,7 +3840,6 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file
if (fNewBlock) *fNewBlock = true;
assert(std::addressof(::ChainActive()) == std::addressof(m_chain));
try {
FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, chainparams, dbp);
if (blockPos.IsNull()) {
@ -3910,7 +3861,6 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock>& block, bool force_processing, bool* new_block)
{
AssertLockNotHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(ActiveChainstate()));
{
CBlockIndex *pindex = nullptr;
@ -3955,7 +3905,6 @@ bool TestBlockValidity(BlockValidationState& state,
bool fCheckMerkleRoot)
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
assert(pindexPrev && pindexPrev == chainstate.m_chain.Tip());
CCoinsViewCache viewNew(&chainstate.CoinsTip());
uint256 block_hash(block.GetHash());
@ -3965,7 +3914,6 @@ bool TestBlockValidity(BlockValidationState& state,
indexDummy.phashBlock = &block_hash;
// NOTE: CheckBlockHeader is called by CheckBlock
assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainstate.m_blockman));
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
@ -4045,7 +3993,6 @@ void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeigh
{
BlockValidationState state;
const CChainParams& chainparams = Params();
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (!active_chainstate.FlushStateToDisk(
chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
@ -4199,7 +4146,6 @@ void BlockManager::Unload() {
bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams)
{
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!m_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree,
setBlockIndexCandidates)) {
@ -4256,7 +4202,6 @@ bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams)
void CChainState::LoadMempool(const ArgsManager& args)
{
if (args.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
::LoadMempool(m_mempool, *this);
}
m_mempool.SetIsLoaded(!ShutdownRequested());
@ -4308,7 +4253,6 @@ bool CVerifyDB::VerifyDB(
{
AssertLockHeld(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(chainstate));
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr)
return true;
@ -4577,7 +4521,6 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
if (m_blockman.m_block_index.count(chainparams.GenesisBlock().GetHash()))
return true;
assert(std::addressof(::ChainActive()) == std::addressof(m_chain));
try {
const CBlock& block = chainparams.GenesisBlock();
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, chainparams, nullptr);
@ -4641,7 +4584,6 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
{
LOCK(cs_main);
// detect out of order blocks, and store them for later
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_blockman));
if (hash != chainparams.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString());
@ -4651,11 +4593,9 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
}
// process in case the block isn't known yet
assert(std::addressof(g_chainman.m_blockman) == std::addressof(m_blockman));
CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) {
nLoaded++;
}
@ -4670,13 +4610,11 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
// Activate the genesis block so normal node progress can continue
if (hash == chainparams.GetConsensus().hashGenesisBlock) {
BlockValidationState state;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (!ActivateBestChain(state, chainparams, nullptr)) {
break;
}
}
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
NotifyHeaderTip(*this);
// Recursively process earlier encountered successors of this block
@ -4695,7 +4633,6 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
head.ToString());
LOCK(cs_main);
BlockValidationState dummy;
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr))
{
nLoaded++;
@ -4704,7 +4641,6 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
}
range.first++;
mapBlocksUnknownParent.erase(it);
assert(std::addressof(::ChainstateActive()) == std::addressof(*this));
NotifyHeaderTip(*this);
}
}
@ -4985,7 +4921,6 @@ bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mocka
}
if (nTime > nNow - nExpiryTimeout) {
LOCK(cs_main);
assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (AcceptToMemoryPoolWithTime(chainparams, pool, active_chainstate, tx, nTime, false /* bypass_limits */,
false /* test_accept */).m_result_type == MempoolAcceptResult::ResultType::VALID) {
++count;
@ -5511,7 +5446,7 @@ void ChainstateManager::MaybeRebalanceCaches()
* from the perspective of peg-in witness validation. Blocks are
* added to this queue in ConnectTip based on the error code returned.
*/
bool MainchainRPCCheck(const bool init)
bool MainchainRPCCheck(const bool init, ChainstateManager* chainman)
{
// First, we can clear out any blocks thatsomehow are now deemed valid
// eg reconsiderblock rpc call manually
@ -5520,9 +5455,8 @@ bool MainchainRPCCheck(const bool init)
std::vector<uint256> vblocksToReconsiderAgain;
for(uint256& blockhash : vblocksToReconsider) {
LOCK(cs_main);
ChainstateManager& chainman = g_chainman;
if (chainman.BlockIndex().count(blockhash)) {
CBlockIndex* pblockindex = chainman.BlockIndex()[blockhash];
if (chainman->BlockIndex().count(blockhash)) {
CBlockIndex* pblockindex = chainman->BlockIndex()[blockhash];
if ((pblockindex->nStatus & BLOCK_FAILED_MASK)) {
vblocksToReconsiderAgain.push_back(blockhash);
}
@ -5596,16 +5530,15 @@ bool MainchainRPCCheck(const bool init)
for(const uint256& blockhash : vblocksToReconsider) {
{
LOCK(cs_main);
ChainstateManager& chainman = g_chainman;
if (chainman.BlockIndex().count(blockhash) == 0)
if (chainman->BlockIndex().count(blockhash) == 0)
continue;
CBlockIndex* pblockindex = chainman.BlockIndex()[blockhash];
::ChainstateActive().ResetBlockFailureFlags(pblockindex);
CBlockIndex* pblockindex = chainman->BlockIndex()[blockhash];
chainman->ActiveChainstate().ResetBlockFailureFlags(pblockindex);
}
}
//All blocks are now being reconsidered
::ChainstateActive().ActivateBestChain(state, Params());
chainman->ActiveChainstate().ActivateBestChain(state, Params());
//This simply checks for DB errors
if (!state.IsValid()) {
//Something scary?
@ -5614,9 +5547,8 @@ bool MainchainRPCCheck(const bool init)
//Now to clear out now-valid blocks
for(const uint256& blockhash : vblocksToReconsider) {
LOCK(cs_main);
ChainstateManager& chainman = g_chainman;
if (chainman.BlockIndex().count(blockhash)) {
CBlockIndex* pblockindex = chainman.BlockIndex()[blockhash];
if (chainman->BlockIndex().count(blockhash)) {
CBlockIndex* pblockindex = chainman->BlockIndex()[blockhash];
//Marked as invalid still, put back into queue
if((pblockindex->nStatus & BLOCK_FAILED_MASK)) {