mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-15 03:12:44 +02:00
validation: Change return value of VerifyDB to enum type
This does not change behavior. It is in preparation for special handling of the case where VerifyDB doesn't finish for various reasons, but doesn't fail.
This commit is contained in:
parent
52ddbd52f9
commit
6360b5302d
@ -187,12 +187,16 @@ ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const C
|
|||||||
"Only rebuild the block database if you are sure that your computer's date and time are correct")};
|
"Only rebuild the block database if you are sure that your computer's date and time are correct")};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CVerifyDB().VerifyDB(
|
VerifyDBResult result = CVerifyDB().VerifyDB(
|
||||||
*chainstate, chainman.GetConsensus(), chainstate->CoinsDB(),
|
*chainstate, chainman.GetConsensus(), chainstate->CoinsDB(),
|
||||||
options.check_level,
|
options.check_level,
|
||||||
options.check_blocks)) {
|
options.check_blocks);
|
||||||
|
switch (result) {
|
||||||
|
case VerifyDBResult::SUCCESS:
|
||||||
|
break;
|
||||||
|
case VerifyDBResult::CORRUPTED_BLOCK_DB:
|
||||||
return {ChainstateLoadStatus::FAILURE, _("Corrupted block database detected")};
|
return {ChainstateLoadStatus::FAILURE, _("Corrupted block database detected")};
|
||||||
}
|
} // no default case, so the compiler can warn about missing cases
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1125,7 +1125,7 @@ static RPCHelpMan verifychain()
|
|||||||
|
|
||||||
Chainstate& active_chainstate = chainman.ActiveChainstate();
|
Chainstate& active_chainstate = chainman.ActiveChainstate();
|
||||||
return CVerifyDB().VerifyDB(
|
return CVerifyDB().VerifyDB(
|
||||||
active_chainstate, chainman.GetParams().GetConsensus(), active_chainstate.CoinsTip(), check_level, check_depth);
|
active_chainstate, chainman.GetParams().GetConsensus(), active_chainstate.CoinsTip(), check_level, check_depth) == VerifyDBResult::SUCCESS;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4057,7 +4057,7 @@ CVerifyDB::~CVerifyDB()
|
|||||||
uiInterface.ShowProgress("", 100, false);
|
uiInterface.ShowProgress("", 100, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVerifyDB::VerifyDB(
|
VerifyDBResult CVerifyDB::VerifyDB(
|
||||||
Chainstate& chainstate,
|
Chainstate& chainstate,
|
||||||
const Consensus::Params& consensus_params,
|
const Consensus::Params& consensus_params,
|
||||||
CCoinsView& coinsview,
|
CCoinsView& coinsview,
|
||||||
@ -4066,7 +4066,7 @@ bool CVerifyDB::VerifyDB(
|
|||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr) {
|
if (chainstate.m_chain.Tip() == nullptr || chainstate.m_chain.Tip()->pprev == nullptr) {
|
||||||
return true;
|
return VerifyDBResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify blocks in the best chain
|
// Verify blocks in the best chain
|
||||||
@ -4106,19 +4106,22 @@ bool CVerifyDB::VerifyDB(
|
|||||||
CBlock block;
|
CBlock block;
|
||||||
// check level 0: read from disk
|
// check level 0: read from disk
|
||||||
if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
|
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
|
// check level 1: verify block validity
|
||||||
if (nCheckLevel >= 1 && !CheckBlock(block, state, consensus_params)) {
|
if (nCheckLevel >= 1 && !CheckBlock(block, state, consensus_params)) {
|
||||||
return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__,
|
LogPrintf("Verification error: found bad block at %d, hash=%s (%s)\n",
|
||||||
pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
|
pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
|
||||||
|
return VerifyDBResult::CORRUPTED_BLOCK_DB;
|
||||||
}
|
}
|
||||||
// check level 2: verify undo validity
|
// check level 2: verify undo validity
|
||||||
if (nCheckLevel >= 2 && pindex) {
|
if (nCheckLevel >= 2 && pindex) {
|
||||||
CBlockUndo undo;
|
CBlockUndo undo;
|
||||||
if (!pindex->GetUndoPos().IsNull()) {
|
if (!pindex->GetUndoPos().IsNull()) {
|
||||||
if (!UndoReadFromDisk(undo, pindex)) {
|
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 +4133,8 @@ bool CVerifyDB::VerifyDB(
|
|||||||
assert(coins.GetBestBlock() == pindex->GetBlockHash());
|
assert(coins.GetBestBlock() == pindex->GetBlockHash());
|
||||||
DisconnectResult res = chainstate.DisconnectBlock(block, pindex, coins);
|
DisconnectResult res = 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());
|
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) {
|
if (res == DISCONNECT_UNCLEAN) {
|
||||||
nGoodTransactions = 0;
|
nGoodTransactions = 0;
|
||||||
@ -4142,14 +4146,16 @@ bool CVerifyDB::VerifyDB(
|
|||||||
skipped_l3_checks = true;
|
skipped_l3_checks = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ShutdownRequested()) return true;
|
if (ShutdownRequested()) return VerifyDBResult::SUCCESS;
|
||||||
}
|
}
|
||||||
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);
|
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) {
|
if (skipped_l3_checks) {
|
||||||
LogPrintf("Skipped verification of level >=3 (insufficient database cache size). Consider increasing -dbcache.\n");
|
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;
|
||||||
|
|
||||||
@ -4165,18 +4171,21 @@ bool CVerifyDB::VerifyDB(
|
|||||||
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
|
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
|
||||||
pindex = chainstate.m_chain.Next(pindex);
|
pindex = chainstate.m_chain.Next(pindex);
|
||||||
CBlock block;
|
CBlock block;
|
||||||
if (!ReadBlockFromDisk(block, pindex, consensus_params))
|
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());
|
||||||
if (!chainstate.ConnectBlock(block, state, pindex, coins)) {
|
return VerifyDBResult::CORRUPTED_BLOCK_DB;
|
||||||
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
|
|
||||||
}
|
}
|
||||||
if (ShutdownRequested()) return true;
|
if (!chainstate.ConnectBlock(block, state, pindex, coins)) {
|
||||||
|
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 VerifyDBResult::SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
|
LogPrintf("Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions);
|
||||||
|
|
||||||
return true;
|
return VerifyDBResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
|
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
|
||||||
|
@ -349,12 +349,17 @@ bool HasValidProofOfWork(const std::vector<CBlockHeader>& headers, const Consens
|
|||||||
/** Return the sum of the work on a given set of headers */
|
/** Return the sum of the work on a given set of headers */
|
||||||
arith_uint256 CalculateHeadersWork(const std::vector<CBlockHeader>& headers);
|
arith_uint256 CalculateHeadersWork(const std::vector<CBlockHeader>& headers);
|
||||||
|
|
||||||
|
enum class VerifyDBResult {
|
||||||
|
SUCCESS,
|
||||||
|
CORRUPTED_BLOCK_DB,
|
||||||
|
};
|
||||||
|
|
||||||
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
|
/** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */
|
||||||
class CVerifyDB {
|
class CVerifyDB {
|
||||||
public:
|
public:
|
||||||
CVerifyDB();
|
CVerifyDB();
|
||||||
~CVerifyDB();
|
~CVerifyDB();
|
||||||
bool VerifyDB(
|
[[nodiscard]] VerifyDBResult VerifyDB(
|
||||||
Chainstate& chainstate,
|
Chainstate& chainstate,
|
||||||
const Consensus::Params& consensus_params,
|
const Consensus::Params& consensus_params,
|
||||||
CCoinsView& coinsview,
|
CCoinsView& coinsview,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user