Skip to content

Commit f7653eb

Browse files
author
MarcoFalke
committed
Merge bitcoin#21345: test: bring p2p_leak.py up to date
a061a29 test: bring p2p_leak.py up to date. (Martin Zumsande) Pull request description: After the introduction of wtxidrelay and sendaddrv2 messages during version handshake, extend p2p_leak.py test to reflect this. Also, some minor fixes and doc improvements. I also added a test that peers not completing the version handshake will be disconnected for timeout, as suggested by MarcoFalke in bitcoin#19723 (comment). ACKs for top commit: brunoerg: Tested ACK a061a29 theStack: Tested ACK a061a29 Tree-SHA512: 26c601491fa8710fc972d1b8f15da6b387a95b42bbfb629ec4c668769ad3824b6dd6a33d97363bca2171e403d8d1ce08abf3e5c9cab34f98d53e0109b1c7a0e5
2 parents da8c7ed + a061a29 commit f7653eb

File tree

1 file changed

+46
-18
lines changed

1 file changed

+46
-18
lines changed

test/functional/p2p_leak.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test message sending before handshake completion.
66
7-
A node should never send anything other than VERSION/VERACK until it's
8-
received a VERACK.
7+
Before receiving a VERACK, a node should not send anything but VERSION/VERACK
8+
and feature negotiation messages (WTXIDRELAY, SENDADDRV2).
99
1010
This test connects to a node and sends it a few messages, trying to entice it
1111
into sending us something it shouldn't."""
@@ -35,10 +35,12 @@ def __init__(self):
3535
super().__init__()
3636
self.unexpected_msg = False
3737
self.ever_connected = False
38+
self.got_wtxidrelay = False
39+
self.got_sendaddrv2 = False
3840

3941
def bad_message(self, message):
4042
self.unexpected_msg = True
41-
self.log.info("should not have received message: %s" % message.msgtype)
43+
print("should not have received message: %s" % message.msgtype)
4244

4345
def on_open(self):
4446
self.ever_connected = True
@@ -64,6 +66,8 @@ def on_sendcmpct(self, message): self.bad_message(message)
6466
def on_cmpctblock(self, message): self.bad_message(message)
6567
def on_getblocktxn(self, message): self.bad_message(message)
6668
def on_blocktxn(self, message): self.bad_message(message)
69+
def on_wtxidrelay(self, message): self.got_wtxidrelay = True
70+
def on_sendaddrv2(self, message): self.got_sendaddrv2 = True
6771

6872

6973
# Peer that sends a version but not a verack.
@@ -94,32 +98,61 @@ def on_version(self, msg):
9498
class P2PLeakTest(BitcoinTestFramework):
9599
def set_test_params(self):
96100
self.num_nodes = 1
101+
self.extra_args = [['-peertimeout=4']]
102+
103+
def create_old_version(self, nversion):
104+
old_version_msg = msg_version()
105+
old_version_msg.nVersion = nversion
106+
old_version_msg.strSubVer = P2P_SUBVERSION
107+
old_version_msg.nServices = P2P_SERVICES
108+
old_version_msg.relay = P2P_VERSION_RELAY
109+
return old_version_msg
97110

98111
def run_test(self):
99-
# Another peer that never sends a version, nor any other messages. It shouldn't receive anything from the node.
112+
self.log.info('Check that the node doesn\'t send unexpected messages before handshake completion')
113+
# Peer that never sends a version, nor any other messages. It shouldn't receive anything from the node.
100114
no_version_idle_peer = self.nodes[0].add_p2p_connection(LazyPeer(), send_version=False, wait_for_verack=False)
101115

102116
# Peer that sends a version but not a verack.
103117
no_verack_idle_peer = self.nodes[0].add_p2p_connection(NoVerackIdlePeer(), wait_for_verack=False)
104118

105-
# Wait until we got the verack in response to the version. Though, don't wait for the node to receive the
106-
# verack, since we never sent one
119+
# Pre-wtxidRelay peer that sends a version but not a verack and does not support feature negotiation
120+
# messages which start at nVersion == 70016
121+
pre_wtxidrelay_peer = self.nodes[0].add_p2p_connection(NoVerackIdlePeer(), send_version=False, wait_for_verack=False)
122+
pre_wtxidrelay_peer.send_message(self.create_old_version(70015))
123+
124+
# Wait until the peer gets the verack in response to the version. Though, don't wait for the node to receive the
125+
# verack, since the peer never sent one
107126
no_verack_idle_peer.wait_for_verack()
127+
pre_wtxidrelay_peer.wait_for_verack()
108128

109129
no_version_idle_peer.wait_until(lambda: no_version_idle_peer.ever_connected)
110130
no_verack_idle_peer.wait_until(lambda: no_verack_idle_peer.version_received)
131+
pre_wtxidrelay_peer.wait_until(lambda: pre_wtxidrelay_peer.version_received)
111132

112133
# Mine a block and make sure that it's not sent to the connected peers
113134
self.nodes[0].generate(nblocks=1)
114135

115-
#Give the node enough time to possibly leak out a message
136+
# Give the node enough time to possibly leak out a message
116137
time.sleep(5)
117138

118-
self.nodes[0].disconnect_p2ps()
139+
# Make sure only expected messages came in
140+
assert not no_version_idle_peer.unexpected_msg
141+
assert not no_version_idle_peer.got_wtxidrelay
142+
assert not no_version_idle_peer.got_sendaddrv2
119143

120-
# Make sure no unexpected messages came in
121-
assert no_version_idle_peer.unexpected_msg == False
122-
assert no_verack_idle_peer.unexpected_msg == False
144+
assert not no_verack_idle_peer.unexpected_msg
145+
assert no_verack_idle_peer.got_wtxidrelay
146+
assert no_verack_idle_peer.got_sendaddrv2
147+
148+
assert not pre_wtxidrelay_peer.unexpected_msg
149+
assert not pre_wtxidrelay_peer.got_wtxidrelay
150+
assert not pre_wtxidrelay_peer.got_sendaddrv2
151+
152+
# Expect peers to be disconnected due to timeout
153+
assert not no_version_idle_peer.is_connected
154+
assert not no_verack_idle_peer.is_connected
155+
assert not pre_wtxidrelay_peer.is_connected
123156

124157
self.log.info('Check that the version message does not leak the local address of the node')
125158
p2p_version_store = self.nodes[0].add_p2p_connection(P2PVersionStore())
@@ -134,13 +167,8 @@ def run_test(self):
134167

135168
self.log.info('Check that old peers are disconnected')
136169
p2p_old_peer = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
137-
old_version_msg = msg_version()
138-
old_version_msg.nVersion = 31799
139-
old_version_msg.strSubVer = P2P_SUBVERSION
140-
old_version_msg.nServices = P2P_SERVICES
141-
old_version_msg.relay = P2P_VERSION_RELAY
142-
with self.nodes[0].assert_debug_log(['peer=3 using obsolete version 31799; disconnecting']):
143-
p2p_old_peer.send_message(old_version_msg)
170+
with self.nodes[0].assert_debug_log(['peer=4 using obsolete version 31799; disconnecting']):
171+
p2p_old_peer.send_message(self.create_old_version(31799))
144172
p2p_old_peer.wait_for_disconnect()
145173

146174

0 commit comments

Comments
 (0)