feature_bind_port_externalip.py raw

   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