mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
7fabe0f359
For each address to be relayed we "randomly" pick 2 nodes to send the address to (in `RelayAddress()`). However we do not take into consideration that it does not make sense to relay the address back to its originator (`CNode::PushAddress()` will do nothing in that case). This means that if the originator is among the "randomly" picked nodes, then we will relay to one node less than intended. Fix this by skipping the originating node when choosing candidates to relay to.
88 lines
2.8 KiB
Python
Executable file
88 lines
2.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright (c) 2020 The Bitcoin Core developers
|
|
# Distributed under the MIT software license, see the accompanying
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
"""
|
|
Test addr relay
|
|
"""
|
|
|
|
from test_framework.messages import (
|
|
CAddress,
|
|
NODE_NETWORK,
|
|
NODE_WITNESS,
|
|
msg_addr,
|
|
)
|
|
from test_framework.p2p import P2PInterface
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
from test_framework.util import (
|
|
assert_equal,
|
|
)
|
|
import time
|
|
|
|
# Keep this with length <= 10. Addresses from larger messages are not relayed.
|
|
ADDRS = []
|
|
num_ipv4_addrs = 10
|
|
|
|
for i in range(num_ipv4_addrs):
|
|
addr = CAddress()
|
|
addr.time = int(time.time()) + i
|
|
addr.nServices = NODE_NETWORK | NODE_WITNESS
|
|
addr.ip = "123.123.123.{}".format(i % 256)
|
|
addr.port = 8333 + i
|
|
ADDRS.append(addr)
|
|
|
|
|
|
class AddrReceiver(P2PInterface):
|
|
num_ipv4_received = 0
|
|
|
|
def on_addr(self, message):
|
|
for addr in message.addrs:
|
|
assert_equal(addr.nServices, 9)
|
|
if not 8333 <= addr.port < 8343:
|
|
raise AssertionError("Invalid addr.port of {} (8333-8342 expected)".format(addr.port))
|
|
assert addr.ip.startswith('123.123.123.')
|
|
self.num_ipv4_received += 1
|
|
|
|
|
|
class AddrTest(BitcoinTestFramework):
|
|
def set_test_params(self):
|
|
self.setup_clean_chain = False
|
|
self.num_nodes = 1
|
|
|
|
def run_test(self):
|
|
self.log.info('Create connection that sends addr messages')
|
|
addr_source = self.nodes[0].add_p2p_connection(P2PInterface())
|
|
msg = msg_addr()
|
|
|
|
self.log.info('Send too-large addr message')
|
|
msg.addrs = ADDRS * 101 # more than 1000 addresses in one message
|
|
with self.nodes[0].assert_debug_log(['addr message size = 1010']):
|
|
addr_source.send_and_ping(msg)
|
|
|
|
self.log.info('Check that addr message content is relayed and added to addrman')
|
|
num_receivers = 7
|
|
receivers = []
|
|
for _ in range(num_receivers):
|
|
receivers.append(self.nodes[0].add_p2p_connection(AddrReceiver()))
|
|
msg.addrs = ADDRS
|
|
with self.nodes[0].assert_debug_log(
|
|
[
|
|
'Added {} addresses from 127.0.0.1: 0 tried'.format(num_ipv4_addrs),
|
|
'received: addr (301 bytes) peer=0',
|
|
]
|
|
):
|
|
addr_source.send_and_ping(msg)
|
|
self.nodes[0].setmocktime(int(time.time()) + 30 * 60)
|
|
for receiver in receivers:
|
|
receiver.sync_with_ping()
|
|
|
|
total_ipv4_received = sum(r.num_ipv4_received for r in receivers)
|
|
|
|
# Every IPv4 address must be relayed to two peers, other than the
|
|
# originating node (addr_source).
|
|
ipv4_branching_factor = 2
|
|
assert_equal(total_ipv4_received, num_ipv4_addrs * ipv4_branching_factor)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
AddrTest().main()
|