Skip to content

Commit 30a0557

Browse files
committed
Merge bitcoin#28805: test: Make existing functional tests compatible with --v2transport
35fb993 test: enable v2 transport for p2p_timeouts.py (Martin Zumsande) 2c1669c test: enable v2 transport for rpc_net.py (Sebastian Falbesoner) cc961c2 test: enable v2 transport for p2p_node_network_limited.py (Sebastian Falbesoner) 3598a1b test: enable --v2transport in combination with --usecli (Martin Zumsande) 68a9001 test: persist -v2transport over restarts and respect -v2transport=0 (Martin Zumsande) Pull request description: This makes the functional test suite compatible with BIP324, so that `python3 test_runner.py --v2transport` should succeed (currently, 12 tests fail for me on master). Includes two commits by TheStack I found in an old discussion bitcoin#28331 (comment) Note that even though all tests should pass, the python `p2p.py` module will do v2 connections only after the merge of bitcoin#24748, so that for now only connections between two full nodes will actually run v2. Some of the fixed tests were added with `--v2transport` to the test runner. Though after bitcoin#24748 we might also want to consider running the entire suite with `--v2transport` in some CI. ACKs for top commit: sipa: utACK 35fb993. Thanks for taking care of this. achow101: ACK 35fb993 theStack: ACK 35fb993 stratospher: ACK 35fb993. Tree-SHA512: 80dc0bf211fa525ff1d092043aea9f222f14c02e5832a548fb8b83b9ede1fcee03c5e8ade0d05c331bdaa492af9c1cf3d0f0b15b846673c6eacea82dd4cefbc3
2 parents fe4e83f + 35fb993 commit 30a0557

File tree

6 files changed

+53
-21
lines changed

6 files changed

+53
-21
lines changed

