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

Code before:
                              HelpExampleCli("getaddrmaninfo", "")
                              + HelpExampleRpc("getaddrmaninfo", "")
                      },
                      [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
                      {
                          NodeContext& node = EnsureAnyNodeContext(request.context);
                          if (!node.addrman) {
                              throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Address manager functionality missing or disabled");
                          }

                          UniValue ret(UniValue::VOBJ);
                          for (int n = 0; n < NET_MAX; ++n) {
                              enum Network network = static_cast<enum Network>(n);
                              if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
                              UniValue obj(UniValue::VOBJ);
                              obj.pushKV("new", node.addrman->Size(network, true));
                              obj.pushKV("tried", node.addrman->Size(network, false));
                              obj.pushKV("total", node.addrman->Size(network));
                              ret.pushKV(GetNetworkName(network), obj);
                          }
                          UniValue obj(UniValue::VOBJ);
                          obj.pushKV("new", node.addrman->Size(std::nullopt, true));
                          obj.pushKV("tried", node.addrman->Size(std::nullopt, false));
                          obj.pushKV("total", node.addrman->Size());
                          ret.pushKV("all_networks", obj);
                          return ret;
                      },
    };
}

UniValue AddrmanEntryToJSON(const AddrInfo& info)
{
    UniValue ret(UniValue::VOBJ);
    ret.pushKV("address", info.ToStringAddr());
    ret.pushKV("port", info.GetPort());
    ret.pushKV("services", (uint64_t)info.nServices);
    ret.pushKV("time", int64_t{TicksSinceEpoch<std::chrono::seconds>(info.nTime)});
    ret.pushKV("network", GetNetworkName(info.GetNetClass()));
    ret.pushKV("source", info.source.ToStringAddr());
    ret.pushKV("source_network", GetNetworkName(info.source.GetNetClass()));
    return ret;
}

UniValue AddrmanTableToJSON(const std::vector<std::pair<AddrInfo, AddressPosition>>& tableInfos)
{
    UniValue table(UniValue::VOBJ);
    for (const auto& e : tableInfos) {
        AddrInfo info = e.first;
        AddressPosition location = e.second;
        std::ostringstream key;
        key << location.bucket << "/" << location.position;

Review comment (refactor):
nit: looks like this is ordered by commands using `network` then commands using `hidden` if you could move this up to line 1075

Code after:
                if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
                UniValue obj(UniValue::VOBJ);
                obj.pushKV("new", addrman.Size(network, true));
                obj.pushKV("tried", addrman.Size(network, false));
                obj.pushKV("total", addrman.Size(network));
                ret.pushKV(GetNetworkName(network), obj);
            }
            UniValue obj(UniValue::VOBJ);
            obj.pushKV("new", addrman.Size(std::nullopt, true));
            obj.pushKV("tried", addrman.Size(std::nullopt, false));
            obj.pushKV("total", addrman.Size());
            ret.pushKV("all_networks", obj);
            return ret;
        },
    };
}

UniValue AddrmanEntryToJSON(const AddrInfo& info)
{
    UniValue ret(UniValue::VOBJ);
    ret.pushKV("address", info.ToStringAddr());
    ret.pushKV("port", info.GetPort());
    ret.pushKV("services", (uint64_t)info.nServices);
    ret.pushKV("time", int64_t{TicksSinceEpoch<std::chrono::seconds>(info.nTime)});
    ret.pushKV("network", GetNetworkName(info.GetNetClass()));
    ret.pushKV("source", info.source.ToStringAddr());
    ret.pushKV("source_network", GetNetworkName(info.source.GetNetClass()));
    return ret;
}

UniValue AddrmanTableToJSON(const std::vector<std::pair<AddrInfo, AddressPosition>>& tableInfos)
{
    UniValue table(UniValue::VOBJ);
    for (const auto& e : tableInfos) {
        AddrInfo info = e.first;
        AddressPosition location = e.second;
        std::ostringstream key;
        key << location.bucket << "/" << location.position;
        // Address manager tables have unique entries so there is no advantage
        // in using UniValue::pushKV, which checks if the key already exists
        // in O(N). UniValue::pushKVEnd is used instead which currently is O(1).
        table.pushKVEnd(key.str(), AddrmanEntryToJSON(info));
    }
    return table;
}

static RPCHelpMan getrawaddrman()
{
    return RPCHelpMan{"getrawaddrman",
        "EXPERIMENTAL warning: this call may be changed in future releases.\n"
        "\nReturns information on all address manager entries for the new and tried tables.\n",