Skip to content

Commit 8c054aa

Browse files
committed
[test] Allow inbound and outbound connections supporting v2 P2P protocol
- Add an optional `supports_v2_p2p` parameter to specify if the inbound and outbound connections support v2 P2P protocol. - In the `addconnection_callback` which gets called when creating outbound connections, call the `addconnection` RPC with v2 P2P protocol support enabled.
1 parent 382894c commit 8c054aa

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

test/functional/rpc_net.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,10 @@ def test_addnode_getaddednodeinfo(self):
241241
def test_service_flags(self):
242242
self.log.info("Test service flags")
243243
self.nodes[0].add_p2p_connection(P2PInterface(), services=(1 << 4) | (1 << 63))
244-
assert_equal(['UNKNOWN[2^4]', 'UNKNOWN[2^63]'], self.nodes[0].getpeerinfo()[-1]['servicesnames'])
244+
if self.options.v2transport:
245+
assert_equal(['UNKNOWN[2^4]', 'P2P_V2', 'UNKNOWN[2^63]'], self.nodes[0].getpeerinfo()[-1]['servicesnames'])
246+
else:
247+
assert_equal(['UNKNOWN[2^4]', 'UNKNOWN[2^63]'], self.nodes[0].getpeerinfo()[-1]['servicesnames'])
245248
self.nodes[0].disconnect_p2ps()
246249

247250
def test_getnodeaddresses(self):

test/functional/test_framework/test_node.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
serialization_fallback,
2828
)
2929
from .descriptors import descsum_create
30-
from .p2p import P2P_SUBVERSION
30+
from .messages import NODE_P2P_V2
31+
from .p2p import P2P_SERVICES, P2P_SUBVERSION
3132
from .util import (
3233
MAX_NODES,
3334
assert_equal,
@@ -646,13 +647,24 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, send_version=Tru
646647
"""Add an inbound p2p connection to the node.
647648
648649
This method adds the p2p connection to the self.p2ps list and also
649-
returns the connection to the caller."""
650+
returns the connection to the caller.
651+
652+
When self.use_v2transport is True, TestNode advertises NODE_P2P_V2 service flag
653+
654+
An inbound connection is made from TestNode <------ P2PConnection
655+
- if TestNode doesn't advertise NODE_P2P_V2 service, P2PConnection sends version message and v1 P2P is followed
656+
- if TestNode advertises NODE_P2P_V2 service, (and if P2PConnections supports v2 P2P)
657+
P2PConnection sends ellswift bytes and v2 P2P is followed
658+
"""
650659
if 'dstport' not in kwargs:
651660
kwargs['dstport'] = p2p_port(self.index)
652661
if 'dstaddr' not in kwargs:
653662
kwargs['dstaddr'] = '127.0.0.1'
654663

655664
p2p_conn.p2p_connected_to_node = True
665+
if self.use_v2transport:
666+
kwargs['services'] = kwargs.get('services', P2P_SERVICES) | NODE_P2P_V2
667+
supports_v2_p2p = self.use_v2transport and supports_v2_p2p
656668
p2p_conn.peer_connect(**kwargs, send_version=send_version, net=self.chain, timeout_factor=self.timeout_factor, supports_v2_p2p=supports_v2_p2p)()
657669

658670
self.p2ps.append(p2p_conn)
@@ -685,7 +697,7 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, send_version=Tru
685697

686698
return p2p_conn
687699

688-
def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx, connection_type="outbound-full-relay", supports_v2_p2p=False, **kwargs):
700+
def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx, connection_type="outbound-full-relay", supports_v2_p2p=False, advertise_v2_p2p=False, **kwargs):
689701
"""Add an outbound p2p connection from node. Must be an
690702
"outbound-full-relay", "block-relay-only", "addr-fetch" or "feeler" connection.
691703
@@ -695,14 +707,34 @@ def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx
695707
p2p_idx must be different for simultaneously connected peers. When reusing it for the next peer
696708
after disconnecting the previous one, it is necessary to wait for the disconnect to finish to avoid
697709
a race condition.
710+
711+
Parameters:
712+
supports_v2_p2p: whether p2p_conn supports v2 P2P or not
713+
advertise_v2_p2p: whether p2p_conn is advertised to support v2 P2P or not
714+
715+
An outbound connection is made from TestNode -------> P2PConnection
716+
- if P2PConnection doesn't advertise_v2_p2p, TestNode sends version message and v1 P2P is followed
717+
- if P2PConnection both supports_v2_p2p and advertise_v2_p2p, TestNode sends ellswift bytes and v2 P2P is followed
718+
- if P2PConnection doesn't supports_v2_p2p but advertise_v2_p2p,
719+
TestNode sends ellswift bytes and P2PConnection disconnects,
720+
TestNode reconnects by sending version message and v1 P2P is followed
698721
"""
699722

700723
def addconnection_callback(address, port):
701724
self.log.debug("Connecting to %s:%d %s" % (address, port, connection_type))
702-
self.addconnection('%s:%d' % (address, port), connection_type)
725+
self.addconnection('%s:%d' % (address, port), connection_type, advertise_v2_p2p)
703726

704727
p2p_conn.p2p_connected_to_node = False
705-
p2p_conn.peer_accept_connection(connect_cb=addconnection_callback, connect_id=p2p_idx + 1, net=self.chain, timeout_factor=self.timeout_factor, supports_v2_p2p=supports_v2_p2p, reconnect=False, **kwargs)()
728+
if advertise_v2_p2p:
729+
kwargs['services'] = kwargs.get('services', P2P_SERVICES) | NODE_P2P_V2
730+
assert self.use_v2transport # only a v2 TestNode could make a v2 outbound connection
731+
732+
# if P2PConnection is advertised to support v2 P2P when it doesn't actually support v2 P2P,
733+
# reconnection needs to be attempted using v1 P2P by sending version message
734+
reconnect = advertise_v2_p2p and not supports_v2_p2p
735+
# P2PConnection needs to be advertised to support v2 P2P so that ellswift bytes are sent instead of msg_version
736+
supports_v2_p2p = supports_v2_p2p and advertise_v2_p2p
737+
p2p_conn.peer_accept_connection(connect_cb=addconnection_callback, connect_id=p2p_idx + 1, net=self.chain, timeout_factor=self.timeout_factor, supports_v2_p2p=supports_v2_p2p, reconnect=reconnect, **kwargs)()
706738

707739
if connection_type == "feeler":
708740
# feeler connections are closed as soon as the node receives a `version` message

0 commit comments

Comments
 (0)