p2p_addrfetch.py raw

   1  #!/usr/bin/env python3
   2  # Copyright (c) 2021-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 p2p addr-fetch connections
   7  """
   8  
   9  import time
  10  
  11  from test_framework.messages import (
  12      CAddress,
  13      msg_addr,
  14  )
  15  from test_framework.p2p import (
  16      P2PInterface,
  17      p2p_lock,
  18      P2P_SERVICES,
  19  )
  20  from test_framework.test_framework import BitcoinTestFramework
  21  from test_framework.util import assert_equal
  22  
  23  ADDR = CAddress()
  24  ADDR.time = int(time.time())
  25  ADDR.nServices = P2P_SERVICES
  26  ADDR.ip = "192.0.0.8"
  27  ADDR.port = 18444
  28  
  29  
  30  class P2PAddrFetch(BitcoinTestFramework):
  31      def set_test_params(self):
  32          self.setup_clean_chain = True
  33          self.num_nodes = 1
  34  
  35      def assert_getpeerinfo(self, *, peer_ids):
  36          num_peers = len(peer_ids)
  37          info = self.nodes[0].getpeerinfo()
  38          assert_equal(len(info), num_peers)
  39          for n in range(0, num_peers):
  40              assert_equal(info[n]['id'], peer_ids[n])
  41              assert_equal(info[n]['connection_type'], 'addr-fetch')
  42  
  43      def run_test(self):
  44          node = self.nodes[0]
  45          self.log.info("Connect to an addr-fetch peer")
  46          peer_id = 0
  47          peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=peer_id, connection_type="addr-fetch")
  48          self.assert_getpeerinfo(peer_ids=[peer_id])
  49  
  50          self.log.info("Check that we send getaddr but don't try to sync headers with the addr-fetch peer")
  51          peer.sync_with_ping()
  52          with p2p_lock:
  53              assert_equal(peer.message_count['getaddr'], 1)
  54              assert_equal(peer.message_count['getheaders'], 0)
  55  
  56          self.log.info("Check that answering the getaddr with a single address does not lead to disconnect")
  57          # This prevents disconnecting on self-announcements
  58          msg = msg_addr()
  59          msg.addrs = [ADDR]
  60          peer.send_and_ping(msg)
  61          self.assert_getpeerinfo(peer_ids=[peer_id])
  62  
  63          self.log.info("Check that answering with larger addr messages leads to disconnect")
  64          msg.addrs = [ADDR] * 2
  65          peer.send_without_ping(msg)
  66          peer.wait_for_disconnect(timeout=5)
  67  
  68          self.log.info("Check timeout for addr-fetch peer that does not send addrs")
  69          peer_id = 1
  70          peer = node.add_outbound_p2p_connection(P2PInterface(), p2p_idx=peer_id, connection_type="addr-fetch")
  71  
  72          time_now = int(time.time())
  73          self.assert_getpeerinfo(peer_ids=[peer_id])
  74  
  75          # Expect addr-fetch peer connection to be maintained up to 5 minutes.
  76          node.setmocktime(time_now + 295)
  77          self.assert_getpeerinfo(peer_ids=[peer_id])
  78  
  79          # Expect addr-fetch peer connection to be disconnected after 5 minutes.
  80          node.setmocktime(time_now + 301)
  81          peer.wait_for_disconnect(timeout=5)
  82          self.assert_getpeerinfo(peer_ids=[])
  83  
  84  
  85  if __name__ == '__main__':
  86      P2PAddrFetch(__file__).main()
  87