test/functional/p2p_node_network_limited.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@
88
and that it responds to getdata requests for blocks correctly:
99
- send a block within 288 + 2 of the tip
1010
- disconnect peers who request blocks older than that."""
11-
from test_framework.messages import CInv, MSG_BLOCK, msg_getdata, msg_verack, NODE_NETWORK_LIMITED, NODE_WITNESS
11+
from test_framework.messages import (
12+
CInv,
13+
MSG_BLOCK,
14+
NODE_NETWORK_LIMITED,
15+
NODE_P2P_V2,
16+
NODE_WITNESS,
17+
msg_getdata,
18+
msg_verack,
19+
)
1220
from test_framework.p2p import P2PInterface
1321
from test_framework.test_framework import BitcoinTestFramework
1422
from test_framework.util import (
@@ -50,6 +58,8 @@ def run_test(self):
5058
node = self.nodes[0].add_p2p_connection(P2PIgnoreInv())
5159

5260
expected_services = NODE_WITNESS | NODE_NETWORK_LIMITED
61+
if self.options.v2transport:
62+
expected_services |= NODE_P2P_V2
5363

5464
self.log.info("Check that node has signalled expected services.")
5565
assert_equal(node.nServices, expected_services)

test/functional/p2p_timeouts.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,27 @@ def run_test(self):
6868

6969
with self.nodes[0].assert_debug_log(['Unsupported message "ping" prior to verack from peer=0']):
7070
no_verack_node.send_message(msg_ping())
71-
with self.nodes[0].assert_debug_log(['non-version message before version handshake. Message "ping" from peer=1']):
72-
no_version_node.send_message(msg_ping())
7371

74-
self.mock_forward(1)
72+
# With v2, non-version messages before the handshake would be interpreted as part of the key exchange.
73+
# Therefore, don't execute this part of the test if v2transport is chosen.
74+
if not self.options.v2transport:
75+
with self.nodes[0].assert_debug_log(['non-version message before version handshake. Message "ping" from peer=1']):
76+
no_version_node.send_message(msg_ping())
7577

78+
self.mock_forward(1)
7679
assert "version" in no_verack_node.last_message
7780

7881
assert no_verack_node.is_connected
7982
assert no_version_node.is_connected
8083
assert no_send_node.is_connected
8184

8285
no_verack_node.send_message(msg_ping())
83-
no_version_node.send_message(msg_ping())
86+
if not self.options.v2transport:
87+
no_version_node.send_message(msg_ping())
8488

8589
expected_timeout_logs = [
8690
"version handshake timeout peer=0",
87-
"socket no message in first 3 seconds, 1 0 peer=1",
91+
f"socket no message in first 3 seconds, {'0' if self.options.v2transport else '1'} 0 peer=1",
8892
"socket no message in first 3 seconds, 0 0 peer=2",
8993
]
9094

@@ -100,5 +104,6 @@ def run_test(self):
100104
extra_args=['-peertimeout=0'],
101105
)
102106

107+
103108
if __name__ == '__main__':
104109
TimeoutsTest().main()

test/functional/rpc_net.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def test_getpeerinfo(self):
150150
"synced_blocks": -1,
151151
"synced_headers": -1,
152152
"timeoffset": 0,
153-
"transport_protocol_type": "v1",
153+
"transport_protocol_type": "v1" if not self.options.v2transport else "detecting",
154154
"version": 0,
155155
},
156156
)
@@ -160,19 +160,23 @@ def test_getpeerinfo(self):
160160
def test_getnettotals(self):
161161
self.log.info("Test getnettotals")
162162
# Test getnettotals and getpeerinfo by doing a ping. The bytes
163-
# sent/received should increase by at least the size of one ping (32
164-
# bytes) and one pong (32 bytes).
163+
# sent/received should increase by at least the size of one ping
164+
# and one pong. Both have a payload size of 8 bytes, but the total
165+
# size depends on the used p2p version:
166+
# - p2p v1: 24 bytes (header) + 8 bytes (payload) = 32 bytes
167+
# - p2p v2: 21 bytes (header/tag with short-id) + 8 bytes (payload) = 29 bytes
168+
ping_size = 32 if not self.options.v2transport else 29
165169
net_totals_before = self.nodes[0].getnettotals()
166170
peer_info_before = self.nodes[0].getpeerinfo()
167171

168172
self.nodes[0].ping()
169-
self.wait_until(lambda: (self.nodes[0].getnettotals()['totalbytessent'] >= net_totals_before['totalbytessent'] + 32 * 2), timeout=1)
170-
self.wait_until(lambda: (self.nodes[0].getnettotals()['totalbytesrecv'] >= net_totals_before['totalbytesrecv'] + 32 * 2), timeout=1)
173+
self.wait_until(lambda: (self.nodes[0].getnettotals()['totalbytessent'] >= net_totals_before['totalbytessent'] + ping_size * 2), timeout=1)
174+
self.wait_until(lambda: (self.nodes[0].getnettotals()['totalbytesrecv'] >= net_totals_before['totalbytesrecv'] + ping_size * 2), timeout=1)
171175

172176
for peer_before in peer_info_before:
173177
peer_after = lambda: next(p for p in self.nodes[0].getpeerinfo() if p['id'] == peer_before['id'])
174-
self.wait_until(lambda: peer_after()['bytesrecv_per_msg'].get('pong', 0) >= peer_before['bytesrecv_per_msg'].get('pong', 0) + 32, timeout=1)
175-
self.wait_until(lambda: peer_after()['bytessent_per_msg'].get('ping', 0) >= peer_before['bytessent_per_msg'].get('ping', 0) + 32, timeout=1)
178+
self.wait_until(lambda: peer_after()['bytesrecv_per_msg'].get('pong', 0) >= peer_before['bytesrecv_per_msg'].get('pong', 0) + ping_size, timeout=1)
179+
self.wait_until(lambda: peer_after()['bytessent_per_msg'].get('ping', 0) >= peer_before['bytessent_per_msg'].get('ping', 0) + ping_size, timeout=1)
176180

177181
def test_getnetworkinfo(self):
178182
self.log.info("Test getnetworkinfo")
@@ -345,7 +349,10 @@ def test_sendmsgtopeer(self):
345349
node = self.nodes[0]
346350

347351
self.restart_node(0)
348-
self.connect_nodes(0, 1)
352+
# we want to use a p2p v1 connection here in order to ensure
353+
# a peer id of zero (a downgrade from v2 to v1 would lead
354+
# to an increase of the peer id)
355+
self.connect_nodes(0, 1, peer_advertises_v2=False)
349356

350357
self.log.info("Test sendmsgtopeer")
351358
self.log.debug("Send a valid message")

test/functional/test_framework/test_framework.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,6 @@ def get_bin_from_version(version, bin_name, bin_default):
507507
assert_equal(len(binary_cli), num_nodes)
508508
for i in range(num_nodes):
509509
args = list(extra_args[i])
510-
if self.options.v2transport and ("-v2transport=0" not in args):
511-
args.append("-v2transport=1")
512510
test_node_i = TestNode(
513511
i,
514512
get_datadir_path(self.options.tmpdir, i),
@@ -527,6 +525,7 @@ def get_bin_from_version(version, bin_name, bin_default):
527525
start_perf=self.options.perf,
528526
use_valgrind=self.options.valgrind,
529527
descriptors=self.options.descriptors,
528+
v2transport=self.options.v2transport,
530529
)
531530
self.nodes.append(test_node_i)
532531
if not test_node_i.version_is_at_least(170000):
@@ -601,7 +600,7 @@ def connect_nodes(self, a, b, *, peer_advertises_v2=None, wait_for_connect: bool
601600
ip_port = "127.0.0.1:" + str(p2p_port(b))
602601

603602
if peer_advertises_v2 is None:
604-
peer_advertises_v2 = self.options.v2transport
603+
peer_advertises_v2 = from_connection.use_v2transport
605604

606605
if peer_advertises_v2:
607606
from_connection.addnode(node=ip_port, command="onetry", v2transport=True)

test/functional/test_framework/test_node.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class TestNode():
6767
To make things easier for the test writer, any unrecognised messages will
6868
be dispatched to the RPC connection."""
6969

