Skip to content

Commit 61431e3

Browse files
committed
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.
1 parent 2b211b4 commit 61431e3

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

src/validation.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4081,6 +4081,7 @@ bool CVerifyDB::VerifyDB(
40814081
int nGoodTransactions = 0;
40824082
BlockValidationState state;
40834083
int reportDone = 0;
4084+
bool skipped_l3_checks{false};
40844085
LogPrintf("[0%%]..."); /* Continued */
40854086

40864087
const bool is_snapshot_cs{!chainstate.m_from_snapshot_blockhash};
@@ -4124,30 +4125,36 @@ bool CVerifyDB::VerifyDB(
41244125
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
41254126
size_t curr_coins_usage = coins.DynamicMemoryUsage() + chainstate.CoinsTip().DynamicMemoryUsage();
41264127

4127-
if (nCheckLevel >= 3 && curr_coins_usage <= chainstate.m_coinstip_cache_size_bytes) {
4128-
assert(coins.GetBestBlock() == pindex->GetBlockHash());
4129-
DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
4130-
if (res == DISCONNECT_FAILED) {
4131-
return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
4132-
}
4133-
if (res == DISCONNECT_UNCLEAN) {
4134-
nGoodTransactions = 0;
4135-
pindexFailure = pindex;
4128+
if (nCheckLevel >= 3) {
4129+
if (curr_coins_usage <= chainstate.m_coinstip_cache_size_bytes) {
4130+
assert(coins.GetBestBlock() == pindex->GetBlockHash());
4131+
DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
4132+
if (res == DISCONNECT_FAILED) {
4133+
return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
4134+
}
4135+
if (res == DISCONNECT_UNCLEAN) {
4136+
nGoodTransactions = 0;
4137+
pindexFailure = pindex;
4138+
} else {
4139+
nGoodTransactions += block.vtx.size();
4140+
}
41364141
} else {
4137-
nGoodTransactions += block.vtx.size();
4142+
skipped_l3_checks = true;
41384143
}
41394144
}
41404145
if (ShutdownRequested()) return true;
41414146
}
41424147
if (pindexFailure) {
41434148
return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
41444149
}
4145-
4150+
if (skipped_l3_checks) {
4151+
LogPrintf("Skipped verification of level >=3 (insufficient database cache size). Consider increasing -dbcache.\n");
4152+
}
41464153
// store block count as we move pindex at check level >= 4
41474154
int block_count = chainstate.m_chain.Height() - pindex->nHeight;
41484155

41494156
// check level 4: try reconnecting blocks
4150-
if (nCheckLevel >= 4) {
4157+
if (nCheckLevel >= 4 && !skipped_l3_checks) {
41514158
while (pindex != chainstate.m_chain.Tip()) {
41524159
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
41534160
if (reportDone < percentageDone / 10) {

0 commit comments

Comments
 (0)