mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
4c89e24f64
When starting up with a populated addrman, ThreadDNSAddressSeed adds a delay during which time the node may be able to connect to some peers. This commit tests the delay changes based on the number of addresses in the addrman.
130 lines
5.6 KiB
Python
Executable File
130 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (c) 2021 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 ThreadDNSAddressSeed logic for querying DNS seeds."""
|
|
|
|
import itertools
|
|
|
|
from test_framework.p2p import P2PInterface
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
|
|
|
|
class P2PDNSSeeds(BitcoinTestFramework):
|
|
def set_test_params(self):
|
|
self.setup_clean_chain = True
|
|
self.num_nodes = 1
|
|
self.extra_args = [["-dnsseed=1"]]
|
|
|
|
def run_test(self):
|
|
self.init_arg_tests()
|
|
self.existing_outbound_connections_test()
|
|
self.existing_block_relay_connections_test()
|
|
self.force_dns_test()
|
|
self.wait_time_tests()
|
|
|
|
def init_arg_tests(self):
|
|
fakeaddr = "fakenodeaddr.fakedomain.invalid."
|
|
|
|
self.log.info("Check that setting -connect disables -dnsseed by default")
|
|
self.nodes[0].stop_node()
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["DNS seeding disabled"]):
|
|
self.start_node(0, [f"-connect={fakeaddr}"])
|
|
|
|
self.log.info("Check that running -connect and -dnsseed means DNS logic runs.")
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["Loading addresses from DNS seed"], timeout=12):
|
|
self.restart_node(0, [f"-connect={fakeaddr}", "-dnsseed=1"])
|
|
|
|
self.log.info("Check that running -forcednsseed and -dnsseed=0 throws an error.")
|
|
self.nodes[0].stop_node()
|
|
self.nodes[0].assert_start_raises_init_error(
|
|
expected_msg="Error: Cannot set -forcednsseed to true when setting -dnsseed to false.",
|
|
extra_args=["-forcednsseed=1", "-dnsseed=0"],
|
|
)
|
|
|
|
self.log.info("Check that running -forcednsseed and -connect throws an error.")
|
|
# -connect soft sets -dnsseed to false, so throws the same error
|
|
self.nodes[0].stop_node()
|
|
self.nodes[0].assert_start_raises_init_error(
|
|
expected_msg="Error: Cannot set -forcednsseed to true when setting -dnsseed to false.",
|
|
extra_args=["-forcednsseed=1", f"-connect={fakeaddr}"],
|
|
)
|
|
|
|
# Restore default bitcoind settings
|
|
self.restart_node(0)
|
|
|
|
def existing_outbound_connections_test(self):
|
|
# Make sure addrman is populated to enter the conditional where we
|
|
# delay and potentially skip DNS seeding.
|
|
self.nodes[0].addpeeraddress("192.0.0.8", 8333)
|
|
|
|
self.log.info("Check that we *do not* query DNS seeds if we have 2 outbound connections")
|
|
|
|
self.restart_node(0)
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["P2P peers available. Skipped DNS seeding."], timeout=12):
|
|
for i in range(2):
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i, connection_type="outbound-full-relay")
|
|
|
|
def existing_block_relay_connections_test(self):
|
|
# Make sure addrman is populated to enter the conditional where we
|
|
# delay and potentially skip DNS seeding. No-op when run after
|
|
# existing_outbound_connections_test.
|
|
self.nodes[0].addpeeraddress("192.0.0.8", 8333)
|
|
|
|
self.log.info("Check that we *do* query DNS seeds if we only have 2 block-relay-only connections")
|
|
|
|
self.restart_node(0)
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["Loading addresses from DNS seed"], timeout=12):
|
|
# This mimics the "anchors" logic where nodes are likely to
|
|
# reconnect to block-relay-only connections on startup.
|
|
# Since we do not participate in addr relay with these connections,
|
|
# we still want to query the DNS seeds.
|
|
for i in range(2):
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=i, connection_type="block-relay-only")
|
|
|
|
def force_dns_test(self):
|
|
self.log.info("Check that we query DNS seeds if -forcednsseed param is set")
|
|
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["Loading addresses from DNS seed"], timeout=12):
|
|
# -dnsseed defaults to 1 in bitcoind, but 0 in the test framework,
|
|
# so pass it explicitly here
|
|
self.restart_node(0, ["-forcednsseed", "-dnsseed=1"])
|
|
|
|
# Restore default for subsequent tests
|
|
self.restart_node(0)
|
|
|
|
def wait_time_tests(self):
|
|
self.log.info("Check the delay before querying DNS seeds")
|
|
|
|
# Populate addrman with < 1000 addresses
|
|
for i in range(5):
|
|
a = f"192.0.0.{i}"
|
|
self.nodes[0].addpeeraddress(a, 8333)
|
|
|
|
# The delay should be 11 seconds
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["Waiting 11 seconds before querying DNS seeds.\n"]):
|
|
self.restart_node(0)
|
|
|
|
# Populate addrman with > 1000 addresses
|
|
for i in itertools.count():
|
|
first_octet = i % 2 + 1
|
|
second_octet = i % 256
|
|
third_octet = i % 100
|
|
a = f"{first_octet}.{second_octet}.{third_octet}.1"
|
|
self.nodes[0].addpeeraddress(a, 8333)
|
|
if (i > 1000 and i % 100 == 0):
|
|
# The addrman size is non-deterministic because new addresses
|
|
# are sorted into buckets, potentially displacing existing
|
|
# addresses. Periodically check if we have met the desired
|
|
# threshold.
|
|
if len(self.nodes[0].getnodeaddresses(0)) > 1000:
|
|
break
|
|
|
|
# The delay should be 5 mins
|
|
with self.nodes[0].assert_debug_log(expected_msgs=["Waiting 300 seconds before querying DNS seeds.\n"]):
|
|
self.restart_node(0)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
P2PDNSSeeds().main()
|