Skip to content

chainparams: add the Dog of Bitcoin Foundation DNS seed for DOG Mode nodes - #7

Open
dogofbitcoin wants to merge 1 commit into
bitcoindogmode:31.1-dogmodefrom
dogofbitcoin:chainparams-dogseed
Open

dogofbitcoin wants to merge 1 commit into
bitcoindogmode:31.1-dogmodefrom
dogofbitcoin:chainparams-dogseed

Conversation

@dogofbitcoin

@dogofbitcoin dogofbitcoin commented Sep 2, 2026 •

Copy link
Copy Markdown

One line. dnsseed.dogofbitcoin.org is a DNS seed for this client, operated by Dog of Bitcoin Foundation Inc: sipa's reference seeder at a pinned commit, plus one published commit of two lines. Every answer, whatever filter is asked, carries only nodes advertising NODE_DOG_MODE (bit 14), and the filter prefix is read in either letter case, since public resolvers such as Google's randomize it. Listed here, a fresh DOG Mode node gets dog nodes into its address book on its first start, alongside the answers of Core's seeds, with no other change to the client. The build is public at https://github.com/dogofbitcoin/bitcoin-seeder, one commit on the pinned base.

Operated under Core's doc/dnsseed-policy.md (fair selection, TTL 3600, minimal logging, published contact). The operating statement, the contact, and a live count of nodes advertising the bit are at https://seed.dogofbitcoin.org.

One dog-specific seed is one operator seeing the first query of nearly every node that joins this network. The fix is a second seed run by someone who is not us: the seeder build is public so another operator can plant one in an afternoon, and the client should list several. If one appears, we will say so here and support listing it beside this line.

State on 2026-09-21: dig +short x4009.dnsseed.dogofbitcoin.org returns 185.100.87.52 through Cloudflare's and Google's public resolvers alike, the one full DOG Mode node on port 8333 that the crawler can reach; the crawler sees 2 reachable nodes advertising the bit in all. @J25dunn checked the same answer independently through four public resolvers on 2026-09-18, below. The page shows both numbers, since an A record carries no port and the reference seeder hands out full nodes on the default port only.

One thing worth knowing, offered and not asked: ThreadDNSAddressSeed records seeded addresses with SeedsServiceFlags() only, so addresses from this seed become candidates for the reserved DOG connections after a first handshake rather than immediately, which @J25dunn also reads below. A small change that asks dog seeds with NODE_DOG_MODE in the required bits, and records the answers with it, would make the reserved slots fill straight from the seed. Happy to draft and measure it if useful; equally happy to leave it.

@tialkan

tialkan commented Sep 7, 2026

Copy link
Copy Markdown

Checked what is checkable here rather than reasoning about it, since a vSeeds line is one of the few places where a one-line diff is a standing trust relationship. Re-verified today (2026-09-08) rather than trusting my read from when this opened, since the state has moved.

What's changed since the PR was opened. The seed was empty ("returns 0 addresses") when this went up. It is not anymore: dig +short dnsseed.dogofbitcoin.com now returns 185.100.87.52, which bitnodes shows as /Satoshi:31.1.0/ advertising service bit 14 (NODE_DOG_MODE) — the only node on the network doing so. That matches the PR's own line, "our own node will be one the day its sync ends." It has. The seed's operating page hasn't caught up to that yet (still reads as pre-sync), but the DNS answer and the network measurement agree, so I'm going by those.

Worth naming what this does and doesn't establish. It confirms the mechanism works end to end: a node advertises the bit, the seed picks it up, a query gets it back. It does not yet test fair selection (expectation 1 of Core's doc/dnsseed-policy.md) in any meaningful sense — with one candidate, "fair" and "only option" look identical. That's not a criticism, just a reason not to read more into a single green light than it shows.

What still verifies independently, unchanged from before:

  • TTL and logging language match expectations 3 and 4.
  • A contact address is published.
  • The operator is named and the name holds up: Dog of Bitcoin Foundation Inc, EIN 39-2748255, Van Nuys CA, 501(c)(3), IRS ruling July 2025 — in the public record. That's the part of expectation 0 that usually can't be checked at all.

The four asks stand, and the first node online makes them slightly more worth settling now rather than later:

  1. Name the entity in the line itself. Core's neighbours carry the operator inline — // Stephan Oeste, // Jason Maurice, // Ava Chow. // Dog of Bitcoin is the brand; the accountable party is the Foundation.
  2. Publish the seeder build. The PR says sipa's reference seeder at a pinned commit "plus one published change." I still can't find either the commit or the change from the operating statement. With a real node behind it now, a fork with the commit hash turns "filters to bit 14" from a description into something reviewable.
  3. Say in the comment what the filter does. This seed returns only NODE_DOG_MODE nodes whatever is asked — worth one clause, the way Ava Chow's line documents her seed's supported filters.
  4. Contact domain. Seed and statement are on .com; published contact is contact@dogofbitcoin.org. Worth confirming that's reachable and under the same control.

On timing. No longer purely hypothetical — there's a real node and a real answer now, which is progress worth acknowledging. It's still one node, so I'd still call this pre-decision rather than urgent. And the earlier structural point stands regardless of node count: a single dog-specific seed means one operator sees the bootstrap query of very nearly every node that ever joins this subnetwork. Worth a release-note line either way, win or lose on timing — you made that case yourself on #3 about consequences an operator should not learn about as a footnote.

@dogofbitcoin

dogofbitcoin commented Sep 14, 2026 •

Copy link
Copy Markdown
Author

Thank you for checking what is checkable; the numbers you read are the ones we read. Answers to the four, in order, and one measurement you may want.

  1. The name in the line. Deliberate. The Foundation is the accountable party and the operating page says so in its own words, with the contact. The line carries the brand because the client is a community project and we would rather not put a legal entity's name into its source. If the maintainers prefer the Foundation named inline, we will change the line the day they say so.

  2. The seeder build. It is sipa/bitcoin-seeder at ff482e465ff84ea6fa276d858ccb7ef32e3355d3 (master of 2024-03-23) plus one line in main.cpp, in CDnsThread::run before cacheHit: requestedFlags |= 0x4000;, so every answer requires NODE_DOG_MODE whatever filter was asked. It is now a public fork with that one commit: https://github.com/dogofbitcoin/bitcoin-seeder. The unit runs it with -w covering Core's filter set plus the DOG combinations.

  3. What the filter does, in the comment. It is in the line already: // Dog of Bitcoin, answers only nodes advertising NODE_DOG_MODE.

  4. Contact domain. contact@dogofbitcoin.org is the Foundation's mailbox on the Foundation's domain; dogofbitcoin.com is the brand's. Both are under the same control, and the address accepts mail (checked by an SMTP probe on 2026-09-03 that accepted it and refused a made-up name at the same host).

On the structural point: agreed, and it will be in our own text rather than argued away. One dog-specific seed is one operator seeing the first query of nearly every node that joins the subnetwork. The mitigations are the published build above so a second operator can plant one in an afternoon, and Core's own policy on logging, which we hold to. A second seed run by someone who is not us is the fix, and we will say so wherever we say the first one exists.

One measurement, because it bears on "does a listed seed do anything": as of 2026-09-14 11:18 UTC bitnodes sees four reachable nodes advertising bit 14, and this seed can answer with exactly one of them. The other three are pruned or on a non-default port (two run the Umbrel package on 8433), and the reference seeder marks both cases not good, by design, since an A record carries no port and Core's seeds only hand out full nodes. So the seed's answer is correct and small, and the count on the page will say both numbers from now on: nodes advertising the bit that the crawler can reach, and the subset it can hand out.

Edited 2026-09-15. Three things above have changed since, each with its reason in the note below: the seed and its page are on the Foundation's domain now (dnsseed.dogofbitcoin.org, seed.dogofbitcoin.org), the line's comment names Dog of Bitcoin Foundation Inc, which was your point, and the seeder build carries a second line so the filter prefix is read in either letter case.

@tialkan

tialkan commented Sep 15, 2026

Copy link
Copy Markdown

Appreciate the full answer, especially the seeder commit — checked it and it's exactly the one line described, on the exact base you named.

No open asks left from me. The structural point about a second independent seed is the right place to leave it; good that you'll say so in your own text rather than waiting to be asked twice.

@dogofbitcoin dogofbitcoin changed the title chainparams: add the Dog of Bitcoin DNS seed for DOG Mode nodes chainparams: add the Dog of Bitcoin Foundation DNS seed for DOG Mode nodes Sep 15, 2026
@dogofbitcoin

Copy link
Copy Markdown
Author

Thank you for checking the commit. One commit on this branch today carries two changes to the line, and the seeder build you checked has changed too, so here are all three with the reason for each.

The name. The seed moves to the Foundation's own domain: the line lists dnsseed.dogofbitcoin.org. The .com is the Dog of Bitcoin brand's, while the seed is volunteer infrastructure the Foundation answers for, on the domain of its contact address. Moving it now, before a merge, is cheap; after a release, the client would ask the old name for as long as it runs. Same seeder, same machine, same answers, and the operating page moved with it: https://seed.dogofbitcoin.org.

The comment. You had it right: the neighbours in this file name the party that answers for each seed, so the comment now reads // Dog of Bitcoin Foundation Inc, answers only nodes advertising NODE_DOG_MODE. A reader of chainparams.cpp should know who to write to if this seed misbehaves. How the line reads stays the maintainers' call.

The seeder build. The commit you checked is replaced by one that carries its line plus a second: the filter prefix is read as x or X. Google Public DNS randomizes the letter case of the names it asks, and upstream reads the filter only from a lowercase x, so through Google most filtered lookups came back empty; the description no longer needs that caveat. It is still one commit on the same base, and git diff ff482e4..dogmode -- main.cpp shows both lines.

@J25dunn

J25dunn commented Sep 18, 2026

Copy link
Copy Markdown

Independent validation on 2026-09-18:

  • x4009.dnsseed.dogofbitcoin.org returned 185.100.87.52 through the local resolver, Cloudflare (1.1.1.1), Google (8.8.8.8), and Quad9 (9.9.9.9). The seed implementation at ab98d793e32a5fc45a77b0d4102ab7f381c43ae2 confirms its DOG-only filter and case-insensitive prefix handling.
  • Built commit 75032400914250c7ad857dc29043761680a66485; p2p_dns_seeds.py and p2p_dogmode_peering.py both passed.

One scoped behavior is worth recording for a follow-up, rather than treating it as a defect in this one-line seed addition: ThreadDNSAddressSeed() queries every seed with SeedsServiceFlags() (NETWORK | WITNESS, 0x9) and creates each returned CAddress with those same flags. The DOG connector later requires NODE_DOG_MODE on the stored address. Therefore this seed gives a fresh node a DOG-node IP, but that address is initially eligible for normal outbound selection, not a reserved dog slot; the DOG flag becomes known only after a handshake or address gossip.

That matches the limitation described in this PR. Using the seed directly for reserved slots would need a deliberately scoped follow-up that distinguishes this DOG-specific seed from ordinary Core-compatible DNS seeds, rather than marking all DNS responses as DOG_MODE.

@dogofbitcoin

Copy link
Copy Markdown
Author

Thank you, @J25dunn, and sorry for the three days without an answer. Your readings match ours: x4009.dnsseed.dogofbitcoin.org still answers 185.100.87.52 through 8.8.8.8 and 1.1.1.1 today, 2026-09-21, and ab98d793e3 is the seeder build behind it, one commit on sipa's ff482e4.

You have the scope right, and it is the limit this pull request states. A fresh node records the seed's answers with SeedsServiceFlags(), so a dog node from this seed arrives as an ordinary outbound candidate, and a reserved dog slot can use it only once NODE_DOG_MODE is known from a handshake or from gossip. Our readings on #3 agree: node1, holding ten ordinary outbound peers, fills 0 of its 4 dog slots, while the Umbrel node, with a much smaller address book, filled one within days.

The follow-up you describe is the one we would propose: a separate list for DOG-specific seeds, asked with NODE_DOG_MODE in the filter and recorded with that bit, while Core's seeds are asked and recorded exactly as they are today. It is not a condition for this line. If the maintainers want it, we will open it as its own pull request with a functional test and a mainnet reading from a fresh node, and credit your comment for the scoping.

@dogofbitcoin

Copy link
Copy Markdown
Author

Rebased onto 7503240091, the current 31.1-dogmode. The branch had been cut from bbc0880, before #3 merged, so building its head alone gave a node without DOG Mode. The change is the same one line, and the new head's tree is exactly GitHub's merge of the old head, so what merging this does has not changed.

@dogofbitcoin

Copy link
Copy Markdown
Author

A mainnet reading of this line, and of the follow-up @J25dunn scoped above. Each run is a new node from an empty datadir for one hour, pruned, no port open, on a home connection that is not the seed's node.

This line as it is. Six nodes on 2026-09-22, three on this head and three with #10 on top.

  • A reserved dog slot filled in 0 of the 6 hours: 1,003 dog attempts, none completed a handshake. Every dog target the address book snapshots caught advertised bits no client defines, except one clean DOG Mode address that never answered its four dials. The one pruned DOG Mode node in those books was never dialled, since a node far from the tip wants NODE_NETWORK.
  • A DOG Mode peer at all in 1 of the 6 hours, as an ordinary outbound peer. In that run Core's shuffle asked the DOG seed first, so its answer was the only address in the book at the first dial, and it was held all hour. In the other five the DOG seed answered 2nd, 3rd, 7th, 7th and 8th, and its answer was never dialled.

With the follow-up (the DOG seed in its own list, asked as x4009 and its answers recorded with NODE_DOG_MODE, Core's seeds unchanged). Two nodes on 2026-09-23, same harness.

  • In both, the seed's answer was in addrman with NODE_DOG_MODE from the first minute, and a dog slot connected to it at minute 9.7 (the DOG seed answered 6th of 9) and at minute 3.3 (1st of 9).
  • The seed's node runs -maxuploadtarget. While its daily target was spent, it closed each dog connection within 3 seconds, as soon as the new node asked it for blocks more than a week old, and the new node dialled it again (101 and 194 times). Once the target's daily cycle reset, during the second hour, the next dog connection held for the rest of the run, 24 minutes.
  • A node in IBD neither requests nor processes transactions, so the slot has relay work once the node is within a day of the tip, when the blocks it asks for are recent and an upload target does not apply to them. An hour cannot show that part.

The follow-up is one commit on this head, not pushed anywhere yet. Its unit test in net_tests fails 5 checks without it and passes with it, and net_tests, p2p_dns_seeds.py, p2p_dogmode_peering.py and the full functional suite pass with it (194 passed, 0 failed). It has no functional test: regtest has no resolver a test controls, so its dummy seed is never answered.

Would you like the follow-up as its own pull request, before a release or after one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants