2017-04-02 15:39:20 +02:00
#!/usr/bin/env python3
2020-12-31 18:50:11 +01:00
# Copyright (c) 2017-2020 The Bitcoin Core developers
2017-04-02 15:39:20 +02:00
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
""" Test RPC calls related to net.
Tests correspond to code in rpc / net . cpp .
"""
2024-01-15 20:35:29 +01:00
from test_framework . p2p import P2PInterface
import test_framework . messages
from test_framework . messages import (
2024-09-19 10:51:45 +02:00
MAX_PROTOCOL_MESSAGE_LENGTH ,
2024-01-15 20:35:29 +01:00
NODE_NETWORK ,
)
2020-08-24 16:53:13 +02:00
from itertools import product
2022-07-25 23:38:07 +02:00
from test_framework . test_framework import DashTestFramework
2017-04-02 15:39:20 +02:00
from test_framework . util import (
2020-08-24 16:53:13 +02:00
assert_approx ,
2017-04-02 15:39:20 +02:00
assert_equal ,
2021-09-16 00:28:55 +02:00
assert_greater_than ,
2019-09-25 11:34:51 +02:00
assert_raises_rpc_error ,
2018-03-13 01:52:29 +01:00
p2p_port ,
2017-04-02 15:39:20 +02:00
)
2021-02-05 14:17:04 +01:00
from test_framework . wallet import MiniWallet
2021-12-12 12:06:13 +01:00
2020-06-04 17:09:53 +02:00
2021-12-12 12:06:13 +01:00
def assert_net_servicesnames ( servicesflag , servicenames ) :
""" Utility that checks if all flags are correctly decoded in
` getpeerinfo ` and ` getnetworkinfo ` .
: param servicesflag : The services as an integer .
2019-09-30 18:12:39 +02:00
: param servicenames : The list of decoded services names , as strings .
2021-12-12 12:06:13 +01:00
"""
2019-09-30 15:32:11 +02:00
servicesflag_generated = 0
for servicename in servicenames :
servicesflag_generated | = getattr ( test_framework . messages , ' NODE_ ' + servicename )
assert servicesflag_generated == servicesflag
2017-04-02 15:39:20 +02:00
2020-06-04 17:09:53 +02:00
2022-07-25 23:38:07 +02:00
class NetTest ( DashTestFramework ) :
2017-09-01 18:47:13 +02:00
def set_test_params ( self ) :
2024-08-27 12:30:39 +02:00
self . set_dash_test_params ( 3 , 1 )
2019-12-09 19:52:38 +01:00
self . supports_cli = False
2017-04-02 15:39:20 +02:00
def run_test ( self ) :
2021-02-05 14:17:04 +01:00
# We need miniwallet to make a transaction
self . wallet = MiniWallet ( self . nodes [ 0 ] )
2024-10-01 21:25:52 +02:00
self . generate ( self . wallet , 1 )
2020-08-24 16:53:13 +02:00
# Get out of IBD for the getpeerinfo tests.
2024-10-01 21:25:52 +02:00
self . generate ( self . nodes [ 0 ] , 101 )
2024-07-08 20:25:08 +02:00
2020-10-28 09:57:29 +01:00
# By default, the test framework sets up an addnode connection from
# node 1 --> node0. By connecting node0 --> node 1, we're left with
# the two nodes being connected both ways.
# Topology will look like: node0 <--> node1
2022-09-24 14:36:35 +02:00
self . connect_nodes ( 0 , 1 )
2020-10-22 01:57:29 +02:00
self . sync_all ( )
2020-04-07 11:20:25 +02:00
2020-08-24 16:53:13 +02:00
self . test_connection_count ( )
self . test_getpeerinfo ( )
self . test_getnettotals ( )
self . test_getnetworkinfo ( )
self . test_getaddednodeinfo ( )
2020-06-04 17:09:53 +02:00
self . test_service_flags ( )
2020-08-24 16:53:13 +02:00
self . test_getnodeaddresses ( )
2021-05-25 09:39:55 +02:00
self . test_addpeeraddress ( )
2024-09-19 10:51:45 +02:00
self . test_sendmsgtopeer ( )
2017-05-01 12:14:20 +02:00
2020-08-24 16:53:13 +02:00
def test_connection_count ( self ) :
self . log . info ( " Test getconnectioncount " )
# After using `connect_nodes` to connect nodes 0 and 1 to each other.
2022-07-25 23:38:07 +02:00
# and node0 was also connected to node2 (a masternode)
# during network setup
assert_equal ( self . nodes [ 0 ] . getconnectioncount ( ) , 3 )
2017-05-01 12:14:20 +02:00
2020-10-28 09:57:29 +01:00
def test_getpeerinfo ( self ) :
self . log . info ( " Test getpeerinfo " )
# Create a few getpeerinfo last_block/last_transaction values.
self . wallet . send_self_transfer ( from_node = self . nodes [ 0 ] ) # Make a transaction so we can see it in the getpeerinfo results
2024-10-01 21:25:52 +02:00
self . generate ( self . nodes [ 1 ] , 1 )
2020-10-28 09:57:29 +01:00
time_now = self . mocktime
peer_info = [ x . getpeerinfo ( ) for x in self . nodes ]
# Verify last_block and last_transaction keys/values.
for node , peer , field in product ( range ( self . num_nodes - self . mn_count ) , range ( 2 ) , [ ' last_block ' , ' last_transaction ' ] ) :
assert field in peer_info [ node ] [ peer ] . keys ( )
if peer_info [ node ] [ peer ] [ field ] != 0 :
assert_approx ( peer_info [ node ] [ peer ] [ field ] , time_now , vspan = 60 )
# check both sides of bidirectional connection between nodes
# the address bound to on one side will be the source address for the other node
assert_equal ( peer_info [ 0 ] [ 0 ] [ ' addrbind ' ] , peer_info [ 1 ] [ 0 ] [ ' addr ' ] )
assert_equal ( peer_info [ 1 ] [ 0 ] [ ' addrbind ' ] , peer_info [ 0 ] [ 0 ] [ ' addr ' ] )
# check the `servicesnames` field
for info in peer_info :
assert_net_servicesnames ( int ( info [ 0 ] [ " services " ] , 0x10 ) , info [ 0 ] [ " servicesnames " ] )
# Check dynamically generated networks list in getpeerinfo help output.
2024-05-27 11:24:31 +02:00
assert " (ipv4, ipv6, onion, i2p, cjdns, not_publicly_routable) " in self . nodes [ 0 ] . help ( " getpeerinfo " )
2020-10-28 09:57:29 +01:00
# This part is slightly different comparing to the Bitcoin implementation. This is expected because we create connections on network setup a bit differently too.
# We also create more connection during the test itself to test mn specific stats
assert_equal ( peer_info [ 0 ] [ 0 ] [ ' connection_type ' ] , ' inbound ' )
assert_equal ( peer_info [ 0 ] [ 1 ] [ ' connection_type ' ] , ' inbound ' )
assert_equal ( peer_info [ 0 ] [ 2 ] [ ' connection_type ' ] , ' manual ' )
assert_equal ( peer_info [ 1 ] [ 0 ] [ ' connection_type ' ] , ' manual ' )
assert_equal ( peer_info [ 1 ] [ 1 ] [ ' connection_type ' ] , ' inbound ' )
assert_equal ( peer_info [ 2 ] [ 0 ] [ ' connection_type ' ] , ' manual ' )
2024-09-13 12:05:48 +02:00
self . log . info ( " Check getpeerinfo output before a version message was sent " )
no_version_peer_id = 3
no_version_peer_conntime = self . mocktime
with self . nodes [ 0 ] . assert_debug_log ( [ f " Added connection peer= { no_version_peer_id } " ] ) :
2024-10-15 09:11:47 +02:00
no_version_peer = self . nodes [ 0 ] . add_p2p_connection ( P2PInterface ( ) , send_version = False , wait_for_verack = False )
2024-09-13 12:05:48 +02:00
peer_info = self . nodes [ 0 ] . getpeerinfo ( ) [ no_version_peer_id ]
peer_info . pop ( " addr " )
peer_info . pop ( " addrbind " )
assert_equal (
peer_info ,
{
" addr_processed " : 0 ,
" addr_rate_limited " : 0 ,
" addr_relay_enabled " : False ,
" bip152_hb_from " : False ,
" bip152_hb_to " : False ,
" bytesrecv " : 0 ,
" bytesrecv_per_msg " : { } ,
" bytessent " : 0 ,
" bytessent_per_msg " : { } ,
" connection_type " : " inbound " ,
" conntime " : no_version_peer_conntime ,
" id " : no_version_peer_id ,
" inbound " : True ,
" inflight " : [ ] ,
" last_block " : 0 ,
" last_transaction " : 0 ,
" lastrecv " : 0 ,
" lastsend " : 0 ,
" masternode " : False ,
" network " : " not_publicly_routable " ,
" permissions " : [ ] ,
" relaytxes " : False ,
" services " : " 0000000000000000 " ,
" servicesnames " : [ ] ,
2024-10-09 14:20:57 +02:00
" session_id " : " " ,
2024-09-13 12:05:48 +02:00
" startingheight " : - 1 ,
" subver " : " " ,
" synced_blocks " : - 1 ,
" synced_headers " : - 1 ,
" timeoffset " : 0 ,
2024-10-09 14:01:58 +02:00
" transport_protocol_type " : " v1 " if not self . options . v2transport else " detecting " ,
2024-09-13 12:05:48 +02:00
" version " : 0 ,
} ,
)
2024-10-15 09:11:47 +02:00
no_version_peer . peer_disconnect ( )
self . wait_until ( lambda : len ( self . nodes [ 0 ] . getpeerinfo ( ) ) == 3 )
2024-09-13 12:05:48 +02:00
2020-08-24 16:53:13 +02:00
def test_getnettotals ( self ) :
self . log . info ( " Test getnettotals " )
2020-10-28 16:27:26 +01:00
# Test getnettotals and getpeerinfo by doing a ping. The bytes
2024-10-09 14:01:58 +02:00
# sent/received should increase by at least the size of one ping
# and one pong. Both have a payload size of 8 bytes, but the total
# size depends on the used p2p version:
# - p2p v1: 24 bytes (header) + 8 bytes (payload) = 32 bytes
# - p2p v2: 21 bytes (header/tag with short-id) + 8 bytes (payload) = 29 bytes
ping_size = 32 if not self . options . v2transport else 29
2018-03-30 17:57:05 +02:00
net_totals_before = self . nodes [ 0 ] . getnettotals ( )
2020-10-28 16:27:26 +01:00
peer_info_before = self . nodes [ 0 ] . getpeerinfo ( )
2017-05-01 12:14:20 +02:00
self . nodes [ 0 ] . ping ( )
2024-10-09 14:01:58 +02:00
self . wait_until ( lambda : ( self . nodes [ 0 ] . getnettotals ( ) [ ' totalbytessent ' ] > = net_totals_before [ ' totalbytessent ' ] + ping_size * 2 ) , timeout = 1 )
self . wait_until ( lambda : ( self . nodes [ 0 ] . getnettotals ( ) [ ' totalbytesrecv ' ] > = net_totals_before [ ' totalbytesrecv ' ] + ping_size * 2 ) , timeout = 1 )
2018-03-13 01:52:29 +01:00
2020-11-04 17:16:38 +01:00
for peer_before in peer_info_before :
peer_after = lambda : next ( p for p in self . nodes [ 0 ] . getpeerinfo ( ) if p [ ' id ' ] == peer_before [ ' id ' ] )
2024-10-09 14:01:58 +02:00
self . wait_until ( lambda : peer_after ( ) [ ' bytesrecv_per_msg ' ] . get ( ' pong ' , 0 ) > = peer_before [ ' bytesrecv_per_msg ' ] . get ( ' pong ' , 0 ) + ping_size , timeout = 1 )
self . wait_until ( lambda : peer_after ( ) [ ' bytessent_per_msg ' ] . get ( ' ping ' , 0 ) > = peer_before [ ' bytessent_per_msg ' ] . get ( ' ping ' , 0 ) + ping_size , timeout = 1 )
2017-05-01 12:14:20 +02:00
2020-08-24 16:53:13 +02:00
def test_getnetworkinfo ( self ) :
self . log . info ( " Test getnetworkinfo " )
info = self . nodes [ 0 ] . getnetworkinfo ( )
2017-04-02 15:39:20 +02:00
assert_equal ( self . nodes [ 0 ] . getnetworkinfo ( ) [ ' networkactive ' ] , True )
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](https://github.com/bitcoin/bitcoin/commit/581b343d5bf517510ab0236583ca96628751177d) on master at [a0a422c](https://github.com/bitcoin/bitcoin/commit/a0a422c34cfd6514d0cc445bd784d3ee1a2d1749), 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
2020-09-04 13:31:35 +02:00
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 )
2017-04-02 15:39:20 +02:00
2020-07-23 18:32:49 +02:00
with self . nodes [ 0 ] . assert_debug_log ( expected_msgs = [ ' SetNetworkActive: false \n ' ] ) :
self . nodes [ 0 ] . setnetworkactive ( state = False )
2017-04-02 15:39:20 +02:00
assert_equal ( self . nodes [ 0 ] . getnetworkinfo ( ) [ ' networkactive ' ] , False )
2018-03-19 17:10:29 +01:00
# Wait a bit for all sockets to close
2020-08-27 08:21:53 +02:00
self . wait_until ( lambda : self . nodes [ 0 ] . getnetworkinfo ( ) [ ' connections ' ] == 0 , timeout = 3 )
self . wait_until ( lambda : self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections ' ] == 0 , timeout = 3 )
2017-04-02 15:39:20 +02:00
2020-07-23 18:32:49 +02:00
with self . nodes [ 0 ] . assert_debug_log ( expected_msgs = [ ' SetNetworkActive: true \n ' ] ) :
self . nodes [ 0 ] . setnetworkactive ( state = True )
2022-09-24 14:36:35 +02:00
self . connect_nodes ( 0 , 1 )
2019-09-18 20:41:14 +02:00
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](https://github.com/bitcoin/bitcoin/commit/581b343d5bf517510ab0236583ca96628751177d) on master at [a0a422c](https://github.com/bitcoin/bitcoin/commit/a0a422c34cfd6514d0cc445bd784d3ee1a2d1749), 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
2020-09-04 13:31:35 +02:00
info = self . nodes [ 1 ] . getnetworkinfo ( )
assert_equal ( info [ ' networkactive ' ] , True )
2020-10-28 09:57:29 +01:00
assert_equal ( info [ ' connections ' ] , 1 )
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](https://github.com/bitcoin/bitcoin/commit/581b343d5bf517510ab0236583ca96628751177d) on master at [a0a422c](https://github.com/bitcoin/bitcoin/commit/a0a422c34cfd6514d0cc445bd784d3ee1a2d1749), 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
2020-09-04 13:31:35 +02:00
assert_equal ( info [ ' connections_in ' ] , 1 )
2020-10-28 09:57:29 +01:00
assert_equal ( info [ ' connections_out ' ] , 0 )
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](https://github.com/bitcoin/bitcoin/commit/581b343d5bf517510ab0236583ca96628751177d) on master at [a0a422c](https://github.com/bitcoin/bitcoin/commit/a0a422c34cfd6514d0cc445bd784d3ee1a2d1749), 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
2020-09-04 13:31:35 +02:00
assert_equal ( info [ ' connections_mn ' ] , 0 )
assert_equal ( info [ ' connections_mn_in ' ] , 0 )
assert_equal ( info [ ' connections_mn_out ' ] , 0 )
2017-04-02 15:39:20 +02:00
2021-12-12 12:06:13 +01:00
# check the `servicesnames` field
network_info = [ node . getnetworkinfo ( ) for node in self . nodes ]
for info in network_info :
2019-09-30 15:32:11 +02:00
assert_net_servicesnames ( int ( info [ " localservices " ] , 0x10 ) , info [ " localservicesnames " ] )
2021-12-12 12:06:13 +01:00
2021-01-19 15:35:56 +01:00
# Check dynamically generated networks list in getnetworkinfo help output.
2024-05-27 11:24:31 +02:00
assert " (ipv4, ipv6, onion, i2p, cjdns) " in self . nodes [ 0 ] . help ( " getnetworkinfo " )
2021-01-19 15:35:56 +01:00
2022-07-25 23:38:07 +02:00
self . log . info ( ' Test extended connections info ' )
2020-10-28 09:57:29 +01:00
# Connect nodes both ways.
self . connect_nodes ( 1 , 0 )
2024-07-08 20:25:08 +02:00
2020-10-28 09:57:29 +01:00
assert_equal ( self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections ' ] , 2 )
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](https://github.com/bitcoin/bitcoin/commit/581b343d5bf517510ab0236583ca96628751177d) on master at [a0a422c](https://github.com/bitcoin/bitcoin/commit/a0a422c34cfd6514d0cc445bd784d3ee1a2d1749), 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
2020-09-04 13:31:35 +02:00
assert_equal ( self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections_in ' ] , 1 )
2020-10-28 09:57:29 +01:00
assert_equal ( self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections_out ' ] , 1 )
assert_equal ( self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections_mn ' ] , 0 )
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](https://github.com/bitcoin/bitcoin/commit/581b343d5bf517510ab0236583ca96628751177d) on master at [a0a422c](https://github.com/bitcoin/bitcoin/commit/a0a422c34cfd6514d0cc445bd784d3ee1a2d1749), 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
2020-09-04 13:31:35 +02:00
assert_equal ( self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections_mn_in ' ] , 0 )
2020-10-28 09:57:29 +01:00
assert_equal ( self . nodes [ 1 ] . getnetworkinfo ( ) [ ' connections_mn_out ' ] , 0 )
2022-07-25 23:38:07 +02:00
2020-08-24 16:53:13 +02:00
def test_getaddednodeinfo ( self ) :
self . log . info ( " Test getaddednodeinfo " )
2017-04-23 17:04:38 +02:00
assert_equal ( self . nodes [ 0 ] . getaddednodeinfo ( ) , [ ] )
# add a node (node2) to node0
ip_port = " 127.0.0.1: {} " . format ( p2p_port ( 2 ) )
2018-11-13 22:49:17 +01:00
self . nodes [ 0 ] . addnode ( node = ip_port , command = ' add ' )
2017-04-23 17:04:38 +02:00
# check that the node has indeed been added
added_nodes = self . nodes [ 0 ] . getaddednodeinfo ( ip_port )
assert_equal ( len ( added_nodes ) , 1 )
assert_equal ( added_nodes [ 0 ] [ ' addednode ' ] , ip_port )
2020-08-12 19:01:04 +02:00
# check that node cannot be added again
assert_raises_rpc_error ( - 23 , " Node already added " , self . nodes [ 0 ] . addnode , node = ip_port , command = ' add ' )
# check that node can be removed
self . nodes [ 0 ] . addnode ( node = ip_port , command = ' remove ' )
assert_equal ( self . nodes [ 0 ] . getaddednodeinfo ( ) , [ ] )
# check that trying to remove the node again returns an error
assert_raises_rpc_error ( - 24 , " Node could not be removed " , self . nodes [ 0 ] . addnode , node = ip_port , command = ' remove ' )
2017-08-16 00:28:57 +02:00
# check that a non-existent node returns an error
2018-03-30 17:57:05 +02:00
assert_raises_rpc_error ( - 24 , " Node has not been added " , self . nodes [ 0 ] . getaddednodeinfo , ' 1.1.1.1 ' )
2017-04-23 17:04:38 +02:00
2020-06-04 17:09:53 +02:00
def test_service_flags ( self ) :
2020-08-24 16:53:13 +02:00
self . log . info ( " Test service flags " )
2020-06-04 17:09:53 +02:00
self . nodes [ 0 ] . add_p2p_connection ( P2PInterface ( ) , services = ( 1 << 4 ) | ( 1 << 63 ) )
assert_equal ( [ ' UNKNOWN[2^4] ' , ' UNKNOWN[2^63] ' ] , self . nodes [ 0 ] . getpeerinfo ( ) [ - 1 ] [ ' servicesnames ' ] )
self . nodes [ 0 ] . disconnect_p2ps ( )
2020-08-24 16:53:13 +02:00
def test_getnodeaddresses ( self ) :
self . log . info ( " Test getnodeaddresses " )
2021-09-16 00:28:55 +02:00
self . nodes [ 0 ] . add_p2p_connection ( P2PInterface ( ) )
2024-04-12 18:38:34 +02:00
services = NODE_NETWORK
2021-09-16 00:28:55 +02:00
2024-04-12 18:38:34 +02:00
# Add an IPv6 address to the address manager.
ipv6_addr = " 1233:3432:2434:2343:3234:2345:6546:4534 "
self . nodes [ 0 ] . addpeeraddress ( address = ipv6_addr , port = 8333 )
# Add 10,000 IPv4 addresses to the address manager. Due to the way bucket
# and bucket positions are calculated, some of these addresses will collide.
2021-09-16 00:28:55 +02:00
imported_addrs = [ ]
2023-06-01 18:59:59 +02:00
for i in range ( 10000 ) :
first_octet = i >> 8
second_octet = i % 256
2024-04-12 18:38:34 +02:00
a = f " { first_octet } . { second_octet } .1.1 "
2021-09-16 00:28:55 +02:00
imported_addrs . append ( a )
2023-06-01 18:59:59 +02:00
self . nodes [ 0 ] . addpeeraddress ( a , 8333 )
2024-04-12 18:38:34 +02:00
# Fetch the addresses via the RPC and test the results.
assert_equal ( len ( self . nodes [ 0 ] . getnodeaddresses ( ) ) , 1 ) # default count is 1
assert_equal ( len ( self . nodes [ 0 ] . getnodeaddresses ( count = 2 ) ) , 2 )
assert_equal ( len ( self . nodes [ 0 ] . getnodeaddresses ( network = " ipv4 " , count = 8 ) ) , 8 )
# Maximum possible addresses in AddrMan is 10000. The actual number will
# usually be less due to bucket and bucket position collisions.
node_addresses = self . nodes [ 0 ] . getnodeaddresses ( 0 , " ipv4 " )
2023-06-01 18:59:59 +02:00
assert_greater_than ( len ( node_addresses ) , 5000 )
assert_greater_than ( 10000 , len ( node_addresses ) )
2021-09-16 00:28:55 +02:00
for a in node_addresses :
2023-06-01 18:59:59 +02:00
assert_equal ( a [ " time " ] , self . mocktime )
2024-04-12 18:38:34 +02:00
assert_equal ( a [ " services " ] , services )
2021-09-16 00:28:55 +02:00
assert a [ " address " ] in imported_addrs
assert_equal ( a [ " port " ] , 8333 )
2024-04-12 18:37:49 +02:00
assert_equal ( a [ " network " ] , " ipv4 " )
2021-09-16 00:28:55 +02:00
2024-04-12 18:38:34 +02:00
# Test the IPv6 address.
res = self . nodes [ 0 ] . getnodeaddresses ( 0 , " ipv6 " )
assert_equal ( len ( res ) , 1 )
assert_equal ( res [ 0 ] [ " address " ] , ipv6_addr )
assert_equal ( res [ 0 ] [ " network " ] , " ipv6 " )
assert_equal ( res [ 0 ] [ " port " ] , 8333 )
assert_equal ( res [ 0 ] [ " services " ] , services )
2023-06-01 18:59:59 +02:00
2024-05-27 11:24:31 +02:00
# Test for the absence of onion, I2P and CJDNS addresses.
for network in [ " onion " , " i2p " , " cjdns " ] :
2024-04-12 18:38:34 +02:00
assert_equal ( self . nodes [ 0 ] . getnodeaddresses ( 0 , network ) , [ ] )
2021-09-16 00:28:55 +02:00
2024-04-12 18:38:34 +02:00
# Test invalid arguments.
assert_raises_rpc_error ( - 8 , " Address count out of range " , self . nodes [ 0 ] . getnodeaddresses , - 1 )
assert_raises_rpc_error ( - 8 , " Network not recognized: Foo " , self . nodes [ 0 ] . getnodeaddresses , 1 , " Foo " )
2021-09-16 00:28:55 +02:00
2021-05-25 09:39:55 +02:00
def test_addpeeraddress ( self ) :
2024-09-01 20:17:32 +02:00
""" RPC addpeeraddress sets the source address equal to the destination address.
If an address with the same / 16 as an existing new entry is passed , it will be
placed in the same new bucket and have a 1 / 64 chance of the bucket positions
colliding ( depending on the value of nKey in the addrman ) , in which case the
new address won ' t be added. The probability of collision can be reduced to
1 / 2 ^ 16 = 1 / 65536 by using an address from a different / 16. We avoid this here
by first testing adding a tried table entry before testing adding a new table one .
"""
2021-05-25 09:39:55 +02:00
self . log . info ( " Test addpeeraddress " )
2024-09-16 20:17:32 +02:00
self . restart_node ( 1 , [ " -checkaddrman=1 " ] )
2021-05-25 09:39:55 +02:00
node = self . nodes [ 1 ]
self . log . debug ( " Test that addpeerinfo is a hidden RPC " )
# It is hidden from general help, but its detailed help may be called directly.
assert " addpeerinfo " not in node . help ( )
assert " addpeerinfo " in node . help ( " addpeerinfo " )
self . log . debug ( " Test that adding an empty address fails " )
assert_equal ( node . addpeeraddress ( address = " " , port = 8333 ) , { " success " : False } )
assert_equal ( node . getnodeaddresses ( count = 0 ) , [ ] )
2024-09-01 20:17:32 +02:00
self . log . debug ( " Test that adding a valid address to the tried table succeeds " )
assert_equal ( node . addpeeraddress ( address = " 1.2.3.4 " , tried = True , port = 8333 ) , { " success " : True } )
2024-09-03 16:57:48 +02:00
with node . assert_debug_log ( expected_msgs = [ " CheckAddrman: new 0, tried 1, total 1 started " ] ) :
2024-09-01 20:17:32 +02:00
addrs = node . getnodeaddresses ( count = 0 ) # getnodeaddresses re-runs the addrman checks
assert_equal ( len ( addrs ) , 1 )
assert_equal ( addrs [ 0 ] [ " address " ] , " 1.2.3.4 " )
assert_equal ( addrs [ 0 ] [ " port " ] , 8333 )
self . log . debug ( " Test that adding an already-present tried address to the new and tried tables fails " )
for value in [ True , False ] :
assert_equal ( node . addpeeraddress ( address = " 1.2.3.4 " , tried = value , port = 8333 ) , { " success " : False } )
2021-05-25 09:39:55 +02:00
assert_equal ( len ( node . getnodeaddresses ( count = 0 ) ) , 1 )
2024-09-01 20:17:32 +02:00
self . log . debug ( " Test that adding a second address, this time to the new table, succeeds " )
assert_equal ( node . addpeeraddress ( address = " 2.0.0.0 " , port = 8333 ) , { " success " : True } )
2024-09-03 16:57:48 +02:00
with node . assert_debug_log ( expected_msgs = [ " CheckAddrman: new 1, tried 1, total 2 started " ] ) :
2024-09-01 20:17:32 +02:00
addrs = node . getnodeaddresses ( count = 0 ) # getnodeaddresses re-runs the addrman checks
assert_equal ( len ( addrs ) , 2 )
2024-09-19 10:51:45 +02:00
def test_sendmsgtopeer ( self ) :
node = self . nodes [ 0 ]
self . restart_node ( 0 )
2024-10-09 14:01:58 +02:00
# we want to use a p2p v1 connection here in order to ensure
# a peer id of zero (a downgrade from v2 to v1 would lead
# to an increase of the peer id)
self . connect_nodes ( 0 , 1 , peer_advertises_v2 = False )
2024-09-19 10:51:45 +02:00
self . log . info ( " Test sendmsgtopeer " )
self . log . debug ( " Send a valid message " )
with self . nodes [ 1 ] . assert_debug_log ( expected_msgs = [ " received: addr " ] ) :
node . sendmsgtopeer ( peer_id = 0 , msg_type = " addr " , msg = " FFFFFF " )
self . log . debug ( " Test error for sending to non-existing peer " )
assert_raises_rpc_error ( - 1 , " Error: Could not send message to peer " , node . sendmsgtopeer , peer_id = 100 , msg_type = " addr " , msg = " FF " )
self . log . debug ( " Test that zero-length msg_type is allowed " )
node . sendmsgtopeer ( peer_id = 0 , msg_type = " addr " , msg = " " )
self . log . debug ( " Test error for msg_type that is too long " )
assert_raises_rpc_error ( - 8 , " Error: msg_type too long, max length is 12 " , node . sendmsgtopeer , peer_id = 0 , msg_type = " long_msg_type " , msg = " FF " )
self . log . debug ( " Test that unknown msg_type is allowed " )
node . sendmsgtopeer ( peer_id = 0 , msg_type = " unknown " , msg = " FF " )
self . log . debug ( " Test that empty msg is allowed " )
node . sendmsgtopeer ( peer_id = 0 , msg_type = " addr " , msg = " FF " )
self . log . debug ( " Test that oversized messages are allowed, but get us disconnected " )
zero_byte_string = b ' \x00 ' * int ( MAX_PROTOCOL_MESSAGE_LENGTH + 1 )
node . sendmsgtopeer ( peer_id = 0 , msg_type = " addr " , msg = zero_byte_string . hex ( ) )
self . wait_until ( lambda : len ( self . nodes [ 0 ] . getpeerinfo ( ) ) == 0 , timeout = 10 )
2020-06-04 17:09:53 +02:00
2017-04-02 15:39:20 +02:00
if __name__ == ' __main__ ' :
NetTest ( ) . main ( )