diff --git a/src/init.cpp b/src/init.cpp index 27aeefd913..5ce60350e2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1642,7 +1642,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node) // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). - if (!::BlockIndex().empty() && + if (!chainman.BlockIndex().empty() && !LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) { return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); } @@ -1922,8 +1922,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node) //// debug print { LOCK(cs_main); - LogPrintf("block tree size = %u\n", ::BlockIndex().size()); - chain_active_height = ::ChainActive().Height(); + LogPrintf("block tree size = %u\n", chainman.BlockIndex().size()); + chain_active_height = chainman.ActiveChain().Height(); } LogPrintf("nBestHeight = %d\n", chain_active_height); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 53582ce30d..b4f67cc282 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1467,50 +1467,48 @@ static UniValue getchaintips(const JSONRPCRequest& request) }, }.Check(request); + ChainstateManager& chainman = EnsureChainman(request.context); LOCK(cs_main); /* - * Idea: the set of chain tips is ::ChainActive().tip, plus orphan blocks which do not have another orphan building off of them. + * Idea: The set of chain tips is the active chain tip, plus orphan blocks which do not have another orphan building off of them. * Algorithm: * - Make one pass through BlockIndex(), 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() + * - Add the active chain tip */ std::set setTips; std::set setOrphans; std::set setPrevs; - for (const std::pair& item : ::BlockIndex()) - { - if (!::ChainActive().Contains(item.second)) { + for (const std::pair& item : chainman.BlockIndex()) { + if (!chainman.ActiveChain().Contains(item.second)) { setOrphans.insert(item.second); setPrevs.insert(item.second->pprev); } } - for (std::set::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) - { + for (std::set::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it) { if (setPrevs.erase(*it) == 0) { setTips.insert(*it); } } // Always report the currently active tip. - setTips.insert(::ChainActive().Tip()); + setTips.insert(chainman.ActiveChain().Tip()); /* Construct the output array. */ UniValue res(UniValue::VARR); - for (const CBlockIndex* block : setTips) - { + for (const CBlockIndex* block : setTips) { UniValue obj(UniValue::VOBJ); obj.pushKV("height", block->nHeight); obj.pushKV("hash", block->phashBlock->GetHex()); - const int branchLen = block->nHeight - ::ChainActive().FindFork(block)->nHeight; + const int branchLen = block->nHeight - chainman.ActiveChain().FindFork(block)->nHeight; obj.pushKV("branchlen", branchLen); std::string status; - if (::ChainActive().Contains(block)) { + if (chainman.ActiveChain().Contains(block)) { // This block is part of the currently active chain. status = "active"; } else if (block->nStatus & BLOCK_FAILED_MASK) { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 0ae4eacf41..749a6acbd1 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -1641,11 +1641,12 @@ UniValue testproposedblock(const JSONRPCRequest& request) if (!DecodeHexBlk(block, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + ChainstateManager& chainman = EnsureChainman(request.context); LOCK(cs_main); uint256 hash = block.GetHash(); - BlockMap::iterator mi = ::BlockIndex().find(hash); - if (mi != ::BlockIndex().end()) + BlockMap::iterator mi = chainman.BlockIndex().find(hash); + if (mi != chainman.BlockIndex().end()) throw JSONRPCError(RPC_VERIFY_ERROR, "already have block"); CBlockIndex* const pindexPrev = ::ChainActive().Tip(); diff --git a/src/validation.cpp b/src/validation.cpp index 7be1266548..3cc18e8a4a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1397,12 +1397,6 @@ bool CChainState::IsInitialBlockDownload() const static CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; -BlockMap& BlockIndex() -{ - LOCK(::cs_main); - return g_chainman.m_blockman.m_block_index; -} - static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); @@ -5647,8 +5641,9 @@ bool MainchainRPCCheck(const bool init) std::vector vblocksToReconsiderAgain; for(uint256& blockhash : vblocksToReconsider) { LOCK(cs_main); - if (::BlockIndex().count(blockhash)) { - CBlockIndex* pblockindex = ::BlockIndex()[blockhash]; + ChainstateManager& chainman = g_chainman; + if (chainman.BlockIndex().count(blockhash)) { + CBlockIndex* pblockindex = chainman.BlockIndex()[blockhash]; if ((pblockindex->nStatus & BLOCK_FAILED_MASK)) { vblocksToReconsiderAgain.push_back(blockhash); } @@ -5723,9 +5718,10 @@ bool MainchainRPCCheck(const bool init) for(const uint256& blockhash : vblocksToReconsider) { { LOCK(cs_main); - if (::BlockIndex().count(blockhash) == 0) + ChainstateManager& chainman = g_chainman; + if (chainman.BlockIndex().count(blockhash) == 0) continue; - CBlockIndex* pblockindex = ::BlockIndex()[blockhash]; + CBlockIndex* pblockindex = chainman.BlockIndex()[blockhash]; ResetBlockFailureFlags(pblockindex); } } @@ -5740,8 +5736,9 @@ bool MainchainRPCCheck(const bool init) //Now to clear out now-valid blocks for(const uint256& blockhash : vblocksToReconsider) { LOCK(cs_main); - if (::BlockIndex().count(blockhash)) { - CBlockIndex* pblockindex = ::BlockIndex()[blockhash]; + ChainstateManager& chainman = g_chainman; + if (chainman.BlockIndex().count(blockhash)) { + CBlockIndex* pblockindex = chainman.BlockIndex()[blockhash]; //Marked as invalid still, put back into queue if((pblockindex->nStatus & BLOCK_FAILED_MASK)) { diff --git a/src/validation.h b/src/validation.h index e2d2ccfafe..b2084ef029 100644 --- a/src/validation.h +++ b/src/validation.h @@ -890,9 +890,6 @@ CChainState& ChainstateActive(); /** Please prefer the identical ChainstateManager::ActiveChain */ CChain& ChainActive(); -/** Please prefer the identical ChainstateManager::BlockIndex */ -BlockMap& BlockIndex(); - /** Global variable that points to the active block tree (protected by cs_main) */ extern std::unique_ptr pblocktree; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c2dcb438d2..d8c366658a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4869,6 +4869,7 @@ UniValue signblock(const JSONRPCRequest& request) if (!DecodeHexBlk(block, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + ChainstateManager& chainman = g_chainman; // FIXME avoid using this global, see #19413 LOCK(cs_main); LegacyScriptPubKeyMan* spk_man = pwallet->GetLegacyScriptPubKeyMan(); @@ -4877,8 +4878,8 @@ UniValue signblock(const JSONRPCRequest& request) } uint256 hash = block.GetHash(); - BlockMap::iterator mi = ::BlockIndex().find(hash); - if (mi != ::BlockIndex().end()) + BlockMap::iterator mi = chainman.BlockIndex().find(hash); + if (mi != chainman.BlockIndex().end()) throw JSONRPCError(RPC_VERIFY_ERROR, "already have block"); CBlockIndex* const pindexPrev = ::ChainActive().Tip(); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index b56a4cb403..2be34e9477 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -337,7 +337,7 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) BOOST_CHECK_EQUAL(wtx.GetImmatureCredit()[CAsset()], 50*COIN); } -static int64_t AddTx(CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime) +static int64_t AddTx(ChainstateManager& chainman, CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime) { CMutableTransaction tx; CWalletTx::Confirmation confirm; @@ -345,7 +345,8 @@ static int64_t AddTx(CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64 SetMockTime(mockTime); CBlockIndex* block = nullptr; if (blockTime > 0) { - auto inserted = ::BlockIndex().emplace(GetRandHash(), new CBlockIndex); + LOCK(cs_main); + auto inserted = chainman.BlockIndex().emplace(GetRandHash(), new CBlockIndex); assert(inserted.second); const uint256& hash = inserted.first->first; block = inserted.first->second; @@ -367,24 +368,24 @@ static int64_t AddTx(CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64 BOOST_AUTO_TEST_CASE(ComputeTimeSmart) { // New transaction should use clock time if lower than block time. - BOOST_CHECK_EQUAL(AddTx(m_wallet, 1, 100, 120), 100); + BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 1, 100, 120), 100); // Test that updating existing transaction does not change smart time. - BOOST_CHECK_EQUAL(AddTx(m_wallet, 1, 200, 220), 100); + BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 1, 200, 220), 100); // New transaction should use clock time if there's no block time. - BOOST_CHECK_EQUAL(AddTx(m_wallet, 2, 300, 0), 300); + BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 2, 300, 0), 300); // New transaction should use block time if lower than clock time. - BOOST_CHECK_EQUAL(AddTx(m_wallet, 3, 420, 400), 400); + BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 3, 420, 400), 400); // New transaction should use latest entry time if higher than // min(block time, clock time). - BOOST_CHECK_EQUAL(AddTx(m_wallet, 4, 500, 390), 400); + BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 4, 500, 390), 400); // If there are future entries, new transaction should use time of the // newest entry that is no more than 300 seconds ahead of the clock time. - BOOST_CHECK_EQUAL(AddTx(m_wallet, 5, 50, 600), 300); + BOOST_CHECK_EQUAL(AddTx(*m_node.chainman, m_wallet, 5, 50, 600), 300); // Reset mock time for other tests. SetMockTime(0);