Repository: bitcoin/bitcoin
File: src/init.cpp (C++)

Code before:
    CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());

    LogPrintf("Cache configuration:\n");
    LogPrintf("* Using %.1f MiB for block index database\n", cache_sizes.block_tree_db * (1.0 / 1024 / 1024));
    if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
        LogPrintf("* Using %.1f MiB for transaction index database\n", cache_sizes.tx_index * (1.0 / 1024 / 1024));
    }
    for (BlockFilterType filter_type : g_enabled_filter_types) {
        LogPrintf("* Using %.1f MiB for %s block filter index database\n",
                  cache_sizes.filter_index * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type));
    }
    LogPrintf("* Using %.1f MiB for chain state database\n", cache_sizes.coins_db * (1.0 / 1024 / 1024));

    assert(!node.mempool);
    assert(!node.chainman);

    bool do_reindex{args.GetBoolArg("-reindex", false)};
    const bool do_reindex_chainstate{args.GetBoolArg("-reindex-chainstate", false)};

    for (bool fLoaded = false; !fLoaded && !ShutdownRequested(node);) {
        auto [status, error] = InitAndLoadChainstate(
            node,
            do_reindex,
            do_reindex_chainstate,
            cache_sizes,
            args);

        if (status == node::ChainstateLoadStatus::FAILURE_FATAL || status == node::ChainstateLoadStatus::FAILURE_INCOMPATIBLE_DB || status == node::ChainstateLoadStatus::FAILURE_INSUFFICIENT_DBCACHE) {
            return InitError(error);
        }

        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.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
                    "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
                if (fRet) {
                    do_reindex = true;
                    if (!Assert(node.shutdown)->reset()) {
                        LogError("Internal error: failed to reset shutdown signal.\n");
                    }
                } else {
                    LogError("Aborted block database rebuild. Exiting.\n");
                    return false;
                }

Review comment (performance):
Not important, for but both of the InitAndLoadChainstate calls in this PR, I'm surprised someone would prefer newline separated arguments over space separated:

```c++
InitAndLoadChainstate(node, do_reindex, do_reindex_chainstate, cache_sizes, args);
```

clang-format has a nice "BinPack" and "Align" options for packing arguments neatly without having to take up large amounts of space

Code after:
    CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());

    LogPrintf("Cache configuration:\n");
    LogPrintf("* Using %.1f MiB for block index database\n", cache_sizes.block_tree_db * (1.0 / 1024 / 1024));
    if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
        LogPrintf("* Using %.1f MiB for transaction index database\n", cache_sizes.tx_index * (1.0 / 1024 / 1024));
    }
    for (BlockFilterType filter_type : g_enabled_filter_types) {
        LogPrintf("* Using %.1f MiB for %s block filter index database\n",
                  cache_sizes.filter_index * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type));
    }
    LogPrintf("* Using %.1f MiB for chain state database\n", cache_sizes.coins_db * (1.0 / 1024 / 1024));

    assert(!node.mempool);
    assert(!node.chainman);

    bool do_reindex{args.GetBoolArg("-reindex", false)};
    const bool do_reindex_chainstate{args.GetBoolArg("-reindex-chainstate", false)};

    // Chainstate initialization and loading may be retried once with reindexing by GUI users
    auto [status, error] = InitAndLoadChainstate(
        node,
        do_reindex,
        do_reindex_chainstate,
        cache_sizes,
        args);
    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.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
            "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
        if (!do_retry) {
            LogError("Aborted block database rebuild. Exiting.\n");
            return false;
        }
        do_reindex = true;
        if (!Assert(node.shutdown)->reset()) {
            LogError("Internal error: failed to reset shutdown signal.\n");
        }
        std::tie(status, error) = InitAndLoadChainstate(
            node,
            do_reindex,
            do_reindex_chainstate,
            cache_sizes,
            args);
    }
    if (status != ChainstateLoadStatus::SUCCESS && status != ChainstateLoadStatus::INTERRUPTED) {
        return InitError(error);
    }