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

Code before:
            if (!(*Assert(node.shutdown))()) {
                LogError("Failed to send shutdown signal after finishing block import\n");
            }
            return;
        }

        // Start indexes initial sync
        if (!StartIndexBackgroundSync(node)) {
            bilingual_str err_str = _("Failed to start indexes, shutting down..");
            chainman.GetNotifications().fatalError(err_str);
            return;
        }
        // Load mempool from disk
        if (auto* pool{chainman.ActiveChainstate().GetMempool()}) {
            LoadMempool(*pool, ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{}, chainman.ActiveChainstate(), {});
            pool->SetLoadTried(!chainman.m_interrupt);
        }
    });

    // Wait for genesis block to be processed
    if (WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip() == nullptr)) {
        WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
        // We previously could hang here if shutdown was requested prior to
        // ImportBlocks getting started, so instead we just wait on a timer to
        // check ShutdownRequested() regularly.
        while (kernel_notifications.m_tip_block.IsNull() && !ShutdownRequested(node)) {
            kernel_notifications.m_tip_block_cv.wait_for(lock, 500ms);
        }
    }

    if (ShutdownRequested(node)) {
        return false;
    }

    // ********************************************************* Step 12: start node

    //// debug print
    int64_t best_block_time{};
    {
        LOCK(cs_main);
        LogPrintf("block tree size = %u\n", chainman.BlockIndex().size());
        chain_active_height = chainman.ActiveChain().Height();
        best_block_time = chainman.ActiveChain().Tip() ? chainman.ActiveChain().Tip()->GetBlockTime() : chainman.GetParams().GenesisBlock().GetBlockTime();
        if (tip_info) {
            tip_info->block_height = chain_active_height;
            tip_info->block_time = best_block_time;
            tip_info->verification_progress = GuessVerificationProgress(chainman.GetParams().TxData(), chainman.ActiveChain().Tip());
        }
        if (tip_info && chainman.m_best_header) {
            tip_info->header_height = chainman.m_best_header->nHeight;
            tip_info->header_time = chainman.m_best_header->GetBlockTime();

Review comment (bug):
In commit "refactor: Replace g_genesis_wait_cv with m_tip_block_cv" (faaf888eb275cecc2d2803c5756afac633e0e2a4)

This code is waiting for `m_tip_block` to be non-null, but then code below will be assuming that `chainman.ActiveTip()` will be non-null. These are similar conditions but not exactly the same, so I think it would be good to add an assert below the if statement like `assert(WITH_LOCK(chainman.GetMutex(), return chainman.ActiveChain().Tip() != nullptr));` to make sure this code is functioning as expected.

Code after:
            t.detach(); // thread runs free
        });
    }
#endif

    std::vector<fs::path> vImportFiles;
    for (const std::string& strFile : args.GetArgs("-loadblock")) {
        vImportFiles.push_back(fs::PathFromString(strFile));
    }

    node.background_init_thread = std::thread(&util::TraceThread, "initload", [=, &chainman, &args, &node] {
        ScheduleBatchPriority();
        // Import blocks
        ImportBlocks(chainman, vImportFiles);
        if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
            LogPrintf("Stopping after block import\n");
            if (!(Assert(node.shutdown_request))()) {
                LogError("Failed to send shutdown signal after finishing block import\n");
            }
            return;
        }

        // Start indexes initial sync
        if (!StartIndexBackgroundSync(node)) {
            bilingual_str err_str = _("Failed to start indexes, shutting down..");
            chainman.GetNotifications().fatalError(err_str);
            return;
        }
        // Load mempool from disk
        if (auto* pool{chainman.ActiveChainstate().GetMempool()}) {
            LoadMempool(*pool, ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{}, chainman.ActiveChainstate(), {});
            pool->SetLoadTried(!chainman.m_interrupt);
        }
    });

    // Wait for genesis block to be processed
    if (WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip() == nullptr)) {
        WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
        kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {
            return !kernel_notifications.m_tip_block.IsNull() || ShutdownRequested(node);
        });
    }

    if (ShutdownRequested(node)) {
        return false;
    }

    // ********************************************************* Step 12: start node

    int64_t best_block_time{};
    {