diff --git a/src/init.cpp b/src/init.cpp index 9f8873b4c26a0..ab1fe7efac6a6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -183,8 +183,7 @@ class CCoinsViewErrorCatcher : public CCoinsViewBacked // Writes do not need similar protection, as failure to write is handled by the caller. }; -static CCoinsViewDB* pcoinsdbview = NULL; -static CCoinsViewErrorCatcher* pcoinscatcher = NULL; +static std::unique_ptr pcoinscatcher; static std::unique_ptr globalVerifyHandle; static boost::thread_group threadGroup; @@ -287,18 +286,12 @@ void PrepareShutdown() //record that client took the proper shutdown procedure pblocktree->WriteFlag("shutdown", true); } - delete pcoinsTip; - pcoinsTip = NULL; - delete pcoinscatcher; - pcoinscatcher = NULL; - delete pcoinsdbview; - pcoinsdbview = NULL; - delete pblocktree; - pblocktree = NULL; - delete zerocoinDB; - zerocoinDB = NULL; - delete pSporkDB; - pSporkDB = NULL; + pcoinsTip.reset(); + pcoinscatcher.reset(); + pcoinsdbview.reset(); + pblocktree.reset(); + zerocoinDB.reset(); + pSporkDB.reset(); deterministicMNManager.reset(); evoDb.reset(); } @@ -1532,24 +1525,20 @@ bool AppInitMain() try { UnloadBlockIndex(); - delete pcoinsTip; - delete pcoinsdbview; - delete pcoinscatcher; - delete pblocktree; - delete zerocoinDB; - delete pSporkDB; + pcoinsTip.reset(); + pcoinsdbview.reset(); + pcoinscatcher.reset(); + pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset)); //PIVX specific: zerocoin and spork DB's - zerocoinDB = new CZerocoinDB(0, false, fReindex); - pSporkDB = new CSporkDB(0, false, false); + zerocoinDB.reset(new CZerocoinDB(0, false, fReindex)); + pSporkDB.reset(new CSporkDB(0, false, false)); deterministicMNManager.reset(); evoDb.reset(); evoDb.reset(new CEvoDB(nEvoDbCache, false, fReindex)); deterministicMNManager.reset(new CDeterministicMNManager(*evoDb)); - pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReset); - if (fReset) { pblocktree->WriteReindexing(true); } @@ -1597,8 +1586,8 @@ bool AppInitMain() // At this point we're either in reindex or we've loaded a useful // block tree into mapBlockIndex! - pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReset || 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 or -reindex-chainstate @@ -1610,13 +1599,13 @@ bool AppInitMain() } // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate - if (!ReplayBlocks(chainparams, pcoinsdbview)) { + if (!ReplayBlocks(chainparams, pcoinsdbview.get())) { strLoadError = strprintf(_("Unable to replay blocks. You will need to rebuild the database using %s."), "-reindex"); break; } // The on-disk coinsdb is now in a good state, create the cache - pcoinsTip = new CCoinsViewCache(pcoinscatcher); + pcoinsTip.reset(new CCoinsViewCache(pcoinscatcher.get())); bool is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull(); if (!is_coinsview_empty) { @@ -1666,7 +1655,7 @@ bool AppInitMain() } } - if (!CVerifyDB().VerifyDB(pcoinsdbview, gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL), + if (!CVerifyDB().VerifyDB(pcoinsdbview.get(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL), gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { strLoadError = _("Corrupted block database detected"); break; diff --git a/src/legacy/validation_zerocoin_legacy.cpp b/src/legacy/validation_zerocoin_legacy.cpp index 6bd16a1d1bb99..4038704229709 100644 --- a/src/legacy/validation_zerocoin_legacy.cpp +++ b/src/legacy/validation_zerocoin_legacy.cpp @@ -8,7 +8,7 @@ #include "zpivchain.h" #include "zpiv/zpivmodule.h" -bool DisconnectZerocoinTx(const CTransaction& tx, CZerocoinDB* zerocoinDB) +bool DisconnectZerocoinTx(const CTransaction& tx) { /** UNDO ZEROCOIN DATABASING * note we only undo zerocoin databasing in the following statement, value to and from PIVX diff --git a/src/legacy/validation_zerocoin_legacy.h b/src/legacy/validation_zerocoin_legacy.h index cae38d80a8e2e..6b5a91d1e1bcb 100644 --- a/src/legacy/validation_zerocoin_legacy.h +++ b/src/legacy/validation_zerocoin_legacy.h @@ -10,7 +10,7 @@ #include "txdb.h" // for the zerocoinDB implementation. #include "validationinterface.h" -bool DisconnectZerocoinTx(const CTransaction& tx, CZerocoinDB* zerocoinDB); +bool DisconnectZerocoinTx(const CTransaction& tx); void DataBaseAccChecksum(const CBlockIndex* pindex, bool fWrite); #endif //VALIDATION_ZEROCOIN_LEGACY_H diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 4650a82246a30..dc64f061fa77a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1490,7 +1490,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR } if (AcceptToMemoryPool(mempool, state, ptx, true, &fMissingInputs, false, ignoreFees)) { - mempool.check(pcoinsTip); + mempool.check(pcoinsTip.get()); RelayTransaction(tx, connman); for (unsigned int i = 0; i < tx.vout.size(); i++) { vWorkQueue.emplace_back(inv.hash, i); @@ -1544,7 +1544,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR assert(recentRejects); recentRejects->insert(orphanHash); } - mempool.check(pcoinsTip); + mempool.check(pcoinsTip.get()); } } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 67e62f8b16ac4..f30eb697b049d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -788,7 +788,7 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request) CCoinsStats stats; FlushStateToDisk(); - if (GetUTXOStats(pcoinsTip, stats)) { + if (GetUTXOStats(pcoinsTip.get(), stats)) { ret.pushKV("height", (int64_t)stats.nHeight); ret.pushKV("bestblock", stats.hashBlock.GetHex()); ret.pushKV("transactions", (int64_t)stats.nTransactions); @@ -853,7 +853,7 @@ UniValue gettxout(const JSONRPCRequest& request) 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: filtering spent coins should be done by the CCoinsViewMemPool return NullUniValue; } @@ -904,7 +904,7 @@ UniValue verifychain(const JSONRPCRequest& request) if (request.params.size() > 0) nCheckDepth = request.params[0].get_int(); - return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB(pcoinsTip.get(), nCheckLevel, nCheckDepth); } /** Implementation of IsSuperMajority with better feedback */ diff --git a/src/test/test_pivx.cpp b/src/test/test_pivx.cpp index 351c045565e66..07a5b7502c711 100644 --- a/src/test/test_pivx.cpp +++ b/src/test/test_pivx.cpp @@ -91,11 +91,11 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha // Ideally we'd move all the RPC tests to the functional testing framework // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); - zerocoinDB = new CZerocoinDB(0, true); - pSporkDB = new CSporkDB(0, true); - pblocktree = new CBlockTreeDB(1 << 20, true); - pcoinsdbview = new CCoinsViewDB(1 << 23, true); - pcoinsTip = new CCoinsViewCache(pcoinsdbview); + zerocoinDB.reset(new CZerocoinDB(0, true)); + pSporkDB.reset(new CSporkDB(0, true)); + pblocktree.reset(new CBlockTreeDB(1 << 20, true)); + pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true)); + pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get())); if (!LoadGenesisBlock()) { throw std::runtime_error("Error initializing block database"); } @@ -121,11 +121,11 @@ TestingSetup::~TestingSetup() peerLogic.reset(); UnloadBlockIndex(); delete pEvoNotificationInterface; - delete pcoinsTip; - delete pcoinsdbview; - delete pblocktree; - delete zerocoinDB; - delete pSporkDB; + pcoinsTip.reset(); + pcoinsdbview.reset(); + pblocktree.reset(); + zerocoinDB.reset(); + pSporkDB.reset(); } // Test chain only available on regtest diff --git a/src/test/test_pivx.h b/src/test/test_pivx.h index 1670a71e8e87c..e2cbb56a543ff 100644 --- a/src/test/test_pivx.h +++ b/src/test/test_pivx.h @@ -55,7 +55,6 @@ class PeerLogicValidation; class EvoNotificationInterface; struct TestingSetup: public BasicTestingSetup { - CCoinsViewDB *pcoinsdbview; boost::thread_group threadGroup; CConnman* connman; EvoNotificationInterface* pEvoNotificationInterface; diff --git a/src/validation.cpp b/src/validation.cpp index 5d65d7c9b0b65..d3e236656ed23 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -205,10 +205,11 @@ CBlockIndex* GetChainTip() return mapBlockIndex.at(p->GetBlockHash()); } -CCoinsViewCache* pcoinsTip = NULL; -CBlockTreeDB* pblocktree = NULL; -CZerocoinDB* zerocoinDB = NULL; -CSporkDB* pSporkDB = NULL; +std::unique_ptr pcoinsdbview; +std::unique_ptr pcoinsTip; +std::unique_ptr pblocktree; +std::unique_ptr zerocoinDB; +std::unique_ptr pSporkDB; enum FlushStateMode { FLUSH_STATE_NONE, @@ -374,7 +375,7 @@ void UpdateMempoolForReorg(DisconnectedBlockTransactions &disconnectpool, bool f mempool.UpdateTransactionsFromBlock(vHashUpdate); // We also need to remove any now-immature transactions - mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + mempool.removeForReorg(pcoinsTip.get(), chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); // Re-limit mempool size, in case we added any transactions LimitMempoolSize(mempool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); @@ -487,7 +488,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C CAmount nValueIn = 0; LOCK(pool.cs); - CCoinsViewMemPool viewMemPool(pcoinsTip, pool); + CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool); view.SetBackend(viewMemPool); // do we already have it? @@ -1333,7 +1334,7 @@ DisconnectResult DisconnectBlock(CBlock& block, const CBlockIndex* pindex, CCoin for (int i = block.vtx.size() - 1; i >= 0; i--) { const CTransaction& tx = *block.vtx[i]; - if (!DisconnectZerocoinTx(tx, zerocoinDB)) + if (!DisconnectZerocoinTx(tx)) return DISCONNECT_FAILED; const uint256& hash = tx.GetHash(); @@ -1928,7 +1929,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara { auto dbTx = evoDb->BeginTransaction(); - 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", pindexDelete->GetBlockHash().ToString()); @@ -2055,7 +2056,7 @@ bool static ConnectTip(CValidationState& state, CBlockIndex* pindexNew, const st { auto dbTx = evoDb->BeginTransaction(); - CCoinsViewCache view(pcoinsTip); + CCoinsViewCache view(pcoinsTip.get()); bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, false); GetMainSignals().BlockChecked(blockConnecting, state); if (!rv) { @@ -2255,7 +2256,7 @@ static bool ActivateBestChainStep(CValidationState& state, CBlockIndex* pindexMo // any disconnected transactions back to the mempool. UpdateMempoolForReorg(disconnectpool, true); } - mempool.check(pcoinsTip); + mempool.check(pcoinsTip.get()); // Callbacks/notifications for a new best chain. if (fInvalidFound) @@ -3237,7 +3238,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockInde // If the stake is not a zPoS then let's check if the inputs were spent on the main chain - const CCoinsViewCache coins(pcoinsTip); + const CCoinsViewCache coins(pcoinsTip.get()); if(!stakeTxIn.HasZerocoinSpendInputs()) { for (const CTxIn& in: stakeTxIn.vin) { const Coin& coin = coins.AccessCoin(in.prevout); @@ -3334,7 +3335,7 @@ bool TestBlockValidity(CValidationState& state, const CBlock& block, CBlockIndex return false; } - CCoinsViewCache viewNew(pcoinsTip); + CCoinsViewCache viewNew(pcoinsTip.get()); CBlockIndex indexDummy(block); indexDummy.pprev = pindexPrev; indexDummy.nHeight = pindexPrev->nHeight + 1; diff --git a/src/validation.h b/src/validation.h index 61285d9604526..2ab6e53da6d20 100644 --- a/src/validation.h +++ b/src/validation.h @@ -40,6 +40,7 @@ class CBlockIndex; class CBlockTreeDB; class CBudgetManager; +class CCoinsViewDB; class CZerocoinDB; class CSporkDB; class CBloomFilter; @@ -357,17 +358,20 @@ bool ReconsiderBlock(CValidationState& state, CBlockIndex* pindex); /** The currently-connected chain of blocks (protected by cs_main). */ extern CChain chainActive; +/** Global variable that points to the coins database (protected by cs_main) */ +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; /** Global variable that points to the zerocoin database (protected by cs_main) */ -extern CZerocoinDB* zerocoinDB; +extern std::unique_ptr zerocoinDB; /** Global variable that points to the spork database (protected by cs_main) */ -extern CSporkDB* pSporkDB; +extern std::unique_ptr pSporkDB; /** * Return a reliable pointer (in mapBlockIndex) to the chain's tip index