Merge 85883a9f8e into merged_master (Bitcoin PR #16443)

This commit is contained in:
Andrew Poelstra 2020-11-09 21:20:14 +00:00
commit 028f2d94d1
17 changed files with 247 additions and 100 deletions

View file

@ -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>
@ -155,7 +154,6 @@ NODISCARD static bool CreatePidFile()
// shutdown thing.
//
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
static boost::thread_group threadGroup;
@ -241,8 +239,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
@ -257,12 +261,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) {
@ -1523,10 +1525,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();
@ -1577,9 +1579,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);
@ -1587,23 +1592,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;
@ -1645,7 +1652,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;