$ bitcoin-cli help getnetworkinfo
getnetworkinfo

返回一个包含有关 P2P 网络的各种状态信息的对象。

结果:
{
  "version": xxxxx,                   (数字)服务器版本
  "subversion": "/Satoshi:x.x.x/",    (字符串)服务器子版本字符串
  "protocolversion": xxxxx,           (数字)协议版本
  "localservices": "xxxxxxxxxxxxxxxx",(字符串)我们为网络提供的服务
  "timeoffset": xxxxx,                (数字)时间偏移量
  "connections": xxxxx,               (数字)连接数
  "networks": [                       (数字)每个网络的信息
  {
    "name": "xxx",                    (字符串)网络(ipv4,ipv6 或 onion)
    "limited": true|false,            (布尔型)是否在使用 -onlynet 限制网络?
    "reachable": true|false,          (布尔型)网络是否可达?
    "proxy": "host:port"              (字符串)用于该网络的代理,若没有则为空
  }
  ,...
  ],
  "relayfee": x.xxxxxxxx,             (数字)以 BTC/kB 为单位的付费交易的最低中继费
  "localaddresses": [                 (数组)本地的地址列表
  {
    "address": "xxxx",                (字符串)网络地址
    "port": xxx,                      (数字)网络端口
    "score": xxx                      (数字)相关分数
  }
  ,...
  ]
  "warnings": "..."                   (字符串)任何网络警告(例如报警消息)
}

例子:
> bitcoin-cli getnetworkinfo
> curl --user myusername:mypassword --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getnetworkinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

源码剖析

getnetworkinfo 对应的函数在文件 rpcserver.h 中被引用。

extern UniValue getnetworkinfo(const UniValue& params, bool fHelp);

实现在文件 rpcnet.cpp 中。

UniValue getnetworkinfo(const UniValue& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error(
            "getnetworkinfo\n"
            "Returns an object containing various state info regarding P2P networking.\n"
            "\nResult:\n"
            "{\n"
            "  \"version\": xxxxx,                      (numeric) the server version\n"
            "  \"subversion\": \"/Satoshi:x.x.x/\",     (string) the server subversion string\n"
            "  \"protocolversion\": xxxxx,              (numeric) the protocol version\n"
            "  \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
            "  \"timeoffset\": xxxxx,                   (numeric) the time offset\n"
            "  \"connections\": xxxxx,                  (numeric) the number of connections\n"
            "  \"networks\": [                          (array) information per network\n"
            "  {\n"
            "    \"name\": \"xxx\",                     (string) network (ipv4, ipv6 or onion)\n"
            "    \"limited\": true|false,               (boolean) is the network limited using -onlynet?\n"
            "    \"reachable\": true|false,             (boolean) is the network reachable?\n"
            "    \"proxy\": \"host:port\"               (string) the proxy that is used for this network, or empty if none\n"
            "  }\n"
            "  ,...\n"
            "  ],\n"
            "  \"relayfee\": x.xxxxxxxx,                (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
            "  \"localaddresses\": [                    (array) list of local addresses\n"
            "  {\n"
            "    \"address\": \"xxxx\",                 (string) network address\n"
            "    \"port\": xxx,                         (numeric) network port\n"
            "    \"score\": xxx                         (numeric) relative score\n"
            "  }\n"
            "  ,...\n"
            "  ]\n"
            "  \"warnings\": \"...\"                    (string) any network warnings (such as alert messages) \n"
            "}\n"
            "\nExamples:\n"
            + HelpExampleCli("getnetworkinfo", "")
            + HelpExampleRpc("getnetworkinfo", "")
        ); // 1. 帮助内容

    LOCK(cs_main);

    UniValue obj(UniValue::VOBJ); // 2. 构建网络信息的对象并返回
    obj.push_back(Pair("version",       CLIENT_VERSION));
    obj.push_back(Pair("subversion",    strSubVersion));
    obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
    obj.push_back(Pair("localservices",       strprintf("%016x", nLocalServices)));
    obj.push_back(Pair("timeoffset",    GetTimeOffset()));
    obj.push_back(Pair("connections",   (int)vNodes.size()));
    obj.push_back(Pair("networks",      GetNetworksInfo()));
    obj.push_back(Pair("relayfee",      ValueFromAmount(::minRelayTxFee.GetFeePerK())));
    UniValue localAddresses(UniValue::VARR);
    {
        LOCK(cs_mapLocalHost);
        BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
        {
            UniValue rec(UniValue::VOBJ);
            rec.push_back(Pair("address", item.first.ToString()));
            rec.push_back(Pair("port", item.second.nPort));
            rec.push_back(Pair("score", item.second.nScore));
            localAddresses.push_back(rec);
        }
    }
    obj.push_back(Pair("localaddresses", localAddresses));
    obj.push_back(Pair("warnings",       GetWarnings("statusbar")));
    return obj;
}

1. 帮助内容

参考比特币 RPC 命令「getbestblockhash」1. 帮助内容

2. 构建网络信息的对象并返回

获取网络信息函数 GetNetworksInfo() 实现在文件 rpcnet.cpp 中。

static UniValue GetNetworksInfo()
{
    UniValue networks(UniValue::VARR);
    for(int n=0; n<NET_MAX; ++n)
    {
        enum Network network = static_cast<enum Network>(n);
        if(network == NET_UNROUTABLE)
            continue;
        proxyType proxy;
        UniValue obj(UniValue::VOBJ);
        GetProxy(network, proxy);
        obj.push_back(Pair("name", GetNetworkName(network)));
        obj.push_back(Pair("limited", IsLimited(network)));
        obj.push_back(Pair("reachable", IsReachable(network)));
        obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
        obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
        networks.push_back(obj);
    }
    return networks;
}

参考链接