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

Code before:
    }

    void FatalErrorHandler(std::string_view error) override
    {
        std::cout << error << std::endl;
    }
};

int main(int argc, char* argv[])
{
    // SETUP: Argument parsing and handling
    const bool has_regtest_flag{argc == 3 && std::string(argv[1]) == "-regtest"};
    if (argc < 2 || argc > 3 || (argc == 3 && !has_regtest_flag)) {
        std::cerr
            << "Usage: " << argv[0] << " [-regtest] DATADIR" << std::endl
            << "Display DATADIR information, and process hex-encoded blocks on standard input." << std::endl
            << "Uses mainnet parameters by default, regtest with -regtest flag" << std::endl
            << std::endl
            << "IMPORTANT: THIS EXECUTABLE IS EXPERIMENTAL, FOR TESTING ONLY, AND EXPECTED TO" << std::endl
            << "           BREAK IN FUTURE VERSIONS. DO NOT USE ON YOUR ACTUAL DATADIR." << std::endl;
        return 1;
    }
    std::filesystem::path abs_datadir{std::filesystem::absolute(argv[argc-1])};
    std::filesystem::create_directories(abs_datadir);

    btck_LoggingOptions logging_options = {
        .log_timestamps = true,
        .log_time_micros = false,
        .log_threadnames = false,
        .log_sourcelocations = false,
        .always_print_category_levels = true,
    };

    logging_set_options(logging_options);

    Logger logger{std::make_unique<KernelLog>()};

    ContextOptions options{};
    ChainParams params{has_regtest_flag ? ChainType::REGTEST : ChainType::MAINNET};
    options.SetChainParams(params);

    options.SetNotifications(std::make_shared<TestKernelNotifications>());
    options.SetValidationInterface(std::make_shared<TestValidationInterface>());

    Context context{options};

    ChainstateManagerOptions chainman_opts{context, abs_datadir.string(), (abs_datadir / "blocks").string()};
    chainman_opts.SetWorkerThreads(4);

    std::unique_ptr<ChainMan> chainman;
    try {

Review comment (suggestion):
I've been thinking lately whether we can reuse some of our own common utilities for these small, kernel-based applications. These small, single use applications should be able to use our usual utilities, while still benefiting from a clearer kernel interface. I think we are at a point now, where we can confidently mix between the two without risking introducing an entanglement regression between what the kernel requires and what new code might introduce in it. For this reason, I added some basic argument handling on my branch over here: https://github.com/sedited/bitcoin/tree/bitcoin_chainstate_args , that might be interesting for this change here.

Code after:
    void WarningSetHandler(Warning warning, std::string_view message) override
    {
        std::cout << message << std::endl;
    }

    void WarningUnsetHandler(Warning warning) override
    {
        std::cout << "Warning unset: " << static_cast<std::underlying_type_t<Warning>>(warning) << std::endl;
    }

    void FlushErrorHandler(std::string_view error) override
    {
        std::cout << error << std::endl;
    }

    void FatalErrorHandler(std::string_view error) override
    {
        std::cout << error << std::endl;
    }
};

int main(int argc, char* argv[])
{
    // SETUP: Argument parsing and handling
    const bool has_regtest_flag{argc == 3 && std::string(argv[1]) == "-regtest"};
    if (argc < 2 || argc > 3 || (argc == 3 && !has_regtest_flag)) {
        std::cerr
            << "Usage: " << argv[0] << " [-regtest] DATADIR" << std::endl
            << "Display DATADIR information, and process hex-encoded blocks on standard input." << std::endl
            << "Uses mainnet parameters by default, regtest with -regtest flag" << std::endl
            << std::endl
            << "IMPORTANT: THIS EXECUTABLE IS EXPERIMENTAL, FOR TESTING ONLY, AND EXPECTED TO" << std::endl
            << "           BREAK IN FUTURE VERSIONS. DO NOT USE ON YOUR ACTUAL DATADIR." << std::endl;
        return 1;
    }
    std::filesystem::path abs_datadir{std::filesystem::absolute(argv[argc-1])};
    std::filesystem::create_directories(abs_datadir);

    btck_LoggingOptions logging_options = {
        .log_timestamps = true,
        .log_time_micros = false,
        .log_threadnames = false,
        .log_sourcelocations = false,
        .always_print_category_levels = true,
    };

    logging_set_options(logging_options);

    Logger logger{std::make_unique<KernelLog>()};

    ContextOptions options{};