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

Code before:
        }
    }

    // Check onion bindings
    for (const auto& onion_bind : conn_options.onion_binds) {
        if (!seen.insert(onion_bind).second) {
            return onion_bind;
        }
    }

    return std::nullopt;
}

// A GUI user may opt to retry once with do_reindex set if there is a failure during chainstate initialization.
// The function therefore has to support re-entry.
static ChainstateLoadResult InitAndLoadChainstate(
    NodeContext& node,
    bool do_reindex,
    const bool do_reindex_chainstate,
    const kernel::CacheSizes& cache_sizes,
    const ArgsManager& args)
{
    // This function may be called twice, so any dirty state must be reset.
    node.notifications->setChainstateLoaded(false); // Drop state, such as a cached tip block
    node.mempool.reset();
    node.chainman.reset(); // Drop state, such as an initialized m_block_tree_db

    const CChainParams& chainparams = Params();

    CTxMemPool::Options mempool_opts{
        .check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
        .signals = node.validation_signals.get(),
    };
    Assert(ApplyArgsManOptions(args, chainparams, mempool_opts)); // no error can happen, already checked in AppInitParameterInteraction
    bilingual_str mempool_error;
    Assert(!node.mempool); // Was reset above
    node.mempool = std::make_unique<CTxMemPool>(mempool_opts, mempool_error);
    if (!mempool_error.empty()) {
        return {ChainstateLoadStatus::FAILURE_FATAL, mempool_error};
    }
    LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)",
            cache_sizes.coins * (1.0 / 1024 / 1024),
            mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    ChainstateManager::Options chainman_opts{
        .chainparams = chainparams,
        .datadir = args.GetDataDirNet(),
        .notifications = *node.notifications,
        .signals = node.validation_signals.get(),
    };
    Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction


Review comment (bug):
In 0564f1e449e83ea875d64aff8f227fa1353a928d _ipc mining: Prevent ``Assertion `m_node.chainman' failed`` errors on early startup_: it seems a bit of an indirection to have `setChainstateLoaded` be responsible for "any dirty state must be reset".

In practice it's trivial, for now.

I think it would be good to have a prep commit that introduces `setChainstateLoaded` (or a a reset helper function). Its commit message could explain why e.g. it's safe to drop `ReadNotificationArgs` below.

Code after:
        if (!seen.insert(bind).second) {
            return bind;
        }
    }

    // Check onion bindings
    for (const auto& onion_bind : conn_options.onion_binds) {
        if (!seen.insert(onion_bind).second) {
            return onion_bind;
        }
    }

    return std::nullopt;
}

// A GUI user may opt to retry once with do_reindex set if there is a failure during chainstate initialization.
// The function therefore has to support re-entry.
static ChainstateLoadResult InitAndLoadChainstate(
    NodeContext& node,
    bool do_reindex,
    const bool do_reindex_chainstate,
    const kernel::CacheSizes& cache_sizes,
    const ArgsManager& args)
{
    // This function may be called twice, so any dirty state must be reset.
    node.notifications->setChainstateLoaded(false); // Drop state, such as a cached tip block
    node.mempool.reset();
    node.chainman.reset(); // Drop state, such as an initialized m_block_tree_db

    const CChainParams& chainparams = Params();

    CTxMemPool::Options mempool_opts{
        .check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
        .signals = node.validation_signals.get(),
    };
    Assert(ApplyArgsManOptions(args, chainparams, mempool_opts)); // no error can happen, already checked in AppInitParameterInteraction
    bilingual_str mempool_error;
    Assert(!node.mempool); // Was reset above
    node.mempool = std::make_unique<CTxMemPool>(mempool_opts, mempool_error);
    if (!mempool_error.empty()) {
        return {ChainstateLoadStatus::FAILURE_FATAL, mempool_error};
    }
    LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)",
            cache_sizes.coins * (1.0 / 1024 / 1024),
            mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
    ChainstateManager::Options chainman_opts{
        .chainparams = chainparams,
        .datadir = args.GetDataDirNet(),
        .notifications = *node.notifications,
        .signals = node.validation_signals.get(),
    };