Merge #19405: rpc, cli: add network in/out connections to getnetworkinfo and -getinfo

581b343d5bf517510ab0236583ca96628751177d Add in/out connections to cli -getinfo (Jon Atack)
d9cc13e88d096c1a171159c01cbb96444f7f8d7f UNIX_EPOCH_TIME fixup in rpc getnettotals (Jon Atack)
1ab49b81cf32b6ef9e312a0a8ac45c68a3262f0d Add in/out connections to rpc getnetworkinfo (Jon Atack)

Pull request description:

  This is basic info that is present in the GUI that I've been wishing to have exposed via the RPC and CLI without needing a bash workaround or script. For human users it would also be useful to have it in `-getinfo`.

  `bitcoin-cli getnetworkinfo`
  ```
    "connections": 15,
    "connections_in": 6,
    "connections_out": 9,
  ```

  `bitcoin-cli -getinfo`
  ```
    "connections": {
      "in": 6,
      "out": 9,
      "total": 15
    },
  ```

  Update the tests, RPC help, and release notes for the changes. Also fixup the `getnettotals` timemillis help while touching `rpc/net.cpp`.

  -----

  Reviewers can manually test this PR by [building from source](https://jonatack.github.io/articles/how-to-compile-bitcoin-core-and-run-the-tests), launching bitcoind, and then running `bitcoin-cli -getinfo`, `bitcoin-cli getnetworkinfo`, `bitcoin-cli help getnetworkinfo`, and `bitcoin-cli help getnettotals` (for the UNIX epoch time change).

ACKs for top commit:
  eriknylund:
    > tACK [581b343](581b343d5b) on master at [a0a422c](a0a422c34c), ran unit & functional tests and and confirmed changes on an existing datadir ✌️
  benthecarman:
    tACK `581b343`
  willcl-ark:
    tACK for 581b343d5bf517510ab0236583ca96628751177d, this time rebased onto master at 862fde88be706adb20a211178253636442c3ae00.
  shesek:
    tACK `581b343`. This provides what I needed, thanks!
  n-thumann:
    tACK 581b343 on master at a0a422c, ran unit & functional tests and and confirmed changes on an existing datadir ✌️

Tree-SHA512: 08dd3ac8fefae401bd8253ff3ac027603c528eeccba53cedcb127771316173a7052fce44af8fa33ac98ebc4cf2a2b11cdefd949995d55e9b9a5942b876d00dc5
This commit is contained in:
Wladimir J. van der Laan 2020-09-04 13:31:35 +02:00 committed by Konstantin Akimov
parent 19aba38cab
commit 9c54cb16de
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524
5 changed files with 70 additions and 23 deletions

View File

@ -0,0 +1,16 @@
## Updated RPCs
- `getnetworkinfo` now returns fields `connections_in`, `connections_out`,
`connections_mn_in`, `connections_mn_out`, `connections_mn`
that provide the number of inbound and outbound peer
connections. These new fields are in addition to the existing `connections`
field, which returns the total number of peer connections. Old fields
`inboundconnections`, `outboundconnections`, `inboundmnconnections`,
`outboundmnconnections` and `mnconnections` are removed (dash#5823)
## CLI
- The `connections` field of `dash-cli -getinfo` is expanded to return a JSON
object with `in`, `out` and `total` numbers of peer connections and `mn_in`,
`mn_out` and `mn_total` numbers of verified mn connections. It previously
returned a single integer value for the total number of peer connections. (dash#5823)

View File

@ -282,7 +282,16 @@ public:
result.pushKV("headers", batch[ID_BLOCKCHAININFO]["result"]["headers"]);
result.pushKV("verificationprogress", batch[ID_BLOCKCHAININFO]["result"]["verificationprogress"]);
result.pushKV("timeoffset", batch[ID_NETWORKINFO]["result"]["timeoffset"]);
result.pushKV("connections", batch[ID_NETWORKINFO]["result"]["connections"]);
UniValue connections(UniValue::VOBJ);
connections.pushKV("in", batch[ID_NETWORKINFO]["result"]["connections_in"]);
connections.pushKV("out", batch[ID_NETWORKINFO]["result"]["connections_out"]);
connections.pushKV("total", batch[ID_NETWORKINFO]["result"]["connections"]);
connections.pushKV("mn_in", batch[ID_NETWORKINFO]["result"]["connections_mn_in"]);
connections.pushKV("mn_out", batch[ID_NETWORKINFO]["result"]["connections_mn_out"]);
connections.pushKV("mn_total", batch[ID_NETWORKINFO]["result"]["connections_mn"]);
result.pushKV("connections", connections);
result.pushKV("proxy", batch[ID_NETWORKINFO]["result"]["networks"][0]["proxy"]);
result.pushKV("difficulty", batch[ID_BLOCKCHAININFO]["result"]["difficulty"]);
result.pushKV("chain", UniValue(batch[ID_BLOCKCHAININFO]["result"]["chain"]));

View File

@ -437,7 +437,7 @@ static UniValue getnettotals(const JSONRPCRequest& request)
{
{RPCResult::Type::NUM, "totalbytesrecv", "Total bytes received"},
{RPCResult::Type::NUM, "totalbytessent", "Total bytes sent"},
{RPCResult::Type::NUM_TIME, "timemillis", "Current UNIX time in milliseconds"},
{RPCResult::Type::NUM_TIME, "timemillis", "Current " + UNIX_EPOCH_TIME + " in milliseconds"},
{RPCResult::Type::OBJ, "uploadtarget", "",
{
{RPCResult::Type::NUM, "timeframe", "Length of the measuring timeframe in seconds"},
@ -447,7 +447,7 @@ static UniValue getnettotals(const JSONRPCRequest& request)
{RPCResult::Type::NUM, "bytes_left_in_cycle", "Bytes left in current time cycle"},
{RPCResult::Type::NUM, "time_left_in_cycle", "Seconds left in current time cycle"},
}},
}
}
},
RPCExamples{
HelpExampleCli("getnettotals", "")
@ -512,12 +512,12 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
}},
{RPCResult::Type::BOOL, "localrelay", "true if transaction relay is requested from peers"},
{RPCResult::Type::NUM, "timeoffset", "the time offset"},
{RPCResult::Type::NUM, "connections", "the number of inbound and outbound connections"},
{RPCResult::Type::NUM, "inboundconnections", "the number of inbound connections"},
{RPCResult::Type::NUM, "outboundconnections", "the number of outbound connections"},
{RPCResult::Type::NUM, "mnconnections", "the number of verified mn connections"},
{RPCResult::Type::NUM, "inboundmnconnections", "the number of inbound verified mn connections"},
{RPCResult::Type::NUM, "outboundmnconnections", "the number of outbound verified mn connections"},
{RPCResult::Type::NUM, "connections", "the total number of connections"},
{RPCResult::Type::NUM, "connections_in", "the number of inbound connections"},
{RPCResult::Type::NUM, "connections_out", "the number of outbound connections"},
{RPCResult::Type::NUM, "connections_mn", "the number of verified mn connections"},
{RPCResult::Type::NUM, "connections_mn_in", "the number of inbound verified mn connections"},
{RPCResult::Type::NUM, "connections_mn_out", "the number of outbound verified mn connections"},
{RPCResult::Type::BOOL, "networkactive", "whether p2p networking is enabled"},
{RPCResult::Type::STR, "socketevents", "the socket events mode, either kqueue, epoll, poll or select"},
{RPCResult::Type::ARR, "networks", "information per network",
@ -570,11 +570,11 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
if (node.connman) {
obj.pushKV("networkactive", node.connman->GetNetworkActive());
obj.pushKV("connections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL));
obj.pushKV("inboundconnections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_IN));
obj.pushKV("outboundconnections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_OUT));
obj.pushKV("mnconnections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED));
obj.pushKV("inboundmnconnections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED_IN));
obj.pushKV("outboundmnconnections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED_OUT));
obj.pushKV("connections_in", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_IN));
obj.pushKV("connections_out", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_OUT));
obj.pushKV("connections_mn", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED));
obj.pushKV("connections_mn_in", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED_IN));
obj.pushKV("connections_mn_out", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_VERIFIED_OUT));
std::string strSocketEvents;
switch (node.connman->GetSocketEventsMode()) {
case CConnman::SOCKETEVENTS_SELECT:

View File

@ -80,7 +80,17 @@ class TestBitcoinCli(BitcoinTestFramework):
assert_equal(cli_get_info['blocks'], blockchain_info['blocks'])
assert_equal(cli_get_info['headers'], blockchain_info['headers'])
assert_equal(cli_get_info['timeoffset'], network_info['timeoffset'])
assert_equal(cli_get_info['connections'], network_info['connections'])
assert_equal(
cli_get_info['connections'],
{
'in': network_info['connections_in'],
'out': network_info['connections_out'],
'total': network_info['connections'],
'mn_in': network_info['connections_mn_in'],
'mn_out': network_info['connections_mn_out'],
'mn_total': network_info['connections_mn'],
}
)
assert_equal(cli_get_info['proxy'], network_info['networks'][0]['proxy'])
assert_equal(cli_get_info['difficulty'], blockchain_info['difficulty'])
assert_equal(cli_get_info['chain'], blockchain_info['chain'])

View File

@ -91,7 +91,13 @@ class NetTest(DashTestFramework):
self.log.info("Test getnetworkinfo")
info = self.nodes[0].getnetworkinfo()
assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
assert_equal(self.nodes[0].getnetworkinfo()['connections'], 3)
assert_equal(info['networkactive'], True)
assert_equal(info['connections'], 3)
assert_equal(info['connections_in'], 2)
assert_equal(info['connections_out'], 1)
assert_equal(info['connections_mn'], 0)
assert_equal(info['connections_mn_in'], 0)
assert_equal(info['connections_mn_out'], 0)
with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']):
self.nodes[0].setnetworkactive(state=False)
@ -106,8 +112,14 @@ class NetTest(DashTestFramework):
self.connect_nodes(0, 1)
self.connect_nodes(1, 0)
assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2)
info = self.nodes[1].getnetworkinfo()
assert_equal(info['networkactive'], True)
assert_equal(info['connections'], 2)
assert_equal(info['connections_in'], 1)
assert_equal(info['connections_out'], 1)
assert_equal(info['connections_mn'], 0)
assert_equal(info['connections_mn_in'], 0)
assert_equal(info['connections_mn_out'], 0)
# check the `servicesnames` field
network_info = [node.getnetworkinfo() for node in self.nodes]
@ -122,11 +134,11 @@ class NetTest(DashTestFramework):
self.nodes[1].ping()
self.wait_until(lambda: all(['pingtime' in n for n in self.nodes[1].getpeerinfo()]))
assert_equal(self.nodes[1].getnetworkinfo()['connections'], 3)
assert_equal(self.nodes[1].getnetworkinfo()['inboundconnections'], 1)
assert_equal(self.nodes[1].getnetworkinfo()['outboundconnections'], 2)
assert_equal(self.nodes[1].getnetworkinfo()['mnconnections'], 1)
assert_equal(self.nodes[1].getnetworkinfo()['inboundmnconnections'], 0)
assert_equal(self.nodes[1].getnetworkinfo()['outboundmnconnections'], 1)
assert_equal(self.nodes[1].getnetworkinfo()['connections_in'], 1)
assert_equal(self.nodes[1].getnetworkinfo()['connections_out'], 2)
assert_equal(self.nodes[1].getnetworkinfo()['connections_mn'], 1)
assert_equal(self.nodes[1].getnetworkinfo()['connections_mn_in'], 0)
assert_equal(self.nodes[1].getnetworkinfo()['connections_mn_out'], 1)
def test_getaddednodeinfo(self):
self.log.info("Test getaddednodeinfo")