Skip to content

Commit e9b9566

Browse files
committed
Merge bitcoin/bitcoin#31046: init: Some small chainstate load improvements
31cc500 init: Return fatal failure on snapshot validation failure (Martin Zumsande) 8f1246e init: Improve chainstate init db error messages (TheCharlatan) cd09304 init: Remove incorrect comment about shutdown condition (MarcoFalke) 635e9f8 init: Remove misleading log line when user chooses not to retry (TheCharlatan) 720ce88 init: Improve comment describing chainstate load retry behaviour (Martin Zumsande) baea842 init: Remove unneeded argument for mempool_opts checks (stickies-v) Pull request description: These are mostly followups from #30968, making the code, log lines, error messages, and comments more consistent. The last commit is an attempt at improving the error reporting when loading the chainstate. It aims to more cleanly distinguish between errors arising from a specific database, and errors where the culprit may be less clear. ACKs for top commit: achow101: ACK 31cc500 mzumsande: Code Review / lightly tested ACK 31cc500 BrandonOdiwuor: Code Review ACK 31cc500. stickies-v: ACK 31cc500 Tree-SHA512: 59fba4845ee45a3d91bf55807ae6b1c81458463b96bf664c8b1badfac503f6b01efd52a915fc399294e68a3f69985362a5a10a3844fa23f7707145ebe9ad349b
2 parents b8c821c + 31cc500 commit e9b9566

File tree

3 files changed

+27
-21
lines changed

3 files changed

+27
-21
lines changed

src/init.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,9 +1062,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
10621062
if (!blockman_result) {
10631063
return InitError(util::ErrorString(blockman_result));
10641064
}
1065-
CTxMemPool::Options mempool_opts{
1066-
.check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
1067-
};
1065+
CTxMemPool::Options mempool_opts{};
10681066
auto mempool_result{ApplyArgsManOptions(args, chainparams, mempool_opts)};
10691067
if (!mempool_result) {
10701068
return InitError(util::ErrorString(mempool_result));
@@ -1173,7 +1171,7 @@ bool CheckHostPortOptions(const ArgsManager& args) {
11731171
return true;
11741172
}
11751173

1176-
// A GUI user may opt to retry once if there is a failure during chainstate initialization.
1174+
// A GUI user may opt to retry once with do_reindex set if there is a failure during chainstate initialization.
11771175
// The function therefore has to support re-entry.
11781176
static ChainstateLoadResult InitAndLoadChainstate(
11791177
NodeContext& node,
@@ -1253,7 +1251,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
12531251
return f();
12541252
} catch (const std::exception& e) {
12551253
LogError("%s\n", e.what());
1256-
return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database"));
1254+
return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error loading databases"));
12571255
}
12581256
};
12591257
auto [status, error] = catch_exceptions([&] { return LoadChainstate(chainman, cache_sizes, options); });
@@ -1634,11 +1632,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
16341632
if (status == ChainstateLoadStatus::FAILURE && !do_reindex && !ShutdownRequested(node)) {
16351633
// suggest a reindex
16361634
bool do_retry = uiInterface.ThreadSafeQuestion(
1637-
error + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
1635+
error + Untranslated(".\n\n") + _("Do you want to rebuild the databases now?"),
16381636
error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
16391637
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
16401638
if (!do_retry) {
1641-
LogError("Aborted block database rebuild. Exiting.\n");
16421639
return false;
16431640
}
16441641
do_reindex = true;
@@ -1658,7 +1655,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
16581655

16591656
// As LoadBlockIndex can take several minutes, it's possible the user
16601657
// requested to kill the GUI during the last operation. If so, exit.
1661-
// As the program has not fully started yet, Shutdown() is possibly overkill.
16621658
if (ShutdownRequested(node)) {
16631659
LogPrintf("Shutdown requested. Exiting.\n");
16641660
return false;

src/node/chainstate.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,17 @@ static ChainstateLoadResult CompleteChainstateInitialization(
4141
// new BlockTreeDB tries to delete the existing file, which
4242
// fails if it's still open from the previous loop. Close it first:
4343
pblocktree.reset();
44-
pblocktree = std::make_unique<BlockTreeDB>(DBParams{
45-
.path = chainman.m_options.datadir / "blocks" / "index",
46-
.cache_bytes = static_cast<size_t>(cache_sizes.block_tree_db),
47-
.memory_only = options.block_tree_db_in_memory,
48-
.wipe_data = options.wipe_block_tree_db,
49-
.options = chainman.m_options.block_tree_db});
44+
try {
45+
pblocktree = std::make_unique<BlockTreeDB>(DBParams{
46+
.path = chainman.m_options.datadir / "blocks" / "index",
47+
.cache_bytes = static_cast<size_t>(cache_sizes.block_tree_db),
48+
.memory_only = options.block_tree_db_in_memory,
49+
.wipe_data = options.wipe_block_tree_db,
50+
.options = chainman.m_options.block_tree_db});
51+
} catch (dbwrapper_error& err) {
52+
LogError("%s\n", err.what());
53+
return {ChainstateLoadStatus::FAILURE, _("Error opening block database")};
54+
}
5055

5156
if (options.wipe_block_tree_db) {
5257
pblocktree->WriteReindexing(true);
@@ -107,10 +112,15 @@ static ChainstateLoadResult CompleteChainstateInitialization(
107112
for (Chainstate* chainstate : chainman.GetAll()) {
108113
LogPrintf("Initializing chainstate %s\n", chainstate->ToString());
109114

110-
chainstate->InitCoinsDB(
111-
/*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction,
112-
/*in_memory=*/options.coins_db_in_memory,
113-
/*should_wipe=*/options.wipe_chainstate_db);
115+
try {
116+
chainstate->InitCoinsDB(
117+
/*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction,
118+
/*in_memory=*/options.coins_db_in_memory,
119+
/*should_wipe=*/options.wipe_chainstate_db);
120+
} catch (dbwrapper_error& err) {
121+
LogError("%s\n", err.what());
122+
return {ChainstateLoadStatus::FAILURE, _("Error opening coins database")};
123+
}
114124

115125
if (options.coins_error_cb) {
116126
chainstate->CoinsErrorCatcher().AddReadErrCallback(options.coins_error_cb);
@@ -236,7 +246,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
236246
return {init_status, init_error};
237247
}
238248
} else {
239-
return {ChainstateLoadStatus::FAILURE, _(
249+
return {ChainstateLoadStatus::FAILURE_FATAL, _(
240250
"UTXO snapshot failed to validate. "
241251
"Restart to resume normal initial block download, or try loading a different snapshot.")};
242252
}

test/functional/feature_init.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ def check_clean_start():
100100

101101
files_to_delete = {
102102
'blocks/index/*.ldb': 'Error opening block database.',
103-
'chainstate/*.ldb': 'Error opening block database.',
103+
'chainstate/*.ldb': 'Error opening coins database.',
104104
'blocks/blk*.dat': 'Error loading block database.',
105105
}
106106

107107
files_to_perturb = {
108108
'blocks/index/*.ldb': 'Error loading block database.',
109-
'chainstate/*.ldb': 'Error opening block database.',
109+
'chainstate/*.ldb': 'Error opening coins database.',
110110
'blocks/blk*.dat': 'Corrupted block database detected.',
111111
}
112112

0 commit comments

Comments
 (0)