27
27
serialization_fallback ,
28
28
)
29
29
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
31
32
from .util import (
32
33
MAX_NODES ,
33
34
assert_equal ,
@@ -646,13 +647,24 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, send_version=Tru
646
647
"""Add an inbound p2p connection to the node.
647
648
648
649
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
+ """
650
659
if 'dstport' not in kwargs :
651
660
kwargs ['dstport' ] = p2p_port (self .index )
652
661
if 'dstaddr' not in kwargs :
653
662
kwargs ['dstaddr' ] = '127.0.0.1'
654
663
655
664
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
656
668
p2p_conn .peer_connect (** kwargs , send_version = send_version , net = self .chain , timeout_factor = self .timeout_factor , supports_v2_p2p = supports_v2_p2p )()
657
669
658
670
self .p2ps .append (p2p_conn )
@@ -685,7 +697,7 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, send_version=Tru
685
697
686
698
return p2p_conn
687
699
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 ):
689
701
"""Add an outbound p2p connection from node. Must be an
690
702
"outbound-full-relay", "block-relay-only", "addr-fetch" or "feeler" connection.
691
703
@@ -695,14 +707,34 @@ def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx
695
707
p2p_idx must be different for simultaneously connected peers. When reusing it for the next peer
696
708
after disconnecting the previous one, it is necessary to wait for the disconnect to finish to avoid
697
709
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
698
721
"""
699
722
700
723
def addconnection_callback (address , port ):
701
724
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 )
703
726
704
727
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 )()
706
738
707
739
if connection_type == "feeler" :
708
740
# feeler connections are closed as soon as the node receives a `version` message
0 commit comments