refactor: Replace init retry for loop with if statement

The for loop has been a long standing source of confusion and bugs, both
because its purpose is not clearly documented and because the body of
the for loop contains a lot of logic.

Co-Authored-By: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
TheCharlatan 2024-09-25 14:14:07 +02:00
parent c1d8870ea4
commit e9d60af988
No known key found for this signature in database
GPG key ID: 9B79B45691DB4173

View file

@ -1635,43 +1635,37 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
bool do_reindex{args.GetBoolArg("-reindex", false)}; bool do_reindex{args.GetBoolArg("-reindex", false)};
const bool do_reindex_chainstate{args.GetBoolArg("-reindex-chainstate", false)}; const bool do_reindex_chainstate{args.GetBoolArg("-reindex-chainstate", false)};
for (bool fLoaded = false; !fLoaded && !ShutdownRequested(node);) { // Chainstate initialization and loading may be retried once with reindexing by GUI users
auto [status, error] = InitAndLoadChainstate( auto [status, error] = InitAndLoadChainstate(
node, node,
do_reindex, do_reindex,
do_reindex_chainstate, do_reindex_chainstate,
cache_sizes, cache_sizes,
args); args);
if (status == ChainstateLoadStatus::FAILURE && !do_reindex && !ShutdownRequested(node)) {
if (status == node::ChainstateLoadStatus::FAILURE_FATAL || status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB || status == node::ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE) { // suggest a reindex
return InitError(error); bool do_retry = uiInterface.ThreadSafeQuestion(
}
if (status == ChainstateLoadStatus::SUCCESS) {
fLoaded = true;
}
if (!fLoaded && !ShutdownRequested(node)) {
// first suggest a reindex
if (!do_reindex) {
bool fRet = 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 block database now?"),
error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
if (fRet) { if (!do_retry) {
LogError("Aborted block database rebuild. Exiting.\n");
return false;
}
do_reindex = true; do_reindex = true;
if (!Assert(node.shutdown)->reset()) { if (!Assert(node.shutdown)->reset()) {
LogError("Internal error: failed to reset shutdown signal.\n"); LogError("Internal error: failed to reset shutdown signal.\n");
} }
} else { std::tie(status, error) = InitAndLoadChainstate(
LogError("Aborted block database rebuild. Exiting.\n"); node,
return false; do_reindex,
do_reindex_chainstate,
cache_sizes,
args);
} }
} else { if (status != ChainstateLoadStatus::SUCCESS && status != ChainstateLoadStatus::INTERRUPTED) {
return InitError(error); return InitError(error);
} }
}
}
// As LoadBlockIndex can take several minutes, it's possible the user // As LoadBlockIndex can take several minutes, it's possible the user
// requested to kill the GUI during the last operation. If so, exit. // requested to kill the GUI during the last operation. If so, exit.