2727 serialization_fallback ,
2828)
2929from .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
3132from .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