1 #!/usr/bin/env python3
2 # Copyright (c) 2020-present The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """
6 Test that the proper port is used for -externalip=
7 """
8 9 from test_framework.test_framework import BitcoinTestFramework, SkipTest
10 from test_framework.test_node import (
11 FailedToStartError,
12 )
13 from test_framework.util import assert_equal, p2p_port
14 15 # We need to bind to a routable address for this test to exercise the relevant
16 # code. Those addresses must be on an interface that is UP and is not a loopback
17 # interface (IFF_LOOPBACK).
18 # To set these routable addresses on the machine, use:
19 # Linux:
20 # First find your interfaces: ip addr show
21 # Then use your actual interface names (replace INTERFACE_NAME with yours):
22 # ip addr add 1.1.1.5/32 dev INTERFACE_NAME # to set up
23 # ip addr del 1.1.1.5/32 dev INTERFACE_NAME # to remove it
24 # FreeBSD and MacOS:
25 # ifconfig INTERFACE_NAME 1.1.1.5/32 alias # to set up
26 # ifconfig INTERFACE_NAME 1.1.1.5 -alias # to remove it, after the test
27 ADDR = '1.1.1.5' # This is set in the CI environment, don't change it just here (keep them in sync).
28 29 # array of tuples [arguments, expected port in localaddresses]
30 EXPECTED = [
31 [['-externalip=2.2.2.2', '-port=30001'], 30001],
32 [['-externalip=2.2.2.2', '-port=30002', f'-bind={ADDR}'], 30002],
33 [['-externalip=2.2.2.2', f'-bind={ADDR}'], 'default_p2p_port'],
34 [['-externalip=2.2.2.2', '-port=30003', f'-bind={ADDR}:30004'], 30004],
35 [['-externalip=2.2.2.2', f'-bind={ADDR}:30005'], 30005],
36 [['-externalip=2.2.2.2:30006', '-port=30007'], 30006],
37 [['-externalip=2.2.2.2:30008', '-port=30009', f'-bind={ADDR}'], 30008],
38 [['-externalip=2.2.2.2:30010', f'-bind={ADDR}'], 30010],
39 [['-externalip=2.2.2.2:30011', '-port=30012', f'-bind={ADDR}:30013'], 30011],
40 [['-externalip=2.2.2.2:30014', f'-bind={ADDR}:30015'], 30014],
41 [['-externalip=2.2.2.2', '-port=30016', f'-bind={ADDR}:30017',
42 f'-whitebind={ADDR}:30018'], 30017],
43 [['-externalip=2.2.2.2', '-port=30019',
44 f'-whitebind={ADDR}:30020'], 30020],
45 ]
46 47 class BindPortExternalIPTest(BitcoinTestFramework):
48 def set_test_params(self):
49 # Avoid any -bind= on the command line. Force the framework to avoid adding -bind=127.0.0.1.
50 self.setup_clean_chain = True
51 self.bind_to_localhost_only = False
52 self.num_nodes = len(EXPECTED)
53 self.extra_args = list(map(lambda e: e[0], EXPECTED))
54 55 def setup_network(self):
56 self.setup_nodes()
57 58 def setup_nodes(self):
59 self.add_nodes(self.num_nodes, self.extra_args)
60 # TestNode.start() will add -bind= to extra_args if has_explicit_bind is
61 # False. We do not want any -bind= thus set has_explicit_bind to True.
62 for node in self.nodes:
63 node.has_explicit_bind = True
64 try:
65 self.start_nodes()
66 except FailedToStartError as e:
67 self.cleanup_partially_started_nodes()
68 if 'Unable to bind to ' in str(e):
69 raise SkipTest(
70 f'To run this test make sure that {ADDR} '
71 '(routable address) is assigned to non-loopback '
72 'interface on this machine')
73 raise
74 75 def run_test(self):
76 self.log.info("Test the proper port is used for -externalip=")
77 for i in range(len(EXPECTED)):
78 expected_port = EXPECTED[i][1]
79 if expected_port == 'default_p2p_port':
80 expected_port = p2p_port(i)
81 found = False
82 for local in self.nodes[i].getnetworkinfo()['localaddresses']:
83 if local['address'] == '2.2.2.2':
84 assert_equal(local['port'], expected_port)
85 found = True
86 break
87 assert found
88 89 if __name__ == '__main__':
90 BindPortExternalIPTest(__file__).main()
91