mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-11 12:22:39 -03:00
validation: Skip VerifyDB checks of level >=3 if dbcache is too small
The previous behavior, skipping some L3 DisconnectBlock calls, but still attempting to reconnect these blocks at L4, makes ConnectBlock assert. The variable skipped_l3_checks is introduced because even with an insufficient cache for the L3 checks, the L1/L2 checks in the same loop should still be completed. Fixes #25563.
This commit is contained in:
parent
2b211b41e3
commit
61431e3a57
1 changed files with 19 additions and 12 deletions
|
@ -4081,6 +4081,7 @@ bool CVerifyDB::VerifyDB(
|
||||||
int nGoodTransactions = 0;
|
int nGoodTransactions = 0;
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
int reportDone = 0;
|
int reportDone = 0;
|
||||||
|
bool skipped_l3_checks{false};
|
||||||
LogPrintf("[0%%]..."); /* Continued */
|
LogPrintf("[0%%]..."); /* Continued */
|
||||||
|
|
||||||
const bool is_snapshot_cs{!chainstate.m_from_snapshot_blockhash};
|
const bool is_snapshot_cs{!chainstate.m_from_snapshot_blockhash};
|
||||||
|
@ -4124,17 +4125,21 @@ bool CVerifyDB::VerifyDB(
|
||||||
// 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
|
||||||
size_t curr_coins_usage = coins.DynamicMemoryUsage() + chainstate.CoinsTip().DynamicMemoryUsage();
|
size_t curr_coins_usage = coins.DynamicMemoryUsage() + chainstate.CoinsTip().DynamicMemoryUsage();
|
||||||
|
|
||||||
if (nCheckLevel >= 3 && curr_coins_usage <= chainstate.m_coinstip_cache_size_bytes) {
|
if (nCheckLevel >= 3) {
|
||||||
assert(coins.GetBestBlock() == pindex->GetBlockHash());
|
if (curr_coins_usage <= chainstate.m_coinstip_cache_size_bytes) {
|
||||||
DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
|
assert(coins.GetBestBlock() == pindex->GetBlockHash());
|
||||||
if (res == DISCONNECT_FAILED) {
|
DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
|
||||||
return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
if (res == DISCONNECT_FAILED) {
|
||||||
}
|
return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
|
||||||
if (res == DISCONNECT_UNCLEAN) {
|
}
|
||||||
nGoodTransactions = 0;
|
if (res == DISCONNECT_UNCLEAN) {
|
||||||
pindexFailure = pindex;
|
nGoodTransactions = 0;
|
||||||
|
pindexFailure = pindex;
|
||||||
|
} else {
|
||||||
|
nGoodTransactions += block.vtx.size();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nGoodTransactions += block.vtx.size();
|
skipped_l3_checks = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ShutdownRequested()) return true;
|
if (ShutdownRequested()) return true;
|
||||||
|
@ -4142,12 +4147,14 @@ bool CVerifyDB::VerifyDB(
|
||||||
if (pindexFailure) {
|
if (pindexFailure) {
|
||||||
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
|
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
|
||||||
}
|
}
|
||||||
|
if (skipped_l3_checks) {
|
||||||
|
LogPrintf("Skipped verification of level >=3 (insufficient database cache size). Consider increasing -dbcache.\n");
|
||||||
|
}
|
||||||
// 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 = chainstate.m_chain.Height() - pindex->nHeight;
|
int block_count = chainstate.m_chain.Height() - pindex->nHeight;
|
||||||
|
|
||||||
// check level 4: try reconnecting blocks
|
// check level 4: try reconnecting blocks
|
||||||
if (nCheckLevel >= 4) {
|
if (nCheckLevel >= 4 && !skipped_l3_checks) {
|
||||||
while (pindex != chainstate.m_chain.Tip()) {
|
while (pindex != chainstate.m_chain.Tip()) {
|
||||||
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
|
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
|
||||||
if (reportDone < percentageDone / 10) {
|
if (reportDone < percentageDone / 10) {
|
||||||
|
|
Loading…
Reference in a new issue