Page MenuHomePhabricator

D10908.id32006.diff
No OneTemporary

D10908.id32006.diff

diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -5,3 +5,6 @@
<https://download.bitcoinabc.org/0.24.11/>
This release includes the following features and fixes:
+ - Add a `-fixedseeds` option which can be set to 0 to disable to hardcoded seeds.
+ This can be used in conjunction with `dsnssed=0` to create a trusted peer only setup.
+ In this case thenodes needs to be added manually with the `-addnode` option or the `addnode` RPC.
diff --git a/src/init.cpp b/src/init.cpp
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -673,12 +673,19 @@
ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg(
"-dnsseed",
- "Query for peer addresses via DNS lookup, if low on addresses "
- "(default: 1 unless -connect used)",
- ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
-
+ strprintf(
+ "Query for peer addresses via DNS lookup, if low on addresses "
+ "(default: %u unless -connect used)",
+ DEFAULT_DNSSEED),
+ ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
argsman.AddArg("-externalip=<ip>", "Specify your own public address",
ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
+ argsman.AddArg(
+ "-fixedseeds",
+ strprintf(
+ "Allow fixed seeds if DNS seeds don't provide peers (default: %u)",
+ DEFAULT_FIXEDSEEDS),
+ ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
argsman.AddArg(
"-forcednsseed",
strprintf(
diff --git a/src/net.h b/src/net.h
--- a/src/net.h
+++ b/src/net.h
@@ -101,6 +101,8 @@
static const int64_t DEFAULT_PEER_CONNECT_TIMEOUT = 60;
static const bool DEFAULT_FORCEDNSSEED = false;
+static const bool DEFAULT_DNSSEED = true;
+static const bool DEFAULT_FIXEDSEEDS = true;
static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
diff --git a/src/net.cpp b/src/net.cpp
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2119,13 +2119,20 @@
}
// Initiate network connections
- int64_t nStart = GetTime();
+ auto start = GetTime<std::chrono::seconds>();
// Minimum time before next feeler connection (in microseconds).
int64_t nNextFeeler =
- PoissonNextSend(nStart * 1000 * 1000, FEELER_INTERVAL);
+ PoissonNextSend(count_microseconds(start), FEELER_INTERVAL);
int64_t nNextExtraBlockRelay = PoissonNextSend(
- nStart * 1000 * 1000, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
+ count_microseconds(start), EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
+ const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
+ bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
+
+ if (!add_fixed_seeds) {
+ LogPrintf("Fixed seeds are disabled\n");
+ }
+
while (!interruptNet) {
ProcessAddrFetch();
@@ -2138,20 +2145,38 @@
return;
}
- // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
- // Note that we only do this if we started with an empty peers.dat,
- // (in which case we will query DNS seeds immediately) *and* the DNS
- // seeds have not returned any results.
- if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
- static bool done = false;
- if (!done) {
- LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be "
- "available.\n");
+ if (add_fixed_seeds && addrman.size() == 0) {
+ // When the node starts with an empty peers.dat, there are a few
+ // other sources of peers before we fallback on to fixed seeds:
+ // -dnsseed, -seednode, -addnode If none of those are available, we
+ // fallback on to fixed seeds immediately, else we allow 60 seconds
+ // for any of those sources to populate addrman.
+ bool add_fixed_seeds_now = false;
+ // It is cheapest to check if enough time has passed first.
+ if (GetTime<std::chrono::seconds>() >
+ start + std::chrono::minutes{1}) {
+ add_fixed_seeds_now = true;
+ LogPrintf("Adding fixed seeds as 60 seconds have passed and "
+ "addrman is empty\n");
+ }
+
+ // Checking !dnsseed is cheaper before locking 2 mutexes.
+ if (!add_fixed_seeds_now && !dnsseed) {
+ LOCK2(m_addr_fetches_mutex, cs_vAddedNodes);
+ if (m_addr_fetches.empty() && vAddedNodes.empty()) {
+ add_fixed_seeds_now = true;
+ LogPrintf(
+ "Adding fixed seeds as -dnsseed=0, -addnode is not "
+ "provided and and all -seednode(s) attempted\n");
+ }
+ }
+
+ if (add_fixed_seeds_now) {
CNetAddr local;
local.SetInternal("fixedseeds");
addrman.Add(convertSeed6(config->GetChainParams().FixedSeeds()),
local);
- done = true;
+ add_fixed_seeds = false;
}
}
@@ -2867,7 +2892,7 @@
&TraceThread<std::function<void()>>, "net",
std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
- if (!gArgs.GetBoolArg("-dnsseed", true)) {
+ if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED)) {
LogPrintf("DNS seeding disabled\n");
} else {
threadDNSAddressSeed =
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test various command line arguments and configuration file parameters."""
import os
+import time
from test_framework.test_framework import BitcoinTestFramework
@@ -161,11 +162,71 @@
self.start_node(0, extra_args=['-nonetworkactive=1'])
self.stop_node(0)
+ def test_seed_peers(self):
+ self.log.info('Test seed peers, this will take about 2 minutes')
+ default_data_dir = self.nodes[0].datadir
+
+ # No peers.dat exists and -dnsseed=1
+ # We expect the node will use DNS Seeds, but Regtest mode has 0 DNS seeds
+ # So after 60 seconds, the node should fallback to fixed seeds (this is
+ # a slow test)
+ assert not os.path.exists(os.path.join(default_data_dir, "peers.dat"))
+ start = time.time()
+ with self.nodes[0].assert_debug_log(expected_msgs=[
+ "Loaded 0 addresses from peers.dat",
+ "0 addresses found from DNS seeds",
+ "Adding fixed seeds as 60 seconds have passed and addrman is empty"], timeout=80):
+ self.start_node(0, extra_args=['-dnsseed=1'])
+ assert time.time() - start >= 60
+ self.stop_node(0)
+
+ # No peers.dat exists and -dnsseed=0
+ # We expect the node will fallback immediately to fixed seeds
+ assert not os.path.exists(os.path.join(default_data_dir, "peers.dat"))
+ start = time.time()
+ with self.nodes[0].assert_debug_log(expected_msgs=[
+ "Loaded 0 addresses from peers.dat",
+ "DNS seeding disabled",
+ "Adding fixed seeds as -dnsseed=0, -addnode is not provided and and all -seednode(s) attempted\n"]):
+ self.start_node(0, extra_args=['-dnsseed=0'])
+ assert time.time() - start < 60
+ self.stop_node(0)
+
+ # No peers.dat exists and dns seeds are disabled.
+ # We expect the node will not add fixed seeds when explicitly disabled.
+ assert not os.path.exists(os.path.join(default_data_dir, "peers.dat"))
+ start = time.time()
+ with self.nodes[0].assert_debug_log(expected_msgs=[
+ "Loaded 0 addresses from peers.dat",
+ "DNS seeding disabled",
+ "Fixed seeds are disabled"]):
+ self.start_node(0, extra_args=['-dnsseed=0', '-fixedseeds=0'])
+ assert time.time() - start < 60
+ self.stop_node(0)
+
+ # No peers.dat exists and -dnsseed=0, but a -addnode is provided
+ # We expect the node will allow 60 seconds prior to using fixed seeds
+ assert not os.path.exists(os.path.join(default_data_dir, "peers.dat"))
+ start = time.time()
+ with self.nodes[0].assert_debug_log(expected_msgs=[
+ "Loaded 0 addresses from peers.dat",
+ "DNS seeding disabled",
+ "Adding fixed seeds as 60 seconds have passed and addrman is empty"],
+ timeout=80):
+ self.start_node(
+ 0,
+ extra_args=[
+ '-dnsseed=0',
+ '-addnode=fakenodeaddr'])
+ assert time.time() - start >= 60
+ self.stop_node(0)
+
def run_test(self):
self.stop_node(0)
self.test_log_buffer()
self.test_args_log()
+ self.test_seed_peers()
self.test_networkactive()
self.test_config_file_parser()
diff --git a/test/functional/p2p_dos_header_tree.py b/test/functional/p2p_dos_header_tree.py
--- a/test/functional/p2p_dos_header_tree.py
+++ b/test/functional/p2p_dos_header_tree.py
@@ -16,6 +16,7 @@
self.setup_clean_chain = True
self.chain = 'testnet3' # Use testnet chain because it has an early checkpoint
self.num_nodes = 2
+ self.extra_args = [["-fixedseeds=0"]] * self.num_nodes
def add_options(self, parser):
parser.add_argument(
@@ -64,7 +65,10 @@
self.log.info("Feed all fork headers (succeeds without checkpoint)")
# On node 0 it succeeds because checkpoints are disabled
- self.restart_node(0, extra_args=['-nocheckpoints'])
+ self.restart_node(
+ 0,
+ extra_args=self.extra_args[0] +
+ ['-nocheckpoints'])
peer_no_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface())
peer_no_checkpoint.send_and_ping(msg_headers(self.headers_fork))
assert {

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 26, 10:34 (5 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5573280
Default Alt Text
D10908.id32006.diff (10 KB)

Event Timeline