diff --git a/src/init.cpp b/src/init.cpp index 883f8fcb89a..7ca9c7b570e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1259,7 +1259,7 @@ static ChainstateLoadResult InitAndLoadChainstate( return f(); } catch (const std::exception& e) { LogError("%s\n", e.what()); - return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database")); + return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error loading databases")); } }; auto [status, error] = catch_exceptions([&] { return LoadChainstate(chainman, cache_sizes, options); }); @@ -1639,7 +1639,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) if (status == ChainstateLoadStatus::FAILURE && !do_reindex && !ShutdownRequested(node)) { // suggest a reindex bool do_retry = uiInterface.ThreadSafeQuestion( - error + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"), + error + Untranslated(".\n\n") + _("Do you want to rebuild the databases now?"), error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); if (!do_retry) { diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index d7e6176be1e..b3b215929a6 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -41,12 +41,17 @@ static ChainstateLoadResult CompleteChainstateInitialization( // new BlockTreeDB tries to delete the existing file, which // fails if it's still open from the previous loop. Close it first: pblocktree.reset(); - pblocktree = std::make_unique(DBParams{ - .path = chainman.m_options.datadir / "blocks" / "index", - .cache_bytes = static_cast(cache_sizes.block_tree_db), - .memory_only = options.block_tree_db_in_memory, - .wipe_data = options.wipe_block_tree_db, - .options = chainman.m_options.block_tree_db}); + try { + pblocktree = std::make_unique(DBParams{ + .path = chainman.m_options.datadir / "blocks" / "index", + .cache_bytes = static_cast(cache_sizes.block_tree_db), + .memory_only = options.block_tree_db_in_memory, + .wipe_data = options.wipe_block_tree_db, + .options = chainman.m_options.block_tree_db}); + } catch (dbwrapper_error& err) { + LogError("%s\n", err.what()); + return {ChainstateLoadStatus::FAILURE, _("Error opening block database")}; + } if (options.wipe_block_tree_db) { pblocktree->WriteReindexing(true); @@ -107,10 +112,15 @@ static ChainstateLoadResult CompleteChainstateInitialization( for (Chainstate* chainstate : chainman.GetAll()) { LogPrintf("Initializing chainstate %s\n", chainstate->ToString()); - chainstate->InitCoinsDB( - /*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction, - /*in_memory=*/options.coins_db_in_memory, - /*should_wipe=*/options.wipe_chainstate_db); + try { + chainstate->InitCoinsDB( + /*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction, + /*in_memory=*/options.coins_db_in_memory, + /*should_wipe=*/options.wipe_chainstate_db); + } catch (dbwrapper_error& err) { + LogError("%s\n", err.what()); + return {ChainstateLoadStatus::FAILURE, _("Error opening coins database")}; + } if (options.coins_error_cb) { chainstate->CoinsErrorCatcher().AddReadErrCallback(options.coins_error_cb); diff --git a/test/functional/feature_init.py b/test/functional/feature_init.py index 659d33684e5..a841052efb2 100755 --- a/test/functional/feature_init.py +++ b/test/functional/feature_init.py @@ -97,13 +97,13 @@ class InitStressTest(BitcoinTestFramework): files_to_delete = { 'blocks/index/*.ldb': 'Error opening block database.', - 'chainstate/*.ldb': 'Error opening block database.', + 'chainstate/*.ldb': 'Error opening coins database.', 'blocks/blk*.dat': 'Error loading block database.', } files_to_perturb = { 'blocks/index/*.ldb': 'Error loading block database.', - 'chainstate/*.ldb': 'Error opening block database.', + 'chainstate/*.ldb': 'Error opening coins database.', 'blocks/blk*.dat': 'Corrupted block database detected.', }