igneum-seed-1 (Hetzner cx23, fsn1, 188.245.5.161:26611): built on the VM in 1,530 s, synced to the live devnet (12,204 blocks, same sink as the live node) through a non-mining relay igneumd on the Mac (the live node's addPeer RPC is refused in safe mode); the live node and the Windows PC learned the seed's address by peer exchange and dialled it. seeds.txt written. Hetzner prices corrected to USD (pricing API currency) in the plans, READMEs and scripts; current-generation types per location (cx23 EU, cpx22 sin, cpx21 US) in the cloud-devnet config. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
8 KiB
Seed nodes: plan
3 October 2026. Scripts in infra/seed-nodes/. The first seed is live.
The first seed
| Item | Value |
|---|---|
| Name | igneum-seed-1 |
| Address | 188.245.5.161:26611 (Hetzner primary IPv4, auto-delete off, so a rebuilt server keeps it) |
| Provider, location, type | Hetzner Cloud, Falkenstein (fsn1), cx23 (2 Intel vCPU, 4 GB, 40 GB), Debian 12 |
| Cost | USD 6.49 per month net, USD 7.79 gross, USD 0.0104 per hour, 20 TB traffic included (Hetzner API, 3 Oct 2026); plus the primary IPv4, USD 0.60 per month net, 0.72 gross (pricing API). Total about USD 7.09 net, USD 8.51 gross per month. The account bills in USD: the pricing API reports currency: USD, VAT 20% |
| Firewall | inbound tcp 26611 from anywhere, tcp 22 from anywhere (the project lead's instruction; SSH_SOURCE=me narrows it to this Mac's IP), icmp; RPC bound to 127.0.0.1 only |
| Network | the shared devnet (--devnet, no suffix), built from vendor/igneum-node HEAD d62708a8 plus the uncommitted finality v2 work and igneum-pow HEAD, with --features igneum-pow |
| Role | p2p open, no mining, address manager on (serves RequestAddresses), --nodnsseed, UPnP off, --externalip set |
| How the Mac reaches it | the Mac's live node sits behind NAT (192.168.68.64), so the seed cannot dial in; the Mac dials out. The addPeer RPC on the live node is refused ("Method unavailable in safe mode. Run the node with --unsaferpc"), so the working path is a relay: infra/seed-nodes/addpeer-from-mac.sh relay start, a second non-mining igneumd on the Mac (appdir /tmp/igneum-seed-relay, RPC 127.0.0.1:26680, wRPC 28680, p2p 127.0.0.1:26681) with --addpeer=192.168.68.64:26611 --addpeer=188.245.5.161:26611; it syncs from the live node and the seed syncs from it. The live node is untouched. When the live node is next restarted by hand, add --addpeer=188.245.5.161:26611 to its flags and the relay is no longer needed |
infra/seed-nodes/seeds.txt holds exactly 188.245.5.161:26611.
Verified 3 Oct 2026, 22:19 to 22:26 UTC: build on the VM 1,530 s (25.5 min, 2 vCPU, 2 jobs, 6 GB swap unused);
igneumd/2.1.0 started with the finality v2 parameters, "External address is publicly routable 188.245.5.161:26611";
the relay on the Mac connected to it at once (protocol 12) and to the live node (protocol 11); the seed completed IBD
from the relay and reported isSynced: true at 22:25:39 UTC with 12,204 blocks and sink a0a776bb129c..., the same
block count and sink the live node reported in the same second. Peer exchange: without any configuration on their
side, the live node (/kaspad:2.1.0/, protocol 11) and the Windows PC's node (192.168.68.67, /igneumd:2.1.0/,
protocol 11) learned the seed's address from the relay and dialled it themselves; the live node's getConnectedPeerInfo
lists 188.245.5.161:26611 as an outbound peer, and the seed shows three inbound peers from the Mac's public IP.
health.sh: OK igneum-seed-1 188.245.5.161 p2p=open unit=active rpc=yes synced=True blocks=12204 headers=12204 peers=3.
The seed's own known-address table is empty because all three peers are behind NAT with no routable advertised address;
the first public node that connects will populate it.
How the seed list reaches clients
- Baked into the node.
vendor/igneum-node/consensus/core/src/config/params.rsholds the per-network seed list asdns_seeders: &'static [&'static str]onParams:MAINNET_PARAMS(line 617 on 3 Oct 2026),TESTNET_PARAMS(670),SIMNET_PARAMS(721),DEVNET_PARAMS(785), all&[]since the rename commit emptied Kaspa's nine mainnet and three testnet hostnames. The connection manager resolves each entry with(seeder, default_p2p_port).to_socket_addrs()(components/connectionmanager/src/lib.rs,dns_seed_single), so a plain IPv4 literal works as an entry with no DNS at all:dns_seeders: &["188.245.5.161"]onDEVNET_PARAMSis the whole change for the devnet, and the testnet list is the same shape with the testnet seeds. The port is the network's default p2p port (devnet 26611; the testnet port is still Kaspa's and must be set with the testnet genesis). The consensus engineer owns this edit. Two consequences for packages: a client that passes--nodnsseedignores the baked list (kaspad/src/daemon.rsline 573:dns_seedersis emptied when--nodnsseedor--connectis given), so the Windows node package (proto-cuda/windows-node/start-node.ps1) and the cloud scripts must drop--nodnsseedonce the list is baked; and the list is consulted only when the node is short of outbound peers, so a node with enough--addpeerentries never asks a seed. SEED_PEERSoverride in every package. Each launcher (Windows node, cloud devnet, seed nodes, the observer's helper node) readsSEED_PEERS(comma-separatedip:port) and turns every entry into--addpeer=<entry>; the baked list is the default when the variable is empty. This is what an operator uses when the baked list is stale between releases.- DNS names only as a convenience.
seed1.igneum.networkand so on can point at the same addresses (the domains are on Vercel nameservers, so a record each), anddns_seedersaccepts a hostname too; but the IPs are the source of truth because a DNS failure or a registrar problem must not stop bootstrapping, and because the public key of nothing is involved: a seed only hands out addresses, it cannot forge blocks.
Public testnet seed set
Three to five seeds across two providers and three regions. Proposed:
| Seed | Provider | Location | Type | Per month net |
|---|---|---|---|---|
| igneum-seed-1 | Hetzner | Falkenstein (EU) | cx23 | USD 6.49 (live) |
| igneum-seed-2 | Hetzner | Ashburn (US east) | cpx11 (2 GB) or cpx21 (4 GB) | USD 20.49 or 37.49 |
| igneum-seed-3 | DigitalOcean | Singapore (sgp1) | s-2vcpu-4gb | USD 24 (DO pricing page) |
| igneum-seed-4 (optional) | DigitalOcean | New York or Frankfurt | s-2vcpu-4gb | USD 24 |
| igneum-seed-5 (optional) | Hetzner | Helsinki | cx23 | USD 6.49 |
Three seeds: about USD 50 per month; five: about USD 80 (approximate, mixed currencies). The US seed is the expensive
one because Hetzner's current cx line is EU-only. Every seed is created with create-seed.sh (the DigitalOcean
variant reserves an IP in the same way) and provisioned with provision-seed.sh, which adds the seeds already in
seeds.txt as --addpeer entries so the seeds form a full mesh among themselves. health.sh checks them all.
Rotation
- Add before removing: create and provision the replacement, run
health.shuntil it is synced and has peers. - Bake the new list (
params.rs) and release packages with it; keep the old address in the list for one release so clients on the previous build still bootstrap. - Keep the old IP alive until the release after that (a Hetzner primary IP or a DO reserved IP costs under USD 1 per
month unattached, approximate), then delete the server and the IP, and remove the entry from
seeds.txtandseeds.tsv. - A compromised seed is the one case to remove first: delete the server, release the IP, bake and release the same day. The damage a bad seed can do is bounded (it hands out addresses; the node's handshake and PoW checks are unchanged), which is why the list may sit in a release rather than behind a signature.
Health and operations
health.sh (one line per seed: p2p port reachable from the Mac, unit active, RPC answering, synced, blocks and
headers, connected peers, known and banned addresses, disk, memory, version); --watch repeats every minute. The
seed's journal: ssh -i ~/.ssh/igneum_ed25519 root@188.245.5.161 journalctl -u igneumd -f. Updating the binary:
provision-seed.sh again (it rebuilds on the VM) or BUILD_WHERE=bin to push a binary built by the cloud-devnet
builder. The database format changes with some fork commits; a seed that refuses to start after an update is wiped
(rm -rf /var/lib/igneum/*) and resyncs from its peers.
No-spend rule
Only the first seed spends tonight (approved). The remaining seeds and the 20-node network wait for the morning.