比特币 RPC 命令「getnetworkinfo」
$ 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;
}