Skip to content

Commit e42ba13

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#26448: test: fix intermittent failure in p2p_sendtxrcncl.py
74d9753 test: fix intermittent failure in p2p_sendtxrcncl.py (Martin Zumsande) Pull request description: `p2p_sendtxrcncl.py` currently fails intermittently in the CI, see e.g. https://cirrus-ci.com/task/5511952184115200?logs=ci#L4024 I believe that this is related to the reuse of the parameter `p2p_idx=2` of `add_outbound_p2p_connection` in this test: When we call `peer_disconnect`, we don't wait until the node has completed the disconnection. So there is a race between setting up the next connection (next `addconnection` RPC), and if the old one hasn't been removed and has an identical port like the new one (because we didn't increment `p2p_idx`), `CConnman::OpenNetworkConnection` just [returns](https://github.com/bitcoin/bitcoin/blob/5274f324375fd31cf8507531fbc612765d03092f/src/net.cpp#L1976) without establishing a connection, and the test fails. Fix this by using distinct `disconnect_p2ps` instead of `peer_disconnect`, which waits for the disconnect to complete. We can then use the same value for `p2p_idx` everywhere. ACKs for top commit: MarcoFalke: review ACK 74d9753 Tree-SHA512: f99f2550b6b320c0a2416a475c1cf189c009fce3a5abf1d4462486e1bfe309e2c3fd4228a4009b0ca38cb77465ce85e3d22298719eb07302fa0a72fbab0e0668
2 parents 83cf055 + 74d9753 commit e42ba13

File tree

2 files changed

+19
-15
lines changed

2 files changed

+19
-15
lines changed

test/functional/p2p_sendtxrcncl.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ def run_test(self):
7474
assert not peer.sendtxrcncl_msg_received.initiator
7575
assert peer.sendtxrcncl_msg_received.responder
7676
assert_equal(peer.sendtxrcncl_msg_received.version, 1)
77-
peer.peer_disconnect()
77+
self.nodes[0].disconnect_p2ps()
7878

7979
self.log.info('SENDTXRCNCL should be sent before VERACK')
8080
peer = self.nodes[0].add_p2p_connection(PeerTrackMsgOrder(), send_version=True, wait_for_verack=True)
8181
peer.wait_for_verack()
8282
verack_index = [i for i, msg in enumerate(peer.messages) if msg.msgtype == b'verack'][0]
8383
sendtxrcncl_index = [i for i, msg in enumerate(peer.messages) if msg.msgtype == b'sendtxrcncl'][0]
8484
assert(sendtxrcncl_index < verack_index)
85-
peer.peer_disconnect()
85+
self.nodes[0].disconnect_p2ps()
8686

8787
self.log.info('SENDTXRCNCL on pre-WTXID version should not be sent')
8888
peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=False, wait_for_verack=False)
@@ -94,7 +94,7 @@ def run_test(self):
9494
peer.send_message(pre_wtxid_version_msg)
9595
peer.wait_for_verack()
9696
assert not peer.sendtxrcncl_msg_received
97-
peer.peer_disconnect()
97+
self.nodes[0].disconnect_p2ps()
9898

9999
self.log.info('SENDTXRCNCL for fRelay=false should not be sent')
100100
peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=False, wait_for_verack=False)
@@ -106,7 +106,7 @@ def run_test(self):
106106
peer.send_message(no_txrelay_version_msg)
107107
peer.wait_for_verack()
108108
assert not peer.sendtxrcncl_msg_received
109-
peer.peer_disconnect()
109+
self.nodes[0].disconnect_p2ps()
110110

111111
self.log.info('valid SENDTXRCNCL received')
112112
peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
@@ -152,39 +152,39 @@ def run_test(self):
152152
with self.nodes[0].assert_debug_log(['Forget txreconciliation state of peer']):
153153
peer.send_message(create_sendtxrcncl_msg())
154154
peer.send_message(msg_verack())
155-
peer.peer_disconnect()
155+
self.nodes[0].disconnect_p2ps()
156156

