aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2019-08-15 12:47:04 -0400
committerMarcoFalke <falke.marco@gmail.com>2019-08-15 12:47:15 -0400
commit85883a9f8ea09f65092dc822a7ca98e64b96f4ab (patch)
tree90edc337e501c248f8a53122089ea29ec93422f0 /src/init.cpp
parent8bd5e0af9983c6892d4076881d634cc524d643fd (diff)
parent582d2cd74754d6b9a2394616a9c82a89d2d71976 (diff)
Merge #16443: refactor: have CCoins* data managed under CChainState
582d2cd74754d6b9a2394616a9c82a89d2d71976 Cover UTXO set access with lock annotations (James O'Beirne) 569353068568444a25b301bbd6513bb510157dc9 refactor: have CCoins* data managed under CChainState (James O'Beirne) fae6ab6aed3b9fdc9201bb19a307dfc3d9b89891 refactor: pcoinsTip -> CChainState::CoinsTip() (James O'Beirne) Pull request description: This is part of the [assumeutxo project](https://github.com/bitcoin/bitcoin/projects/11): Parent PR: #15606 Issue: #15605 Specification: https://github.com/jamesob/assumeutxo-docs/tree/2019-04-proposal/proposal --- This change encapsulates UTXO set data within CChainState instances, removing global data `pcoinsTip` and `pcoinsviewdb`. This is necessary if we want to maintain multiple chainstates with their own rendering of the UTXO set. We introduce a class CoinsViews which consolidates the construction of a CCoins* hierarchy. This commit could be broken into smaller pieces, but it would require more ephemeral diffs to, e.g., temporarily change CCoinsViewDB's constructor invocations. ACKs for top commit: Sjors: reACK 582d2cd74754d6b9a2394616a9c82a89d2d71976 MarcoFalke: ACK 582d2cd747 Tree-SHA512: ec9d904fe5dca8cd2dc4b7916daa5d8bab30856dd4645987300f905e0a19f9919fce4f9d1ff03eda982943ca73e6e9a746be6cf53b46510de36e8c81a1eafba1
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 25c964205a..8870f379fb 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -15,7 +15,6 @@
#include <blockfilter.h>
#include <chain.h>
#include <chainparams.h>
-#include <coins.h>
#include <compat/sanity.h>
#include <consensus/validation.h>
#include <fs.h>
@@ -150,7 +149,6 @@ NODISCARD static bool CreatePidFile()
// shutdown thing.
//
-static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
static boost::thread_group threadGroup;
@@ -235,8 +233,14 @@ void Shutdown(InitInterfaces& interfaces)
}
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
- if (pcoinsTip != nullptr) {
- ::ChainstateActive().ForceFlushStateToDisk();
+ //
+ // g_chainstate is referenced here directly (instead of ::ChainstateActive()) because it
+ // may not have been initialized yet.
+ {
+ LOCK(cs_main);
+ if (g_chainstate && g_chainstate->CanFlushToDisk()) {
+ g_chainstate->ForceFlushStateToDisk();
+ }
}
// After there are no more peers/RPC left to give us new data which may generate
@@ -251,12 +255,10 @@ void Shutdown(InitInterfaces& interfaces)
{
LOCK(cs_main);
- if (pcoinsTip != nullptr) {
- ::ChainstateActive().ForceFlushStateToDisk();
+ if (g_chainstate && g_chainstate->CanFlushToDisk()) {
+ g_chainstate->ForceFlushStateToDisk();
+ g_chainstate->ResetCoinsViews();
}
- pcoinsTip.reset();
- pcoinscatcher.reset();
- pcoinsdbview.reset();
pblocktree.reset();
}
for (const auto& client : interfaces.chain_clients) {
@@ -1467,10 +1469,10 @@ bool AppInitMain(InitInterfaces& interfaces)
bool is_coinsview_empty;
try {
LOCK(cs_main);
+ // This statement makes ::ChainstateActive() usable.
+ g_chainstate = MakeUnique<CChainState>();
UnloadBlockIndex();
- pcoinsTip.reset();
- pcoinsdbview.reset();
- pcoinscatcher.reset();
+
// new CBlockTreeDB tries to delete the existing file, which
// fails if it's still open from the previous loop. Close it first:
pblocktree.reset();
@@ -1521,9 +1523,12 @@ bool AppInitMain(InitInterfaces& interfaces)
// At this point we're either in reindex or we've loaded a useful
// block tree into BlockIndex()!
- pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
- pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
- pcoinscatcher->AddReadErrCallback([]() {
+ ::ChainstateActive().InitCoinsDB(
+ /* cache_size_bytes */ nCoinDBCache,
+ /* in_memory */ false,
+ /* should_wipe */ fReset || fReindexChainState);
+
+ ::ChainstateActive().CoinsErrorCatcher().AddReadErrCallback([]() {
uiInterface.ThreadSafeMessageBox(
_("Error reading from database, shutting down.").translated,
"", CClientUIInterface::MSG_ERROR);
@@ -1531,23 +1536,25 @@ bool AppInitMain(InitInterfaces& interfaces)
// If necessary, upgrade from older database format.
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
- if (!pcoinsdbview->Upgrade()) {
+ if (!::ChainstateActive().CoinsDB().Upgrade()) {
strLoadError = _("Error upgrading chainstate database").translated;
break;
}
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
- if (!ReplayBlocks(chainparams, pcoinsdbview.get())) {
+ if (!ReplayBlocks(chainparams, &::ChainstateActive().CoinsDB())) {
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.").translated;
break;
}
// The on-disk coinsdb is now in a good state, create the cache
- pcoinsTip.reset(new CCoinsViewCache(pcoinscatcher.get()));
+ ::ChainstateActive().InitCoinsCache();
+ assert(::ChainstateActive().CanFlushToDisk());
- is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull();
+ is_coinsview_empty = fReset || fReindexChainState ||
+ ::ChainstateActive().CoinsTip().GetBestBlock().IsNull();
if (!is_coinsview_empty) {
- // LoadChainTip sets ::ChainActive() based on pcoinsTip's best block
+ // LoadChainTip sets ::ChainActive() based on CoinsTip()'s best block
if (!LoadChainTip(chainparams)) {
strLoadError = _("Error initializing block database").translated;
break;
@@ -1589,7 +1596,7 @@ bool AppInitMain(InitInterfaces& interfaces)
break;
}
- if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview.get(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
+ if (!CVerifyDB().VerifyDB(chainparams, &::ChainstateActive().CoinsDB(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
strLoadError = _("Corrupted block database detected").translated;
break;