diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -263,7 +263,7 @@ } bool getUnspentOutput(const COutPoint &output, Coin &coin) override { LOCK(::cs_main); - return ::pcoinsTip->GetCoin(output, coin); + return ::ChainstateActive().CoinsTip().GetCoin(output, coin); } std::string getWalletDir() override { return GetWalletDir().string(); } std::vector listWalletDir() override { diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1577,6 +1577,8 @@ return true; } } + const CCoinsViewCache &coins_cache = + ::ChainstateActive().CoinsTip(); // Use pcoinsTip->HaveCoinInCache as a quick approximation to // exclude requesting or processing some txs which have already been @@ -1586,8 +1588,8 @@ const TxId txid(inv.hash); return recentRejects->contains(inv.hash) || g_mempool.exists(txid) || - pcoinsTip->HaveCoinInCache(COutPoint(txid, 0)) || - pcoinsTip->HaveCoinInCache(COutPoint(txid, 1)); + coins_cache.HaveCoinInCache(COutPoint(txid, 0)) || + coins_cache.HaveCoinInCache(COutPoint(txid, 1)); } case MSG_BLOCK: return LookupBlockIndex(BlockHash(inv.hash)) != nullptr; @@ -2239,7 +2241,7 @@ EraseOrphanTx(orphanTxId); done = true; } - g_mempool.check(pcoinsTip.get()); + g_mempool.check(&::ChainstateActive().CoinsTip()); } } @@ -3004,7 +3006,7 @@ AcceptToMemoryPool(config, g_mempool, state, ptx, false /* bypass_limits */, Amount::zero() /* nAbsurdFee */)) { - g_mempool.check(pcoinsTip.get()); + g_mempool.check(&::ChainstateActive().CoinsTip()); RelayTransaction(tx.GetId(), *connman); for (size_t i = 0; i < tx.vout.size(); i++) { auto it_by_prev = diff --git a/src/node/coin.cpp b/src/node/coin.cpp --- a/src/node/coin.cpp +++ b/src/node/coin.cpp @@ -9,8 +9,7 @@ void FindCoins(std::map &coins) { LOCK2(cs_main, ::g_mempool.cs); - assert(pcoinsTip); - CCoinsViewCache &chain_view = *::pcoinsTip; + CCoinsViewCache &chain_view = ::ChainstateActive().CoinsTip(); CCoinsViewMemPool mempool_view(&chain_view, ::g_mempool); for (auto &coin : coins) { if (!mempool_view.GetCoin(coin.first, coin.second)) { diff --git a/src/node/transaction.cpp b/src/node/transaction.cpp --- a/src/node/transaction.cpp +++ b/src/node/transaction.cpp @@ -36,7 +36,7 @@ LOCK(cs_main); // If the transaction is already confirmed in the chain, don't do // anything and return early. - CCoinsViewCache &view = *pcoinsTip; + CCoinsViewCache &view = ::ChainstateActive().CoinsTip(); for (size_t o = 0; o < tx->vout.size(); o++) { const Coin &existingCoin = view.AccessCoin(COutPoint(txid, o)); // IsSpent doesnt mean the coin is spent, it means the output diff --git a/src/rest.cpp b/src/rest.cpp --- a/src/rest.cpp +++ b/src/rest.cpp @@ -573,13 +573,13 @@ // use db+mempool as cache backend in case user likes to query // mempool LOCK2(cs_main, g_mempool.cs); - CCoinsViewCache &viewChain = *pcoinsTip; + CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, g_mempool); process_utxos(viewMempool, g_mempool); } else { // no need to lock mempool! LOCK(cs_main); - process_utxos(*pcoinsTip, CTxMemPool()); + process_utxos(::ChainstateActive().CoinsTip(), CTxMemPool()); } for (size_t i = 0; i < hits.size(); ++i) { diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1208,19 +1208,21 @@ } Coin coin; + CCoinsViewCache *coins_view = &::ChainstateActive().CoinsTip(); + if (fMempool) { LOCK(g_mempool.cs); - CCoinsViewMemPool view(pcoinsTip.get(), g_mempool); + CCoinsViewMemPool view(coins_view, g_mempool); if (!view.GetCoin(out, coin) || g_mempool.isSpent(out)) { return NullUniValue; } } else { - if (!pcoinsTip->GetCoin(out, coin)) { + if (!coins_view->GetCoin(out, coin)) { return NullUniValue; } } - const CBlockIndex *pindex = LookupBlockIndex(pcoinsTip->GetBestBlock()); + const CBlockIndex *pindex = LookupBlockIndex(coins_view->GetBestBlock()); ret.pushKV("bestblock", pindex->GetBlockHash().GetHex()); if (coin.GetHeight() == MEMPOOL_HEIGHT) { ret.pushKV("confirmations", 0); @@ -1267,8 +1269,8 @@ nCheckDepth = request.params[1].get_int(); } - return CVerifyDB().VerifyDB(config, pcoinsTip.get(), nCheckLevel, - nCheckDepth); + return CVerifyDB().VerifyDB(config, &::ChainstateActive().CoinsTip(), + nCheckLevel, nCheckDepth); } static void BIP9SoftForkDescPushBack(UniValue &softforks, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -317,7 +317,8 @@ // Loop through txids and try to find which block they're in. Exit loop // once a block is found. for (const auto &txid : setTxIds) { - const Coin &coin = AccessByTxid(*pcoinsTip, txid); + const Coin &coin = + AccessByTxid(::ChainstateActive().CoinsTip(), txid); if (!coin.IsSpent()) { pblockindex = ::ChainActive()[coin.GetHeight()]; break; @@ -709,7 +710,7 @@ { LOCK(cs_main); LOCK(g_mempool.cs); - CCoinsViewCache &viewChain = *pcoinsTip; + CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, g_mempool); // temporarily switch cache backend to db+mempool view view.SetBackend(viewMempool); @@ -1724,7 +1725,7 @@ CCoinsViewCache view(&viewDummy); { LOCK2(cs_main, g_mempool.cs); - CCoinsViewCache &viewChain = *pcoinsTip; + CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip(); CCoinsViewMemPool viewMempool(&viewChain, g_mempool); // temporarily switch cache backend to db+mempool view view.SetBackend(viewMempool); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -438,7 +438,7 @@ CBlockIndex *prev = ::ChainActive().Tip(); CBlockIndex *next = new CBlockIndex(); next->phashBlock = new BlockHash(InsecureRand256()); - pcoinsTip->SetBestBlock(next->GetBlockHash()); + ::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash()); next->pprev = prev; next->nHeight = prev->nHeight + 1; next->BuildSkip(); @@ -451,7 +451,7 @@ CBlockIndex *prev = ::ChainActive().Tip(); CBlockIndex *next = new CBlockIndex(); next->phashBlock = new BlockHash(InsecureRand256()); - pcoinsTip->SetBestBlock(next->GetBlockHash()); + ::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash()); next->pprev = prev; next->nHeight = prev->nHeight + 1; next->BuildSkip(); @@ -487,7 +487,8 @@ while (::ChainActive().Tip()->nHeight > nHeight) { CBlockIndex *del = ::ChainActive().Tip(); ::ChainActive().SetTip(del->pprev); - pcoinsTip->SetBestBlock(del->pprev->GetBlockHash()); + ::ChainstateActive().CoinsTip().SetBestBlock( + del->pprev->GetBlockHash()); delete del->phashBlock; delete del; } diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -117,7 +117,7 @@ pBlockLimitSigChecks, pvChecks); } -// Run CheckInputs (using pcoinsTip) on the given transaction, for all script +// Run CheckInputs (using CoinTip()) on the given transaction, for all script // flags. Test that CheckInputs passes for all flags that don't overlap with the // failing_flags argument, but otherwise fails. // CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may @@ -148,8 +148,9 @@ } int nSigChecksDirect = 0xf00d; - bool ret = CheckInputs(tx, state, pcoinsTip.get(), test_flags, true, - add_to_cache, txdata, nSigChecksDirect); + bool ret = + CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, + true, add_to_cache, txdata, nSigChecksDirect); // CheckInputs should succeed iff test_flags doesn't intersect with // failing_flags @@ -165,8 +166,8 @@ // Check that we get a cache hit if the tx was valid std::vector scriptchecks; int nSigChecksCached = 0xbeef; - BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), test_flags, - true, add_to_cache, txdata, + BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), + test_flags, true, add_to_cache, txdata, nSigChecksCached, &scriptchecks)); BOOST_CHECK(nSigChecksCached == nSigChecksDirect); BOOST_CHECK(scriptchecks.empty()); @@ -175,10 +176,11 @@ // was invalid, or we didn't add to cache. std::vector scriptchecks; int nSigChecksUncached = 0xbabe; - BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), test_flags, - true, add_to_cache, txdata, + BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), + test_flags, true, add_to_cache, txdata, nSigChecksUncached, &scriptchecks)); BOOST_CHECK(!ret || nSigChecksUncached == 0); + BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); } } @@ -231,7 +233,8 @@ { CBlock block = CreateAndProcessBlock({funding_tx}, p2pk_scriptPubKey); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); - BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); + BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == + block.GetHash()); } // flags to test: SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, @@ -276,7 +279,7 @@ PrecomputedTransactionData ptd_spend_tx(tx); int nSigChecksDummy; - BOOST_CHECK(!CheckInputs(tx, state, pcoinsTip.get(), + BOOST_CHECK(!CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), STANDARD_SCRIPT_VERIFY_FLAGS, true, true, ptd_spend_tx, nSigChecksDummy, nullptr)); @@ -284,7 +287,7 @@ // 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(CheckInputs(tx, state, pcoinsTip.get(), + BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), STANDARD_SCRIPT_VERIFY_FLAGS, true, true, ptd_spend_tx, nSigChecksDummy, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); @@ -304,7 +307,8 @@ block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey); LOCK(cs_main); BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash()); - BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash()); + BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == + block.GetHash()); // Test P2SH: construct a transaction that is valid without P2SH, and then // test validity with P2SH. @@ -358,7 +362,8 @@ PrecomputedTransactionData txdata(transaction); int nSigChecksRet; - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), + BOOST_CHECK(CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), STANDARD_SCRIPT_VERIFY_FLAGS, true, true, txdata, nSigChecksRet, nullptr)); BOOST_CHECK(nSigChecksRet == 1); @@ -397,7 +402,8 @@ PrecomputedTransactionData txdata(transaction); int nSigChecksRet; - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), + BOOST_CHECK(CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), STANDARD_SCRIPT_VERIFY_FLAGS, true, true, txdata, nSigChecksRet, nullptr)); BOOST_CHECK(nSigChecksRet == 1); @@ -460,7 +466,8 @@ */ std::vector scriptchecks1; CheckInputsLimiter sigchecklimiter1(1); - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), flags, + BOOST_CHECK(CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), flags, true, true, txdata, nSigChecksDummy, &scriptchecks1, &sigchecklimiter1)); // the first check passes but it did consume the limit. @@ -475,8 +482,9 @@ // Serial validation fails with the limiter. CheckInputsLimiter sigchecklimiter2(1); TxValidationState state2; - BOOST_CHECK(!CheckInputs(transaction, state2, pcoinsTip.get(), - flags, true, true, txdata, nSigChecksDummy, + BOOST_CHECK(!CheckInputs(transaction, state2, + &::ChainstateActive().CoinsTip(), flags, + true, true, txdata, nSigChecksDummy, nullptr, &sigchecklimiter2)); BOOST_CHECK(!sigchecklimiter2.check()); BOOST_CHECK_EQUAL(state2.GetRejectReason(), @@ -490,7 +498,8 @@ std::vector scriptchecks3; CheckInputsLimiter sigchecklimiter3(2); // first in parallel - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), flags, + BOOST_CHECK(CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), flags, true, true, txdata, nSigChecksDummy, &scriptchecks3, &sigchecklimiter3)); BOOST_CHECK(scriptchecks3[1]()); @@ -498,14 +507,16 @@ BOOST_CHECK(sigchecklimiter3.check()); // then in serial, caching the result. CheckInputsLimiter sigchecklimiter4(2); - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), flags, + BOOST_CHECK(CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), flags, true, true, txdata, nSigChecksDummy, nullptr, &sigchecklimiter4)); BOOST_CHECK(sigchecklimiter4.check()); // now in parallel again, grabbing the cached result. std::vector scriptchecks5; CheckInputsLimiter sigchecklimiter5(2); - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), flags, + BOOST_CHECK(CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), flags, true, true, txdata, nSigChecksDummy, &scriptchecks5, &sigchecklimiter5)); BOOST_CHECK(scriptchecks5.empty()); @@ -517,8 +528,9 @@ */ CheckInputsLimiter sigchecklimiter6(1); TxValidationState state6; - BOOST_CHECK(!CheckInputs(transaction, state6, pcoinsTip.get(), - flags, true, true, txdata, nSigChecksDummy, + BOOST_CHECK(!CheckInputs(transaction, state6, + &::ChainstateActive().CoinsTip(), flags, + true, true, txdata, nSigChecksDummy, nullptr, &sigchecklimiter6)); BOOST_CHECK_EQUAL(state6.GetRejectReason(), "too-many-sigchecks"); BOOST_CHECK_EQUAL(state6.GetResult(), @@ -528,8 +540,9 @@ std::vector scriptchecks7; CheckInputsLimiter sigchecklimiter7(1); TxValidationState state7; - BOOST_CHECK(!CheckInputs(transaction, state7, pcoinsTip.get(), - flags, true, true, txdata, nSigChecksDummy, + BOOST_CHECK(!CheckInputs(transaction, state7, + &::ChainstateActive().CoinsTip(), flags, + true, true, txdata, nSigChecksDummy, &scriptchecks7, &sigchecklimiter7)); BOOST_CHECK_EQUAL(state7.GetRejectReason(), "too-many-sigchecks"); BOOST_CHECK_EQUAL(state6.GetResult(), @@ -550,7 +563,8 @@ // This transaction is now invalid because the second signature is // missing. int nSigChecksDummy; - BOOST_CHECK(!CheckInputs(transaction, state, pcoinsTip.get(), + BOOST_CHECK(!CheckInputs(transaction, state, + &::ChainstateActive().CoinsTip(), STANDARD_SCRIPT_VERIFY_FLAGS, true, true, txdata, nSigChecksDummy, nullptr)); @@ -558,7 +572,7 @@ // was valid) std::vector scriptchecks; BOOST_CHECK( - CheckInputs(transaction, state, pcoinsTip.get(), + CheckInputs(transaction, state, &::ChainstateActive().CoinsTip(), STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_ENFORCE_SIGCHECKS, true, true, txdata, nSigChecksDummy, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction diff --git a/src/txmempool.h b/src/txmempool.h --- a/src/txmempool.h +++ b/src/txmempool.h @@ -522,11 +522,11 @@ * * 1. Locking both `cs_main` and `mempool.cs` will give a view of mempool * that is consistent with current chain tip (`::ChainActive()` and - * `pcoinsTip`) and is fully populated. Fully populated means that if the - * current active chain is missing transactions that were present in a - * previously active chain, all the missing transactions will have been - * re-added to the mempool and should be present if they meet size and - * consistency constraints. + * `CoinsTip()`) and is fully populated. Fully populated means that if + * the current active chain is missing transactions that were present + * in a previously active chain, all the missing transactions will have + * been re-added to the mempool and should be present if they meet size + * and consistency constraints. * * 2. Locking `mempool.cs` without `cs_main` will give a view of a mempool * consistent with some chain that was active since `cs_main` was last diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -767,6 +767,11 @@ EXCLUSIVE_LOCKS_REQUIRED(cs_main); }; +/** + * Global variable that points to the active CCoinsView (protected by cs_main) + */ +extern std::unique_ptr pcoinsTip; + /** * CChainState stores and provides an API to update our local knowledge of the * current best chain. @@ -834,6 +839,11 @@ */ std::set setBlockIndexCandidates; + /** + * @returns A reference to the in-memory cache of the UTXO set. + */ + CCoinsViewCache &CoinsTip() { return *::pcoinsTip; } + /** * Update the on-disk chain state. * The caches and indexes are flushed depending on the mode we're called @@ -1009,11 +1019,6 @@ */ extern std::unique_ptr pcoinsdbview; -/** - * Global variable that points to the active CCoinsView (protected by cs_main) - */ -extern std::unique_ptr pcoinsTip; - /** * Global variable that points to the active block tree (protected by cs_main) */ diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -220,8 +220,8 @@ lockPair.first = lp->height; lockPair.second = lp->time; } else { - // pcoinsTip contains the UTXO set for ::ChainActive().Tip() - CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool); + // CoinsTip() contains the UTXO set for ::ChainActive().Tip() + CCoinsViewMemPool viewMemPool(&::ChainstateActive().CoinsTip(), pool); std::vector prevheights; prevheights.resize(tx.vin.size()); for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { @@ -319,7 +319,8 @@ assert(txFrom->vout.size() > txin.prevout.GetN()); assert(txFrom->vout[txin.prevout.GetN()] == coin.GetTxOut()); } else { - const Coin &coinFromDisk = pcoinsTip->AccessCoin(txin.prevout); + const Coin &coinFromDisk = + ::ChainstateActive().CoinsTip().AccessCoin(txin.prevout); assert(!coinFromDisk.IsSpent()); assert(coinFromDisk.GetTxOut() == coin.GetTxOut()); } @@ -400,12 +401,13 @@ CCoinsViewCache view(&dummy); LockPoints lp; - CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool); + CCoinsViewCache &coins_cache = ::ChainstateActive().CoinsTip(); + CCoinsViewMemPool viewMemPool(&coins_cache, pool); view.SetBackend(viewMemPool); // Do all inputs exist? for (const CTxIn &txin : tx.vin) { - if (!pcoinsTip->HaveCoinInCache(txin.prevout)) { + if (!coins_cache.HaveCoinInCache(txin.prevout)) { coins_to_uncache.push_back(txin.prevout); } @@ -418,7 +420,7 @@ for (size_t out = 0; out < tx.vout.size(); out++) { // Optimistically just do efficient check of cache for // outputs. - if (pcoinsTip->HaveCoinInCache(COutPoint(txid, out))) { + if (coins_cache.HaveCoinInCache(COutPoint(txid, out))) { return state.Invalid(TxValidationResult::TX_CONFLICT, REJECT_DUPLICATE, "txn-already-known"); @@ -639,7 +641,7 @@ // (`CCoinsViewCache::cacheCoins`). for (const COutPoint &outpoint : coins_to_uncache) { - pcoinsTip->Uncache(outpoint); + ::ChainstateActive().CoinsTip().Uncache(outpoint); } } @@ -1932,7 +1934,7 @@ } int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; - int64_t cacheSize = pcoinsTip->DynamicMemoryUsage(); + int64_t cacheSize = CoinsTip().DynamicMemoryUsage(); int64_t nTotalSpace = nCoinCacheUsage + std::max(nMempoolSizeMax - nMempoolUsage, 0); @@ -2005,7 +2007,7 @@ } // Flush best chain related state. This can only be done if the // blocks / block index write was also done. - if (fDoFullFlush && !pcoinsTip->GetBestBlock().IsNull()) { + if (fDoFullFlush && !CoinsTip().GetBestBlock().IsNull()) { // Typical Coin structures on disk are around 48 bytes in size. // Pushing a new one to the database can cause it to be written // twice (once in the log, and once in the tables). This is @@ -2013,7 +2015,7 @@ // entry or overwrite one. Still, use a conservative safety // factor of 2. if (!CheckDiskSpace(GetDataDir(), - 48 * 2 * 2 * pcoinsTip->GetCacheSize())) { + 48 * 2 * 2 * CoinsTip().GetCacheSize())) { return AbortNode( state, "Disk space is too low!", _("Error: Disk space is too low!").translated, @@ -2022,7 +2024,7 @@ // Flush the chainstate (which may refer to block index // entries). - if (!pcoinsTip->Flush()) { + if (!CoinsTip().Flush()) { return AbortNode(state, "Failed to write to coin database"); } nLastFlush = nNow; @@ -2079,8 +2081,9 @@ pindexNew->GetChainTxCount(), FormatISO8601DateTime(pindexNew->GetBlockTime()), GuessVerificationProgress(params.TxData(), pindexNew), - pcoinsTip->DynamicMemoryUsage() * (1.0 / (1 << 20)), - pcoinsTip->GetCacheSize()); + ::ChainstateActive().CoinsTip().DynamicMemoryUsage() * + (1.0 / (1 << 20)), + ::ChainstateActive().CoinsTip().GetCacheSize()); } /** @@ -2113,7 +2116,7 @@ // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { - CCoinsViewCache view(pcoinsTip.get()); + CCoinsViewCache view(&CoinsTip()); assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); if (DisconnectBlock(block, pindexDelete, view) != DisconnectResult::OK) { @@ -2364,7 +2367,7 @@ LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO); { - CCoinsViewCache view(pcoinsTip.get()); + CCoinsViewCache view(&CoinsTip()); bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, params, BlockValidationOptions(config)); GetMainSignals().BlockChecked(blockConnecting, state); @@ -2731,7 +2734,7 @@ disconnectpool.updateMempoolForReorg(config, true, g_mempool); } - g_mempool.check(pcoinsTip.get()); + g_mempool.check(&CoinsTip()); // Callbacks/notifications for a new best chain. if (fInvalidFound) { @@ -4251,7 +4254,7 @@ BlockValidationOptions validationOptions) { AssertLockHeld(cs_main); assert(pindexPrev && pindexPrev == ::ChainActive().Tip()); - CCoinsViewCache viewNew(pcoinsTip.get()); + CCoinsViewCache viewNew(&::ChainstateActive().CoinsTip()); BlockHash block_hash(block.GetHash()); CBlockIndex indexDummy(block); indexDummy.pprev = pindexPrev; @@ -4670,16 +4673,17 @@ bool LoadChainTip(const Config &config) { AssertLockHeld(cs_main); + const CCoinsViewCache &coins_cache = ::ChainstateActive().CoinsTip(); // Never called when the coins view is empty - assert(!pcoinsTip->GetBestBlock().IsNull()); + assert(!coins_cache.GetBestBlock().IsNull()); if (::ChainActive().Tip() && - ::ChainActive().Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) { + ::ChainActive().Tip()->GetBlockHash() == coins_cache.GetBestBlock()) { return true; } // Load pointer to end of best chain - CBlockIndex *pindex = LookupBlockIndex(pcoinsTip->GetBestBlock()); + CBlockIndex *pindex = LookupBlockIndex(coins_cache.GetBestBlock()); if (!pindex) { return false; } @@ -4794,7 +4798,8 @@ // check level 3: check for inconsistencies during memory-only // disconnect of tip blocks if (nCheckLevel >= 3 && - (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= + (coins.DynamicMemoryUsage() + + ::ChainstateActive().CoinsTip().DynamicMemoryUsage()) <= nCoinCacheUsage) { assert(coins.GetBestBlock() == pindex->GetBlockHash()); DisconnectResult res = diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py --- a/test/functional/feature_dbcrash.py +++ b/test/functional/feature_dbcrash.py @@ -61,7 +61,7 @@ "-noparkdeepreorg"] # Set different crash ratios and cache sizes. Note that not all of - # -dbcache goes to pcoinsTip. + # -dbcache goes to the in-memory coins cache. self.node0_args = ["-dbcrashratio=8", "-dbcache=4"] + self.base_args self.node1_args = ["-dbcrashratio=16", "-dbcache=8"] + self.base_args self.node2_args = ["-dbcrashratio=24", "-dbcache=16"] + self.base_args