aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp66
1 files changed, 43 insertions, 23 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index f0ffb748dd..1357de3c01 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1511,13 +1511,9 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
return nSubsidy;
}
-CoinsViews::CoinsViews(
- fs::path ldb_name,
- size_t cache_size_bytes,
- bool in_memory,
- bool should_wipe) : m_dbview(
- gArgs.GetDataDirNet() / ldb_name, cache_size_bytes, in_memory, should_wipe),
- m_catcherview(&m_dbview) {}
+CoinsViews::CoinsViews(DBParams db_params, CoinsViewOptions options)
+ : m_dbview{std::move(db_params), std::move(options)},
+ m_catcherview(&m_dbview) {}
void CoinsViews::InitCache()
{
@@ -1546,7 +1542,14 @@ void Chainstate::InitCoinsDB(
}
m_coins_views = std::make_unique<CoinsViews>(
- leveldb_name, cache_size_bytes, in_memory, should_wipe);
+ DBParams{
+ .path = m_chainman.m_options.datadir / leveldb_name,
+ .cache_bytes = cache_size_bytes,
+ .memory_only = in_memory,
+ .wipe_data = should_wipe,
+ .obfuscate = true,
+ .options = m_chainman.m_options.coins_db},
+ m_chainman.m_options.coins_view);
}
void Chainstate::InitCoinsCache(size_t cache_size_bytes)
@@ -4057,7 +4060,7 @@ CVerifyDB::~CVerifyDB()
uiInterface.ShowProgress("", 100, false);
}
-bool CVerifyDB::VerifyDB(
+VerifyDBResult CVerifyDB::VerifyDB(
Chainstate& chainstate,
const Consensus::Params& consensus_params,
CCoinsView& coinsview,
@@ -4066,7 +4069,7 @@ bool CVerifyDB::VerifyDB(
AssertLockHeld(cs_main);
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr) {
- return true;
+ return VerifyDBResult::SUCCESS;
}
// Verify blocks in the best chain
@@ -4081,6 +4084,7 @@ bool CVerifyDB::VerifyDB(
int nGoodTransactions = 0;
BlockValidationState state;
int reportDone = 0;
+ bool skipped_no_block_data{false};
bool skipped_l3_checks{false};
LogPrintf("Verification progress: 0%%\n");
@@ -4100,25 +4104,29 @@ bool CVerifyDB::VerifyDB(
if ((chainstate.m_blockman.IsPruneMode() || is_snapshot_cs) && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
// If pruning or running under an assumeutxo snapshot, only go
// back as far as we have data.
- LogPrintf("VerifyDB(): block verification stopping at height %d (pruning, no data)\n", pindex->nHeight);
+ LogPrintf("VerifyDB(): block verification stopping at height %d (no data). This could be due to pruning or use of an assumeutxo snapshot.\n", pindex->nHeight);
+ skipped_no_block_data = true;
break;
}
CBlock block;
// check level 0: read from disk
if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
- return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
// check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(block, state, consensus_params)) {
- return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
- pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
+ LogPrintf("Verification error: found bad block at %d, hash=%s (%s)\n",
+ pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
// check level 2: verify undo validity
if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo;
if (!pindex->GetUndoPos().IsNull()) {
if (!UndoReadFromDisk(undo, pindex)) {
- return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ LogPrintf("Verification error: found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
}
}
@@ -4130,7 +4138,8 @@ bool CVerifyDB::VerifyDB(
assert(coins.GetBestBlock() == pindex->GetBlockHash());
DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
if (res == DISCONNECT_FAILED) {
- return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ LogPrintf("Verification error: irrecoverable inconsistency in block data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
if (res == DISCONNECT_UNCLEAN) {
nGoodTransactions = 0;
@@ -4142,14 +4151,16 @@ bool CVerifyDB::VerifyDB(
skipped_l3_checks = true;
}
}
- if (ShutdownRequested()) return true;
+ if (ShutdownRequested()) return VerifyDBResult::INTERRUPTED;
}
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);
+ LogPrintf("Verification error: coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainstate.m_chain.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
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
int block_count = chainstate.m_chain.Height() - pindex->nHeight;
@@ -4165,18 +4176,27 @@ bool CVerifyDB::VerifyDB(
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
pindex = chainstate.m_chain.Next(pindex);
CBlock block;
- if (!ReadBlockFromDisk(block, pindex, consensus_params))
- return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
+ LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
+ }
if (!chainstate.ConnectBlock(block, state, pindex, coins)) {
- return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
+ LogPrintf("Verification error: found unconnectable block at %d, hash=%s (%s)\n", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
+ return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
- if (ShutdownRequested()) return true;
+ if (ShutdownRequested()) return VerifyDBResult::INTERRUPTED;
}
}
LogPrintf("Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
- return true;
+ if (skipped_l3_checks) {
+ return VerifyDBResult::SKIPPED_L3_CHECKS;
+ }
+ if (skipped_no_block_data) {
+ return VerifyDBResult::SKIPPED_MISSING_BLOCKS;
+ }
+ return VerifyDBResult::SUCCESS;
}
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */