-
Notifications
You must be signed in to change notification settings - Fork 6k
EIP-778: Ethereum Node Records #778
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
329591a
7aef5b6
095488a
427163c
fc9749b
95e28ff
f80eb12
22fdb9a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # Preamble | ||
|
|
||
| EIP: 778 | ||
| Title: Ethereum Node Records (ENR) | ||
| Author: Felix Lange <fjl@ethereum.org> | ||
| Type: Standard Track | ||
| Category Networking | ||
| Status: Draft | ||
| Created: 2017-11-23 | ||
|
|
||
| # Abstract | ||
|
|
||
| This EIP defines Ethereum Node Records, an open format for p2p connectivity information. | ||
|
|
||
| # Motivation | ||
|
|
||
| Ethereum nodes discover each other through the node discovery protocol. The purpose of | ||
| that protocol is relaying node identity public keys (on the secp256k1 curve), their IP | ||
| address and two port numbers. No other information can be relayed. | ||
|
|
||
| This specification seeks to lift the restrictions of the discovery v4 protocol by defining | ||
| a flexible format, the *node record*, for connectivity-related information. Node records | ||
| can be relayed through a future version of the node discovery protocol. They can also be | ||
| relayed through arbitrary other mechanisms such as DNS, ENS, a devp2p subprotocol, etc. | ||
|
|
||
| Node records improve cryptographic agility and handling of protocol upgrades. A record can | ||
| contain information about arbitrary transport protocols and public key material associated | ||
| with them. | ||
|
|
||
| Another goal of the new format is to provide authoritative updates of connectivity | ||
| information. If a node changes its endpoint and publishes a new record, other nodes should | ||
| be able to determine which record is newer. | ||
|
|
||
| # Specification | ||
|
|
||
| The components of a node record are: | ||
|
|
||
| - `signature`: cryptographic signature of record contents | ||
| - `seq`: The sequence number, a 64 bit integer. Nodes should increase the number whenever | ||
| the record changes and republish the record. | ||
| - The remainder of the record consists of arbitrary key/value pairs, which must be sorted | ||
| by key. | ||
|
|
||
| A record's signature is made and validated according to an *identy scheme*. The identity | ||
| scheme is also responsible for deriving a node's address in the DHT. | ||
|
|
||
| ### RLP Encoding | ||
|
|
||
| The canonical encoding of a node record is an RLP list of `[signature, seq, k, v, ...]`. | ||
| The maximum encoded size of a node record is 300 bytes. Implementations should reject | ||
| records larger than this size. | ||
|
|
||
| Records are signed and encoded as follows: | ||
|
|
||
| content = rlp(seq) || rlp(k) || rlp(v) || ... | ||
| signature = rlp(sign(rlp_list(content))) | ||
| record = rlp_list(signature || content) | ||
|
|
||
| ### Key/Value Pairs | ||
|
|
||
| The keys in key/value pairs can technically be any byte sequence, but ASCII text is | ||
| preferred. The following keys are pre-defined: | ||
|
|
||
| | Key | Value | | ||
| |:-------------|:-------------------------------------------------| | ||
| | `id` | name of identity scheme, e.g. "secp256k1-keccak" | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps use IDs here specified in a table?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree the name is a bit long. |
||
| | `secp256k1` | compressed secp256k1 public key, 33 bytes | | ||
| | `ip4` | IPv4 address, 4 bytes | | ||
| | `ip6` | IPv6 address, 16 bytes | | ||
| | `discv5` | UDP port for discovery v5 | | ||
|
|
||
| ### secp256k1-keccak Identity Scheme | ||
|
|
||
| This specification defines a single scheme to be used as the default: "secp256k1-keccak". | ||
|
|
||
| - To sign record `content` with this scheme, apply the keccak256[^1] hash function to | ||
| `content`, then create a signature of the hash. The resulting 64-byte signature is | ||
| encoded as the concatenation of the `r` and `s` signature values. | ||
| - To verify a record, check that the signature was made by the public key in the | ||
| "secp256k1" key/value pair. | ||
| - To derive a node address, take the keccak256 hash of the public key. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the definition of a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's the byte sequence used for Kademlia distance calculations.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An interesting consequence of using hash(node id) for XOR distance calculations is that it becomes very difficult to implement the Kademlia bucket refresh part of the Kademlia system. The Maymounkov and Mazieres paper explains that after the idle k-bucket timeout (1 hour in the v4 rlpx.md), the k-bucket should refresh itself by calling FindNeighbours on a random node id within the k-bucket range. I don't see how that can be implemented if the k-bucket range is hash(node id) and FindNeighbours accepts (node id). I see the go implementation avoids the issue by just picking a random id irrespective of the bucket. For 'distant' buckets, the contents could get stale quickly (1 hour).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In v5, FindNode will contain hash instead of the public key. See ethereum/devp2p#25 |
||
|
|
||
| [^1]: As used by the EVM | ||
|
|
||
| # Rationale | ||
|
|
||
| The format is meant to suit future needs in two ways: | ||
|
|
||
| - Adding new key/value pairs: This is always possible and doesn't require implementation | ||
| consensus. Existing clients will accept any key/value pairs regardless of whether they | ||
| can interpret their content. | ||
| - Adding identity schemes: these need implementation consensus because the network won't | ||
| accept the signature otherwise. To introduce a new identity scheme, propose an EIP and | ||
| get it implemented. The scheme can be used as soon as most clients accept it. | ||
|
|
||
| The size of a record is limited because records are relayed frequently and may be included | ||
| in size-constrained protocols such as DNS. A record containing IPv4 address, when signed | ||
| using the "secp256k1-keccak" scheme occupies roughly 120 bytes, leaving plenty of room for | ||
| additional metadata. | ||
|
|
||
| # Copyright | ||
|
|
||
| Copyright and related rights waived via CC0. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small typo - should be "identity scheme"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed