diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp index 4f6e1122b8..8703a1cf94 100644 --- a/src/bench/duplicate_inputs.cpp +++ b/src/bench/duplicate_inputs.cpp @@ -25,7 +25,6 @@ static void DuplicateInputs(benchmark::Bench& bench) CMutableTransaction naughtyTx{}; LOCK(cs_main); - assert(std::addressof(::ChainActive()) == std::addressof(testing_setup->m_node.chainman->ActiveChain())); CBlockIndex* pindexPrev = testing_setup->m_node.chainman->ActiveChain().Tip(); assert(pindexPrev != nullptr); block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); diff --git a/src/index/base.cpp b/src/index/base.cpp index 3a61af28b7..6fd2701e2e 100644 --- a/src/index/base.cpp +++ b/src/index/base.cpp @@ -340,7 +340,6 @@ void BaseIndex::Interrupt() 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. diff --git a/src/init.cpp b/src/init.cpp index 725df9a620..8f7954259f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -293,7 +293,7 @@ void Shutdown(NodeContext& node) init::UnsetGlobals(); node.mempool.reset(); node.fee_estimator.reset(); - node.chainman = nullptr; + node.chainman.reset(); node.scheduler.reset(); node.reverification_scheduler.reset(); @@ -1235,8 +1235,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.mempool = std::make_unique(node.fee_estimator.get(), check_ratio); assert(!node.chainman); - node.chainman = &g_chainman; - ChainstateManager& chainman = *Assert(node.chainman); + node.chainman = std::make_unique(); + ChainstateManager& chainman = *node.chainman; assert(!node.peerman); node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), @@ -1441,7 +1441,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). if (!chainman.BlockIndex().empty() && - !g_chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) { + !chainman.m_blockman.LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) { return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); } @@ -1456,7 +1456,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // If we're not mid-reindex (based on disk + args), add a genesis block on disk // (otherwise we use the one already on disk). // This is called again in ThreadImport after the reindex completes. - if (!fReindex && !::ChainstateActive().LoadGenesisBlock(chainparams)) { + if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock(chainparams)) { strLoadError = _("Error initializing block database"); break; } @@ -1605,21 +1605,21 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 8: start indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { g_txindex = std::make_unique(nTxIndexCache, false, fReindex); - if (!g_txindex->Start(::ChainstateActive())) { + if (!g_txindex->Start(chainman.ActiveChainstate())) { return false; } } for (const auto& filter_type : g_enabled_filter_types) { InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex); - if (!GetBlockFilterIndex(filter_type)->Start(::ChainstateActive())) { + if (!GetBlockFilterIndex(filter_type)->Start(chainman.ActiveChainstate())) { return false; } } if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) { g_coin_stats_index = std::make_unique(/* cache size */ 0, false, fReindex); - if (!g_coin_stats_index->Start(::ChainstateActive())) { + if (!g_coin_stats_index->Start(chainman.ActiveChainstate())) { return false; } } @@ -1667,7 +1667,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. // No locking, as this happens before any background thread is started. boost::signals2::connection block_notify_genesis_wait_connection; - if (::ChainActive().Tip() == nullptr) { + if (chainman.ActiveChain().Tip() == nullptr) { block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2)); } else { fHaveGenesis = true; @@ -1848,7 +1848,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) if (gArgs.GetBoolArg("-validatepegin", Params().GetConsensus().has_parent_chain)) { uiInterface.InitMessage(_("Awaiting mainchain RPC warmup").translated); } - if (!MainchainRPCCheck(true)) { //Initial check only + if (!MainchainRPCCheck(true, node.chainman.get())) { //Initial check only const std::string err_msg = "ERROR: elements is set to verify pegins but cannot get a valid response from the mainchain daemon. Please check debug.log for more information.\n\nIf you haven't setup a bitcoind please get the latest stable version from https://bitcoincore.org/en/download/ or if you do not need to validate pegins set in your elements configuration validatepegin=0"; // We fail immediately if this node has RPC server enabled if (gArgs.GetBoolArg("-server", false)) { @@ -1864,7 +1864,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // Start the lightweight block re-evaluation scheduler thread node.reverification_scheduler->m_service_thread = std::thread([&] { util::TraceThread( "reevaluation_scheduler", [&] { node.reverification_scheduler->serviceQueue(); }); }); - CScheduler::Function f2 = std::bind(&MainchainRPCCheck, false); + CScheduler::Function f2 = std::bind(&MainchainRPCCheck, false, node.chainman.get()); unsigned int check_rpc_every = gArgs.GetArg("-recheckpeginblockinterval", 120); if (check_rpc_every) { node.reverification_scheduler->scheduleEvery(f2, std::chrono::seconds(check_rpc_every)); diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index e060ef64b2..73d35e8465 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -281,7 +281,9 @@ public: virtual void requestMempoolTransactions(Notifications& notifications) = 0; // ELEMENTS + virtual CBlockIndex* getTip() = 0; virtual MempoolAcceptResult testPeginClaimAcceptance(const CTransactionRef tx) = 0; + virtual bool testBlockValidity(BlockValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) = 0; }; //! Interface to let node manage chain clients (wallets, or maybe tools for diff --git a/src/miner.cpp b/src/miner.cpp index 856aafdccd..606f7b4cb4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -58,15 +58,7 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman) tx.witness.vtxoutwit.erase(tx.witness.vtxoutwit.begin() + GetWitnessCommitmentIndex(block)); block.vtx.at(0) = MakeTransactionRef(tx); - CBlockIndex* prev_block; - { - // TODO: Temporary scope to check correctness of refactored code. - // Should be removed manually after merge of - // https://github.com/bitcoin/bitcoin/pull/20158 - LOCK(::cs_main); - assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman.m_blockman)); - prev_block = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock); - } + CBlockIndex* prev_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock)); GenerateCoinbaseCommitment(block, prev_block, Params().GetConsensus()); block.hashMerkleRoot = BlockMerkleRoot(block); @@ -139,7 +131,6 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc pblocktemplate->vTxSigOpsCost.push_back(-1); // updated at end LOCK2(cs_main, m_mempool.cs); - assert(std::addressof(*::ChainActive().Tip()) == std::addressof(*m_chainstate.m_chain.Tip())); CBlockIndex* pindexPrev = m_chainstate.m_chain.Tip(); assert(pindexPrev != nullptr); nHeight = pindexPrev->nHeight + 1; @@ -169,7 +160,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()); if (IsDynaFedEnabled(pindexPrev, chainparams.GetConsensus())) { - const DynaFedParamEntry current_params = ComputeNextBlockCurrentParameters(::ChainActive().Tip(), chainparams.GetConsensus()); + const DynaFedParamEntry current_params = ComputeNextBlockCurrentParameters(m_chainstate.m_chain.Tip(), chainparams.GetConsensus()); const DynaFedParams block_params(current_params, proposed_entry ? *proposed_entry : DynaFedParamEntry()); pblock->m_dynafed_params = block_params; nBlockWeight += ::GetSerializeSize(block_params, PROTOCOL_VERSION)*WITNESS_SCALE_FACTOR; @@ -234,7 +225,6 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]); BlockValidationState state; - assert(std::addressof(::ChainstateActive()) == std::addressof(m_chainstate)); if (!TestBlockValidity(state, chainparams, m_chainstate, *pblock, pindexPrev, false, false)) { throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString())); } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index c5a389f228..5f68646af5 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1361,7 +1361,6 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn m_stale_tip_check_time(0), m_ignore_incoming_txs(ignore_incoming_txs) { - assert(std::addressof(g_chainman) == std::addressof(m_chainman)); // Initialize global variables that cannot be constructed at startup. recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 5a77da5ff9..f5b0d11b56 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -249,7 +249,6 @@ bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, // when the undo file is keeping up with the block file, we want to flush it explicitly // when it is lagging behind (more blocks arrive than are being connected), we let the // undo block write case handle it - assert(std::addressof(::ChainActive()) == std::addressof(active_chain)); finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight); nFile++; if (vinfoBlockFile.size() <= nFile) { diff --git a/src/node/coin.cpp b/src/node/coin.cpp index 23d4fa2aae..50fddf3ab0 100644 --- a/src/node/coin.cpp +++ b/src/node/coin.cpp @@ -13,7 +13,6 @@ void FindCoins(const NodeContext& node, std::map& coins) assert(node.mempool); assert(node.chainman); LOCK2(cs_main, node.mempool->cs); - assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate())); CCoinsViewCache& chain_view = node.chainman->ActiveChainstate().CoinsTip(); CCoinsViewMemPool mempool_view(&chain_view, *node.mempool); for (auto& coin : coins) { diff --git a/src/node/coinstats.cpp b/src/node/coinstats.cpp index 2ecc5fd32d..fec2718ee5 100644 --- a/src/node/coinstats.cpp +++ b/src/node/coinstats.cpp @@ -101,7 +101,6 @@ static bool GetUTXOStats(CCoinsView* view, BlockManager& blockman, CCoinsStats& if (!pindex) { { LOCK(cs_main); - assert(std::addressof(g_chainman.m_blockman) == std::addressof(blockman)); pindex = blockman.LookupBlockIndex(view->GetBestBlock()); } } diff --git a/src/node/context.cpp b/src/node/context.cpp index 6d22a6b110..9afadd09a9 100644 --- a/src/node/context.cpp +++ b/src/node/context.cpp @@ -12,6 +12,7 @@ #include #include #include +#include NodeContext::NodeContext() {} NodeContext::~NodeContext() {} diff --git a/src/node/context.h b/src/node/context.h index 2809a2bf66..daab401d96 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -44,7 +44,7 @@ struct NodeContext { std::unique_ptr mempool; std::unique_ptr fee_estimator; std::unique_ptr peerman; - ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct + std::unique_ptr chainman; std::unique_ptr banman; ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct std::unique_ptr chain; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index ba471db986..38adcf4049 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -197,26 +197,16 @@ public: int getNumBlocks() override { LOCK(::cs_main); - assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain())); return chainman().ActiveChain().Height(); } uint256 getBestBlockHash() override { - const CBlockIndex* tip; - { - // TODO: Temporary scope to check correctness of refactored code. - // Should be removed manually after merge of - // https://github.com/bitcoin/bitcoin/pull/20158 - LOCK(cs_main); - assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain())); - tip = chainman().ActiveChain().Tip(); - } + const CBlockIndex* tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()); return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash(); } int64_t getLastBlockTime() override { LOCK(::cs_main); - assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain())); if (chainman().ActiveChain().Tip()) { return chainman().ActiveChain().Tip()->GetBlockTime(); } @@ -227,22 +217,12 @@ public: const CBlockIndex* tip; { LOCK(::cs_main); - assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain())); tip = chainman().ActiveChain().Tip(); } return GuessVerificationProgress(tip, Params().GetConsensus().nPowTargetSpacing); } bool isInitialBlockDownload() override { - const CChainState* active_chainstate; - { - // TODO: Temporary scope to check correctness of refactored code. - // Should be removed manually after merge of - // https://github.com/bitcoin/bitcoin/pull/20158 - LOCK(::cs_main); - active_chainstate = &m_context->chainman->ActiveChainstate(); - assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate)); - } - return active_chainstate->IsInitialBlockDownload(); + return chainman().ActiveChainstate().IsInitialBlockDownload(); } bool getReindex() override { return ::fReindex; } bool getImporting() override { return ::fImporting; } @@ -269,7 +249,6 @@ public: bool getUnspentOutput(const COutPoint& output, Coin& coin) override { LOCK(::cs_main); - assert(std::addressof(::ChainstateActive()) == std::addressof(chainman().ActiveChainstate())); return chainman().ActiveChainstate().CoinsTip().GetCoin(output, coin); } WalletClient& walletClient() override @@ -476,14 +455,12 @@ public: bool checkFinalTx(const CTransaction& tx) override { LOCK(cs_main); - assert(std::addressof(::ChainActive()) == std::addressof(chainman().ActiveChain())); return CheckFinalTx(chainman().ActiveChain().Tip(), tx); } std::optional findLocatorFork(const CBlockLocator& locator) override { LOCK(cs_main); const CChain& active = Assert(m_node.chainman)->ActiveChain(); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); if (CBlockIndex* fork = m_node.chainman->m_blockman.FindForkInGlobalIndex(active, locator)) { return fork->nHeight; } @@ -493,7 +470,6 @@ public: { WAIT_LOCK(cs_main, lock); const CChain& active = Assert(m_node.chainman)->ActiveChain(); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash), block, lock, active); } bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override @@ -506,7 +482,6 @@ public: { WAIT_LOCK(cs_main, lock); const CChain& active = Assert(m_node.chainman)->ActiveChain(); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); if (const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) { if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) { return FillBlock(ancestor, ancestor_out, lock, active); @@ -518,9 +493,7 @@ public: { WAIT_LOCK(cs_main, lock); const CChain& active = Assert(m_node.chainman)->ActiveChain(); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); const CBlockIndex* block = m_node.chainman->m_blockman.LookupBlockIndex(block_hash); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); const CBlockIndex* ancestor = m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash); if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr; return FillBlock(ancestor, ancestor_out, lock, active); @@ -529,9 +502,7 @@ public: { WAIT_LOCK(cs_main, lock); const CChain& active = Assert(m_node.chainman)->ActiveChain(); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); const CBlockIndex* block1 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash1); - assert(std::addressof(g_chainman) == std::addressof(*m_node.chainman)); const CBlockIndex* block2 = m_node.chainman->m_blockman.LookupBlockIndex(block_hash2); const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr; // Using & instead of && below to avoid short circuiting and leaving @@ -542,7 +513,6 @@ public: double guessVerificationProgress(const uint256& block_hash) override { LOCK(cs_main); - assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman)); return GuessVerificationProgress(chainman().m_blockman.LookupBlockIndex(block_hash), Params().GetConsensus().nPowTargetSpacing); } bool hasBlocks(const uint256& block_hash, int min_height, std::optional max_height) override @@ -555,7 +525,6 @@ public: // used to limit the range, and passing min_height that's too low or // max_height that's too high will not crash or change the result. LOCK(::cs_main); - assert(std::addressof(g_chainman.m_blockman) == std::addressof(chainman().m_blockman)); if (CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) { if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height); for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) { @@ -648,16 +617,7 @@ public: } bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !isInitialBlockDownload(); } bool isInitialBlockDownload() override { - const CChainState* active_chainstate; - { - // TODO: Temporary scope to check correctness of refactored code. - // Should be removed manually after merge of - // https://github.com/bitcoin/bitcoin/pull/20158 - LOCK(::cs_main); - active_chainstate = &chainman().ActiveChainstate(); - assert(std::addressof(::ChainstateActive()) == std::addressof(*active_chainstate)); - } - return active_chainstate->IsInitialBlockDownload(); + return chainman().ActiveChainstate().IsInitialBlockDownload(); } bool shutdownRequested() override { return ShutdownRequested(); } int64_t getAdjustedTime() override { return GetAdjustedTime(); } @@ -723,7 +683,17 @@ public: // ELEMENTS MempoolAcceptResult testPeginClaimAcceptance(const CTransactionRef tx) override { LOCK(::cs_main); - return ::AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, tx, false /* bypass_limits */, true /* test_accept */); + return ::AcceptToMemoryPool(chainman().ActiveChainstate(), *m_node.mempool, tx, false /* bypass_limits */, true /* test_accept */); + } + CBlockIndex* getTip() override { + LOCK(::cs_main); + const CChain& active = Assert(m_node.chainman)->ActiveChain(); + return active.Tip(); + } + bool testBlockValidity(BlockValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) override { + LOCK(::cs_main); + Assert(m_node.chainman); + return TestBlockValidity(state, chainparams, m_node.chainman->ActiveChainstate(), block, pindexPrev, fCheckPOW, fCheckMerkleRoot); } // end ELEMENTS NodeContext& m_node; diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp index a1e7a71e2c..f21b390915 100644 --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -40,7 +40,6 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t { // cs_main scope assert(node.chainman); LOCK(cs_main); - assert(std::addressof(::ChainstateActive()) == std::addressof(node.chainman->ActiveChainstate())); // If the transaction is already confirmed in the chain, don't do anything // and return early. CCoinsViewCache &view = node.chainman->ActiveChainstate().CoinsTip(); diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp index 38d6ade765..19bc0e1f65 100644 --- a/src/qt/test/apptests.cpp +++ b/src/qt/test/apptests.cpp @@ -86,11 +86,6 @@ void AppTests::appTests() ClearGlobalAssetDir(); LogInstance().DisconnectTestLogger(); AbortShutdown(); - { - LOCK(cs_main); - UnloadBlockIndex(/* mempool */ nullptr, g_chainman); - g_chainman.Reset(); - } } //! Entry point for BitcoinGUI tests. diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 7ab9e48539..50a4202109 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -147,14 +147,14 @@ void TestGUI(interfaces::Node& node) LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore); wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive"); spk_man->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey()); - wallet->SetLastBlockProcessed(105, ::ChainActive().Tip()->GetBlockHash()); + wallet->SetLastBlockProcessed(105, node.context()->chainman->ActiveChain().Tip()->GetBlockHash()); } { WalletRescanReserver reserver(*wallet); reserver.reserve(); CWallet::ScanResult result = wallet->ScanForWalletTransactions(Params().GetConsensus().hashGenesisBlock, 0 /* block height */, {} /* max height */, reserver, true /* fUpdate */); QCOMPARE(result.status, CWallet::ScanResult::SUCCESS); - QCOMPARE(result.last_scanned_block, ::ChainActive().Tip()->GetBlockHash()); + QCOMPARE(result.last_scanned_block, node.context()->chainman->ActiveChain().Tip()->GetBlockHash()); QVERIFY(result.last_failed_block.IsNull()); } wallet->SetBroadcastTransactions(true); diff --git a/src/rest.cpp b/src/rest.cpp index b1c44e114e..79bf786406 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -125,7 +125,7 @@ static ChainstateManager* GetChainman(const std::any& context, HTTPRequest* req) __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT)); return nullptr; } - return node_context->chainman; + return node_context->chainman.get(); } static RetFormat ParseDataFormat(std::string& param, const std::string& strReq) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 136d199f2b..c7d8e8f145 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -86,7 +86,6 @@ ChainstateManager& EnsureChainman(const NodeContext& node) if (!node.chainman) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found"); } - WITH_LOCK(::cs_main, CHECK_NONFATAL(std::addressof(g_chainman) == std::addressof(*node.chainman))); return *node.chainman; } @@ -1589,7 +1588,7 @@ RPCHelpMan getblockchaininfo() CScript sign_block_script = chainparams.GetConsensus().signblockscript; obj.pushKV("signblock_asm", ScriptToAsmStr(sign_block_script)); obj.pushKV("signblock_hex", HexStr(sign_block_script)); - if (!IsDynaFedEnabled(::ChainActive().Tip(), chainparams.GetConsensus())) { + if (!IsDynaFedEnabled(tip, chainparams.GetConsensus())) { obj.pushKV("current_signblock_asm", ScriptToAsmStr(sign_block_script)); obj.pushKV("current_signblock_hex", HexStr(sign_block_script)); obj.pushKV("max_block_witness", (uint64_t)chainparams.GetConsensus().max_block_signature_size); @@ -1599,7 +1598,7 @@ RPCHelpMan getblockchaininfo() } obj.pushKV("extension_space", arr); } else { - const DynaFedParamEntry entry = ComputeNextBlockFullCurrentParameters(::ChainActive().Tip(), chainparams.GetConsensus()); + const DynaFedParamEntry entry = ComputeNextBlockFullCurrentParameters(tip, chainparams.GetConsensus()); obj.pushKV("current_params_root", entry.CalculateRoot().GetHex()); obj.pushKV("current_signblock_asm", ScriptToAsmStr(entry.m_signblockscript)); obj.pushKV("current_signblock_hex", HexStr(entry.m_signblockscript)); @@ -1613,7 +1612,7 @@ RPCHelpMan getblockchaininfo() obj.pushKV("extension_space", arr); obj.pushKV("epoch_length", (uint64_t)chainparams.GetConsensus().dynamic_epoch_length); obj.pushKV("total_valid_epochs", (uint64_t)chainparams.GetConsensus().total_valid_epochs); - obj.pushKV("epoch_age", (uint64_t)(::ChainActive().Tip()->nHeight % chainparams.GetConsensus().dynamic_epoch_length)); + obj.pushKV("epoch_age", (uint64_t)(tip->nHeight % chainparams.GetConsensus().dynamic_epoch_length)); } } @@ -2847,13 +2846,15 @@ static RPCHelpMan getsidechaininfo() { LOCK(cs_main); + NodeContext& node = EnsureAnyNodeContext(request.context); + ChainstateManager& chainman = EnsureChainman(node); const Consensus::Params& consensus = Params().GetConsensus(); const uint256& parent_blockhash = Params().ParentGenesisBlockHash(); UniValue obj(UniValue::VOBJ); obj.pushKV("fedpegscript", HexStr(consensus.fedpegScript)); // We use mempool_validation as true to show what is enforced for *next* block - std::vector> fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), consensus, true /* nextblock_validation */); + std::vector> fedpegscripts = GetValidFedpegScripts(chainman.ActiveChain().Tip(), consensus, true /* nextblock_validation */); UniValue fedpeg_prog_entries(UniValue::VARR); UniValue fedpeg_entries(UniValue::VARR); for (const auto& scripts : fedpegscripts) { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 9e41e1822e..02d4790052 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -121,7 +121,6 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& { LOCK(cs_main); - CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain())); IncrementExtraNonce(&block, chainman.ActiveChain().Tip(), extra_nonce); } @@ -167,7 +166,6 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me { // Don't keep cs_main locked LOCK(cs_main); - CHECK_NONFATAL(std::addressof(::ChainActive()) == std::addressof(chainman.ActiveChain())); nHeight = chainman.ActiveChain().Height(); nHeightEnd = nHeight+nGenerate; } @@ -1300,6 +1298,8 @@ static RPCHelpMan getnewblockhex() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + ChainstateManager& chainman = EnsureAnyChainman(request.context); + int required_wait = !request.params[0].isNull() ? request.params[0].get_int() : 0; if (required_wait < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "min_tx_age must be non-negative."); @@ -1308,7 +1308,7 @@ static RPCHelpMan getnewblockhex() // Construct proposed parameter entry, if any DynaFedParamEntry proposed; if (!request.params[1].isNull()) { - if (!IsDynaFedEnabled(::ChainActive().Tip(), Params().GetConsensus())) { + if (!IsDynaFedEnabled(chainman.ActiveChain().Tip(), Params().GetConsensus())) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Dynamic federations is not active on this network. Proposed parameters are not needed."); } @@ -1356,7 +1356,7 @@ static RPCHelpMan getnewblockhex() CScript feeDestinationScript = Params().GetConsensus().mandatory_coinbase_destination; if (feeDestinationScript == CScript()) feeDestinationScript = CScript() << OP_TRUE; const NodeContext& node = EnsureAnyNodeContext(request.context); - std::unique_ptr pblocktemplate(BlockAssembler(::ChainstateActive(), *node.mempool, Params()).CreateNewBlock(feeDestinationScript, std::chrono::seconds(required_wait), &proposed, data_commitment.empty() ? nullptr : &data_commitment)); + std::unique_ptr pblocktemplate(BlockAssembler(chainman.ActiveChainstate(), *node.mempool, Params()).CreateNewBlock(feeDestinationScript, std::chrono::seconds(required_wait), &proposed, data_commitment.empty() ? nullptr : &data_commitment)); if (!pblocktemplate.get()) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet keypool empty"); } @@ -1365,7 +1365,7 @@ static RPCHelpMan getnewblockhex() // IncrementExtraNonce sets coinbase flags and builds merkle tree LOCK(cs_main); unsigned int nExtraNonce = 0; - IncrementExtraNonce(&pblocktemplate->block, ::ChainActive().Tip(), nExtraNonce); + IncrementExtraNonce(&pblocktemplate->block, chainman.ActiveChain().Tip(), nExtraNonce); } // If WSH(OP_TRUE) block, fill in witness @@ -1718,13 +1718,13 @@ static RPCHelpMan testproposedblock() if (mi != chainman.BlockIndex().end()) throw JSONRPCError(RPC_VERIFY_ERROR, "already have block"); - CBlockIndex* const pindexPrev = ::ChainActive().Tip(); + CBlockIndex* const pindexPrev = chainman.ActiveChain().Tip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) throw JSONRPCError(RPC_VERIFY_ERROR, "proposal was not based on our best chain"); BlockValidationState state; - if (!TestBlockValidity(state, Params(), ::ChainstateActive(), block, pindexPrev, false, true) || !state.IsValid()) { + if (!TestBlockValidity(state, Params(), chainman.ActiveChainstate(), block, pindexPrev, false, true) || !state.IsValid()) { std::string strRejectReason = state.GetRejectReason(); if (strRejectReason.empty()) throw JSONRPCError(RPC_VERIFY_ERROR, state.IsInvalid() ? "Block proposal was invalid" : "Error checking block proposal"); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0f2fdb0531..10f5c27c2c 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -804,7 +804,8 @@ static RPCHelpMan tweakfedpegscript() throw JSONRPCError(RPC_TYPE_ERROR, "the first argument must be a hex string"); } - CScript fedpegscript = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */).front().second; + ChainstateManager& chainman = EnsureAnyChainman(request.context); + CScript fedpegscript = GetValidFedpegScripts(chainman.ActiveChain().Tip(), Params().GetConsensus(), true /* nextblock_validation */).front().second; if (!request.params[1].isNull()) { if (IsHex(request.params[1].get_str())) { @@ -870,7 +871,8 @@ static RPCHelpMan getpakinfo() LOCK(cs_main); UniValue ret(UniValue::VOBJ); - CPAKList paklist = GetActivePAKList(::ChainActive().Tip(), Params().GetConsensus()); + ChainstateManager& chainman = EnsureAnyChainman(request.context); + CPAKList paklist = GetActivePAKList(chainman.ActiveChain().Tip(), Params().GetConsensus()); ret.pushKV("block_paklist", FormatPAKList(paklist)); return ret; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 5e62ec312f..b53f1391ee 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -470,6 +470,8 @@ static RPCHelpMan createrawtransaction() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + ChainstateManager& chainman = EnsureAnyChainman(request.context); + RPCTypeCheck(request.params, { UniValue::VARR, UniValueType(), // ARR or OBJ, checked later @@ -483,7 +485,7 @@ static RPCHelpMan createrawtransaction() if (!request.params[3].isNull()) { rbf = request.params[3].isTrue(); } - CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, request.params[4]); + CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, chainman.ActiveChain().Tip(), request.params[4]); return EncodeHexTx(CTransaction(rawTx)); }, @@ -831,6 +833,8 @@ static RPCHelpMan signrawtransactionwithkey() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + ChainstateManager& chainman = EnsureAnyChainman(request.context); + RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VARR, UniValue::VSTR}, true); CMutableTransaction mtx; @@ -861,7 +865,7 @@ static RPCHelpMan signrawtransactionwithkey() ParsePrevouts(request.params[2], &keystore, coins); UniValue result(UniValue::VOBJ); - SignTransaction(mtx, &keystore, coins, request.params[3], result); + SignTransaction(mtx, &keystore, coins, request.params[3], result, chainman.ActiveChain().Tip()); return result; }, }; @@ -1780,6 +1784,8 @@ static RPCHelpMan createpsbt() if (!g_con_elementsmode) throw std::runtime_error("PSBT operations are disabled when not in elementsmode.\n"); + ChainstateManager& chainman = EnsureAnyChainman(request.context); + RPCTypeCheck(request.params, { UniValue::VARR, UniValueType(), // ARR or OBJ, checked later @@ -1793,7 +1799,7 @@ static RPCHelpMan createpsbt() if (!request.params[3].isNull()) { rbf = request.params[3].isTrue(); } - CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, request.params[4], &output_pubkeys); + CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, chainman.ActiveChain().Tip(), request.params[4], &output_pubkeys); // Make a blank psbt PartiallySignedTransaction psbtx(rawTx); @@ -2269,6 +2275,8 @@ static RPCHelpMan rawblindrawtransaction() RPCExamples{""}, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + NodeContext& node = EnsureAnyNodeContext(request.context); + ChainstateManager& chainman = EnsureChainman(node); std::vector txData(ParseHexV(request.params[0], "argument 1")); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); CMutableTransaction tx; @@ -2307,7 +2315,7 @@ static RPCHelpMan rawblindrawtransaction() "Invalid parameter: one (potentially empty) input asset blind for each input must be provided"); } - const auto& fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto& fedpegscripts = GetValidFedpegScripts(chainman.ActiveChain().Tip(), Params().GetConsensus(), true /* nextblock_validation */); std::vector input_amounts; std::vector input_blinds; diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp index aeadd25694..5bdf794294 100644 --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -43,7 +43,7 @@ unsigned int GetPeginTxnOutputIndex(const T_tx& txn, const CScript& witnessProgr // Modifies an existing transaction input in-place to be a valid peg-in input, and inserts the witness if deemed valid. template -static void CreatePegInInputInner(CMutableTransaction& mtx, uint32_t input_idx, T_tx_ref& txBTCRef, T_merkle_block& merkleBlock, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData) +static void CreatePegInInputInner(CMutableTransaction& mtx, uint32_t input_idx, T_tx_ref& txBTCRef, T_merkle_block& merkleBlock, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData, const CBlockIndex* active_chain_tip) { if ((mtx.vin.size() > input_idx && !mtx.vin[input_idx].scriptSig.empty()) || (mtx.witness.vtxinwit.size() > input_idx && !mtx.witness.vtxinwit[input_idx].IsNull())) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Attempting to add a peg-in to an input that already has a scriptSig or witness"); @@ -79,7 +79,7 @@ static void CreatePegInInputInner(CMutableTransaction& mtx, uint32_t input_idx, CScript witness_script; unsigned int nOut = txBTCRef->vout.size(); - const auto fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto fedpegscripts = GetValidFedpegScripts(active_chain_tip, Params().GetConsensus(), true /* nextblock_validation */); for (const CScript& script : claim_scripts) { nOut = GetPeginTxnOutputIndex(*txBTCRef, script, fedpegscripts); if (nOut != txBTCRef->vout.size()) { @@ -134,16 +134,16 @@ static void CreatePegInInputInner(CMutableTransaction& mtx, uint32_t input_idx, mtx.witness.vtxinwit[input_idx] = txinwit; } -void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, CTransactionRef& tx_btc, CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData) +void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, CTransactionRef& tx_btc, CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData, const CBlockIndex* active_chain_tip) { - CreatePegInInputInner(mtx, input_idx, tx_btc, merkle_block, claim_scripts, txData, txOutProofData); + CreatePegInInputInner(mtx, input_idx, tx_btc, merkle_block, claim_scripts, txData, txOutProofData, active_chain_tip); } -void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, Sidechain::Bitcoin::CTransactionRef& tx_btc, Sidechain::Bitcoin::CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData) +void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, Sidechain::Bitcoin::CTransactionRef& tx_btc, Sidechain::Bitcoin::CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData, const CBlockIndex* active_chain_tip) { - CreatePegInInputInner(mtx, input_idx, tx_btc, merkle_block, claim_scripts, txData, txOutProofData); + CreatePegInInputInner(mtx, input_idx, tx_btc, merkle_block, claim_scripts, txData, txOutProofData, active_chain_tip); } -CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, bool rbf, const UniValue& assets_in, std::vector* output_pubkeys_out, bool allow_peg_in) +CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, bool rbf, const CBlockIndex* active_chain_tip, const UniValue& assets_in, std::vector* output_pubkeys_out, bool allow_peg_in) { if (outputs_in.isNull()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output argument must be non-null"); @@ -225,14 +225,14 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal if (Params().GetConsensus().ParentChainHasPow()) { Sidechain::Bitcoin::CTransactionRef tx_btc; Sidechain::Bitcoin::CMerkleBlock merkle_block; - CreatePegInInput(rawTx, idx, tx_btc, merkle_block, claim_scripts, ParseHex(pegin_tx.get_str()), ParseHex(pegin_tx_proof.get_str())); + CreatePegInInput(rawTx, idx, tx_btc, merkle_block, claim_scripts, ParseHex(pegin_tx.get_str()), ParseHex(pegin_tx_proof.get_str()), active_chain_tip); if (!CheckParentProofOfWork(merkle_block.header.GetHash(), merkle_block.header.nBits, Params().GetConsensus())) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof"); } } else { CTransactionRef tx_btc; CMerkleBlock merkle_block; - CreatePegInInput(rawTx, idx, tx_btc, merkle_block, claim_scripts, ParseHex(pegin_tx.get_str()), ParseHex(pegin_tx_proof.get_str())); + CreatePegInInput(rawTx, idx, tx_btc, merkle_block, claim_scripts, ParseHex(pegin_tx.get_str()), ParseHex(pegin_tx_proof.get_str()), active_chain_tip); if (!CheckProofSignedParent(merkle_block.header, Params().GetConsensus())) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid tx out proof"); } @@ -503,9 +503,9 @@ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keyst } // ELEMENTS: check whether pegin inputs make sense against the current fedpegscript -bool ValidateTransactionPeginInputs(const CMutableTransaction& mtx, std::map& input_errors) +bool ValidateTransactionPeginInputs(const CMutableTransaction& mtx, const CBlockIndex* active_chain_tip, std::map& input_errors) { - const auto& fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto& fedpegscripts = GetValidFedpegScripts(active_chain_tip, Params().GetConsensus(), true /* nextblock_validation */); // Track an immature peg-in that's otherwise valid, give warning bool immature_pegin = false; @@ -525,14 +525,14 @@ bool ValidateTransactionPeginInputs(const CMutableTransaction& mtx, std::map& coins, const UniValue& hashType, UniValue& result) +void SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map& coins, const UniValue& hashType, UniValue& result, const CBlockIndex* active_chain_tip) { int nHashType = ParseSighashString(hashType); // Script verification errors std::map input_errors; - bool immature_pegin = ValidateTransactionPeginInputs(mtx, input_errors); + bool immature_pegin = ValidateTransactionPeginInputs(mtx, active_chain_tip, input_errors); bool complete = SignTransaction(mtx, keystore, coins, nHashType, input_errors); SignTransactionResultToJSON(mtx, complete, coins, input_errors, immature_pegin, result); } diff --git a/src/rpc/rawtransaction_util.h b/src/rpc/rawtransaction_util.h index 4c8946e082..8ef30720e7 100644 --- a/src/rpc/rawtransaction_util.h +++ b/src/rpc/rawtransaction_util.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -31,7 +32,7 @@ class SigningProvider; * @param hashType The signature hash type * @param result JSON object where signed transaction results accumulate */ -void SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map& coins, const UniValue& hashType, UniValue& result); +void SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, const std::map& coins, const UniValue& hashType, UniValue& result, const CBlockIndex* active_chain_tip); void SignTransactionResultToJSON(CMutableTransaction& mtx, bool complete, const std::map& coins, const std::map& input_errors, bool immature_pegin, UniValue& result); /** @@ -46,13 +47,13 @@ void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keyst /** Create a transaction from univalue parameters. If (and only if) output_pubkeys_out is null, the "nonce hack" of storing Confidential Assets output pubkeys in nonces will be used. */ -CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, bool rbf, const UniValue& assets_in, std::vector* output_pubkeys_out = nullptr, bool allow_peg_in = true); +CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime, bool rbf, const CBlockIndex* active_chain_tip, const UniValue& assets_in, std::vector* output_pubkeys_out = nullptr, bool allow_peg_in = true); /** Create a peg-in input */ -void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, CTransactionRef& tx_btc, CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData); -void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, Sidechain::Bitcoin::CTransactionRef& tx_btc, Sidechain::Bitcoin::CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData); +void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, CTransactionRef& tx_btc, CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData, const CBlockIndex* active_chain_tip); +void CreatePegInInput(CMutableTransaction& mtx, uint32_t input_idx, Sidechain::Bitcoin::CTransactionRef& tx_btc, Sidechain::Bitcoin::CMerkleBlock& merkle_block, const std::set& claim_scripts, const std::vector& txData, const std::vector& txOutProofData, const CBlockIndex* active_chain_tip); /** Check a peg-in input against the current fedpeg parameters */ -bool ValidateTransactionPeginInputs(const CMutableTransaction& mtx, std::map& input_errors); +bool ValidateTransactionPeginInputs(const CMutableTransaction& mtx, const CBlockIndex* active_chain_tip, std::map& input_errors); #endif // BITCOIN_RPC_RAWTRANSACTION_UTIL_H diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp index 2f532ef598..2eb653e9ec 100644 --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -62,7 +62,7 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev, const CScript& scriptPubKey) { const CChainParams& chainparams = Params(); - std::unique_ptr pblocktemplate = BlockAssembler(::ChainstateActive(), *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey); + std::unique_ptr pblocktemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), *m_node.mempool, chainparams).CreateNewBlock(scriptPubKey); CBlock& block = pblocktemplate->block; block.hashPrevBlock = prev->GetBlockHash(); block.nTime = prev->nTime + 1; @@ -117,9 +117,9 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) std::vector filters; std::vector filter_hashes; - for (const CBlockIndex* block_index = ::ChainActive().Genesis(); + for (const CBlockIndex* block_index = m_node.chainman->ActiveChain().Genesis(); block_index != nullptr; - block_index = ::ChainActive().Next(block_index)) { + block_index = m_node.chainman->ActiveChain().Next(block_index)) { BOOST_CHECK(!filter_index.LookupFilter(block_index, filter)); BOOST_CHECK(!filter_index.LookupFilterHeader(block_index, filter_header)); BOOST_CHECK(!filter_index.LookupFilterRange(block_index->nHeight, block_index, filters)); @@ -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(::ChainstateActive())); + BOOST_REQUIRE(filter_index.Start(m_node.chainman->ActiveChainstate())); // Allow filter index to catch up with the block index. constexpr int64_t timeout_ms = 10 * 1000; @@ -145,9 +145,9 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) { LOCK(cs_main); const CBlockIndex* block_index; - for (block_index = ::ChainActive().Genesis(); + for (block_index = m_node.chainman->ActiveChain().Genesis(); block_index != nullptr; - block_index = ::ChainActive().Next(block_index)) { + block_index = m_node.chainman->ActiveChain().Next(block_index)) { CheckFilterLookups(filter_index, block_index, last_header); } } @@ -156,7 +156,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) const CBlockIndex* tip; { LOCK(cs_main); - tip = ::ChainActive().Tip(); + tip = m_node.chainman->ActiveChain().Tip(); } CKey coinbase_key_A, coinbase_key_B; coinbase_key_A.MakeNewKey(true); @@ -178,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) const CBlockIndex* block_index; { LOCK(cs_main); - block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash()); + block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash()); } BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); @@ -196,7 +196,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) const CBlockIndex* block_index; { LOCK(cs_main); - block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash()); + block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash()); } BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); @@ -210,7 +210,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) const CBlockIndex* block_index; { LOCK(cs_main); - block_index = g_chainman.m_blockman.LookupBlockIndex(block->GetHash()); + block_index = m_node.chainman->m_blockman.LookupBlockIndex(block->GetHash()); } BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); @@ -231,14 +231,14 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) { LOCK(cs_main); - block_index = g_chainman.m_blockman.LookupBlockIndex(chainA[i]->GetHash()); + block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainA[i]->GetHash()); } BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); CheckFilterLookups(filter_index, block_index, chainA_last_header); { LOCK(cs_main); - block_index = g_chainman.m_blockman.LookupBlockIndex(chainB[i]->GetHash()); + block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainB[i]->GetHash()); } BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); CheckFilterLookups(filter_index, block_index, chainB_last_header); @@ -250,7 +250,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) { LOCK(cs_main); - tip = ::ChainActive().Tip(); + tip = m_node.chainman->ActiveChain().Tip(); } BOOST_CHECK(filter_index.LookupFilterRange(0, tip, filters)); BOOST_CHECK(filter_index.LookupFilterHashRange(0, tip, filter_hashes)); diff --git a/src/test/coinstatsindex_tests.cpp b/src/test/coinstatsindex_tests.cpp index 106fcd2a33..597d7a7340 100644 --- a/src/test/coinstatsindex_tests.cpp +++ b/src/test/coinstatsindex_tests.cpp @@ -22,7 +22,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup) const CBlockIndex* block_index; { LOCK(cs_main); - block_index = ChainActive().Tip(); + block_index = m_node.chainman->ActiveChain().Tip(); } // CoinStatsIndex should not be found before it is started. @@ -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(::ChainstateActive())); + BOOST_REQUIRE(coin_stats_index.Start(m_node.chainman->ActiveChainstate())); // Allow the CoinStatsIndex to catch up with the block index that is syncing // in a background thread. @@ -46,7 +46,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup) const CBlockIndex* genesis_block_index; { LOCK(cs_main); - genesis_block_index = ChainActive().Genesis(); + genesis_block_index = m_node.chainman->ActiveChain().Genesis(); } BOOST_CHECK(coin_stats_index.LookUpStats(genesis_block_index, coin_stats)); @@ -64,7 +64,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup) const CBlockIndex* new_block_index; { LOCK(cs_main); - new_block_index = ChainActive().Tip(); + new_block_index = m_node.chainman->ActiveChain().Tip(); } coin_stats_index.LookUpStats(new_block_index, new_coin_stats); diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index 2b9a616f17..57178d015d 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -66,8 +66,8 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction) // This test requires that we have a chain with non-zero work. { LOCK(cs_main); - BOOST_CHECK(::ChainActive().Tip() != nullptr); - BOOST_CHECK(::ChainActive().Tip()->nChainWork > 0); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip() != nullptr); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->nChainWork > 0); } // Test starts here diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index 3eb08cdc98..a7156d03ff 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -27,6 +27,7 @@ #include namespace { +const TestingSetup* g_setup; const Coin EMPTY_COIN{}; bool operator==(const Coin& a, const Coin& b) @@ -39,6 +40,7 @@ bool operator==(const Coin& a, const Coin& b) void initialize_coins_view() { static const auto testing_setup = MakeNoLogFileContext(); + g_setup = testing_setup.get(); } FUZZ_TARGET_INIT(coins_view, initialize_coins_view) @@ -279,7 +281,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view) CCoinsStats stats{CoinStatsHashType::HASH_SERIALIZED}; bool expected_code_path = false; try { - (void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats); + (void)GetUTXOStats(&coins_view_cache, WITH_LOCK(::cs_main, return std::ref(g_setup->m_node.chainman->m_blockman)), stats); } catch (const std::logic_error&) { expected_code_path = true; } diff --git a/src/test/fuzz/load_external_block_file.cpp b/src/test/fuzz/load_external_block_file.cpp index dbd0c76d42..a7770c90e8 100644 --- a/src/test/fuzz/load_external_block_file.cpp +++ b/src/test/fuzz/load_external_block_file.cpp @@ -13,9 +13,14 @@ #include #include +namespace { +const TestingSetup* g_setup; +} // namespace + void initialize_load_external_block_file() { static const auto testing_setup = MakeNoLogFileContext(); + g_setup = testing_setup.get(); } FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file) @@ -27,5 +32,5 @@ FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file) return; } FlatFilePos flat_file_pos; - ::ChainstateActive().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr); + g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr); } diff --git a/src/test/fuzz/validation_load_mempool.cpp b/src/test/fuzz/validation_load_mempool.cpp index e1a21b6c53..c2aaf486c5 100644 --- a/src/test/fuzz/validation_load_mempool.cpp +++ b/src/test/fuzz/validation_load_mempool.cpp @@ -14,9 +14,14 @@ #include #include +namespace { +const TestingSetup* g_setup; +} // namespace + void initialize_validation_load_mempool() { static const auto testing_setup = MakeNoLogFileContext(); + g_setup = testing_setup.get(); } FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool) @@ -29,6 +34,6 @@ FUZZ_TARGET_INIT(validation_load_mempool, initialize_validation_load_mempool) auto fuzzed_fopen = [&](const fs::path&, const char*) { return fuzzed_file_provider.open(); }; - (void)LoadMempool(pool, ::ChainstateActive(), fuzzed_fopen); + (void)LoadMempool(pool, g_setup->m_node.chainman->ActiveChainstate(), fuzzed_fopen); (void)DumpMempool(pool, fuzzed_fopen, true); } diff --git a/src/test/interfaces_tests.cpp b/src/test/interfaces_tests.cpp index 73463b071e..42a7c7798c 100644 --- a/src/test/interfaces_tests.cpp +++ b/src/test/interfaces_tests.cpp @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findCommonAncestor) auto* orig_tip = active.Tip(); for (int i = 0; i < 10; ++i) { BlockValidationState state; - ChainstateActive().InvalidateBlock(state, Params(), active.Tip()); + m_node.chainman->ActiveChainstate().InvalidateBlock(state, Params(), active.Tip()); } BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10); coinbaseKey.MakeNewKey(true); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 508a923226..f6bc0ace01 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -45,7 +45,7 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params) options.nBlockMaxWeight = MAX_BLOCK_WEIGHT; options.blockMinFeeRate = blockMinFeeRate; - return BlockAssembler(::ChainstateActive(), *m_node.mempool, params, options); + return BlockAssembler(m_node.chainman->ActiveChainstate(), *m_node.mempool, params, options); } constexpr static struct { @@ -82,11 +82,11 @@ constexpr static struct { {2, 0xbbbeb305}, {2, 0xfe1c810a}, }; -static CBlockIndex CreateBlockIndex(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +static CBlockIndex CreateBlockIndex(int nHeight, CBlockIndex* active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { CBlockIndex index; index.nHeight = nHeight; - index.pprev = ::ChainActive().Tip(); + index.pprev = active_chain_tip; return index; } @@ -228,17 +228,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { LOCK(cs_main); pblock->nVersion = 1; - pblock->nTime = ::ChainActive().Tip()->GetMedianTimePast()+1; + pblock->nTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1; CMutableTransaction txCoinbase(*pblock->vtx[0]); txCoinbase.nVersion = 1; txCoinbase.vin[0].scriptSig = CScript(); txCoinbase.vin[0].scriptSig.push_back(bi.extranonce); - txCoinbase.vin[0].scriptSig.push_back(::ChainActive().Height()); + txCoinbase.vin[0].scriptSig.push_back(m_node.chainman->ActiveChain().Height()); txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.vout[0].scriptPubKey = CScript(); pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase)); if (txFirst.size() == 0) - baseheight = ::ChainActive().Height(); + baseheight = m_node.chainman->ActiveChain().Height(); if (txFirst.size() < 4) txFirst.push_back(pblock->vtx[0]); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); @@ -364,29 +364,29 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) m_node.mempool->clear(); // subsidy changing - int nHeight = ::ChainActive().Height(); + int nHeight = m_node.chainman->ActiveChain().Height(); // Create an actual 209999-long block chain (without valid blocks). - while (::ChainActive().Tip()->nHeight < 209999) { - CBlockIndex* prev = ::ChainActive().Tip(); + while (m_node.chainman->ActiveChain().Tip()->nHeight < 209999) { + CBlockIndex* prev = m_node.chainman->ActiveChain().Tip(); CBlockIndex* next = new CBlockIndex(); next->phashBlock = new uint256(InsecureRand256()); - ::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash()); + m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash()); next->pprev = prev; next->nHeight = prev->nHeight + 1; next->BuildSkip(); - ::ChainActive().SetTip(next); + m_node.chainman->ActiveChain().SetTip(next); } BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); // Extend to a 210000-long block chain. - while (::ChainActive().Tip()->nHeight < 210000) { - CBlockIndex* prev = ::ChainActive().Tip(); + while (m_node.chainman->ActiveChain().Tip()->nHeight < 210000) { + CBlockIndex* prev = m_node.chainman->ActiveChain().Tip(); CBlockIndex* next = new CBlockIndex(); next->phashBlock = new uint256(InsecureRand256()); - ::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash()); + m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(next->GetBlockHash()); next->pprev = prev; next->nHeight = prev->nHeight + 1; next->BuildSkip(); - ::ChainActive().SetTip(next); + m_node.chainman->ActiveChain().SetTip(next); } BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); @@ -409,16 +409,16 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) m_node.mempool->clear(); // Delete the dummy blocks again. - while (::ChainActive().Tip()->nHeight > nHeight) { - CBlockIndex* del = ::ChainActive().Tip(); - ::ChainActive().SetTip(del->pprev); - ::ChainstateActive().CoinsTip().SetBestBlock(del->pprev->GetBlockHash()); + while (m_node.chainman->ActiveChain().Tip()->nHeight > nHeight) { + CBlockIndex* del = m_node.chainman->ActiveChain().Tip(); + m_node.chainman->ActiveChain().SetTip(del->pprev); + m_node.chainman->ActiveChainstate().CoinsTip().SetBestBlock(del->pprev->GetBlockHash()); delete del->phashBlock; delete del; } // non-final txs in mempool - SetMockTime(::ChainActive().Tip()->GetMedianTimePast()+1); + SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1); int flags = LOCKTIME_VERIFY_SEQUENCE|LOCKTIME_MEDIAN_TIME_PAST; // height map std::vector prevheights; @@ -430,7 +430,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[0]->GetHash(); // only 1 transaction tx.vin[0].prevout.n = 0; tx.vin[0].scriptSig = CScript() << OP_1; - tx.vin[0].nSequence = ::ChainActive().Tip()->nHeight + 1; // txFirst[0] is the 2nd block + tx.vin[0].nSequence = m_node.chainman->ActiveChain().Tip()->nHeight + 1; // txFirst[0] is the 2nd block prevheights[0] = baseheight + 1; tx.vout.resize(1); tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; @@ -438,53 +438,62 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.nLockTime = 0; hash = tx.GetHash(); m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); - BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes + BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail - BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 2))); // Sequence locks pass on 2nd block + + { + CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip(); + BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 2, active_chain_tip))); // Sequence locks pass on 2nd block + } // relative time locked tx.vin[0].prevout.hash = txFirst[1]->GetHash(); - tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((::ChainActive().Tip()->GetMedianTimePast()+1-::ChainActive()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block + tx.vin[0].nSequence = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | (((m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1-m_node.chainman->ActiveChain()[1]->GetMedianTimePast()) >> CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) + 1); // txFirst[1] is the 3rd block prevheights[0] = baseheight + 2; hash = tx.GetHash(); m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes + BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) - ::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast - BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 1))); // Sequence locks pass 512 seconds later + m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast + + { + CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip(); + BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip))); // Sequence locks pass 512 seconds later + } + for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) - ::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP + m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP // absolute height locked tx.vin[0].prevout.hash = txFirst[2]->GetHash(); tx.vin[0].nSequence = CTxIn::SEQUENCE_FINAL - 1; prevheights[0] = baseheight + 3; - tx.nLockTime = ::ChainActive().Tip()->nHeight + 1; + tx.nLockTime = m_node.chainman->ActiveChain().Tip()->nHeight + 1; hash = tx.GetHash(); m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(!CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime fails + BOOST_CHECK(!CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime fails BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass - BOOST_CHECK(IsFinalTx(CTransaction(tx), ::ChainActive().Tip()->nHeight + 2, ::ChainActive().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block + BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast())); // Locktime passes on 2nd block // absolute time locked tx.vin[0].prevout.hash = txFirst[3]->GetHash(); - tx.nLockTime = ::ChainActive().Tip()->GetMedianTimePast(); + tx.nLockTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast(); prevheights.resize(1); prevheights[0] = baseheight + 4; hash = tx.GetHash(); m_node.mempool->addUnchecked(entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(!CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime fails + BOOST_CHECK(!CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime fails BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass - BOOST_CHECK(IsFinalTx(CTransaction(tx), ::ChainActive().Tip()->nHeight + 2, ::ChainActive().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later + BOOST_CHECK(IsFinalTx(CTransaction(tx), m_node.chainman->ActiveChain().Tip()->nHeight + 2, m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1)); // Locktime passes 1 second later // mempool-dependent transactions (not added) tx.vin[0].prevout.hash = hash; - prevheights[0] = ::ChainActive().Tip()->nHeight + 1; + prevheights[0] = m_node.chainman->ActiveChain().Tip()->nHeight + 1; tx.nLockTime = 0; tx.vin[0].nSequence = 0; - BOOST_CHECK(CheckFinalTx(::ChainActive().Tip(), CTransaction(tx), flags)); // Locktime passes + BOOST_CHECK(CheckFinalTx(m_node.chainman->ActiveChain().Tip(), CTransaction(tx), flags)); // Locktime passes BOOST_CHECK(TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks pass tx.vin[0].nSequence = 1; BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail @@ -502,14 +511,14 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U); // However if we advance height by 1 and time by 512, all of them should be mined for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) - ::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast - ::ChainActive().Tip()->nHeight++; - SetMockTime(::ChainActive().Tip()->GetMedianTimePast() + 1); + m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast + m_node.chainman->ActiveChain().Tip()->nHeight++; + SetMockTime(m_node.chainman->ActiveChain().Tip()->GetMedianTimePast() + 1); BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U); - ::ChainActive().Tip()->nHeight--; + m_node.chainman->ActiveChain().Tip()->nHeight--; SetMockTime(0); m_node.mempool->clear(); diff --git a/src/test/txindex_tests.cpp b/src/test/txindex_tests.cpp index 6edb7db230..67591f20d2 100644 --- a/src/test/txindex_tests.cpp +++ b/src/test/txindex_tests.cpp @@ -28,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(::ChainstateActive())); + BOOST_REQUIRE(txindex.Start(m_node.chainman->ActiveChainstate())); // Allow tx index to catch up with the block index. constexpr int64_t timeout_ms = 10 * 1000; diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp index 95ad85d0f8..ade9e210f2 100644 --- a/src/test/txvalidation_tests.cpp +++ b/src/test/txvalidation_tests.cpp @@ -37,7 +37,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup) LOCK(cs_main); unsigned int initialPoolSize = m_node.mempool->size(); - const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(coinbaseTx), + const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(coinbaseTx), true /* bypass_limits */); BOOST_CHECK(result.m_result_type == MempoolAcceptResult::ResultType::INVALID); diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index c4cf4ac3f1..7955ed5360 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -32,7 +32,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) const auto ToMemPool = [this](const CMutableTransaction& tx) { LOCK(cs_main); - const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, MakeTransactionRef(tx), + const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, MakeTransactionRef(tx), true /* bypass_limits */); return result.m_result_type == MempoolAcceptResult::ResultType::VALID; }; @@ -64,7 +64,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) block = CreateAndProcessBlock(spends, scriptPubKey); { LOCK(cs_main); - BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash()); } // Test 2: ... and should be rejected if spend1 is in the memory pool @@ -72,7 +72,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) block = CreateAndProcessBlock(spends, scriptPubKey); { LOCK(cs_main); - BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash()); } m_node.mempool->clear(); @@ -81,7 +81,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) block = CreateAndProcessBlock(spends, scriptPubKey); { LOCK(cs_main); - BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() != block.GetHash()); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() != block.GetHash()); } m_node.mempool->clear(); @@ -92,7 +92,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) block = CreateAndProcessBlock(oneSpend, scriptPubKey); { LOCK(cs_main); - BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() == block.GetHash()); } // spends[1] should have been removed from the mempool when the // block with spends[0] is accepted: @@ -110,7 +110,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) // should fail. // Capture this interaction with the upgraded_nop argument: set it when evaluating // any script flag that is implemented as an upgraded NOP code. -static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache, CCoinsViewCache& active_coins_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { PrecomputedTransactionData txdata; // If we add many more flags, this loop can get too expensive, but we can @@ -127,7 +127,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail // WITNESS requires P2SH test_flags |= SCRIPT_VERIFY_P2SH; } - bool ret = CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr); + bool ret = CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, nullptr); // CheckInputScripts should succeed iff test_flags doesn't intersect with // failing_flags bool expected_return_value = !(test_flags & failing_flags); @@ -137,14 +137,14 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail if (ret && add_to_cache) { // Check that we get a cache hit if the tx was valid std::vector scriptchecks; - BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(scriptchecks.empty()); for (auto check : scriptchecks) delete check; } else { // Check that we get script executions to check, if the transaction // was invalid, or we didn't add to cache. std::vector scriptchecks; - BOOST_CHECK(CheckInputScripts(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputScripts(tx, state, &active_coins_tip, test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); for (auto check : scriptchecks) delete check; } @@ -208,13 +208,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) TxValidationState state; PrecomputedTransactionData ptd_spend_tx; - BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); + BOOST_CHECK(!CheckInputScripts(CTransaction(spend_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); // If we call again asking for scriptchecks (as happens in // ConnectBlock), we should add a script check object for this -- we're // not caching invalidity (if that changes, delete this test case). std::vector scriptchecks; - BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); + BOOST_CHECK(CheckInputScripts(CTransaction(spend_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); for (auto check : scriptchecks) delete check; @@ -222,7 +222,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) // not present. Don't add these checks to the cache, so that we can // test later that block validation works fine in the absence of cached // successes. - ValidateCheckInputsForAllFlags(CTransaction(spend_tx), SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false); + ValidateCheckInputsForAllFlags(CTransaction(spend_tx), SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false, m_node.chainman->ActiveChainstate().CoinsTip()); } // And if we produce a block with this tx, it should be valid (DERSIG not @@ -231,8 +231,8 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); LOCK(cs_main); - BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); - BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == block.GetHash()); + BOOST_CHECK(m_node.chainman->ActiveChain().Tip()->GetBlockHash() == block.GetHash()); + BOOST_CHECK(m_node.chainman->ActiveChainstate().CoinsTip().GetBestBlock() == block.GetHash()); // Test P2SH: construct a transaction that is valid without P2SH, and // then test validity with P2SH. @@ -248,7 +248,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) std::vector vchSig2(p2pk_scriptPubKey.begin(), p2pk_scriptPubKey.end()); invalid_under_p2sh_tx.vin[0].scriptSig << vchSig2; - ValidateCheckInputsForAllFlags(CTransaction(invalid_under_p2sh_tx), SCRIPT_VERIFY_P2SH, true); + ValidateCheckInputsForAllFlags(CTransaction(invalid_under_p2sh_tx), SCRIPT_VERIFY_P2SH, true, m_node.chainman->ActiveChainstate().CoinsTip()); } // Test CHECKLOCKTIMEVERIFY @@ -271,13 +271,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) vchSig.push_back((unsigned char)SIGHASH_ALL); invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 101; - ValidateCheckInputsForAllFlags(CTransaction(invalid_with_cltv_tx), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true); + ValidateCheckInputsForAllFlags(CTransaction(invalid_with_cltv_tx), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, m_node.chainman->ActiveChainstate().CoinsTip()); // Make it valid, and check again invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; TxValidationState state; PrecomputedTransactionData txdata; - BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); + BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_cltv_tx), state, m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); } // TEST CHECKSEQUENCEVERIFY @@ -299,13 +299,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) vchSig.push_back((unsigned char)SIGHASH_ALL); invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 101; - ValidateCheckInputsForAllFlags(CTransaction(invalid_with_csv_tx), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true); + ValidateCheckInputsForAllFlags(CTransaction(invalid_with_csv_tx), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, m_node.chainman->ActiveChainstate().CoinsTip()); // Make it valid, and check again invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; TxValidationState state; PrecomputedTransactionData txdata; - BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); + BOOST_CHECK(CheckInputScripts(CTransaction(invalid_with_csv_tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); } // TODO: add tests for remaining script flags @@ -329,11 +329,11 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) UpdateTransaction(valid_with_witness_tx, 0, sigdata); // This should be valid under all script flags. - ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), 0, true); + ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), 0, true, m_node.chainman->ActiveChainstate().CoinsTip()); // Remove the witness, and check that it is now invalid. valid_with_witness_tx.witness.vtxinwit[0].scriptWitness.SetNull(); - ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), SCRIPT_VERIFY_WITNESS, true); + ValidateCheckInputsForAllFlags(CTransaction(valid_with_witness_tx), SCRIPT_VERIFY_WITNESS, true, m_node.chainman->ActiveChainstate().CoinsTip()); } { @@ -359,7 +359,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) } // This should be valid under all script flags - ValidateCheckInputsForAllFlags(CTransaction(tx), 0, true); + ValidateCheckInputsForAllFlags(CTransaction(tx), 0, true, m_node.chainman->ActiveChainstate().CoinsTip()); // Check that if the second input is invalid, but the first input is // valid, the transaction is not cached. @@ -369,12 +369,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) TxValidationState state; PrecomputedTransactionData txdata; // This transaction is now invalid under segwit, because of the second input. - BOOST_CHECK(!CheckInputScripts(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); + BOOST_CHECK(!CheckInputScripts(CTransaction(tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); std::vector scriptchecks; // Make sure this transaction was not cached (ie because the first // input was valid) - BOOST_CHECK(CheckInputScripts(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputScripts(CTransaction(tx), state, &m_node.chainman->ActiveChainstate().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction basis. BOOST_CHECK_EQUAL(scriptchecks.size(), 2U); for (auto check : scriptchecks) delete check; diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp index 1204873828..f6a11bc02e 100644 --- a/src/test/util/mining.cpp +++ b/src/test/util/mining.cpp @@ -74,12 +74,12 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) std::shared_ptr PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) { auto block = std::make_shared( - BlockAssembler{::ChainstateActive(), *Assert(node.mempool), Params()} + BlockAssembler{Assert(node.chainman)->ActiveChainstate(), *Assert(node.mempool), Params()} .CreateNewBlock(coinbase_scriptPubKey) ->block); LOCK(cs_main); - block->nTime = ::ChainActive().Tip()->GetMedianTimePast() + 1; + block->nTime = Assert(node.chainman)->ActiveChain().Tip()->GetMedianTimePast() + 1; block->hashMerkleRoot = BlockMerkleRoot(*block); return block; diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 8074774238..8eb93751e0 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -171,7 +171,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::st m_node.fee_estimator = std::make_unique(); m_node.mempool = std::make_unique(m_node.fee_estimator.get(), 1); - m_node.chainman = &::g_chainman; + m_node.chainman = std::make_unique(); // Start script-checking threads. Set g_parallel_script_checks to true so they are used. constexpr int script_check_threads = 2; @@ -193,7 +193,7 @@ ChainTestingSetup::~ChainTestingSetup() m_node.mempool.reset(); m_node.scheduler.reset(); m_node.chainman->Reset(); - m_node.chainman = nullptr; + m_node.chainman.reset(); pblocktree.reset(); } @@ -206,17 +206,17 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::string& fedp RegisterAllCoreRPCCommands(tableRPC); m_node.chainman->InitializeChainstate(*m_node.mempool); - ::ChainstateActive().InitCoinsDB( + m_node.chainman->ActiveChainstate().InitCoinsDB( /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); - assert(!::ChainstateActive().CanFlushToDisk()); - ::ChainstateActive().InitCoinsCache(1 << 23); - assert(::ChainstateActive().CanFlushToDisk()); - if (!::ChainstateActive().LoadGenesisBlock(chainparams)) { + assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk()); + m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23); + assert(m_node.chainman->ActiveChainstate().CanFlushToDisk()); + if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock(chainparams)) { throw std::runtime_error("LoadGenesisBlock failed."); } BlockValidationState state; - if (!::ChainstateActive().ActivateBestChain(state, chainparams)) { + if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state, chainparams)) { throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString())); } @@ -266,7 +266,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vectorblock; + CBlock block = BlockAssembler(m_node.chainman->ActiveChainstate(), empty_pool, chainparams).CreateNewBlock(scriptPubKey)->block; Assert(block.vtx.size() == 1); for (const CMutableTransaction& tx : txns) { @@ -325,7 +325,7 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio // If submit=true, add transaction to the mempool. if (submit) { LOCK(cs_main); - const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool.get(), MakeTransactionRef(mempool_txn), /* bypass_limits */ false); + const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool.get(), MakeTransactionRef(mempool_txn), /* bypass_limits */ false); assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID); } diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp index 2c161b3642..3e6b8797de 100644 --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -86,8 +86,8 @@ std::shared_ptr MinerTestingSetup::Block(const uint256& prev_hash) std::shared_ptr MinerTestingSetup::FinalizeBlock(std::shared_ptr pblock) { - LOCK(cs_main); // For g_chainman.m_blockman.LookupBlockIndex - GenerateCoinbaseCommitment(*pblock, g_chainman.m_blockman.LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus()); + LOCK(cs_main); // For m_node.chainman->m_blockman.LookupBlockIndex + GenerateCoinbaseCommitment(*pblock, m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus()); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering) const CBlockIndex* initial_tip = nullptr; { LOCK(cs_main); - initial_tip = ::ChainActive().Tip(); + initial_tip = m_node.chainman->ActiveChain().Tip(); } auto sub = std::make_shared(initial_tip->GetBlockHash()); RegisterSharedValidationInterface(sub); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering) UnregisterSharedValidationInterface(sub); LOCK(cs_main); - BOOST_CHECK_EQUAL(sub->m_expected_tip, ::ChainActive().Tip()->GetBlockHash()); + BOOST_CHECK_EQUAL(sub->m_expected_tip, m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } /** @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg) // Run the test multiple times for (int test_runs = 3; test_runs > 0; --test_runs) { - BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash()); + BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); // Later on split from here const uint256 split_hash{last_mined->hashPrevBlock}; @@ -276,7 +276,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg) { LOCK(cs_main); for (const auto& tx : txs) { - const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool, tx, false /* bypass_limits */); + const MempoolAcceptResult result = AcceptToMemoryPool(m_node.chainman->ActiveChainstate(), *m_node.mempool, tx, false /* bypass_limits */); BOOST_REQUIRE(result.m_result_type == MempoolAcceptResult::ResultType::VALID); } } @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg) } LOCK(cs_main); // We are done with the reorg, so the tip must have changed - assert(tip_init != ::ChainActive().Tip()->GetBlockHash()); + assert(tip_init != m_node.chainman->ActiveChain().Tip()->GetBlockHash()); }}; // Submit the reorg in this thread to invalidate and remove the txs from the tx pool @@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg) ProcessBlock(b); } // Check that the reorg was eventually successful - BOOST_CHECK_EQUAL(last_mined->GetHash(), ::ChainActive().Tip()->GetBlockHash()); + BOOST_CHECK_EQUAL(last_mined->GetHash(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); // We can join the other thread, which returns when the reorg was successful rpc_thread.join(); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 4b16d7b017..a9ae8bf3b1 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -516,7 +516,6 @@ void CTxMemPool::removeForReorg(CChainState& active_chainstate, int flags) for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); LockPoints lp = it->GetLockPoints(); - assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate)); bool validLP = TestLockPointValidity(active_chainstate.m_chain, &lp); CCoinsViewMemPool view_mempool(&active_chainstate.CoinsTip(), *this); if (!CheckFinalTx(active_chainstate.m_chain.Tip(), tx, flags) @@ -670,13 +669,13 @@ void CTxMemPool::clear() _clear(); } -static void CheckInputsAndUpdateCoins(const CTxMemPoolEntry& entry, CCoinsViewCache& mempoolDuplicate, const int64_t spendheight, std::set>& setGlobalPeginsSpent) +static void CheckInputsAndUpdateCoins(CChainState& active_chainstate, const CTxMemPoolEntry& entry, CCoinsViewCache& mempoolDuplicate, const int64_t spendheight, std::set>& setGlobalPeginsSpent) { CTransaction tx = entry.GetTx(); TxValidationState dummy_state; // Not used. CheckTxInputs() should always pass CAmountMap fee_map; std::set > setPeginsSpent; - const auto& fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto& fedpegscripts = GetValidFedpegScripts(active_chainstate.m_chain.Tip(), Params().GetConsensus(), true /* nextblock_validation */); bool fCheckResult = tx.IsCoinBase() || Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate, spendheight, fee_map, setPeginsSpent, NULL, false, true, fedpegscripts); assert(fCheckResult); UpdateCoins(tx, mempoolDuplicate, std::numeric_limits::max()); @@ -703,10 +702,8 @@ void CTxMemPool::check(CChainState& active_chainstate) const uint64_t innerUsage = 0; CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip(); - assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(active_coins_tip)); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT CCoinsViewCache mempoolDuplicate(const_cast(&active_coins_tip)); const int64_t spendheight = active_chainstate.m_chain.Height() + 1; - assert(g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate) == spendheight); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT std::list waitingOnDependants; // ELEMENTS: @@ -786,7 +783,7 @@ void CTxMemPool::check(CChainState& active_chainstate) const if (fDependsWait) waitingOnDependants.push_back(&(*it)); else { - CheckInputsAndUpdateCoins(*it, mempoolDuplicate, spendheight, setGlobalPeginsSpent); + CheckInputsAndUpdateCoins(active_chainstate, *it, mempoolDuplicate, spendheight, setGlobalPeginsSpent); } } unsigned int stepsSinceLastRemove = 0; @@ -798,7 +795,7 @@ void CTxMemPool::check(CChainState& active_chainstate) const stepsSinceLastRemove++; assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { - CheckInputsAndUpdateCoins(*entry, mempoolDuplicate, spendheight, setGlobalPeginsSpent); + CheckInputsAndUpdateCoins(active_chainstate, *entry, mempoolDuplicate, spendheight, setGlobalPeginsSpent); stepsSinceLastRemove = 0; } } diff --git a/src/validation.cpp b/src/validation.cpp index 1cae736cba..764fadd1c9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -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 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() - 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 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> fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), chainparams.GetConsensus(), true /* nextblock_validation */); + std::vector> 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& 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& 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& pblock, Block bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr& 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 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)) { diff --git a/src/validation.h b/src/validation.h index ba5041fe2e..ed32efbea8 100644 --- a/src/validation.h +++ b/src/validation.h @@ -893,10 +893,6 @@ private: CAutoFile& coins_file, const SnapshotMetadata& metadata); - // For access to m_active_chainstate. - friend CChainState& ChainstateActive(); - friend CChain& ChainActive(); - public: std::thread m_load_block; //! A single BlockManager instance is shared across each constructed @@ -1019,17 +1015,14 @@ public: //! Check to see if caches are out of balance and if so, call //! ResizeCoinsCaches() as needed. void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); + + ~ChainstateManager() { + LOCK(::cs_main); + UnloadBlockIndex(/* mempool */ nullptr, *this); + Reset(); + } }; -/** DEPRECATED! Please use node.chainman instead. May only be used in validation.cpp internally */ -extern ChainstateManager g_chainman GUARDED_BY(::cs_main); - -/** Please prefer the identical ChainstateManager::ActiveChainstate */ -CChainState& ChainstateActive(); - -/** Please prefer the identical ChainstateManager::ActiveChain */ -CChain& ChainActive(); - /** Global variable that points to the active block tree (protected by cs_main) */ extern std::unique_ptr pblocktree; @@ -1059,6 +1052,6 @@ const AssumeutxoData* ExpectedAssumeutxo(const int height, const CChainParams& p // ELEMENTS: /** Check if bitcoind connection via RPC is correctly working*/ -bool MainchainRPCCheck(bool init); +bool MainchainRPCCheck(const bool init, ChainstateManager* chainman); #endif // BITCOIN_VALIDATION_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f6b98dd7c4..4193fae5ee 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -63,6 +63,8 @@ using interfaces::FoundBlock; +ChainstateManager& EnsureAnyChainman(const std::any& context); // ELEMENTS: from rpc/blockchain.cpp + static const std::string WALLET_ENDPOINT_BASE = "/wallet/"; static const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"}; @@ -3474,7 +3476,7 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, // Check any existing inputs for peg-in data and add to external txouts if so // Fetch specified UTXOs from the UTXO set - const auto& fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto& fedpegscripts = GetValidFedpegScripts(wallet.chain().getTip(), Params().GetConsensus(), true /* nextblock_validation */); std::map coins; for (unsigned int i = 0; i < tx.vin.size(); ++i ) { const CTxIn& txin = tx.vin[i]; @@ -3712,7 +3714,7 @@ RPCHelpMan signrawtransactionwithwallet() // Script verification errors std::map input_errors; - bool immature_pegin = ValidateTransactionPeginInputs(mtx, input_errors); + bool immature_pegin = ValidateTransactionPeginInputs(mtx, pwallet->chain().getTip(), input_errors); bool complete = pwallet->SignTransaction(mtx, coins, nHashType, input_errors); UniValue result(UniValue::VOBJ); SignTransactionResultToJSON(mtx, complete, coins, input_errors, immature_pegin, result); @@ -4594,7 +4596,7 @@ static RPCHelpMan send() if (options.exists("replaceable")) { rbf = options["replaceable"].get_bool(); } - CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf, NullUniValue /* CA: assets_in */, nullptr /* output_pubkey_out */, true /* allow_peg_in */); + CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf, pwallet->chain().getTip(), NullUniValue /* CA: assets_in */, nullptr /* output_pubkey_out */, true /* allow_peg_in */); CCoinControl coin_control; // Automatically select coins, unless at least one is manually selected. Can // be overridden by options.add_inputs. @@ -5038,7 +5040,7 @@ static RPCHelpMan walletcreatefundedpsbt() // It's hard to control the behavior of FundTransaction, so we will wait // until after it's done, then extract the blinding keys from the output // nonces. - CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, NullUniValue /* CA: assets_in */, nullptr /* output_pubkeys_out */, true /* allow_peg_in */); + CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, pwallet->chain().getTip(), NullUniValue /* CA: assets_in */, nullptr /* output_pubkeys_out */, true /* allow_peg_in */); CCoinControl coin_control; // Automatically select coins, unless at least one is manually selected. Can // be overridden by options.add_inputs. @@ -5271,8 +5273,6 @@ static RPCHelpMan signblock() 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 - LegacyScriptPubKeyMan* spk_man = pwallet->GetLegacyScriptPubKeyMan(); if (!spk_man) { throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command"); @@ -5281,17 +5281,16 @@ static RPCHelpMan signblock() { LOCK(cs_main); uint256 hash = block.GetHash(); - BlockMap::iterator mi = chainman.BlockIndex().find(hash); - if (mi != chainman.BlockIndex().end()) + if (pwallet->chain().hasBlocks(hash, 0, std::nullopt)) throw JSONRPCError(RPC_VERIFY_ERROR, "already have block"); - CBlockIndex* const pindexPrev = ::ChainActive().Tip(); + CBlockIndex* const pindexPrev = wallet->chain().getTip(); // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != pindexPrev->GetBlockHash()) throw JSONRPCError(RPC_VERIFY_ERROR, "proposal was not based on our best chain"); BlockValidationState state; - if (!TestBlockValidity(state, Params(), ::ChainstateActive(), block, pindexPrev, false, true) || !state.IsValid()) { + if (!wallet->chain().testBlockValidity(state, Params(), block, pindexPrev, false, true) || !state.IsValid()) { std::string strRejectReason = state.GetRejectReason(); if (strRejectReason.empty()) throw JSONRPCError(RPC_VERIFY_ERROR, state.IsInvalid() ? "Block proposal was invalid" : "Error checking block proposal"); @@ -5377,11 +5376,11 @@ static RPCHelpMan getpeginaddress() spk_man->AddCScript(dest_script); // Get P2CH deposit address on mainchain from most recent fedpegscript. - const auto& fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto& fedpegscripts = GetValidFedpegScripts(pwallet->chain().getTip(), Params().GetConsensus(), true /* nextblock_validation */); CTxDestination mainchain_dest(WitnessV0ScriptHash(calculate_contract(fedpegscripts.front().second, dest_script))); // P2SH-wrapped is the only valid choice for non-dynafed chains but still an // option for dynafed-enabled ones as well - if (!IsDynaFedEnabled(::ChainActive().Tip(), Params().GetConsensus()) || + if (!IsDynaFedEnabled(pwallet->chain().getTip(), Params().GetConsensus()) || fedpegscripts.front().first.IsPayToScriptHash()) { mainchain_dest = ScriptHash(GetScriptForDestination(mainchain_dest)); } @@ -5769,7 +5768,7 @@ static RPCHelpMan sendtomainchain_pak() subtract_fee = request.params[2].get_bool(); } - CPAKList paklist = GetActivePAKList(::ChainActive().Tip(), Params().GetConsensus()); + CPAKList paklist = GetActivePAKList(pwallet->chain().getTip(), Params().GetConsensus()); if (paklist.IsReject()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pegout freeze is under effect to aid a pak transition to a new list. Please consult the network operator."); } @@ -5994,7 +5993,7 @@ static UniValue createrawpegin(const JSONRPCRequest& request, T_tx_ref& txBTCRef CMutableTransaction mtx; // Construct pegin input - CreatePegInInput(mtx, 0, txBTCRef, merkleBlock, claim_scripts, txData, txOutProofData); + CreatePegInInput(mtx, 0, txBTCRef, merkleBlock, claim_scripts, txData, txOutProofData, wallet->chain().getTip()); // Manually construct peg-in transaction, sign it, and send it off. // Decrement the output value as much as needed given the total vsize to @@ -6128,7 +6127,7 @@ static RPCHelpMan claimpegin() LOCK(pwallet->cs_wallet); - if (::ChainstateActive().IsInitialBlockDownload()) { + if (pwallet->chain().isInitialBlockDownload()) { throw JSONRPCError(RPC_WALLET_ERROR, "Peg-ins cannot be completed during initial sync or reindexing."); } @@ -6359,7 +6358,7 @@ static RPCHelpMan blindrawtransaction() LOCK(pwallet->cs_wallet); - const auto& fedpegscripts = GetValidFedpegScripts(::ChainActive().Tip(), Params().GetConsensus(), true /* nextblock_validation */); + const auto& fedpegscripts = GetValidFedpegScripts(pwallet->chain().getTip(), Params().GetConsensus(), true /* nextblock_validation */); std::vector input_blinds; std::vector input_asset_blinds; @@ -6948,7 +6947,7 @@ static RPCHelpMan generatepegoutproof() if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &onlinepubkey_secp, &onlinepubkeybytes[0], onlinepubkeybytes.size())) throw JSONRPCError(RPC_WALLET_ERROR, "Invalid online pubkey"); - CPAKList paklist = GetActivePAKList(::ChainActive().Tip(), Params().GetConsensus()); + CPAKList paklist = GetActivePAKList(pwallet->chain().getTip(), Params().GetConsensus()); if (paklist.IsReject()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pegout freeze is under effect to aid a pak transition to a new list. Please consult the network operator."); } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 881ade66ee..cfac571616 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -87,17 +87,17 @@ static void AddKey(CWallet& wallet, const CKey& key) BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) { // Cap last block file size, and mine new block in a new block file. - CBlockIndex* oldTip = ::ChainActive().Tip(); + CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip(); GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); - CBlockIndex* newTip = ::ChainActive().Tip(); + CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip(); // Verify ScanForWalletTransactions fails to read an unknown start block. { CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); { LOCK(wallet.cs_wallet); - wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } AddKey(wallet, coinbaseKey); WalletRescanReserver reserver(wallet); @@ -116,7 +116,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); { LOCK(wallet.cs_wallet); - wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } AddKey(wallet, coinbaseKey); WalletRescanReserver reserver(wallet); @@ -142,7 +142,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); { LOCK(wallet.cs_wallet); - wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } AddKey(wallet, coinbaseKey); WalletRescanReserver reserver(wallet); @@ -167,7 +167,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) CWallet wallet(m_node.chain.get(), "", CreateDummyWalletDatabase()); { LOCK(wallet.cs_wallet); - wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } AddKey(wallet, coinbaseKey); WalletRescanReserver reserver(wallet); @@ -184,10 +184,10 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) { // Cap last block file size, and mine new block in a new block file. - CBlockIndex* oldTip = ::ChainActive().Tip(); + CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip(); GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); - CBlockIndex* newTip = ::ChainActive().Tip(); + CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip(); // Prune the older block file. { @@ -246,7 +246,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) { // Create two blocks with same timestamp to verify that importwallet rescan // will pick up both blocks, not just the first. - const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5; + const int64_t BLOCK_TIME = m_node.chainman->ActiveChain().Tip()->GetBlockTimeMax() + 5; SetMockTime(BLOCK_TIME); m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]); @@ -269,7 +269,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); AddWallet(wallet); - wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } JSONRPCRequest request; request.params.setArray(); @@ -290,7 +290,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) request.params.setArray(); request.params.push_back(backup_file); AddWallet(wallet); - wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); ::importwallet().HandleRequest(request); RemoveWallet(wallet, std::nullopt); @@ -317,9 +317,9 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) CWalletTx wtx(&wallet, m_coinbase_txns.back()); LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore); - wallet.SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); - CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 0); + CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 0); wtx.m_confirm = confirm; // Call GetImmatureCredit() once before adding the key to the wallet to @@ -487,16 +487,16 @@ public: wallet = std::make_unique(m_node.chain.get(), "", CreateMockWalletDatabase()); { LOCK2(wallet->cs_wallet, ::cs_main); - wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash()); + wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash()); } wallet->LoadWallet(); AddKey(*wallet, coinbaseKey); WalletRescanReserver reserver(*wallet); reserver.reserve(); - CWallet::ScanResult result = wallet->ScanForWalletTransactions(::ChainActive().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */); + CWallet::ScanResult result = wallet->ScanForWalletTransactions(m_node.chainman->ActiveChain().Genesis()->GetBlockHash(), 0 /* start_height */, {} /* max_height */, reserver, false /* update */); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); - BOOST_CHECK_EQUAL(result.last_scanned_block, ::ChainActive().Tip()->GetBlockHash()); - BOOST_CHECK_EQUAL(*result.last_scanned_height, ::ChainActive().Height()); + BOOST_CHECK_EQUAL(result.last_scanned_block, m_node.chainman->ActiveChain().Tip()->GetBlockHash()); + BOOST_CHECK_EQUAL(*result.last_scanned_height, m_node.chainman->ActiveChain().Height()); BOOST_CHECK(result.last_failed_block.IsNull()); } @@ -525,10 +525,10 @@ public: CreateAndProcessBlock({CMutableTransaction(blocktx)}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); LOCK(wallet->cs_wallet); - wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, ::ChainActive().Tip()->GetBlockHash()); + wallet->SetLastBlockProcessed(wallet->GetLastBlockHeight() + 1, m_node.chainman->ActiveChain().Tip()->GetBlockHash()); auto it = wallet->mapWallet.find(tx->GetHash()); BOOST_CHECK(it != wallet->mapWallet.end()); - CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, ::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash(), 1); + CWalletTx::Confirmation confirm(CWalletTx::Status::CONFIRMED, m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash(), 1); it->second.m_confirm = confirm; return it->second; }