70-
def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor, bitcoind, bitcoin_cli, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False, use_valgrind=False, version=None, descriptors=False):
70+
def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor, bitcoind, bitcoin_cli, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False, use_valgrind=False, version=None, descriptors=False, v2transport=False):
7171
"""
7272
Kwargs:
7373
start_perf (bool): If True, begin profiling the node with `perf` as soon as
@@ -126,6 +126,12 @@ def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor,
126126
if self.version_is_at_least(239000):
127127
self.args.append("-loglevel=trace")
128128

129+
# Default behavior from global -v2transport flag is added to args to persist it over restarts.
130+
# May be overwritten in individual tests, using extra_args.
131+
self.default_to_v2 = v2transport
132+
if self.default_to_v2:
133+
self.args.append("-v2transport=1")
134+
129135
self.cli = TestNodeCLI(bitcoin_cli, self.datadir_path)
130136
self.use_cli = use_cli
131137
self.start_perf = start_perf
@@ -198,6 +204,8 @@ def start(self, extra_args=None, *, cwd=None, stdout=None, stderr=None, env=None
198204
if extra_args is None:
199205
extra_args = self.extra_args
200206

207+
self.use_v2transport = "-v2transport=1" in extra_args or (self.default_to_v2 and "-v2transport=0" not in extra_args)
208+
201209
# Add a new stdout and stderr file each time bitcoind is started
202210
if stderr is None:
203211
stderr = tempfile.NamedTemporaryFile(dir=self.stderr_dir, delete=False)
@@ -782,15 +790,15 @@ def batch(self, requests):
782790
results.append(dict(error=e))
783791
return results
784792

785-
def send_cli(self, command=None, *args, **kwargs):
793+
def send_cli(self, clicommand=None, *args, **kwargs):
786794
"""Run bitcoin-cli command. Deserializes returned string as python object."""
787795
pos_args = [arg_to_cli(arg) for arg in args]
788796
named_args = [str(key) + "=" + arg_to_cli(value) for (key, value) in kwargs.items()]
789797
p_args = [self.binary, f"-datadir={self.datadir}"] + self.options
790798
if named_args:
791799
p_args += ["-named"]
792-
if command is not None:
793-
p_args += [command]
800+
if clicommand is not None:
801+
p_args += [clicommand]
794802
p_args += pos_args + named_args
795803
self.log.debug("Running bitcoin-cli {}".format(p_args[2:]))
796804
process = subprocess.Popen(p_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

test/functional/test_runner.py

+3
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
'p2p_invalid_messages.py',
157157
'rpc_createmultisig.py',
158158
'p2p_timeouts.py',
159+
'p2p_timeouts.py --v2transport',
159160
'wallet_dump.py --legacy-wallet',
160161
'rpc_signer.py',
161162
'wallet_signer.py --descriptors',
@@ -243,6 +244,7 @@
243244
'p2p_getdata.py',
244245
'p2p_addrfetch.py',
245246
'rpc_net.py',
247+
'rpc_net.py --v2transport',
246248
'wallet_keypool.py --legacy-wallet',
247249
'wallet_keypool.py --descriptors',
248250
'wallet_descriptor.py --descriptors',
@@ -368,6 +370,7 @@
368370
'wallet_orphanedreward.py',
369371
'wallet_timelock.py',
370372
'p2p_node_network_limited.py',
373+
'p2p_node_network_limited.py --v2transport',
371374
'p2p_permissions.py',
372375
'feature_blocksdir.py',
373376
'wallet_startup.py',

0 commit comments

Comments
 (0)