@@ -157,8 +157,6 @@ using kernel::DumpMempool;
157157
158158using node::CacheSizes;
159159using node::CalculateCacheSizes;
160- using node::ChainstateLoadingError;
161- using node::ChainstateLoadVerifyError;
162160using node::DashChainstateSetupClose;
163161using node::DEFAULT_PERSIST_MEMPOOL ;
164162using node::DEFAULT_PRINTPRIORITY ;
@@ -1474,21 +1472,8 @@ static bool LockDataDirectory(bool probeOnly)
14741472bool AppInitSanityChecks (const kernel::Context& kernel)
14751473{
14761474 // ********************************************************* Step 4: sanity checks
1477- auto maybe_error = kernel::SanityChecks (kernel);
1478-
1479- if (maybe_error.has_value ()) {
1480- switch (maybe_error.value ()) {
1481- case kernel::SanityCheckError::ERROR_ECC :
1482- InitError (Untranslated (" Elliptic curve cryptography sanity check failure. Aborting." ));
1483- break ;
1484- case kernel::SanityCheckError::ERROR_BLS :
1485- InitError (Untranslated (" BLS cryptographic sanity check failure. Aborting." ));
1486- break ;
1487- case kernel::SanityCheckError::ERROR_RANDOM :
1488- InitError (Untranslated (" OS cryptographic RNG sanity check failure. Aborting." ));
1489- break ;
1490- } // no default case, so the compiler can warn about missing cases
1491-
1475+ if (auto error = kernel::SanityChecks (kernel)) {
1476+ InitError (*error);
14921477 return InitError (strprintf (_ (" Initialization sanity check failed. %s is shutting down." ), PACKAGE_NAME ));
14931478 }
14941479
@@ -2036,147 +2021,84 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
20362021 */
20372022 node.mn_sync = std::make_unique<CMasternodeSync>(std::make_unique<NodeSyncNotifierImpl>(*node.connman , *node.netfulfilledman ));
20382023
2039- const bool fReset = fReindex ;
20402024 bilingual_str strLoadError;
20412025
2026+ node::ChainstateLoadOptions options;
2027+ options.mempool = Assert (node.mempool .get ());
2028+ options.reindex = node::fReindex ;
2029+ options.reindex_chainstate = fReindexChainState ;
2030+ options.prune = node::fPruneMode ;
2031+ options.bls_threads = [&args]() -> int8_t {
2032+ int64_t threads = args.GetIntArg (" -parbls" , llmq::DEFAULT_BLSCHECK_THREADS );
2033+ if (threads <= 0 ) {
2034+ // -parbls=0 means autodetect (number of cores - 1 validator threads)
2035+ // -parbls=-n means "leave n cores free" (number of cores - n - 1 validator threads)
2036+ threads += GetNumCores ();
2037+ }
2038+ // Subtract 1 because the main thread counts towards the par threads
2039+ const int64_t adjusted_threads = std::clamp<int64_t >(threads, 1 , int64_t {llmq::MAX_BLSCHECK_THREADS } + 1 ) - 1 ;
2040+ return static_cast <int8_t >(adjusted_threads);
2041+ }();
2042+ options.worker_count = llmq::DEFAULT_WORKER_COUNT ;
2043+ options.max_recsigs_age = args.GetIntArg (" -maxrecsigsage" , llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE );
2044+ options.check_blocks = args.GetIntArg (" -checkblocks" , DEFAULT_CHECKBLOCKS );
2045+ options.check_level = args.GetIntArg (" -checklevel" , DEFAULT_CHECKLEVEL );
2046+ options.check_interrupt = ShutdownRequested;
2047+ options.coins_error_cb = [] {
2048+ uiInterface.ThreadSafeMessageBox (
2049+ _ (" Error reading from database, shutting down." ),
2050+ " " , CClientUIInterface::MSG_ERROR );
2051+ };
2052+ options.notify_bls_state = [](bool bls_state) {
2053+ LogPrintf (" %s: bls_legacy_scheme=%d\n " , __func__, bls_state);
2054+ };
2055+
20422056 uiInterface.InitMessage (_ (" Loading block index…" ).translated );
20432057 const auto load_block_index_start_time{SteadyClock::now ()};
2044- std::optional<ChainstateLoadingError> maybe_load_error;
2045- try {
2046- maybe_load_error = LoadChainstate (fReset ,
2047- chainman,
2048- *node.mn_metaman ,
2049- *node.sporkman ,
2050- *node.chainlocks ,
2051- *node.mn_sync ,
2052- node.chain_helper ,
2053- node.dmnman ,
2054- node.evodb ,
2055- node.llmq_ctx ,
2056- Assert (node.mempool .get ()),
2057- args.GetDataDirNet (),
2058- fPruneMode ,
2059- fReindexChainState ,
2060- cache_sizes.block_tree_db ,
2061- cache_sizes.coins_db ,
2062- cache_sizes.coins ,
2063- /* block_tree_db_in_memory=*/ false ,
2064- /* coins_db_in_memory=*/ false ,
2065- /* dash_dbs_in_memory=*/ false ,
2066- /* bls_threads=*/ [&args]() -> int8_t {
2067- int64_t threads = args.GetIntArg (" -parbls" , llmq::DEFAULT_BLSCHECK_THREADS );
2068- if (threads <= 0 ) {
2069- // -parbls=0 means autodetect (number of cores - 1 validator threads)
2070- // -parbls=-n means "leave n cores free" (number of cores - n - 1 validator threads)
2071- threads += GetNumCores ();
2072- }
2073- // Subtract 1 because the main thread counts towards the par threads
2074- const int64_t adjusted_threads = std::clamp<int64_t >(
2075- threads, 1 , int64_t {llmq::MAX_BLSCHECK_THREADS } + 1 ) - 1 ;
2076- return static_cast <int8_t >(adjusted_threads);
2077- }(),
2078- llmq::DEFAULT_WORKER_COUNT ,
2079- args.GetIntArg (" -maxrecsigsage" , llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE ),
2080- /* shutdown_requested=*/ ShutdownRequested,
2081- /* coins_error_cb=*/ []() {
2082- uiInterface.ThreadSafeMessageBox (
2083- _ (" Error reading from database, shutting down." ),
2084- " " , CClientUIInterface::MSG_ERROR );
2085- });
2086- } catch (const std::exception& e) {
2087- LogPrintf (" %s\n " , e.what ());
2088- maybe_load_error = ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED ;
2089- }
2090- if (maybe_load_error.has_value ()) {
2091- switch (maybe_load_error.value ()) {
2092- case ChainstateLoadingError::ERROR_LOADING_BLOCK_DB :
2093- strLoadError = _ (" Error loading block database" );
2094- break ;
2095- case ChainstateLoadingError::ERROR_BAD_GENESIS_BLOCK :
2096- // If the loaded chain has a wrong genesis, bail out immediately
2097- // (we're likely using a testnet datadir, or the other way around).
2098- return InitError (_ (" Incorrect or no genesis block found. Wrong datadir for network?" ));
2099- case ChainstateLoadingError::ERROR_BAD_DEVNET_GENESIS_BLOCK :
2100- return InitError (_ (" Incorrect or no devnet genesis block found. Wrong datadir for devnet specified?" ));
2101- case ChainstateLoadingError::ERROR_PRUNED_NEEDS_REINDEX :
2102- strLoadError = _ (" You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain" );
2103- break ;
2104- case ChainstateLoadingError::ERROR_LOAD_GENESIS_BLOCK_FAILED :
2105- strLoadError = _ (" Error initializing block database" );
2106- break ;
2107- case ChainstateLoadingError::ERROR_CHAINSTATE_UPGRADE_FAILED :
2108- return InitError (_ (" Unsupported chainstate database format found. "
2109- " Please restart with -reindex-chainstate. This will "
2110- " rebuild the chainstate database." ));
2111- case ChainstateLoadingError::ERROR_REPLAYBLOCKS_FAILED :
2112- strLoadError = _ (" Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate." );
2113- break ;
2114- case ChainstateLoadingError::ERROR_LOADCHAINTIP_FAILED :
2115- strLoadError = _ (" Error initializing block database" );
2116- break ;
2117- case ChainstateLoadingError::ERROR_GENERIC_BLOCKDB_OPEN_FAILED :
2118- strLoadError = _ (" Error opening block database" );
2119- break ;
2120- case ChainstateLoadingError::ERROR_COMMITING_EVO_DB :
2121- strLoadError = _ (" Failed to commit Evo database" );
2122- break ;
2123- case ChainstateLoadingError::ERROR_UPGRADING_EVO_DB :
2124- strLoadError = _ (" Failed to upgrade Evo database" );
2125- break ;
2126- case ChainstateLoadingError::ERROR_UPGRADING_SIGNALS_DB :
2127- strLoadError = _ (" Error upgrading evo database for EHF" );
2128- break ;
2129- case ChainstateLoadingError::SHUTDOWN_PROBED :
2130- break ;
2131- }
2132- } else {
2133- std::optional<ChainstateLoadVerifyError> maybe_verify_error;
2058+ auto catch_exceptions = [](auto && fn) -> node::ChainstateLoadResult {
21342059 try {
2135- uiInterface.InitMessage (_ (" Verifying blocks…" ).translated );
2136- auto check_blocks = args.GetIntArg (" -checkblocks" , DEFAULT_CHECKBLOCKS );
2137- if (chainman.m_blockman .m_have_pruned && check_blocks > MIN_BLOCKS_TO_KEEP ) {
2138- LogWarning (" pruned datadir may not have more than %d blocks; only checking available blocks\n " ,
2139- MIN_BLOCKS_TO_KEEP );
2140- }
2141- maybe_verify_error = VerifyLoadedChainstate (chainman,
2142- *Assert (node.evodb .get ()),
2143- fReset ,
2144- fReindexChainState ,
2145- check_blocks,
2146- args.GetIntArg (" -checklevel" , DEFAULT_CHECKLEVEL ),
2147- [](bool bls_state) {
2148- LogPrintf (" %s: bls_legacy_scheme=%d\n " , __func__, bls_state);
2149- });
2060+ return fn ();
21502061 } catch (const std::exception& e) {
21512062 LogPrintf (" %s\n " , e.what ());
2152- maybe_verify_error = ChainstateLoadVerifyError:: ERROR_GENERIC_FAILURE ;
2063+ return {node::ChainstateLoadStatus:: FAILURE , _ ( " Error opening block database " )} ;
21532064 }
2154- if (maybe_verify_error. has_value ()) {
2155- switch (maybe_verify_error. value ()) {
2156- case ChainstateLoadVerifyError:: ERROR_BLOCK_FROM_FUTURE :
2157- strLoadError = _ ( " The block database contains a block which appears to be from the future. "
2158- " This may be due to your computer's date and time being set incorrectly. "
2159- " Only rebuild the block database if you are sure that your computer's date and time are correct " );
2160- break ;
2161- case ChainstateLoadVerifyError:: ERROR_CORRUPTED_BLOCK_DB :
2162- strLoadError = _ ( " Corrupted block database detected " );
2163- break ;
2164- case ChainstateLoadVerifyError:: ERROR_EVO_DB_SANITY_FAILED :
2165- strLoadError = _ ( " Error initializing block database " );
2166- break ;
2167- case ChainstateLoadVerifyError:: ERROR_GENERIC_FAILURE :
2168- strLoadError = _ ( " Error opening block database " );
2169- break ;
2170- }
2171- } else {
2172- fLoaded = true ;
2173- LogPrintf ( " block index %15dms \n " , Ticks<std::chrono::milliseconds>( SteadyClock::now () - load_block_index_start_time) );
2065+ };
2066+ auto [status, error] = catch_exceptions ([&] {
2067+ return LoadChainstate (chainman,
2068+ *node. mn_metaman ,
2069+ *node. sporkman ,
2070+ *node. chainlocks ,
2071+ *node. mn_sync ,
2072+ node. chain_helper ,
2073+ node. dmnman ,
2074+ node. evodb ,
2075+ node. llmq_ctx ,
2076+ args. GetDataDirNet (),
2077+ cache_sizes,
2078+ options);
2079+ } );
2080+ if (status == node::ChainstateLoadStatus:: SUCCESS ) {
2081+ uiInterface. InitMessage ( _ ( " Verifying blocks… " ). translated );
2082+ if (chainman. m_blockman . m_have_pruned && options. check_blocks > MIN_BLOCKS_TO_KEEP ) {
2083+ LogWarning ( " pruned datadir may not have more than %d blocks; only checking available blocks \n " ,
2084+ MIN_BLOCKS_TO_KEEP );
21742085 }
2086+ std::tie (status, error) = catch_exceptions ([&] {
2087+ return VerifyLoadedChainstate (chainman, *Assert (node.evodb ), options);
2088+ });
2089+ }
2090+ if (status == node::ChainstateLoadStatus::SUCCESS ) {
2091+ fLoaded = true ;
2092+ LogPrintf (" block index %15dms\n " , Ticks<std::chrono::milliseconds>(SteadyClock::now () - load_block_index_start_time));
2093+ } else if (status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB ) {
2094+ return InitError (error);
2095+ } else {
2096+ strLoadError = error;
21752097 }
21762098
21772099 if (!fLoaded && !ShutdownRequested ()) {
21782100 // first suggest a reindex
2179- if (!fReset ) {
2101+ if (!options. reindex ) {
21802102 bool fRet = uiInterface.ThreadSafeQuestion (
21812103 strLoadError + Untranslated (" .\n\n " ) + _ (" Do you want to rebuild the block database now?" ),
21822104 strLoadError.original + " .\n Please restart with -reindex or -reindex-chainstate to recover." ,
0 commit comments