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

Code before:

    // ********************************************************* Step 5: verify wallet database integrity
    for (const auto& client : node.chain_clients) {
        if (!client->verify()) {
            return false;
        }
    }

    // ********************************************************* Step 6: network initialization
    // Note that we absolutely cannot open any actual connections
    // until the very end ("start node") as the UTXO/block state
    // is not yet setup and may end up being set up twice if we
    // need to reindex later.

    fListen = args.GetBoolArg("-listen", DEFAULT_LISTEN);
    fDiscover = args.GetBoolArg("-discover", true);

    PeerManager::Options peerman_opts{};
    ApplyArgsManOptions(args, peerman_opts);

    {

        // Read asmap file if configured
        std::vector<bool> asmap;
        if (args.IsArgSet("-asmap") && !args.IsArgNegated("-asmap")) {
            fs::path asmap_path = args.GetPathArg("-asmap");
            if (!asmap_path.is_absolute()) {
                asmap_path = args.GetDataDirNet() / asmap_path;
            }
            if (!fs::is_regular_file(asmap_path)) {
                InitError(strprintf(_("Could not find asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
                return false;
            }
            asmap = DecodeAsmap(asmap_path);
            if (asmap.size() == 0) {
                InitError(strprintf(_("Could not parse asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
                return false;
            }
            const uint256 asmap_version = (HashWriter{} << asmap).GetHash();
            LogInfo("Using asmap version %s for IP bucketing", asmap_version.ToString());
        } else {
            LogInfo("Using /16 prefix for IP bucketing");
        }

        // Initialize netgroup manager
        assert(!node.netgroupman);
        node.netgroupman = std::make_unique<NetGroupManager>(std::move(asmap));

        // Initialize addrman
        assert(!node.addrman);
        uiInterface.InitMessage(_("Loading P2P addresses…"));

Review comment (bug):
Effectively the arg is not allowed anymore without a path to a file, so I think it would make sense to return an explicit error here which gives the user that feedback. The current error for the empty `-asmap` is "Could not find asmap file /path/to/datadir" which suggests there still is a default location where the file (without a name) could not be found. This error message would also be more helpful for anyone who might still try to use the default location feature with the next release.

Code after:

    // ********************************************************* Step 5: verify wallet database integrity
    for (const auto& client : node.chain_clients) {
        if (!client->verify()) {
            return false;
        }
    }

    // ********************************************************* Step 6: network initialization
    // Note that we absolutely cannot open any actual connections
    // until the very end ("start node") as the UTXO/block state
    // is not yet setup and may end up being set up twice if we
    // need to reindex later.

    fListen = args.GetBoolArg("-listen", DEFAULT_LISTEN);
    fDiscover = args.GetBoolArg("-discover", true);

    PeerManager::Options peerman_opts{};
    ApplyArgsManOptions(args, peerman_opts);

    {

        // Read asmap file if configured
        std::vector<bool> asmap;
        if (args.IsArgSet("-asmap") && !args.IsArgNegated("-asmap")) {
            fs::path asmap_path = args.GetPathArg("-asmap");
            if (asmap_path.empty()) {
                InitError(_("-asmap requires a file path. Use -asmap=<file>."));
                return false;
            }
            if (!asmap_path.is_absolute()) {
                asmap_path = args.GetDataDirNet() / asmap_path;
            }
            if (!fs::exists(asmap_path)) {
                InitError(strprintf(_("Could not find asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
                return false;
            }
            asmap = DecodeAsmap(asmap_path);
            if (asmap.size() == 0) {
                InitError(strprintf(_("Could not parse asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
                return false;
            }
            const uint256 asmap_version = (HashWriter{} << asmap).GetHash();
            LogInfo("Using asmap version %s for IP bucketing", asmap_version.ToString());
        } else {
            LogInfo("Using /16 prefix for IP bucketing");
        }

        // Initialize netgroup manager
        assert(!node.netgroupman);
        node.netgroupman = std::make_unique<NetGroupManager>(std::move(asmap));