157157
self.log.info('SENDTXRCNCL sent to an outbound')
158158
peer = self.nodes[0].add_outbound_p2p_connection(
159-
SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=1, connection_type="outbound-full-relay")
159+
SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="outbound-full-relay")
160160
assert peer.sendtxrcncl_msg_received
161161
assert peer.sendtxrcncl_msg_received.initiator
162162
assert not peer.sendtxrcncl_msg_received.responder
163163
assert_equal(peer.sendtxrcncl_msg_received.version, 1)
164-
peer.peer_disconnect()
164+
self.nodes[0].disconnect_p2ps()
165165

166166
self.log.info('SENDTXRCNCL should not be sent if block-relay-only')
167167
peer = self.nodes[0].add_outbound_p2p_connection(
168-
SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=2, connection_type="block-relay-only")
168+
SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="block-relay-only")
169169
assert not peer.sendtxrcncl_msg_received
170-
peer.peer_disconnect()
170+
self.nodes[0].disconnect_p2ps()
171171

172172
self.log.info("SENDTXRCNCL should not be sent if feeler")
173-
peer = self.nodes[0].add_outbound_p2p_connection(P2PFeelerReceiver(), p2p_idx=2, connection_type="feeler")
173+
peer = self.nodes[0].add_outbound_p2p_connection(P2PFeelerReceiver(), p2p_idx=0, connection_type="feeler")
174174
assert not peer.sendtxrcncl_msg_received
175-
peer.peer_disconnect()
175+
self.nodes[0].disconnect_p2ps()
176176

177177
self.log.info('SENDTXRCNCL if block-relay-only triggers a disconnect')
178178
peer = self.nodes[0].add_outbound_p2p_connection(
179-
PeerNoVerack(), wait_for_verack=False, p2p_idx=3, connection_type="block-relay-only")
179+
PeerNoVerack(), wait_for_verack=False, p2p_idx=0, connection_type="block-relay-only")
180180
with self.nodes[0].assert_debug_log(["we indicated no tx relay; disconnecting"]):
181181
peer.send_message(create_sendtxrcncl_msg(initiator=False))
182182
peer.wait_for_disconnect()
183183

184184
self.log.info('SENDTXRCNCL with initiator=1 and responder=0 from outbound triggers a disconnect')
185185
sendtxrcncl_wrong_role = create_sendtxrcncl_msg(initiator=True)
186186
peer = self.nodes[0].add_outbound_p2p_connection(
187-
PeerNoVerack(), wait_for_verack=False, p2p_idx=4, connection_type="outbound-full-relay")
187+
PeerNoVerack(), wait_for_verack=False, p2p_idx=0, connection_type="outbound-full-relay")
188188
with self.nodes[0].assert_debug_log(["txreconciliation protocol violation"]):
189189
peer.send_message(sendtxrcncl_wrong_role)
190190
peer.wait_for_disconnect()
@@ -193,13 +193,13 @@ def run_test(self):
193193
self.restart_node(0, [])
194194
peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
195195
assert not peer.sendtxrcncl_msg_received
196-
peer.peer_disconnect()
196+
self.nodes[0].disconnect_p2ps()
197197

198198
self.log.info('SENDTXRCNCL not sent if blocksonly is set')
199199
self.restart_node(0, ["-txreconciliation", "-blocksonly"])
200200
peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
201201
assert not peer.sendtxrcncl_msg_received
202-
peer.peer_disconnect()
202+
self.nodes[0].disconnect_p2ps()
203203

204204

205205
if __name__ == '__main__':

test/functional/test_framework/test_node.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,10 @@ def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx
625625
626626
This method adds the p2p connection to the self.p2ps list and returns
627627
the connection to the caller.
628+
629+
p2p_idx must be different for simultaneously connected peers. When reusing it for the next peer
630+
after disconnecting the previous one, it is necessary to wait for the disconnect to finish to avoid
631+
a race condition.
628632
"""
629633

630634
def addconnection_callback(address, port):

0 commit comments

Comments
 (0)