From dde6cd810f3a0875609476fdab855ddb87751781 Mon Sep 17 00:00:00 2001 From: DanS Date: Wed, 26 Aug 2026 00:22:56 +0200 Subject: [PATCH] net: seed from a round-robin DNS record instead of hardcoded hosts seed.dragonx.is is now an A-record set over the five seed nodes (DNS-only, TTL 300, created in Cloudflare alongside this change). One lookup returns all of them, and the set can change -- a node added, a node retired -- with a DNS edit rather than a release. That is the actual point. Before this the network's entry points were hardcoded into the binary twice over: here in vSeeds, and again in the -addnode injection in hush_utils.h. Adding a sixth node meant shipping a new version and waiting for users to upgrade. node1 and node5 stay as static fallbacks against the round-robin record being mistyped or deleted. They resolve to the same hosts, so that is insurance against a DNS mistake rather than real redundancy. Verified end to end on a fresh datadir (empty addrman, real node untouched, and crucially with NO custom -port -- see below): before: 0 addresses found from DNS seeds, 0 handshakes, 1 block (genesis) after: 7 addresses found, connection attempts to all five seeds on :21768, 3 version handshakes, 3296 blocks connected and syncing The earlier run of this test appeared to fail with 0 handshakes. That was the harness, not the code: -port overrides ASSETCHAINS_P2PPORT, and net.cpp builds DNS-seeded addresses as CAddress(CService(ip, ASSETCHAINS_P2PPORT)), so a test node with a custom port dials every seeded peer on its own port and reaches nothing. That is the mechanism behind the long-standing "never use a custom -port on a test node" rule; use -listen=0 instead. Co-Authored-By: Claude Opus 5 (1M context) --- src/chainparams.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 24aaf1e2f..12ffc5402 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -191,14 +191,18 @@ public: // path that worked was the node1..node5.dragonx.is -addnode injection in // hush_utils.h, which is almost certainly why that injection exists. // - // These are single-A-record hosts, so each contributes one address rather than - // the spread a real seeder returns. That is still strictly better than nothing; - // a dedicated seeder (or a round-robin A record over the seed set) would be the - // proper fix and needs only a DNS change, not a release. + // seed.dragonx.is is a round-robin A record over the seed set, so ONE lookup + // returns all of them and the set can be changed -- a node added, a node retired + // -- with a DNS edit instead of a release. That is the point of it: the previous + // arrangement hardcoded the seed list into the binary twice over (here and in the + // -addnode injection in hush_utils.h), so the network's entry points could only + // change by shipping a new version. + // + // node1/node5 stay as static fallbacks in case the round-robin record is ever + // mistyped or removed. They are the same hosts, so this is insurance against a + // DNS mistake rather than genuine redundancy. + vSeeds.push_back(CDNSSeedData("seed", "seed.dragonx.is")); vSeeds.push_back(CDNSSeedData("node1", "node1.dragonx.is")); - vSeeds.push_back(CDNSSeedData("node2", "node2.dragonx.is")); - vSeeds.push_back(CDNSSeedData("node3", "node3.dragonx.is")); - vSeeds.push_back(CDNSSeedData("node4", "node4.dragonx.is")); vSeeds.push_back(CDNSSeedData("node5", "node5.dragonx.is")); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,60);