@@ -108,8 +108,6 @@ using kernel::DumpMempool;
108108
109109using node::CacheSizes;
110110using node::CalculateCacheSizes;
111- using node::ChainstateLoadVerifyError;
112- using node::ChainstateLoadingError;
113111using node::DEFAULT_PERSIST_MEMPOOL;
114112using node::DEFAULT_PRINTPRIORITY;
115113using node::DEFAULT_STOPAFTERBLOCKIMPORT;
@@ -1098,21 +1096,8 @@ static bool LockDataDirectory(bool probeOnly)
10981096bool AppInitSanityChecks (const kernel::Context& kernel)
10991097{
11001098 // ********************************************************* Step 4: sanity checks
1101- auto maybe_error = kernel::SanityChecks (kernel);
1102-
1103- if (maybe_error.has_value ()) {
1104- switch (maybe_error.value ()) {
1105- case kernel::SanityCheckError::ERROR_ECC:
1106- InitError (Untranslated (" Elliptic curve cryptography sanity check failure. Aborting." ));
1107- break ;
1108- case kernel::SanityCheckError::ERROR_RANDOM:
1109- InitError (Untranslated (" OS cryptographic RNG sanity check failure. Aborting." ));
1110- break ;
1111- case kernel::SanityCheckError::ERROR_CHRONO:
1112- InitError (Untranslated (" Clock epoch mismatch. Aborting." ));
1113- break ;
1114- } // no default case, so the compiler can warn about missing cases
1115-
1099+ if (auto error = kernel::SanityChecks (kernel)) {
1100+ InitError (*error);
11161101 return InitError (strprintf (_ (" Initialization sanity check failed. %s is shutting down." ), PACKAGE_NAME));
11171102 }
11181103
@@ -1452,112 +1437,54 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14521437 node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
14531438 ChainstateManager& chainman = *node.chainman ;
14541439
1455- const bool fReset = fReindex ;
1456- bilingual_str strLoadError;
1440+ node::ChainstateLoadOptions options;
1441+ options.mempool = Assert (node.mempool .get ());
1442+ options.reindex = node::fReindex ;
1443+ options.reindex_chainstate = fReindexChainState ;
1444+ options.prune = node::fPruneMode ;
1445+ options.check_blocks = args.GetIntArg (" -checkblocks" , DEFAULT_CHECKBLOCKS);
1446+ options.check_level = args.GetIntArg (" -checklevel" , DEFAULT_CHECKLEVEL);
1447+ options.check_interrupt = ShutdownRequested;
1448+ options.coins_error_cb = [] {
1449+ uiInterface.ThreadSafeMessageBox (
1450+ _ (" Error reading from database, shutting down." ),
1451+ " " , CClientUIInterface::MSG_ERROR);
1452+ };
14571453
14581454 uiInterface.InitMessage (_ (" Loading block index…" ).translated );
14591455 const int64_t load_block_index_start_time = GetTimeMillis ();
1460- std::optional<ChainstateLoadingError> maybe_load_error;
1461- try {
1462- maybe_load_error = LoadChainstate (fReset ,
1463- chainman,
1464- Assert (node.mempool .get ()),
1465- fPruneMode ,
1466- fReindexChainState ,
1467- cache_sizes.block_tree_db ,
1468- cache_sizes.coins_db ,
1469- cache_sizes.coins ,
1470- /* block_tree_db_in_memory=*/ false ,
1471- /* coins_db_in_memory=*/ false ,
1472- /* shutdown_requested=*/ ShutdownRequested,
1473- /* coins_error_cb=*/ []() {
1474- uiInterface.ThreadSafeMessageBox (
1475- _ (" Error reading from database, shutting down." ),
1476- " " , CClientUIInterface::MSG_ERROR);
1477- });
1478- } catch (const std::exception& e) {
1479- LogPrintf (" %s\n " , e.what ());
1480- maybe_load_error = ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED;
1481- }
1482- if (maybe_load_error.has_value ()) {
1483- switch (maybe_load_error.value ()) {
1484- case ChainstateLoadingError::ERROR_LOADING_BLOCK_DB:
1485- strLoadError = _ (" Error loading block database" );
1486- break ;
1487- case ChainstateLoadingError::ERROR_BAD_GENESIS_BLOCK:
1488- // If the loaded chain has a wrong genesis, bail out immediately
1489- // (we're likely using a testnet datadir, or the other way around).
1490- return InitError (_ (" Incorrect or no genesis block found. Wrong datadir for network?" ));
1491- case ChainstateLoadingError::ERROR_PRUNED_NEEDS_REINDEX:
1492- strLoadError = _ (" You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain" );
1493- break ;
1494- case ChainstateLoadingError::ERROR_LOAD_GENESIS_BLOCK_FAILED:
1495- strLoadError = _ (" Error initializing block database" );
1496- break ;
1497- case ChainstateLoadingError::ERROR_CHAINSTATE_UPGRADE_FAILED:
1498- return InitError (_ (" Unsupported chainstate database format found. "
1499- " Please restart with -reindex-chainstate. This will "
1500- " rebuild the chainstate database." ));
1501- case ChainstateLoadingError::ERROR_REPLAYBLOCKS_FAILED:
1502- strLoadError = _ (" Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate." );
1503- break ;
1504- case ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED:
1505- strLoadError = _ (" Error initializing block database" );
1506- break ;
1507- case ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED:
1508- strLoadError = _ (" Error opening block database" );
1509- break ;
1510- case ChainstateLoadingError::ERROR_BLOCKS_WITNESS_INSUFFICIENTLY_VALIDATED:
1511- strLoadError = strprintf (_ (" Witness data for blocks after height %d requires validation. Please restart with -reindex." ),
1512- chainman.GetConsensus ().SegwitHeight );
1513- break ;
1514- case ChainstateLoadingError::SHUTDOWN_PROBED:
1515- break ;
1516- }
1517- } else {
1518- std::optional<ChainstateLoadVerifyError> maybe_verify_error;
1456+ auto catch_exceptions = [](auto && f) {
15191457 try {
1520- uiInterface.InitMessage (_ (" Verifying blocks…" ).translated );
1521- auto check_blocks = args.GetIntArg (" -checkblocks" , DEFAULT_CHECKBLOCKS);
1522- if (chainman.m_blockman .m_have_pruned && check_blocks > MIN_BLOCKS_TO_KEEP) {
1523- LogPrintfCategory (BCLog::PRUNE, " pruned datadir may not have more than %d blocks; only checking available blocks\n " ,
1524- MIN_BLOCKS_TO_KEEP);
1525- }
1526- maybe_verify_error = VerifyLoadedChainstate (chainman,
1527- fReset ,
1528- fReindexChainState ,
1529- check_blocks,
1530- args.GetIntArg (" -checklevel" , DEFAULT_CHECKLEVEL));
1458+ return f ();
15311459 } catch (const std::exception& e) {
15321460 LogPrintf (" %s\n " , e.what ());
1533- maybe_verify_error = ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE ;
1461+ return std::make_tuple (node::ChainstateLoadStatus::FAILURE, _ ( " Error opening block database " )) ;
15341462 }
1535- if (maybe_verify_error.has_value ()) {
1536- switch (maybe_verify_error.value ()) {
1537- case ChainstateLoadVerifyError::ERROR_BLOCK_FROM_FUTURE:
1538- strLoadError = _ (" The block database contains a block which appears to be from the future. "
1539- " This may be due to your computer's date and time being set incorrectly. "
1540- " Only rebuild the block database if you are sure that your computer's date and time are correct" );
1541- break ;
1542- case ChainstateLoadVerifyError::ERROR_CORRUPTED_BLOCK_DB:
1543- strLoadError = _ (" Corrupted block database detected" );
1544- break ;
1545- case ChainstateLoadVerifyError::ERROR_GENERIC_FAILURE:
1546- strLoadError = _ (" Error opening block database" );
1547- break ;
1548- }
1549- } else {
1463+ };
1464+ auto [status, error] = catch_exceptions ([&]{ return LoadChainstate (chainman, cache_sizes, options); });
1465+ if (status == node::ChainstateLoadStatus::SUCCESS) {
1466+ uiInterface.InitMessage (_ (" Verifying blocks…" ).translated );
1467+ if (chainman.m_blockman .m_have_pruned && options.check_blocks > MIN_BLOCKS_TO_KEEP) {
1468+ LogPrintfCategory (BCLog::PRUNE, " pruned datadir may not have more than %d blocks; only checking available blocks\n " ,
1469+ MIN_BLOCKS_TO_KEEP);
1470+ }
1471+ std::tie (status, error) = catch_exceptions ([&]{ return VerifyLoadedChainstate (chainman, options);});
1472+ if (status == node::ChainstateLoadStatus::SUCCESS) {
15501473 fLoaded = true ;
15511474 LogPrintf (" block index %15dms\n " , GetTimeMillis () - load_block_index_start_time);
15521475 }
15531476 }
15541477
1478+ if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB) {
1479+ return InitError (error);
1480+ }
1481+
15551482 if (!fLoaded && !ShutdownRequested ()) {
15561483 // first suggest a reindex
1557- if (!fReset ) {
1484+ if (!options. reindex ) {
15581485 bool fRet = uiInterface.ThreadSafeQuestion (
1559- strLoadError + Untranslated (" .\n\n " ) + _ (" Do you want to rebuild the block database now?" ),
1560- strLoadError .original + " .\n Please restart with -reindex or -reindex-chainstate to recover." ,
1486+ error + Untranslated (" .\n\n " ) + _ (" Do you want to rebuild the block database now?" ),
1487+ error .original + " .\n Please restart with -reindex or -reindex-chainstate to recover." ,
15611488 " " , CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
15621489 if (fRet ) {
15631490 fReindex = true ;
@@ -1567,7 +1494,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15671494 return false ;
15681495 }
15691496 } else {
1570- return InitError (strLoadError );
1497+ return InitError (error );
15711498 }
15721499 }
15731500 }
0 commit comments