diff --git a/doc/release-notes-19405.md b/doc/release-notes-19405.md new file mode 100644 index 00000000000..14f2a81c7a5 --- /dev/null +++ b/doc/release-notes-19405.md @@ -0,0 +1,12 @@ +## Updated RPCs + +- `getnetworkinfo` now returns two new fields, `connections_in` and + `connections_out`, 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. (#19405) + +## CLI + +- The `connections` field of `bitcoin-cli -getinfo` is expanded to return a JSON + object with `in`, `out` and `total` numbers of peer connections. It previously + returned a single integer value for the total number of peer connections. (#19405) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index cf52b710cb2..437251a02e2 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -271,7 +271,13 @@ 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"]); + 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"])); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 7e2052c7cb5..5af43898576 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -414,7 +414,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"}, @@ -490,7 +490,9 @@ 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 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::BOOL, "networkactive", "whether p2p networking is enabled"}, {RPCResult::Type::ARR, "networks", "information per network", { @@ -538,7 +540,9 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request) obj.pushKV("timeoffset", GetTimeOffset()); if (node.connman) { obj.pushKV("networkactive", node.connman->GetNetworkActive()); - obj.pushKV("connections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL)); + obj.pushKV("connections", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_ALL)); + obj.pushKV("connections_in", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_IN)); + obj.pushKV("connections_out", (int)node.connman->GetNodeCount(CConnman::CONNECTIONS_OUT)); } obj.pushKV("networks", GetNetworksInfo()); obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py index 80003aca0d1..81c007c27bd 100755 --- a/test/functional/interface_bitcoin_cli.py +++ b/test/functional/interface_bitcoin_cli.py @@ -71,7 +71,14 @@ 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'] + } + ) 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']) diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py index 506c77c5676..bc0e5b458e6 100755 --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -102,8 +102,11 @@ class NetTest(BitcoinTestFramework): def test_getnetworkinfo(self): self.log.info("Test getnetworkinfo") - assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True) - assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2) + info = self.nodes[0].getnetworkinfo() + assert_equal(info['networkactive'], True) + assert_equal(info['connections'], 2) + assert_equal(info['connections_in'], 1) + assert_equal(info['connections_out'], 1) with self.nodes[0].assert_debug_log(expected_msgs=['SetNetworkActive: false\n']): self.nodes[0].setnetworkactive(state=False) @@ -117,8 +120,11 @@ class NetTest(BitcoinTestFramework): connect_nodes(self.nodes[0], 1) connect_nodes(self.nodes[1], 0) - assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True) - assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2) + info = self.nodes[0].getnetworkinfo() + assert_equal(info['networkactive'], True) + assert_equal(info['connections'], 2) + assert_equal(info['connections_in'], 1) + assert_equal(info['connections_out'], 1) # check the `servicesnames` field network_info = [node.getnetworkinfo() for node in self.nodes]