Skip to content

Commit d4209fc

Browse files
committed
test: Fix intermittent failure in p2p_v2_misbehaving.py
The ellswift bytes are computed in the NetworkThread and sent in the MainThread. Add a `wait_until()` to make sure that ellswift computation is completed in NetworkThread before sending it in the MainThread. Also use mocktime for more robust disconnection checking.
1 parent 9adebe1 commit d4209fc

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

test/functional/p2p_v2_misbehaving.py

+27-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

66
import random
7+
import time
78
from enum import Enum
89

910
from test_framework.messages import MAGIC_BYTES
@@ -128,6 +129,10 @@ def set_test_params(self):
128129
self.num_nodes = 1
129130
self.extra_args = [["-v2transport=1", "-peertimeout=3"]]
130131

132+
def mock_forward(self, delta):
133+
self.mock_time += delta
134+
self.nodes[0].setmocktime(self.mock_time)
135+
131136
def run_test(self):
132137
self.test_earlykeyresponse()
133138
self.test_v2disconnection()
@@ -136,25 +141,34 @@ def test_earlykeyresponse(self):
136141
self.log.info('Sending ellswift bytes in parts to ensure that response from responder is received only when')
137142
self.log.info('ellswift bytes have a mismatch from the 16 bytes(network magic followed by "version\\x00\\x00\\x00\\x00\\x00")')
138143
node0 = self.nodes[0]
144+
self.mock_time = int(time.time())
145+
self.mock_forward(0)
139146
self.log.info('Sending first 4 bytes of ellswift which match network magic')
140147
self.log.info('If a response is received, assertion failure would happen in our custom data_received() function')
141148
peer1 = node0.add_p2p_connection(MisbehavingV2Peer(TestType.EARLY_KEY_RESPONSE), wait_for_verack=False, send_version=False, supports_v2_p2p=True, wait_for_v2_handshake=False)
142149
peer1.send_raw_message(MAGIC_BYTES['regtest'])
143150
self.log.info('Sending remaining ellswift and garbage which are different from V1_PREFIX. Since a response is')
144151
self.log.info('expected now, our custom data_received() function wouldn\'t result in assertion failure')
145152
peer1.v2_state.can_data_be_received = True
153+
self.wait_until(lambda: peer1.v2_state.ellswift_ours)
146154
peer1.send_raw_message(peer1.v2_state.ellswift_ours[4:] + peer1.v2_state.sent_garbage)
155+
self.mock_forward(3)
156+
# `InactivityCheck()` displays a different net log message compared to the one specified below if `sendSet` isn't populated.
157+
# Make a passing connection so that there's time to populate `sendSet` for consistent logging.
158+
peer2 = node0.add_p2p_connection(P2PInterface())
159+
assert peer2.is_connected
147160
with node0.assert_debug_log(['V2 handshake timeout peer=0']):
148-
peer1.wait_for_disconnect(timeout=5)
161+
self.mock_forward(1) # `InactivityCheck()` triggers now
162+
peer1.wait_for_disconnect(timeout=1)
149163
self.log.info('successful disconnection since modified ellswift was sent as response')
150164

151165
def test_v2disconnection(self):
152166
# test v2 disconnection scenarios
153167
node0 = self.nodes[0]
154168
expected_debug_message = [
155169
[], # EARLY_KEY_RESPONSE
156-
["V2 transport error: missing garbage terminator, peer=1"], # EXCESS_GARBAGE
157-
["V2 handshake timeout peer=2"], # WRONG_GARBAGE_TERMINATOR
170+
["V2 transport error: missing garbage terminator, peer=2"], # EXCESS_GARBAGE
171+
["V2 handshake timeout peer=4"], # WRONG_GARBAGE_TERMINATOR
158172
["V2 transport error: packet decryption failure"], # WRONG_GARBAGE
159173
["V2 transport error: packet decryption failure"], # SEND_NO_AAD
160174
[], # SEND_NON_EMPTY_VERSION_PACKET
@@ -167,8 +181,16 @@ def test_v2disconnection(self):
167181
self.log.info(f"No disconnection for {test_type.name}")
168182
else:
169183
with node0.assert_debug_log(expected_debug_message[test_type.value], timeout=5):
170-
peer = node0.add_p2p_connection(MisbehavingV2Peer(test_type), wait_for_verack=False, send_version=False, supports_v2_p2p=True, expect_success=False)
171-
peer.wait_for_disconnect()
184+
self.mock_time = int(time.time())
185+
self.mock_forward(0)
186+
peer1 = node0.add_p2p_connection(MisbehavingV2Peer(test_type), wait_for_verack=False, send_version=False, supports_v2_p2p=True, expect_success=False)
187+
# `InactivityCheck()` displays a different net log message compared to the one specified below if `sendSet` isn't populated.
188+
# Make a passing connection so that there's time to populate `sendSet` for consistent logging
189+
# and for more robust disconnection checking.
190+
peer2 = node0.add_p2p_connection(P2PInterface())
191+
assert peer2.is_connected
192+
self.mock_forward(4) # `InactivityCheck()` triggers now
193+
peer1.wait_for_disconnect()
172194
self.log.info(f"Expected disconnection for {test_type.name}")
173195

174196

0 commit comments

Comments
 (0)