66Test P2P behaviour during the handshake phase (VERSION, VERACK messages).
77"""
88import itertools
9+ import time
910
1011from test_framework .test_framework import BitcoinTestFramework
1112from test_framework .messages import (
1213 NODE_NETWORK ,
14+ NODE_NETWORK_LIMITED ,
1315 NODE_NONE ,
1416 NODE_P2P_V2 ,
1517 NODE_WITNESS ,
1618)
1719from test_framework .p2p import P2PInterface
1820
1921
20- # usual desirable service flags for outbound non-pruned peers
21- DESIRABLE_SERVICE_FLAGS = NODE_NETWORK | NODE_WITNESS
22+ # Desirable service flags for outbound non-pruned and pruned peers. Note that
23+ # the desirable service flags for pruned peers are dynamic and only apply if
24+ # 1. the peer's service flag NODE_NETWORK_LIMITED is set *and*
25+ # 2. the local chain is close to the tip (<24h)
26+ DESIRABLE_SERVICE_FLAGS_FULL = NODE_NETWORK | NODE_WITNESS
27+ DESIRABLE_SERVICE_FLAGS_PRUNED = NODE_NETWORK_LIMITED | NODE_WITNESS
2228
2329
2430class P2PHandshakeTest (BitcoinTestFramework ):
@@ -36,7 +42,7 @@ def add_outbound_connection(self, node, connection_type, services, wait_for_disc
3642 peer .peer_disconnect ()
3743 peer .wait_for_disconnect ()
3844
39- def test_desirable_service_flags (self , node , service_flag_tests , expect_disconnect ):
45+ def test_desirable_service_flags (self , node , service_flag_tests , desirable_service_flags , expect_disconnect ):
4046 """Check that connecting to a peer either fails or succeeds depending on its offered
4147 service flags in the VERSION message. The test is exercised for all relevant
4248 outbound connection types where the desirable service flags check is done."""
@@ -47,18 +53,30 @@ def test_desirable_service_flags(self, node, service_flag_tests, expect_disconne
4753 expected_result = "disconnect" if expect_disconnect else "connect"
4854 self .log .info (f' - services 0x{ services :08x} , type "{ conn_type } " [{ expected_result } ]' )
4955 if expect_disconnect :
56+ assert (services & desirable_service_flags ) != desirable_service_flags
5057 expected_debug_log = f'does not offer the expected services ' \
51- f'({ services :08x} offered, { DESIRABLE_SERVICE_FLAGS :08x} expected)'
58+ f'({ services :08x} offered, { desirable_service_flags :08x} expected)'
5259 with node .assert_debug_log ([expected_debug_log ]):
5360 self .add_outbound_connection (node , conn_type , services , wait_for_disconnect = True )
5461 else :
62+ assert (services & desirable_service_flags ) == desirable_service_flags
5563 self .add_outbound_connection (node , conn_type , services , wait_for_disconnect = False )
5664
5765 def run_test (self ):
5866 node = self .nodes [0 ]
5967 self .log .info ("Check that lacking desired service flags leads to disconnect (non-pruned peers)" )
60- self .test_desirable_service_flags (node , [NODE_NONE , NODE_NETWORK , NODE_WITNESS ], expect_disconnect = True )
61- self .test_desirable_service_flags (node , [NODE_NETWORK | NODE_WITNESS ], expect_disconnect = False )
68+ self .test_desirable_service_flags (node , [NODE_NONE , NODE_NETWORK , NODE_WITNESS ],
69+ DESIRABLE_SERVICE_FLAGS_FULL , expect_disconnect = True )
70+ self .test_desirable_service_flags (node , [NODE_NETWORK | NODE_WITNESS ],
71+ DESIRABLE_SERVICE_FLAGS_FULL , expect_disconnect = False )
72+
73+ self .log .info ("Check that limited peers are only desired if the local chain is close to the tip (<24h)" )
74+ node .setmocktime (int (time .time ()) + 25 * 3600 ) # tip outside the 24h window, should fail
75+ self .test_desirable_service_flags (node , [NODE_NETWORK_LIMITED | NODE_WITNESS ],
76+ DESIRABLE_SERVICE_FLAGS_FULL , expect_disconnect = True )
77+ node .setmocktime (int (time .time ()) + 23 * 3600 ) # tip inside the 24h window, should succeed
78+ self .test_desirable_service_flags (node , [NODE_NETWORK_LIMITED | NODE_WITNESS ],
79+ DESIRABLE_SERVICE_FLAGS_PRUNED , expect_disconnect = False )
6280
6381 self .log .info ("Check that feeler connections get disconnected immediately" )
6482 with node .assert_debug_log ([f"feeler connection completed" ]):
0 commit comments