From 98f4bdae81804de17f125bd7c2cd8a48e850a6d2 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 7 Jan 2021 16:41:51 -0500 Subject: [PATCH 1/8] refactor: Convert warningcache to std::array --- src/validation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 3676316f76f..76dc5b7fc4c 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1921,7 +1921,7 @@ public: } }; -static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_main); +static std::array warningcache GUARDED_BY(cs_main); static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& consensusparams) { @@ -2550,7 +2550,7 @@ void CChainState::UpdateTip(const CBlockIndex* pindexNew) const CBlockIndex* pindex = pindexNew; for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { WarningBitsConditionChecker checker(bit); - ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), warningcache[bit]); + ThresholdState state = checker.GetStateFor(pindex, m_params.GetConsensus(), warningcache.at(bit)); if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) { const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit); if (state == ThresholdState::ACTIVE) { @@ -4152,8 +4152,8 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman) chainman.Unload(); if (mempool) mempool->clear(); g_versionbitscache.Clear(); - for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) { - warningcache[b].clear(); + for (auto& i : warningcache) { + i.clear(); } } From 6e747e80e7094df0b5bee1eed57e57e82015d0ee Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Fri, 15 Apr 2022 07:47:20 +1000 Subject: [PATCH 2/8] validation: default initialize and guard chainman members --- src/test/validation_chainstate_tests.cpp | 2 +- src/test/validation_chainstatemanager_tests.cpp | 4 ++-- src/validation.h | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/validation_chainstate_tests.cpp b/src/test/validation_chainstate_tests.cpp index b0d7389d39b..2a3990bb7c7 100644 --- a/src/test/validation_chainstate_tests.cpp +++ b/src/test/validation_chainstate_tests.cpp @@ -93,7 +93,7 @@ BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup) BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(m_node, m_path_root)); // Ensure our active chain is the snapshot chainstate. - BOOST_CHECK(chainman.IsSnapshotActive()); + BOOST_CHECK(WITH_LOCK(::cs_main, return chainman.IsSnapshotActive())); curr_tip = ::g_best_block; diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 5d0ec593e3c..6dc522b4214 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); BOOST_CHECK(!manager.IsSnapshotActive()); - BOOST_CHECK(!manager.IsSnapshotValidated()); + BOOST_CHECK(WITH_LOCK(::cs_main, return !manager.IsSnapshotValidated())); auto all = manager.GetAll(); BOOST_CHECK_EQUAL_COLLECTIONS(all.begin(), all.end(), chainstates.begin(), chainstates.end()); @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager) BOOST_CHECK(c2.ActivateBestChain(_, nullptr)); BOOST_CHECK(manager.IsSnapshotActive()); - BOOST_CHECK(!manager.IsSnapshotValidated()); + BOOST_CHECK(WITH_LOCK(::cs_main, return !manager.IsSnapshotValidated())); BOOST_CHECK_EQUAL(&c2, &manager.ActiveChainstate()); BOOST_CHECK(&c1 != &manager.ActiveChainstate()); auto all2 = manager.GetAll(); diff --git a/src/validation.h b/src/validation.h index 38d3d984657..a8f6f007c31 100644 --- a/src/validation.h +++ b/src/validation.h @@ -831,9 +831,9 @@ private: //! If true, the assumed-valid chainstate has been fully validated //! by the background validation chainstate. - bool m_snapshot_validated{false}; + bool m_snapshot_validated GUARDED_BY(::cs_main){false}; - CBlockIndex* m_best_invalid; + CBlockIndex* m_best_invalid GUARDED_BY(::cs_main){nullptr}; //! Internal helper for ActivateSnapshot(). [[nodiscard]] bool PopulateAndValidateSnapshot( @@ -940,7 +940,7 @@ public: std::optional SnapshotBlockhash() const; //! Is there a snapshot in use and has it been fully validated? - bool IsSnapshotValidated() const { return m_snapshot_validated; } + bool IsSnapshotValidated() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main) { return m_snapshot_validated; } /** * Process an incoming block. This only returns after the best known valid From 5921b863e39e5c3997895ffee1c87159e37a5d6f Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Mon, 13 Sep 2021 17:02:55 -0400 Subject: [PATCH 3/8] init: Reset mempool and chainman via reconstruction Fixes https://github.com/bitcoin/bitcoin/issues/22964 Previously, we used UnloadBlockIndex() in order to reset node.mempool and node.chainman. However, that has proven to be fragile (see https://github.com/bitcoin/bitcoin/issues/22964), and requires UnloadBlockIndex and its callees to be updated manually for each member that's introduced to the mempool and chainman classes. In this commit, we stop using the UnloadBlockIndex function and we simply reconstruct node.mempool and node.chainman. Since PeerManager needs a valid reference to both node.mempool and node.chainman, we also move PeerManager's construction via `::make` to after the chainstate activation sequence is complete. There are no more callers to UnloadBlockIndex after this commit, so it and its sole callees can be pruned. --- src/init.cpp | 29 ++++++++++++++++------------- src/node/chainstate.cpp | 2 -- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index cccb088eec7..11d2b61da87 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1288,19 +1288,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // as they would never get updated. if (!ignores_incoming_txs) node.fee_estimator = std::make_unique(); - assert(!node.mempool); - int check_ratio = std::min(std::max(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); - node.mempool = std::make_unique(node.fee_estimator.get(), check_ratio); - - 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(), - chainman, *node.mempool, ignores_incoming_txs); - RegisterValidationInterface(node.peerman.get()); - // sanitize comments per BIP-0014, format user agent and check total size std::vector uacomments; for (const std::string& cmt : args.GetArgs("-uacomment")) { @@ -1429,8 +1416,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) LogPrintf("* Using %.1f MiB for chain state database\n", cache_sizes.coins_db * (1.0 / 1024 / 1024)); LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024)); + assert(!node.mempool); + assert(!node.chainman); + int check_ratio = std::min(std::max(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); + bool fLoaded = false; while (!fLoaded && !ShutdownRequested()) { + node.mempool = std::make_unique(node.fee_estimator.get(), check_ratio); + + node.chainman = std::make_unique(); + ChainstateManager& chainman = *node.chainman; + const bool fReset = fReindex; bilingual_str strLoadError; @@ -1562,6 +1558,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) return false; } + ChainstateManager& chainman = *Assert(node.chainman); + + assert(!node.peerman); + node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(), + chainman, *node.mempool, ignores_incoming_txs); + RegisterValidationInterface(node.peerman.get()); + // ********************************************************* Step 8: start indexers if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (const auto error{WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(chainman.m_blockman.m_block_tree_db)))}) { diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index e43211402ca..99615dea692 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -32,8 +32,6 @@ std::optional LoadChainstate(bool fReset, chainman.m_total_coinstip_cache = nCoinCacheUsage; chainman.m_total_coinsdb_cache = nCoinDBCache; - UnloadBlockIndex(mempool, chainman); - auto& pblocktree{chainman.m_blockman.m_block_tree_db}; // new CBlockTreeDB tries to delete the existing file, which // fails if it's still open from the previous loop. Close it first: From fe96a2e4bd87768df8001eb4117926a0977d876e Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 22 Feb 2022 14:20:55 -0500 Subject: [PATCH 4/8] style-only: Use for instead of when loading Chainstate It's a bit clearer and restricts the scope of fLoaded --- src/init.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 11d2b61da87..6ea25bc36db 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1420,8 +1420,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) assert(!node.chainman); int check_ratio = std::min(std::max(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); - bool fLoaded = false; - while (!fLoaded && !ShutdownRequested()) { + for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) { node.mempool = std::make_unique(node.fee_estimator.get(), check_ratio); node.chainman = std::make_unique(); From eca4ca4d60599c9dbdd4e03a73beb33e9b44655a Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 22 Feb 2022 14:30:31 -0500 Subject: [PATCH 5/8] style-only: Use std::clamp for check_ratio, rename --- src/init.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 6ea25bc36db..fdcb2b8ac76 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -73,6 +73,7 @@ #include #include +#include #include #include #include @@ -1418,10 +1419,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) assert(!node.mempool); assert(!node.chainman); - int check_ratio = std::min(std::max(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); + const int mempool_check_ratio = std::clamp(args.GetIntArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0, 1000000); for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) { - node.mempool = std::make_unique(node.fee_estimator.get(), check_ratio); + node.mempool = std::make_unique(node.fee_estimator.get(), mempool_check_ratio); node.chainman = std::make_unique(); ChainstateManager& chainman = *node.chainman; From 572d8319272ae84a81d6bfd53dd9685585697f65 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 11 Jan 2022 14:49:28 -0500 Subject: [PATCH 6/8] Clear {versionbits,warning}cache in ~Chainstatemanager Also add TODO item to deglobalize the {versionbits,warning}cache, which should really only need to be cleared if we change the chainparams. --- src/validation.cpp | 17 +++++++++++++---- src/validation.h | 5 +---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 76dc5b7fc4c..8448e45051d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4151,10 +4151,6 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman) AssertLockHeld(::cs_main); chainman.Unload(); if (mempool) mempool->clear(); - g_versionbitscache.Clear(); - for (auto& i : warningcache) { - i.clear(); - } } bool ChainstateManager::LoadBlockIndex() @@ -5231,3 +5227,16 @@ void ChainstateManager::MaybeRebalanceCaches() } } } + +ChainstateManager::~ChainstateManager() +{ + LOCK(::cs_main); + UnloadBlockIndex(/*mempool=*/nullptr, *this); + + // TODO: The version bits cache and warning cache should probably become + // non-globals + g_versionbitscache.Clear(); + for (auto& i : warningcache) { + i.clear(); + } +} diff --git a/src/validation.h b/src/validation.h index a8f6f007c31..3996086cedf 100644 --- a/src/validation.h +++ b/src/validation.h @@ -995,10 +995,7 @@ public: //! ResizeCoinsCaches() as needed. void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); - ~ChainstateManager() { - LOCK(::cs_main); - UnloadBlockIndex(/*mempool=*/nullptr, *this); - } + ~ChainstateManager(); }; using FopenFn = std::function; From 7d99d725cdb5428ed25dc07c2d7fddf420da7786 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 11 Jan 2022 15:11:56 -0500 Subject: [PATCH 7/8] validation: No mempool clearing in UnloadBlockIndex The only caller that uses this is ~ChainTestingSetup() where we immediately destroy the mempool afterwards. --- src/bitcoin-chainstate.cpp | 2 +- src/test/util/setup_common.cpp | 2 +- src/validation.cpp | 5 ++--- src/validation.h | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index fcbb6aaccee..973b866ec8b 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -256,7 +256,7 @@ epilogue: } GetMainSignals().UnregisterBackgroundSignalScheduler(); - WITH_LOCK(::cs_main, UnloadBlockIndex(nullptr, chainman)); + WITH_LOCK(::cs_main, UnloadBlockIndex(chainman)); init::UnsetGlobals(); } diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 1830ec05afc..3959bf7ae7c 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -182,7 +182,7 @@ ChainTestingSetup::~ChainTestingSetup() m_node.addrman.reset(); m_node.netgroupman.reset(); m_node.args = nullptr; - WITH_LOCK(::cs_main, UnloadBlockIndex(m_node.mempool.get(), *m_node.chainman)); + WITH_LOCK(::cs_main, UnloadBlockIndex(*m_node.chainman)); m_node.mempool.reset(); m_node.scheduler.reset(); m_node.chainman.reset(); diff --git a/src/validation.cpp b/src/validation.cpp index 8448e45051d..70762a3a51d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4146,11 +4146,10 @@ void CChainState::UnloadBlockIndex() // May NOT be used after any connections are up as much // of the peer-processing logic assumes a consistent // block index state -void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman) +void UnloadBlockIndex(ChainstateManager& chainman) { AssertLockHeld(::cs_main); chainman.Unload(); - if (mempool) mempool->clear(); } bool ChainstateManager::LoadBlockIndex() @@ -5231,7 +5230,7 @@ void ChainstateManager::MaybeRebalanceCaches() ChainstateManager::~ChainstateManager() { LOCK(::cs_main); - UnloadBlockIndex(/*mempool=*/nullptr, *this); + UnloadBlockIndex(*this); // TODO: The version bits cache and warning cache should probably become // non-globals diff --git a/src/validation.h b/src/validation.h index 3996086cedf..5fb7c5b4cfa 100644 --- a/src/validation.h +++ b/src/validation.h @@ -135,7 +135,7 @@ extern arith_uint256 nMinimumChainWork; extern const std::vector CHECKLEVEL_DOC; /** Unload database information */ -void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +void UnloadBlockIndex(ChainstateManager& chainman) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); /** Run instances of script checking worker threads */ void StartScriptCheckWorkerThreads(int threads_num); /** Stop all of the script checking worker threads */ From 7ab07e033237d6ea179a6a2c76575ed6bd01a670 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Tue, 12 Jan 2021 13:38:53 -0500 Subject: [PATCH 8/8] validation: Prune UnloadBlockIndex and callees In previous commits in this patchset, we've made sure that every Unload/UnloadBlockIndex member function resets its own members, and does not reach out to globals. This means that their corresponding classes' default destructors can now replace them, and do an even more thorough job without the need to be updated for every new member variable. Therefore, we can remove them, and also remove UnloadBlockIndex since that's not used anymore. Unfortunately, chainstatemanager_loadblockindex relies on CChainState::UnloadBlockIndex, so that needs to stay for now. --- src/bitcoin-chainstate.cpp | 2 -- src/node/blockstorage.cpp | 14 -------------- src/node/blockstorage.h | 8 -------- src/test/util/setup_common.cpp | 1 - src/validation.cpp | 24 ------------------------ src/validation.h | 5 ----- 6 files changed, 54 deletions(-) diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 973b866ec8b..1e4200db029 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -256,7 +256,5 @@ epilogue: } GetMainSignals().UnregisterBackgroundSignalScheduler(); - WITH_LOCK(::cs_main, UnloadBlockIndex(chainman)); - init::UnsetGlobals(); } diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 8ed22bbbce8..25771aaceeb 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -297,20 +297,6 @@ bool BlockManager::LoadBlockIndex(const Consensus::Params& consensus_params) return true; } -void BlockManager::Unload() -{ - m_blocks_unlinked.clear(); - - m_block_index.clear(); - - m_blockfile_info.clear(); - m_last_blockfile = 0; - m_dirty_blockindex.clear(); - m_dirty_fileinfo.clear(); - - m_have_pruned = false; -} - bool BlockManager::WriteBlockIndexDB() { AssertLockHeld(::cs_main); diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index e4b96573726..622eac7fef7 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -154,9 +154,6 @@ public: bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); - /** Clear all data members. */ - void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main); - CBlockIndex* AddToBlockIndex(const CBlockHeader& block, CBlockIndex*& best_header) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Create a new block index entry for a given block hash */ CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main); @@ -189,11 +186,6 @@ public: //! Create or update a prune lock identified by its name void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); - - ~BlockManager() - { - Unload(); - } }; //! Find the first block that is not pruned diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 3959bf7ae7c..2fc71c2a6ec 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -182,7 +182,6 @@ ChainTestingSetup::~ChainTestingSetup() m_node.addrman.reset(); m_node.netgroupman.reset(); m_node.args = nullptr; - WITH_LOCK(::cs_main, UnloadBlockIndex(*m_node.chainman)); m_node.mempool.reset(); m_node.scheduler.reset(); m_node.chainman.reset(); diff --git a/src/validation.cpp b/src/validation.cpp index 70762a3a51d..208bcee0081 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4143,15 +4143,6 @@ void CChainState::UnloadBlockIndex() setBlockIndexCandidates.clear(); } -// May NOT be used after any connections are up as much -// of the peer-processing logic assumes a consistent -// block index state -void UnloadBlockIndex(ChainstateManager& chainman) -{ - AssertLockHeld(::cs_main); - chainman.Unload(); -} - bool ChainstateManager::LoadBlockIndex() { AssertLockHeld(cs_main); @@ -5182,20 +5173,6 @@ bool ChainstateManager::IsSnapshotActive() const return m_snapshot_chainstate && m_active_chainstate == m_snapshot_chainstate.get(); } -void ChainstateManager::Unload() -{ - AssertLockHeld(::cs_main); - for (CChainState* chainstate : this->GetAll()) { - chainstate->m_chain.SetTip(nullptr); - chainstate->UnloadBlockIndex(); - } - - m_failed_blocks.clear(); - m_blockman.Unload(); - m_best_header = nullptr; - m_best_invalid = nullptr; -} - void ChainstateManager::MaybeRebalanceCaches() { AssertLockHeld(::cs_main); @@ -5230,7 +5207,6 @@ void ChainstateManager::MaybeRebalanceCaches() ChainstateManager::~ChainstateManager() { LOCK(::cs_main); - UnloadBlockIndex(*this); // TODO: The version bits cache and warning cache should probably become // non-globals diff --git a/src/validation.h b/src/validation.h index 5fb7c5b4cfa..e3ea8617e79 100644 --- a/src/validation.h +++ b/src/validation.h @@ -134,8 +134,6 @@ extern arith_uint256 nMinimumChainWork; /** Documentation for argument 'checklevel'. */ extern const std::vector CHECKLEVEL_DOC; -/** Unload database information */ -void UnloadBlockIndex(ChainstateManager& chainman) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); /** Run instances of script checking worker threads */ void StartScriptCheckWorkerThreads(int threads_num); /** Stop all of the script checking worker threads */ @@ -988,9 +986,6 @@ public: //! Load the block tree and coins database from disk, initializing state if we're running with -reindex bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main); - //! Unload block index and chain data before shutdown. - void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); - //! Check to see if caches are out of balance and if so, call //! ResizeCoinsCaches() as needed. void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);