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

Code before:
            LogError("Shutting down due to lack of disk space!\n");
            if (!(Assert(node.shutdown_request))()) {
                LogError("Failed to send shutdown signal after disk space check\n");
            }
        }
    }, std::chrono::minutes{5});

    if (args.GetBoolArg("-logratelimit", BCLog::DEFAULT_LOGRATELIMIT)) {
        LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create(
            [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); },
            BCLog::RATELIMIT_MAX_BYTES,
            BCLog::RATELIMIT_WINDOW));
    } else {
        LogInfo("Log rate limiting disabled");
    }

    assert(!node.validation_signals);
    node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<SerialTaskRunner>(scheduler));
    auto& validation_signals = *node.validation_signals;

    assert(!node.notifications);
    node.notifications = std::make_unique<KernelNotifications>(Assert(node.shutdown_request), node.exit_status, *Assert(node.warnings));
    ReadNotificationArgs(args, *node.notifications);

    // Create client interfaces for wallets that are supposed to be loaded
    // according to -wallet and -disablewallet options. This only constructs
    // the interfaces, it doesn't load wallet data. Wallets actually get loaded
    // when load() and start() interface methods are called below.
    g_wallet_init_interface.Construct(node);
    uiInterface.InitWallet();

    if (interfaces::Ipc* ipc = node.init->ipc()) {
        for (std::string address : gArgs.GetArgs("-ipcbind")) {
            try {
                ipc->listenAddress(address);
            } catch (const std::exception& e) {
                return InitError(Untranslated(strprintf("Unable to bind to IPC address '%s'. %s", address, e.what())));
            }
            LogInfo("Listening for IPC requests on address %s", address);
        }
    }

    /* Register RPC commands regardless of -server setting so they will be
     * available in the GUI RPC console even if external calls are disabled.
     */
    RegisterAllCoreRPCCommands(tableRPC);
    for (const auto& client : node.chain_clients) {
        client->registerRpcs();
    }
#ifdef ENABLE_ZMQ
    RegisterZMQRPCCommands(tableRPC);

Review comment (bug):
In 0564f1e449e83ea875d64aff8f227fa1353a928d _ipc mining: Prevent ``Assertion `m_node.chainman' failed`` errors on early startup_: let's add a note that it's important to do this before any IPC interface listens, since the `wait_loaded` mechanism relies on kernel notifications.

Code after:
        constexpr uint64_t min_disk_space = 50 << 20; // 50 MB
        if (!CheckDiskSpace(args.GetBlocksDirPath(), min_disk_space)) {
            LogError("Shutting down due to lack of disk space!\n");
            if (!(Assert(node.shutdown_request))()) {
                LogError("Failed to send shutdown signal after disk space check\n");
            }
        }
    }, std::chrono::minutes{5});

    if (args.GetBoolArg("-logratelimit", BCLog::DEFAULT_LOGRATELIMIT)) {
        LogInstance().SetRateLimiting(BCLog::LogRateLimiter::Create(
            [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); },
            BCLog::RATELIMIT_MAX_BYTES,
            BCLog::RATELIMIT_WINDOW));
    } else {
        LogInfo("Log rate limiting disabled");
    }

    assert(!node.validation_signals);
    node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<SerialTaskRunner>(scheduler));
    auto& validation_signals = *node.validation_signals;

    // Create KernelNotifications object. Important to do this early before
    // calling ipc->listenAddress() below so makeMining and other IPC methods
    // can use this.
    assert(!node.notifications);
    node.notifications = std::make_unique<KernelNotifications>(Assert(node.shutdown_request), node.exit_status, *Assert(node.warnings));
    ReadNotificationArgs(args, *node.notifications);

    // Create client interfaces for wallets that are supposed to be loaded
    // according to -wallet and -disablewallet options. This only constructs
    // the interfaces, it doesn't load wallet data. Wallets actually get loaded
    // when load() and start() interface methods are called below.
    g_wallet_init_interface.Construct(node);
    uiInterface.InitWallet();

    if (interfaces::Ipc* ipc = node.init->ipc()) {
        for (std::string address : gArgs.GetArgs("-ipcbind")) {
            try {
                ipc->listenAddress(address);
            } catch (const std::exception& e) {
                return InitError(Untranslated(strprintf("Unable to bind to IPC address '%s'. %s", address, e.what())));
            }
            LogInfo("Listening for IPC requests on address %s", address);
        }
    }

    /* Register RPC commands regardless of -server setting so they will be
     * available in the GUI RPC console even if external calls are disabled.
     */
    RegisterAllCoreRPCCommands(tableRPC);