1010from test_framework .util import (
1111 assert_equal ,
1212 assert_not_equal ,
13+ p2p_port ,
14+ tor_port ,
1315)
1416
15- # We need to bind to a routable address for this test to exercise the relevant code
16- # and also must have another routable address on another interface which must not
17- # be named "lo" or "lo0".
18- # To set these routable addresses on the machine, use:
17+ # We need to bind to routable addresses for this test. Both addresses must be on an
18+ # interface that is UP and not a loopback interface (IFF_LOOPBACK). To set these
19+ # routable addresses on the machine, use:
1920# Linux:
20- # ifconfig lo:0 1.1.1.1/32 up && ifconfig lo:1 2.2.2.2/32 up # to set up
21- # ifconfig lo:0 down && ifconfig lo:1 down # to remove it, after the test
21+ # First find your interfaces: ip addr show
22+ # Then use your actual interface names (replace INTERFACE_NAME with yours):
23+ # ip addr add 1.1.1.1/32 dev INTERFACE_NAME && ip addr add 2.2.2.2/32 dev INTERFACE_NAME # to set up
24+ # ip addr del 1.1.1.1/32 dev INTERFACE_NAME && ip addr del 2.2.2.2/32 dev INTERFACE_NAME # to remove it
25+ #
26+ # macOS:
27+ # ifconfig en0 alias 1.1.1.1 && ifconfig en0 alias 2.2.2.2 # to set up
28+ # ifconfig en0 1.1.1.1 -alias && ifconfig en0 2.2.2.2 -alias # to remove it, after the test
29+ #
2230# FreeBSD:
2331# ifconfig em0 1.1.1.1/32 alias && ifconfig wlan0 2.2.2.2/32 alias # to set up
2432# ifconfig em0 1.1.1.1 -alias && ifconfig wlan0 2.2.2.2 -alias # to remove it, after the test
2533ADDR1 = '1.1.1.1'
2634ADDR2 = '2.2.2.2'
2735
28- BIND_PORT = 31001
29-
3036class BindPortDiscoverTest (BitcoinTestFramework ):
3137 def set_test_params (self ):
3238 # Avoid any -bind= on the command line. Force the framework to avoid adding -bind=127.0.0.1.
33- self .setup_clean_chain = True
3439 self .bind_to_localhost_only = False
40+ # Get dynamic ports for each node from the test framework
41+ self .bind_ports = [
42+ p2p_port (0 ),
43+ p2p_port (2 ), # node0 will use their port + 1 for onion listen, which is the same as p2p_port(1), so avoid collision
44+ p2p_port (3 ),
45+ p2p_port (4 ),
46+ ]
3547 self .extra_args = [
36- ['-discover' , f'-port={ BIND_PORT } ' ], # bind on any
37- ['-discover' , f'-bind={ ADDR1 } :{ BIND_PORT } ' ],
48+ ['-discover' , f'-port={ self .bind_ports [0 ]} ' , '-listen=1' ], # Without any -bind
49+ ['-discover' , f'-bind=0.0.0.0:{ self .bind_ports [1 ]} ' ], # Explicit -bind=0.0.0.0
50+ # Explicit -whitebind=0.0.0.0, add onion bind to avoid port conflict
51+ ['-discover' , f'-whitebind=0.0.0.0:{ self .bind_ports [2 ]} ' , f'-bind=127.0.0.1:{ tor_port (3 )} =onion' ],
52+ ['-discover' , f'-bind={ ADDR1 } :{ self .bind_ports [3 ]} ' ], # Explicit -bind=routable_addr
3853 ]
3954 self .num_nodes = len (self .extra_args )
4055
56+ def setup_network (self ):
57+ """
58+ Override to avoid connecting nodes together. This test intentionally does not connect nodes
59+ because each node is bound to a different address or interface, and connections are not needed.
60+ """
61+ self .setup_nodes ()
62+
63+ def setup_nodes (self ):
64+ """
65+ Override to set has_explicit_bind=True for nodes with explicit bind arguments.
66+ """
67+ self .add_nodes (self .num_nodes , self .extra_args )
68+ # TestNode.start() will add -bind= to extra_args if has_explicit_bind is
69+ # False. We do not want any -bind= thus set has_explicit_bind to True.
70+ for node in self .nodes :
71+ node .has_explicit_bind = True
72+ self .start_nodes ()
73+
4174 def add_options (self , parser ):
4275 parser .add_argument (
4376 "--ihave1111and2222" , action = 'store_true' , dest = "ihave1111and2222" ,
@@ -52,28 +85,35 @@ def skip_test_if_missing_module(self):
5285
5386 def run_test (self ):
5487 self .log .info (
55- "Test that if -bind= is not passed then all addresses are "
88+ "Test that if -bind= is not passed or -bind=0.0.0.0 is used then all addresses are "
5689 "added to localaddresses" )
57- found_addr1 = False
58- found_addr2 = False
59- for local in self .nodes [0 ].getnetworkinfo ()['localaddresses' ]:
60- if local ['address' ] == ADDR1 :
61- found_addr1 = True
62- assert_equal (local ['port' ], BIND_PORT )
63- if local ['address' ] == ADDR2 :
64- found_addr2 = True
65- assert_equal (local ['port' ], BIND_PORT )
66- assert found_addr1
67- assert found_addr2
90+ for i in [0 , 1 , 2 ]:
91+ found_addr1 = False
92+ found_addr2 = False
93+ localaddresses = self .nodes [i ].getnetworkinfo ()['localaddresses' ]
94+ for local in localaddresses :
95+ if local ['address' ] == ADDR1 :
96+ found_addr1 = True
97+ assert_equal (local ['port' ], self .bind_ports [i ])
98+ if local ['address' ] == ADDR2 :
99+ found_addr2 = True
100+ assert_equal (local ['port' ], self .bind_ports [i ])
101+ if not found_addr1 :
102+ self .log .error (f"Address { ADDR1 } not found in node{ i } 's local addresses: { localaddresses } " )
103+ assert False
104+ if not found_addr2 :
105+ self .log .error (f"Address { ADDR2 } not found in node{ i } 's local addresses: { localaddresses } " )
106+ assert False
68107
69108 self .log .info (
70- "Test that if -bind= is passed then only that address is "
109+ "Test that if -bind=routable_addr is passed then only that address is "
71110 "added to localaddresses" )
72111 found_addr1 = False
73- for local in self .nodes [1 ].getnetworkinfo ()['localaddresses' ]:
112+ i = 3
113+ for local in self .nodes [i ].getnetworkinfo ()['localaddresses' ]:
74114 if local ['address' ] == ADDR1 :
75115 found_addr1 = True
76- assert_equal (local ['port' ], BIND_PORT )
116+ assert_equal (local ['port' ], self . bind_ports [ i ] )
77117 assert_not_equal (local ['address' ], ADDR2 )
78118 assert found_addr1
79119
0 commit comments