0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-05 14:06:27 -05:00

validation: Pass in chainstate to CVerifyDB::VerifyDB

This commit is contained in:
Carl Dong 2020-09-15 16:30:32 -04:00
parent 31eac50c72
commit 2bdf37fe18
4 changed files with 19 additions and 18 deletions

View file

@ -1741,7 +1741,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
// work when we allow VerifyDB to be parameterized by chainstate. // work when we allow VerifyDB to be parameterized by chainstate.
if (&::ChainstateActive() == chainstate && if (&::ChainstateActive() == chainstate &&
!CVerifyDB().VerifyDB( !CVerifyDB().VerifyDB(
chainparams, &chainstate->CoinsDB(), chainparams, *chainstate, &chainstate->CoinsDB(),
args.GetArg("-checklevel", DEFAULT_CHECKLEVEL), args.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
strLoadError = _("Corrupted block database detected"); strLoadError = _("Corrupted block database detected");

View file

@ -1200,7 +1200,7 @@ static RPCHelpMan verifychain()
LOCK(cs_main); LOCK(cs_main);
return CVerifyDB().VerifyDB(Params(), &::ChainstateActive().CoinsTip(), check_level, check_depth); return CVerifyDB().VerifyDB(Params(), ::ChainstateActive(), &::ChainstateActive().CoinsTip(), check_level, check_depth);
}, },
}; };
} }

View file

@ -4235,15 +4235,16 @@ CVerifyDB::~CVerifyDB()
uiInterface.ShowProgress("", 100, false); uiInterface.ShowProgress("", 100, false);
} }
bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CChainState& active_chainstate, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
{ {
LOCK(cs_main); LOCK(cs_main);
if (::ChainActive().Tip() == nullptr || ::ChainActive().Tip()->pprev == nullptr) assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
if (active_chainstate.m_chain.Tip() == nullptr || active_chainstate.m_chain.Tip()->pprev == nullptr)
return true; return true;
// Verify blocks in the best chain // Verify blocks in the best chain
if (nCheckDepth <= 0 || nCheckDepth > ::ChainActive().Height()) if (nCheckDepth <= 0 || nCheckDepth > active_chainstate.m_chain.Height())
nCheckDepth = ::ChainActive().Height(); nCheckDepth = active_chainstate.m_chain.Height();
nCheckLevel = std::max(0, std::min(4, nCheckLevel)); nCheckLevel = std::max(0, std::min(4, nCheckLevel));
LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel); LogPrintf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
CCoinsViewCache coins(coinsview); CCoinsViewCache coins(coinsview);
@ -4253,15 +4254,15 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
BlockValidationState state; BlockValidationState state;
int reportDone = 0; int reportDone = 0;
LogPrintf("[0%%]..."); /* Continued */ LogPrintf("[0%%]..."); /* Continued */
for (pindex = ::ChainActive().Tip(); pindex && pindex->pprev; pindex = pindex->pprev) { for (pindex = active_chainstate.m_chain.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
const int percentageDone = std::max(1, std::min(99, (int)(((double)(::ChainActive().Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100)))); const int percentageDone = std::max(1, std::min(99, (int)(((double)(active_chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
if (reportDone < percentageDone/10) { if (reportDone < percentageDone/10) {
// report every 10% step // report every 10% step
LogPrintf("[%d%%]...", percentageDone); /* Continued */ LogPrintf("[%d%%]...", percentageDone); /* Continued */
reportDone = percentageDone/10; reportDone = percentageDone/10;
} }
uiInterface.ShowProgress(_("Verifying blocks...").translated, percentageDone, false); uiInterface.ShowProgress(_("Verifying blocks...").translated, percentageDone, false);
if (pindex->nHeight <= ::ChainActive().Height()-nCheckDepth) if (pindex->nHeight <= active_chainstate.m_chain.Height()-nCheckDepth)
break; break;
if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) { if (fPruneMode && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
// If pruning, only go back as far as we have data. // If pruning, only go back as far as we have data.
@ -4286,9 +4287,9 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
} }
} }
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks // check level 3: check for inconsistencies during memory-only disconnect of tip blocks
if (nCheckLevel >= 3 && (coins.DynamicMemoryUsage() + ::ChainstateActive().CoinsTip().DynamicMemoryUsage()) <= ::ChainstateActive().m_coinstip_cache_size_bytes) { if (nCheckLevel >= 3 && (coins.DynamicMemoryUsage() + active_chainstate.CoinsTip().DynamicMemoryUsage()) <= active_chainstate.m_coinstip_cache_size_bytes) {
assert(coins.GetBestBlock() == pindex->GetBlockHash()); assert(coins.GetBestBlock() == pindex->GetBlockHash());
DisconnectResult res = ::ChainstateActive().DisconnectBlock(block, pindex, coins); DisconnectResult res = active_chainstate.DisconnectBlock(block, pindex, coins);
if (res == DISCONNECT_FAILED) { if (res == DISCONNECT_FAILED) {
return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
} }
@ -4302,26 +4303,26 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
if (ShutdownRequested()) return true; if (ShutdownRequested()) return true;
} }
if (pindexFailure) if (pindexFailure)
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", ::ChainActive().Height() - pindexFailure->nHeight + 1, nGoodTransactions); return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", active_chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
// store block count as we move pindex at check level >= 4 // store block count as we move pindex at check level >= 4
int block_count = ::ChainActive().Height() - pindex->nHeight; int block_count = active_chainstate.m_chain.Height() - pindex->nHeight;
// check level 4: try reconnecting blocks // check level 4: try reconnecting blocks
if (nCheckLevel >= 4) { if (nCheckLevel >= 4) {
while (pindex != ::ChainActive().Tip()) { while (pindex != active_chainstate.m_chain.Tip()) {
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(::ChainActive().Height() - pindex->nHeight)) / (double)nCheckDepth * 50))); const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(active_chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
if (reportDone < percentageDone/10) { if (reportDone < percentageDone/10) {
// report every 10% step // report every 10% step
LogPrintf("[%d%%]...", percentageDone); /* Continued */ LogPrintf("[%d%%]...", percentageDone); /* Continued */
reportDone = percentageDone/10; reportDone = percentageDone/10;
} }
uiInterface.ShowProgress(_("Verifying blocks...").translated, percentageDone, false); uiInterface.ShowProgress(_("Verifying blocks...").translated, percentageDone, false);
pindex = ::ChainActive().Next(pindex); pindex = active_chainstate.m_chain.Next(pindex);
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!::ChainstateActive().ConnectBlock(block, state, pindex, coins, chainparams)) if (!active_chainstate.ConnectBlock(block, state, pindex, coins, chainparams))
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString()); return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
if (ShutdownRequested()) return true; if (ShutdownRequested()) return true;
} }

View file

@ -340,7 +340,7 @@ class CVerifyDB {
public: public:
CVerifyDB(); CVerifyDB();
~CVerifyDB(); ~CVerifyDB();
bool VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); bool VerifyDB(const CChainParams& chainparams, CChainState& active_chainstate, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth);
}; };
enum DisconnectResult enum DisconnectResult