diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -155,7 +155,7 @@ // the caller. }; -static CCoinsViewErrorCatcher *pcoinscatcher = nullptr; +static std::unique_ptr pcoinscatcher; static std::unique_ptr globalVerifyHandle; void Interrupt(boost::thread_group &threadGroup) { @@ -244,14 +244,10 @@ if (pcoinsTip != nullptr) { FlushStateToDisk(); } - delete pcoinsTip; - pcoinsTip = nullptr; - delete pcoinscatcher; - pcoinscatcher = nullptr; - delete pcoinsdbview; - pcoinsdbview = nullptr; - delete pblocktree; - pblocktree = nullptr; + pcoinsTip.reset(); + pcoinscatcher.reset(); + pcoinsdbview.reset(); + pblocktree.reset(); } #ifdef ENABLE_WALLET for (CWalletRef pwallet : vpwallets) { @@ -2000,13 +1996,11 @@ do { try { UnloadBlockIndex(); - delete pcoinsTip; - delete pcoinsdbview; - delete pcoinscatcher; - delete pblocktree; - - pblocktree = - new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); + pcoinsTip.reset(); + pcoinsdbview.reset(); + pcoinscatcher.reset(); + pblocktree.reset( + new CBlockTreeDB(nBlockTreeDBCache, false, fReset)); if (fReindex) { pblocktree->WriteReindexing(true); @@ -2069,9 +2063,10 @@ // At this point we're either in reindex or we've loaded a // useful block tree into mapBlockIndex! - pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, - fReindex || fReindexChainState); - pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); + pcoinsdbview.reset(new CCoinsViewDB( + nCoinDBCache, false, fReset || fReindexChainState)); + pcoinscatcher.reset( + new CCoinsViewErrorCatcher(pcoinsdbview.get())); // If necessary, upgrade from older database format. // This is a no-op if we cleared the coinsviewdb with -reindex @@ -2083,7 +2078,7 @@ // ReplayBlocks is a no-op if we cleared the coinsviewdb with // -reindex or -reindex-chainstate - if (!ReplayBlocks(config, pcoinsdbview)) { + if (!ReplayBlocks(config, pcoinsdbview.get())) { strLoadError = _("Unable to replay blocks. You will need to rebuild " "the database using -reindex-chainstate."); @@ -2091,7 +2086,7 @@ } // The on-disk coinsdb is now in a good state, create the cache - pcoinsTip = new CCoinsViewCache(pcoinscatcher); + pcoinsTip.reset(new CCoinsViewCache(pcoinscatcher.get())); if (!fReindex && !fReindexChainState) { // LoadChainTip sets chainActive based on pcoinsTip's best @@ -2146,7 +2141,7 @@ } if (!CVerifyDB().VerifyDB( - config, pcoinsdbview, + config, pcoinsdbview.get(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL), gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2393,7 +2393,7 @@ if (!AlreadyHave(inv) && AcceptToMemoryPool(config, mempool, state, ptx, true, &fMissingInputs)) { - mempool.check(pcoinsTip); + mempool.check(pcoinsTip.get()); RelayTransaction(tx, connman); for (size_t i = 0; i < tx.vout.size(); i++) { vWorkQueue.emplace_back(inv.hash, i); @@ -2466,7 +2466,7 @@ recentRejects->insert(orphanId); } } - mempool.check(pcoinsTip); + mempool.check(pcoinsTip.get()); } } diff --git a/src/qt/test/rpcnestedtests.h b/src/qt/test/rpcnestedtests.h --- a/src/qt/test/rpcnestedtests.h +++ b/src/qt/test/rpcnestedtests.h @@ -16,9 +16,6 @@ private Q_SLOTS: void rpcNestedTests(); - -private: - CCoinsViewDB *pcoinsdbview; }; #endif // BITCOIN_QT_TEST_RPC_NESTED_TESTS_H diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1015,7 +1015,7 @@ CCoinsStats stats; FlushStateToDisk(); - if (GetUTXOStats(pcoinsdbview, stats)) { + if (GetUTXOStats(pcoinsdbview.get(), stats)) { ret.push_back(Pair("height", int64_t(stats.nHeight))); ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); ret.push_back(Pair("transactions", int64_t(stats.nTransactions))); @@ -1092,7 +1092,7 @@ Coin coin; if (fMempool) { LOCK(mempool.cs); - CCoinsViewMemPool view(pcoinsTip, mempool); + CCoinsViewMemPool view(pcoinsTip.get(), mempool); if (!view.GetCoin(out, coin) || mempool.isSpent(out)) { // TODO: this should be done by the CCoinsViewMemPool return NullUniValue; @@ -1151,7 +1151,8 @@ nCheckDepth = request.params[1].get_int(); } - return CVerifyDB().VerifyDB(config, pcoinsTip, nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB(config, pcoinsTip.get(), nCheckLevel, + nCheckDepth); } /** Implementation of IsSuperMajority with better feedback */ diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -70,7 +70,6 @@ class PeerLogicValidation; struct TestingSetup : public BasicTestingSetup { - CCoinsViewDB *pcoinsdbview; fs::path pathTemp; boost::thread_group threadGroup; CConnman *connman; diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -98,9 +98,9 @@ GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); mempool.setSanityCheck(1.0); - pblocktree = new CBlockTreeDB(1 << 20, true); - pcoinsdbview = new CCoinsViewDB(1 << 23, true); - pcoinsTip = new CCoinsViewCache(pcoinsdbview); + pblocktree.reset(new CBlockTreeDB(1 << 20, true)); + pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true)); + pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get())); if (!LoadGenesisBlock(chainparams)) { throw std::runtime_error("InitBlockIndex failed."); } @@ -129,9 +129,9 @@ g_connman.reset(); peerLogic.reset(); UnloadBlockIndex(); - delete pcoinsTip; - delete pcoinsdbview; - delete pblocktree; + pcoinsTip.reset(); + pcoinsdbview.reset(); + pblocktree.reset(); fs::remove_all(pathTemp); } 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 @@ -112,8 +112,8 @@ // Make sure the mandatory flags are enabled. test_flags |= MANDATORY_SCRIPT_VERIFY_FLAGS; - bool ret = CheckInputs(tx, state, pcoinsTip, true, test_flags, true, - add_to_cache, txdata, nullptr); + bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, + true, add_to_cache, txdata, nullptr); // CheckInputs should succeed iff test_flags doesn't intersect with // failing_flags @@ -132,15 +132,17 @@ if (ret && add_to_cache) { // Check that we get a cache hit if the tx was valid std::vector scriptchecks; - BOOST_CHECK(CheckInputs(tx, state, pcoinsTip, true, test_flags, - true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, + test_flags, true, add_to_cache, txdata, + &scriptchecks)); BOOST_CHECK(scriptchecks.empty()); } 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(CheckInputs(tx, state, pcoinsTip, true, test_flags, - true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, + test_flags, true, add_to_cache, txdata, + &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); } } @@ -209,7 +211,7 @@ CValidationState state; PrecomputedTransactionData ptd_spend_tx(spend_tx); - BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip, true, + BOOST_CHECK(!CheckInputs(spend_tx, state, pcoinsTip.get(), true, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_CLEANSTACK, true, true, ptd_spend_tx, nullptr)); @@ -218,7 +220,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(spend_tx, state, pcoinsTip, true, + BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_CLEANSTACK, true, true, ptd_spend_tx, &scriptchecks)); @@ -290,7 +292,7 @@ CTransaction transaction(invalid_with_cltv_tx); PrecomputedTransactionData txdata(transaction); - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip, true, + BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), true, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); @@ -326,7 +328,7 @@ CTransaction transaction(invalid_with_csv_tx); PrecomputedTransactionData txdata(transaction); - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip, true, + BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), true, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); @@ -373,14 +375,14 @@ // This transaction is now invalid because the second signature is // missing. - BOOST_CHECK(!CheckInputs(transaction, state, pcoinsTip, true, + BOOST_CHECK(!CheckInputs(transaction, state, pcoinsTip.get(), true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, true, txdata, nullptr)); // Make sure this transaction was not cached (ie becausethe first input // was valid) std::vector scriptchecks; - BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip, true, + BOOST_CHECK(CheckInputs(transaction, state, pcoinsTip.get(), true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, true, txdata, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction diff --git a/src/txmempool.cpp b/src/txmempool.cpp --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1371,7 +1371,8 @@ mempool.UpdateTransactionsFromBlock(txidsUpdate); // We also need to remove any now-immature transactions - mempool.removeForReorg(config, pcoinsTip, chainActive.Tip()->nHeight + 1, + mempool.removeForReorg(config, pcoinsTip.get(), + chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); // Re-limit mempool size, in case we added any transactions diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -638,17 +638,17 @@ /** * Global variable that points to the coins database (protected by cs_main) */ -extern CCoinsViewDB *pcoinsdbview; +extern std::unique_ptr pcoinsdbview; /** * Global variable that points to the active CCoinsView (protected by cs_main) */ -extern CCoinsViewCache *pcoinsTip; +extern std::unique_ptr pcoinsTip; /** * Global variable that points to the active block tree (protected by cs_main) */ -extern CBlockTreeDB *pblocktree; +extern std::unique_ptr pblocktree; /** * Return the spend height, which is one more than the inputs.GetBestBlock(). diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -159,9 +159,9 @@ return chain.Genesis(); } -CCoinsViewDB *pcoinsdbview = nullptr; -CCoinsViewCache *pcoinsTip = nullptr; -CBlockTreeDB *pblocktree = nullptr; +std::unique_ptr pcoinsdbview; +std::unique_ptr pcoinsTip; +std::unique_ptr pblocktree; enum FlushStateMode { FLUSH_STATE_NONE, @@ -223,7 +223,7 @@ lockPair.second = lp->time; } else { // pcoinsTip contains the UTXO set for chainActive.Tip() - CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); + CCoinsViewMemPool viewMemPool(pcoinsTip.get(), mempool); std::vector prevheights; prevheights.resize(tx.vin.size()); for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { @@ -433,7 +433,7 @@ Amount nValueIn = Amount::zero(); LockPoints lp; - CCoinsViewMemPool viewMemPool(pcoinsTip, pool); + CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool); view.SetBackend(viewMemPool); // Do all inputs exist? @@ -2147,7 +2147,7 @@ // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); { - CCoinsViewCache view(pcoinsTip); + CCoinsViewCache view(pcoinsTip.get()); assert(view.GetBestBlock() == pindexDelete->GetBlockHash()); if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK) { return error("DisconnectTip(): DisconnectBlock %s failed", @@ -2316,7 +2316,7 @@ LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); { - CCoinsViewCache view(pcoinsTip); + CCoinsViewCache view(pcoinsTip.get()); bool rv = ConnectBlock(config, blockConnecting, state, pindexNew, view); GetMainSignals().BlockChecked(blockConnecting, state); if (!rv) { @@ -2552,7 +2552,7 @@ disconnectpool.updateMempoolForReorg(config, true); } - mempool.check(pcoinsTip); + mempool.check(pcoinsTip.get()); // Callbacks/notifications for a new best chain. if (fInvalidFound) { @@ -3644,7 +3644,7 @@ state.GetRejectReason().c_str()); } - CCoinsViewCache viewNew(pcoinsTip); + CCoinsViewCache viewNew(pcoinsTip.get()); CBlockIndex indexDummy(block); indexDummy.pprev = pindexPrev; indexDummy.nHeight = pindexPrev->nHeight + 1;