mirror of
https://github.com/status-im/EIPs.git
synced 2025-02-24 20:58:13 +00:00
EIP-1459: Node Discovery via DNS (#1459)
This commit is contained in:
parent
d9f8e2ca23
commit
c27d8e0854
150
EIPS/eip-1459.md
Normal file
150
EIPS/eip-1459.md
Normal file
@ -0,0 +1,150 @@
|
||||
---
|
||||
eip: 1459
|
||||
title: Node Discovery via DNS
|
||||
author: Felix Lange <fjl@ethereum.org>, Péter Szilágyi <peter@ethereum.org>
|
||||
type: Standards Track
|
||||
category: Networking
|
||||
status: Draft
|
||||
created: 2018-09-26
|
||||
requires: 778
|
||||
discussions-to: https://github.com/ethereum/devp2p/issues/50
|
||||
---
|
||||
|
||||
# Abstract
|
||||
|
||||
This document describes a scheme for authenticated, updateable Ethereum node lists
|
||||
retrievable via DNS.
|
||||
|
||||
# Motivation
|
||||
|
||||
Many Ethereum clients contain hard-coded bootstrap node lists. Updating those
|
||||
lists requires a software update. The current lists are small, giving the client
|
||||
little choice of initial entry point into the Ethereum network. We would like to
|
||||
maintain larger node lists containing hundreds of nodes, and update them
|
||||
regularly.
|
||||
|
||||
The scheme described here is a replacement for client bootstrap node lists with
|
||||
equivalent security and many additional benefits. DNS node lists may also be
|
||||
useful to Ethereum peering providers because their customers can configure the
|
||||
client to use the provider's list. Finally, the scheme serves as a fallback
|
||||
option for nodes which can't join the node discovery DHT.
|
||||
|
||||
# Specification
|
||||
|
||||
### DNS Record Structure
|
||||
|
||||
Node lists are encoded as TXT records. The records form a merkle tree. The root
|
||||
of the tree is a record with content:
|
||||
|
||||
enrtree-root=v1 hash=<roothash> seq=<seqnum> sig=<signature>
|
||||
|
||||
`roothash` is the abbreviated root hash of the tree in base32 encoding. `seqnum`
|
||||
is the tree's update sequence number, a decimal integer. `signature` is a
|
||||
65-byte secp256k1 EC signature over the keccak256 hash of the record content,
|
||||
encoded as URL-safe base64.
|
||||
|
||||
Further TXT records on subdomains map hashes to one of three entry types. The
|
||||
subdomain name of any entry is the base32 encoding of the abbreviated keccak256
|
||||
hash of its text content.
|
||||
|
||||
- `enrtree=<h₁>,<h₂>,...,<hₙ>` is an intermediate tree containing further hash
|
||||
subdomains.
|
||||
- `enrtree-link=<key>@<fqdn>` is a leaf pointing to a different list located at
|
||||
another fully qualified domain name. The key is the expected signer of the
|
||||
remote list, a base32 encoded secp256k1 public key,
|
||||
- `enr=<node-record>` is a leaf containing a node record [as defined in EIP-778][eip-778].
|
||||
The node record is encoded as a URL-safe base64 string.
|
||||
|
||||
No particular ordering or structure is defined for the tree. Whenever the tree
|
||||
is updated, its sequence number should increase. The content of any TXT record
|
||||
should be small enough to fit into the 512 byte limit imposed on UDP DNS
|
||||
packets. This limits the number of hashes that can be placed into a `enrtree=`
|
||||
entry.
|
||||
|
||||
Example in zone file format:
|
||||
|
||||
```text
|
||||
; name ttl class type content
|
||||
@ 60 IN TXT "enrtree-root=v1 hash=TO4Q75OQ2N7DX4EOOR7X66A6OM seq=3 sig=N-YY6UB9xD0hFx1Gmnt7v0RfSxch5tKyry2SRDoLx7B4GfPXagwLxQqyf7gAMvApFn_ORwZQekMWa_pXrcGCtwE="
|
||||
TO4Q75OQ2N7DX4EOOR7X66A6OM 86900 IN TXT "enrtree=F4YWVKW4N6B2DDZWFS4XCUQBHY,JTNOVTCP6XZUMXDRANXA6SWXTM,JGUFMSAGI7KZYB3P7IZW4S5Y3A"
|
||||
F4YWVKW4N6B2DDZWFS4XCUQBHY 86900 IN TXT "enr=-H24QI0fqW39CMBZjJvV-EJZKyBYIoqvh69kfkF4X8DsJuXOZC6emn53SrrZD8P4v9Wp7NxgDYwtEUs3zQkxesaGc6UBgmlkgnY0gmlwhMsAcQGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOA=="
|
||||
JTNOVTCP6XZUMXDRANXA6SWXTM 86900 IN TXT "enr=-H24QDquAsLj8mCMzJh8ka2BhVFg3n4V9efBJBiaXHcoL31vRJJef-lAseMhuQBEVpM_8Zrin0ReuUXJE7Fs8jy9FtwBgmlkgnY0gmlwhMYzZGOJc2VjcDI1NmsxoQLtfC0F55K2s1egRhrc6wWX5dOYjqla-OuKCELP92O3kA=="
|
||||
JGUFMSAGI7KZYB3P7IZW4S5Y3A 86900 IN TXT "enrtree-link=AM5FCQLWIZX2QFPNJAP7VUERCCRNGRHWZG3YYHIUV7BVDQ5FDPRT2@morenodes.example.org"
|
||||
```
|
||||
|
||||
### Referencing Trees by URL
|
||||
|
||||
When referencing a record tree, e.g. in source code, the preferred form is a
|
||||
URL. References should use the scheme `enrtree://` and encode the DNS domain in
|
||||
the hostname. The expected public key that signs the tree should be encoded in
|
||||
33-byte compressed form as a base32 string in the username portion of the URL.
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
enrtree://AP62DT7WOTEQZGQZOU474PP3KMEGVTTE7A7NPRXKX3DUD57TQHGIA@nodes.example.org
|
||||
```
|
||||
|
||||
### Client Protocol
|
||||
|
||||
To find nodes at a given DNS name, say "mynodes.org":
|
||||
|
||||
1. Resolve the TXT record of the name and check whether it contains a valid
|
||||
"enrtree-root=v1" entry. Let's say the root hash contained in the entry is
|
||||
"CFZUWDU7JNQR4VTCZVOJZ5ROV4".
|
||||
2. Optionally verify the signature on the root against a known public key and
|
||||
check whether the sequence number is larger than or equal to any previous
|
||||
number seen for that name.
|
||||
3. Resolve the TXT record of the hash subdomain, e.g. "CFZUWDU7JNQR4VTCZVOJZ5ROV4.mynodes.org"
|
||||
and verify whether the content matches the hash.
|
||||
4. The next step depends on the entry type found:
|
||||
- for `enrtree`: parse the list of hashes and continue resolving those (step 3).
|
||||
- for `enrtree-link`: continue traversal on the linked domain (step 1).
|
||||
- for `enr`: decode, verify the node record and import it to local node storage.
|
||||
|
||||
During traversal, the client should track hashes and domains which are already
|
||||
resolved to avoid going into an infinite loop.
|
||||
|
||||
# Rationale
|
||||
|
||||
### Why DNS?
|
||||
|
||||
We have chosen DNS as the distribution medium because it is always available,
|
||||
even under restrictive network conditions. The protocol provides low latency and
|
||||
answers to DNS queries can be cached by intermediate resolvers. No custom server
|
||||
software is needed. Node lists can be deployed to any DNS provider such as
|
||||
CloudFlare DNS, dnsimple, Amazon Route 53 using their respective client
|
||||
libraries.
|
||||
|
||||
### Why is this a merkle tree?
|
||||
|
||||
Being a merkle tree, any node list can be authenticated by a single signature on
|
||||
the root. Hash subdomains protect the integrity of the list. At worst
|
||||
intermediate resolvers can block access to the list or disallow updates to it,
|
||||
but cannot corrupt its content. The sequence number prevents replacing the root
|
||||
with an older version.
|
||||
|
||||
Synchronizing updates on the client side can be done incrementally, which
|
||||
matters for large lists. Individual entries of the tree are small enough to fit
|
||||
into a single UDP packet, ensuring compatibility with environments where only
|
||||
basic UDP DNS is available. The tree format also works well with caching
|
||||
resolvers: only the root of the tree needs a short TTL. Intermediate entries and
|
||||
leaves can be cached for days.
|
||||
|
||||
### Why does `enrtree-link` exist?
|
||||
|
||||
Links between lists enable federation and web-of-trust functionality. The
|
||||
operator of a large list can delegate maintenance to other list providers. If
|
||||
two node lists link to each other, users can use either list and get nodes from
|
||||
both.
|
||||
|
||||
# References
|
||||
|
||||
1. The base64 and base32 encodings used to represent binary data are defined in
|
||||
RFC 4648 (https://tools.ietf.org/html/rfc4648). No padding is used for base32.
|
||||
|
||||
[eip-778]: https://eips.ethereum.org/EIPS/eip-778
|
||||
|
||||
# Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
Loading…
x
Reference in New Issue
Block a user