diff --git a/src/init.cpp b/src/init.cpp index 5b486854e0..b24ae8606a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1502,6 +1502,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) options.prune = chainman.m_blockman.IsPruneMode(); options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_level = args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL); + options.require_full_verification = args.IsArgSet("-checkblocks") || args.IsArgSet("-checklevel"); options.check_interrupt = ShutdownRequested; options.coins_error_cb = [] { uiInterface.ThreadSafeMessageBox( @@ -1533,7 +1534,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } } - if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB) { + if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB || status == node::ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE) { return InitError(error); } diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 7d6e0f3bb0..c521b20b2a 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -197,6 +197,11 @@ ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const C break; case VerifyDBResult::CORRUPTED_BLOCK_DB: return {ChainstateLoadStatus::FAILURE, _("Corrupted block database detected")}; + case VerifyDBResult::SKIPPED_L3_CHECKS: + if (options.require_full_verification) { + return {ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE, _("Insufficient dbcache for block verification")}; + } + break; } // no default case, so the compiler can warn about missing cases } } diff --git a/src/node/chainstate.h b/src/node/chainstate.h index d3c7656bf2..7838a62d0c 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -25,6 +25,7 @@ struct ChainstateLoadOptions { bool reindex{false}; bool reindex_chainstate{false}; bool prune{false}; + bool require_full_verification{true}; int64_t check_blocks{DEFAULT_CHECKBLOCKS}; int64_t check_level{DEFAULT_CHECKLEVEL}; std::function check_interrupt; @@ -35,7 +36,13 @@ struct ChainstateLoadOptions { //! case, and treat other cases as errors. More complex applications may want to //! try reindexing in the generic failure case, and pass an interrupt callback //! and exit cleanly in the interrupted case. -enum class ChainstateLoadStatus { SUCCESS, FAILURE, FAILURE_INCOMPATIBLE_DB, INTERRUPTED }; +enum class ChainstateLoadStatus { + SUCCESS, + FAILURE, + FAILURE_INCOMPATIBLE_DB, + FAILURE_INSUFFICIENT_DBCACHE, + INTERRUPTED, +}; //! Chainstate load status code and optional error string. using ChainstateLoadResult = std::tuple; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index e2a1efea55..28a619fe54 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1110,7 +1110,7 @@ static RPCHelpMan verifychain() {"nblocks", RPCArg::Type::NUM, RPCArg::DefaultHint{strprintf("%d, 0=all", DEFAULT_CHECKBLOCKS)}, "The number of blocks to check."}, }, RPCResult{ - RPCResult::Type::BOOL, "", "Verified or not"}, + RPCResult::Type::BOOL, "", "Verification finished successfully. If false, check debug.log for reason."}, RPCExamples{ HelpExampleCli("verifychain", "") + HelpExampleRpc("verifychain", "") diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 6e72f69968..0b347d3141 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -218,6 +218,7 @@ void TestingSetup::LoadVerifyActivateChainstate() options.prune = chainman.m_blockman.IsPruneMode(); options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL); + options.require_full_verification = m_args.IsArgSet("-checkblocks") || m_args.IsArgSet("-checklevel"); auto [status, error] = LoadChainstate(chainman, m_cache_sizes, options); assert(status == node::ChainstateLoadStatus::SUCCESS); diff --git a/src/validation.cpp b/src/validation.cpp index 5a6db2674d..4da52b7d8b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4185,6 +4185,9 @@ VerifyDBResult CVerifyDB::VerifyDB( LogPrintf("Verification: No coin database inconsistencies in last %i blocks (%i transactions)\n", block_count, nGoodTransactions); + if (skipped_l3_checks) { + return VerifyDBResult::SKIPPED_L3_CHECKS; + } return VerifyDBResult::SUCCESS; } diff --git a/src/validation.h b/src/validation.h index a9977e76e3..044b4ef823 100644 --- a/src/validation.h +++ b/src/validation.h @@ -353,6 +353,7 @@ enum class VerifyDBResult { SUCCESS, CORRUPTED_BLOCK_DB, INTERRUPTED, + SKIPPED_L3_CHECKS, }; /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */