p2p_addrv2_relay.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2020-2021 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 addrv2 relay 7 """ 8 9 import time 10 11 from test_framework.messages import ( 12 CAddress, 13 msg_addrv2, 14 ) 15 from test_framework.p2p import ( 16 P2PInterface, 17 P2P_SERVICES, 18 ) 19 from test_framework.test_framework import BitcoinTestFramework 20 from test_framework.util import assert_equal 21 22 I2P_ADDR = "c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p" 23 ONION_ADDR = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion" 24 25 ADDRS = [] 26 for i in range(10): 27 addr = CAddress() 28 addr.time = int(time.time()) + i 29 addr.port = 8333 + i 30 addr.nServices = P2P_SERVICES 31 # Add one I2P and one onion V3 address at an arbitrary position. 32 if i == 5: 33 addr.net = addr.NET_I2P 34 addr.ip = I2P_ADDR 35 addr.port = 0 36 elif i == 8: 37 addr.net = addr.NET_TORV3 38 addr.ip = ONION_ADDR 39 else: 40 addr.ip = f"123.123.123.{i % 256}" 41 ADDRS.append(addr) 42 43 44 class AddrReceiver(P2PInterface): 45 addrv2_received_and_checked = False 46 47 def __init__(self): 48 super().__init__(support_addrv2 = True) 49 50 def on_addrv2(self, message): 51 expected_set = set((addr.ip, addr.port) for addr in ADDRS) 52 received_set = set((addr.ip, addr.port) for addr in message.addrs) 53 if expected_set == received_set: 54 self.addrv2_received_and_checked = True 55 56 def wait_for_addrv2(self): 57 self.wait_until(lambda: "addrv2" in self.last_message) 58 59 60 def calc_addrv2_msg_size(addrs): 61 size = 1 # vector length byte 62 for addr in addrs: 63 size += 4 # time 64 size += 1 # services, COMPACTSIZE(P2P_SERVICES) 65 size += 1 # network id 66 size += 1 # address length byte 67 size += addr.ADDRV2_ADDRESS_LENGTH[addr.net] # address 68 size += 2 # port 69 return size 70 71 class AddrTest(BitcoinTestFramework): 72 def set_test_params(self): 73 self.setup_clean_chain = True 74 self.num_nodes = 1 75 self.extra_args = [["-whitelist=addr@127.0.0.1"]] 76 77 def run_test(self): 78 self.log.info('Create connection that sends addrv2 messages') 79 addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) 80 msg = msg_addrv2() 81 82 self.log.info('Send too-large addrv2 message') 83 msg.addrs = ADDRS * 101 84 with self.nodes[0].assert_debug_log(['addrv2 message size = 1010']): 85 addr_source.send_and_ping(msg) 86 87 self.log.info('Check that addrv2 message content is relayed and added to addrman') 88 addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver()) 89 msg.addrs = ADDRS 90 msg_size = calc_addrv2_msg_size(ADDRS) 91 with self.nodes[0].assert_debug_log([ 92 f'received: addrv2 ({msg_size} bytes) peer=0', 93 f'sending addrv2 ({msg_size} bytes) peer=1', 94 ]): 95 addr_source.send_and_ping(msg) 96 self.nodes[0].setmocktime(int(time.time()) + 30 * 60) 97 addr_receiver.wait_for_addrv2() 98 99 assert addr_receiver.addrv2_received_and_checked 100 assert_equal(len(self.nodes[0].getnodeaddresses(count=0, network="i2p")), 0) 101 102 103 if __name__ == '__main__': 104 AddrTest().main()