diff options
author | Sebastian Falbesoner <sebastian.falbesoner@gmail.com> | 2024-01-30 04:34:43 +0100 |
---|---|---|
committer | Sebastian Falbesoner <sebastian.falbesoner@gmail.com> | 2024-02-01 13:33:23 +0100 |
commit | c340503b67585b631909584f1acaa327f5af25d3 (patch) | |
tree | ed81146cdf412cbd6479a54e9ea11228e8d79dd8 | |
parent | 7ddfc28309e6b70c273112a93f01e518409ceaa0 (diff) | |
download | bitcoin-c340503b67585b631909584f1acaa327f5af25d3.tar.xz |
test: p2p: adhere to typical VERSION message protocol flow
The test framework's p2p implementation currently sends out it's VERSION
message immediately after an inbound connection (i.e. TestNode outbound
connection) is made. This doesn't follow the usual protocol flow where
the initiator sends a version first, and the responders processes that
and only then responds with its own version message. Change that
accordingly by only sending immediate VERSION message for outbound
connections (or after v2 handshake for v2 connections, respectively),
and sending out VERSION messages as response for incoming VERSION
messages (i.e. in the function `on_version`) for inbound connections.
Note that some of the overruled `on_version` methods in functional tests
needed to be changed to send the version explicitly.
-rwxr-xr-x | test/functional/p2p_add_connections.py | 2 | ||||
-rwxr-xr-x | test/functional/p2p_addr_relay.py | 1 | ||||
-rwxr-xr-x | test/functional/p2p_sendtxrcncl.py | 4 | ||||
-rwxr-xr-x | test/functional/test_framework/p2p.py | 15 |
4 files changed, 14 insertions, 8 deletions
diff --git a/test/functional/p2p_add_connections.py b/test/functional/p2p_add_connections.py index f4462673f2..bd766a279e 100755 --- a/test/functional/p2p_add_connections.py +++ b/test/functional/p2p_add_connections.py @@ -17,7 +17,7 @@ class P2PFeelerReceiver(P2PInterface): # message is received from the test framework. Don't send any responses # to the node's version message since the connection will already be # closed. - pass + self.send_version() class P2PAddConnections(BitcoinTestFramework): def set_test_params(self): diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py index 2adcaf178c..b23ec1028b 100755 --- a/test/functional/p2p_addr_relay.py +++ b/test/functional/p2p_addr_relay.py @@ -75,6 +75,7 @@ class AddrReceiver(P2PInterface): return self.num_ipv4_received != 0 def on_version(self, message): + self.send_version() self.send_message(msg_verack()) if (self.send_getaddr): self.send_message(msg_getaddr()) diff --git a/test/functional/p2p_sendtxrcncl.py b/test/functional/p2p_sendtxrcncl.py index 0e349ef70c..8f5e6c0387 100755 --- a/test/functional/p2p_sendtxrcncl.py +++ b/test/functional/p2p_sendtxrcncl.py @@ -29,6 +29,7 @@ class PeerNoVerack(P2PInterface): # Avoid sending verack in response to version. # When calling add_p2p_connection, wait_for_verack=False must be set (see # comment in add_p2p_connection). + self.send_version() if message.nVersion >= 70016 and self.wtxidrelay: self.send_message(msg_wtxidrelay()) @@ -43,7 +44,8 @@ class SendTxrcnclReceiver(P2PInterface): class P2PFeelerReceiver(SendTxrcnclReceiver): def on_version(self, message): - pass # feeler connections can not send any message other than their own version + # feeler connections can not send any message other than their own version + self.send_version() class PeerTrackMsgOrder(P2PInterface): diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py index d766800902..ddb68dd4e2 100755 --- a/test/functional/test_framework/p2p.py +++ b/test/functional/test_framework/p2p.py @@ -224,9 +224,9 @@ class P2PConnection(asyncio.Protocol): if self.supports_v2_p2p and self.v2_state.initiating and not self.v2_state.tried_v2_handshake: send_handshake_bytes = self.v2_state.initiate_v2_handshake() self.send_raw_message(send_handshake_bytes) - # if v2 connection, send `on_connection_send_msg` after initial v2 handshake. - # if reconnection situation, send `on_connection_send_msg` after version message is received in `on_version()`. - if not self.supports_v2_p2p and not self.reconnect: + # for v1 outbound connections, send version message immediately after opening + # (for v2 outbound connections, send it after the initial v2 handshake) + if self.p2p_connected_to_node and not self.supports_v2_p2p: self.send_version() self.on_open() @@ -284,7 +284,9 @@ class P2PConnection(asyncio.Protocol): raise ValueError("invalid v2 mac tag in handshake authentication") self.recvbuf = self.recvbuf[length:] if self.v2_state.tried_v2_handshake: - self.send_version() + # for v2 outbound connections, send version message immediately after v2 handshake + if self.p2p_connected_to_node: + self.send_version() # process post-v2-handshake data immediately, if available if len(self.recvbuf) > 0: self._on_data() @@ -558,8 +560,9 @@ class P2PInterface(P2PConnection): def on_version(self, message): assert message.nVersion >= MIN_P2P_VERSION_SUPPORTED, "Version {} received. Test framework only supports versions greater than {}".format(message.nVersion, MIN_P2P_VERSION_SUPPORTED) - # reconnection using v1 P2P has happened since version message can be processed, previously unsent version message is sent using v1 P2P here - if self.reconnect: + # for inbound connections, reply to version with own version message + # (could be due to v1 reconnect after a failed v2 handshake) + if not self.p2p_connected_to_node: self.send_version() self.reconnect = False if message.nVersion >= 70016 and self.wtxidrelay: |