Skip to content

Commit 8f4ae65

Browse files
committed
Merge bitcoin/bitcoin#27009: validation: Skip VerifyDB checks of level >=3 if dbcache is too small
fe683f3 log: Log VerifyDB Progress over multiple lines (Martin Zumsande) 61431e3 validation: Skip VerifyDB checks of level >=3 if dbcache is too small (Martin Zumsande) Pull request description: This is the first two commits from #25574, leaving out all changes to `-verifychain` error-handling : - The Problem of [25563](bitcoin/bitcoin#25563) is that when we skip blocks at level 3 due to an insufficient dbcache (skipping some `DisconnectBlock()` calls), we would still attempt the level 4 checks, attempting to reconnect a block that was never disconnected, leading to an assert in `ConnectBlock()`. Fix this by not attempting level 4 checks in this case. - Logging of verification progress is now split over multiple lines. This is more verbose, but now each update has its own timestamp, and other threads logging concurrently will no longer lead to mangled output. This can be tested with a small `dbcache` value, for example: `bitcoind -signet -dbcache=10` `bitcoin-cli -signet verifychain 4 1000` Fixes #25563 ACKs for top commit: MarcoFalke: review ACK fe683f3 🗄 john-moffett: ACK fe683f3 Tree-SHA512: 3e2e0f8b73cbc518a0fa17912c1956da437787aab95001c110b01048472e0dfe4783c44df22bd903d198069dd2f6b02bfdf74e0b934c7a776f144c2e86cb818a
2 parents d71b0e7 + fe683f3 commit 8f4ae65

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

src/validation.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4081,15 +4081,16 @@ bool CVerifyDB::VerifyDB(
40814081
int nGoodTransactions = 0;
40824082
BlockValidationState state;
40834083
int reportDone = 0;
4084-
LogPrintf("[0%%]..."); /* Continued */
4084+
bool skipped_l3_checks{false};
4085+
LogPrintf("Verification progress: 0%%\n");
40854086

40864087
const bool is_snapshot_cs{!chainstate.m_from_snapshot_blockhash};
40874088

40884089
for (pindex = chainstate.m_chain.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
40894090
const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainstate.m_chain.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
40904091
if (reportDone < percentageDone / 10) {
40914092
// report every 10% step
4092-
LogPrintf("[%d%%]...", percentageDone); /* Continued */
4093+
LogPrintf("Verification progress: %d%%\n", percentageDone);
40934094
reportDone = percentageDone / 10;
40944095
}
40954096
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
@@ -4124,35 +4125,41 @@ 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) {
41544161
// report every 10% step
4155-
LogPrintf("[%d%%]...", percentageDone); /* Continued */
4162+
LogPrintf("Verification progress: %d%%\n", percentageDone);
41564163
reportDone = percentageDone / 10;
41574164
}
41584165
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
@@ -4167,8 +4174,7 @@ bool CVerifyDB::VerifyDB(
41674174
}
41684175
}
41694176

4170-
LogPrintf("[DONE].\n");
4171-
LogPrintf("No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
4177+
LogPrintf("Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
41724178

41734179
return true;
41744180
}

0 commit comments

Comments
 (0)