EIP 778: Ethereum Node Records (ENR) Source

AuthorFelix Lange
Discussions-Tohttps://github.com/ethereum/devp2p/issues/43
StatusDraft
TypeStandards Track
CategoryNetworking
Created2017-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 unsigned 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. Keys must be unique.

A record’s signature is made and validated according to an identity 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   = [seq, k, v, ...]
signature = sign(content)
record    = [signature, seq, k, v, ...]

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. “v4”
secp256k1 compressed secp256k1 public key, 33 bytes
ip IP address, 4 or 16 bytes
tcp TCP port, big endian integer
udp UDP port, big endian integer

“v4” Identity Scheme

This specification defines a single scheme to be used as the default. The “v4” scheme is backwards-compatible with the cryptosystem used by Node Discovery v4.

  • To sign record content with this scheme, apply the keccak256 hash function (as used by the EVM) 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 (the recovery ID v is omitted).
  • To verify a record, check that the signature was made by the public key in the “secp256k1” key/value pair of the record.
  • To derive a node address, take the keccak256 hash of the uncompressed public key.

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 a IPv4 address, when signed using the “v4” scheme occupies roughly 120 bytes, leaving plenty of room for additional metadata.

Test Vectors

Example (valid) record:

f884b8407098ad865b00a582051940cb9cf36836572411a4727878307701
1599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11
df72ecf1145ccb9c01826964827634826970847f00000189736563703235
366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1
400f3258cd31388375647082765f

The raw RLP structure of this record is:

[
  7098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c,
  01,
  "id",
  "v4",
  "ip",
  7f000001,
  "secp256k1",
  03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138,
  "udp",
  765f,
]

The record contains sequence number 1.

A v4 enode URL containing the same information (but no signature or sequence number):

enode://ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f@127.0.0.1:0?discport=30303

Copyright

Copyright and related rights waived via CC0.