Please describe the feature you’d like to see added.
Right now, Bitcoin Core can only receive IPv4 and IPv6 node addresses from DNS seeds. Adding support for darknet addresses would bring the advantages of using DNS seeds (more privacy, faster bootstrapping, etc.) for node discovery to darknet nodes.
Is your feature related to a problem, if so please describe it.
No response
Describe the solution you’d like
Before TorV2 addresses were deprecated, Bitcoin Core and seeds using sipa’s seeder (and maybe others) supported distributing such addresses by encoding them in AAAA records: Since TorV2 addresses used only 80-bit hashes, they neatly fitted into the 128-bit data field of an AAAA record, leaving plenty of room for a 48bit prefix (from the not publicly routable fc00::/7 subnet) to signal the custom encoding.
TorV3 and I2p addresses use 256-bits of data, making them too large for single AAAA records. However, such addresses can be serialized using a trimmed BIP155 format (just the net id and address), concatenated, and broken into chunks that fit into AAAA record data fields.
In addition to a prefix to signal the custom encoding, correct deserialization requires a sequence number since public resolvers may reorder records.
To get a rough estimate for the numbers, consider the following: DNS messages should be at most 512B. The header has a fixed size of 12B. The question section has variable size because it contains the query domain. 30 chars should be sufficient for most seeds, which implies a size of 36B for the question section (32B for the 30 chars, plus 2B each for query type and class). This leaves 464B for the record section. Since AAAA records are 28B each (2B each for name pointer, type, class, length, 4B for TTL, and 128b/16B for data), a DNS reply for regular-length domains can at most contain 16 AAAA records. Hence four bits are required to encode sequence numbers.
The publicly unroutable fc00::/7 prefix used in the past uses 7 bits. Extending these by e.g. five more bits for versioning to accommodate for future updates results in a signaling-prefix size of 12 bits, leaving 112 bit (or 14B) for payload:
0 0 11 12 15 16 127
1+------------+----------+------------------------------------------------------------+
2| Prefix | Seq# | Payload |
3| (12 bits) | (4 bits) | (112 bits) |
4+------------+----------+------------------------------------------------------------+
At 16 AAAA records per DNS message, 14B of payload per record and 33B per TorV3/I2P address (net id plus 256-bit data), six TorV3/I2P addresses can be encoded per message.
CJDNS addresses, which are IPv6 addresses, could be encoded as well; at 17B per address (net id plus 128-bit data), 13 addresses could be encoded per message.
To avoid interfering with legacy software, darknet addresses could only be distributed via special subdomains (similar to x
used for version bits), e.g. ni
, where n
stands for network id and i
for a particular network id specified in BIP155. Example x9.n4.seed.acme.com.
Demo implementation: https://github.com/virtu/darkseed
Demo DNS seed: dnsseed.21.ninja
Describe any alternatives you’ve considered
Originally, I considered using DNS NULL records, because their data fields allow for an arbitrary amount of binary data, resulting in a much better encoding efficiency than ~50% offered by the proposed AAAA encoding (14B of overhead-including payload per 28B record).
This approach, however, has the following shortcomings (as pointed out by sipa in the forum):
- Depend on external DNS library or extra code to create DNS request with NULL query type
- Public recursive resolvers might not cache DNS NULL records
Please leave any additional context
No response