[][src]Crate enr

Ethereum Node Record (ENR)

This crate contains an implementation of an Ethereum Node Record (ENR) as specified by EIP-778 extended to allow for the use of ed25519 keys.

An ENR is a signed, key-value record which has an associated NodeId (a 32-byte identifier). Updating/modifying an ENR requires an EnrKey in order to re-sign the record with the associated key-pair.

ENR's are identified by their sequence number. When updating an ENR, the sequence number is increased.

Different identity schemes can be used to define the node id and signatures. Currently only the "v4" identity is supported and is set by default.

Signing Algorithms

User's wishing to implement their own singing algorithms simply need to implement the EnrKey trait and apply it to an Enr.

By default, libsecp256k1::SecretKey implement EnrKey and can be used to sign and verify ENR records. This library also implements EnrKey for ed25519_dalek::Keypair via the ed25519 feature flag.

Furthermore, a CombinedKey is provided if the ed25519 feature flag is set, which provides an ENR type that can support both secp256k1 and ed25519 signed ENR records. Examples of the use of each of these key types is given below.

Additionally there is support for conversion of rust-libp2p Keypair to the CombinedKey type via the libp2p feature flag.

Features

This crate supports a number of features.

  • serde: Allows for serde serialization and deserialization for ENRs.
  • libp2p: Provides libp2p integration. Libp2p Keypair's can be converted to CombinedKey types which can be used to sign and modify ENRs. This feature also adds the peer_id() and multiaddr() functions to an ENR which provides an ENR's associated PeerId and list of MultiAddr's respectively.
  • ed25519: Provides support for ed25519_dalek keypair types.

These can be enabled via adding the feature flag in your Cargo.toml

enr = { version = "*", features = ["serde", "libp2p", "ed25519"] }

Examples

To build an ENR, an EnrBuilder is provided.

Building an ENR with the default secp256k1 key type

use enr::{EnrBuilder, secp256k1};
use std::net::Ipv4Addr;
use rand::thread_rng;

// generate a random secp256k1 key
let mut rng = thread_rng();
let key = secp256k1::SecretKey::random(&mut rng);

let ip = Ipv4Addr::new(192,168,0,1);
let enr = EnrBuilder::new("v4").ip(ip.into()).tcp(8000).build(&key).unwrap();

assert_eq!(enr.ip(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(enr.id(), Some("v4".into()));

Building an ENR with the CombinedKey type (support for multiple signing

algorithms).

Note the ed25519 feature flag must be set. This makes use of the EnrBuilder struct.

use enr::{EnrBuilder, CombinedKey};
use std::net::Ipv4Addr;

// create a new secp256k1 key
let key = CombinedKey::generate_secp256k1();

// or create a new ed25519 key
let key = CombinedKey::generate_ed25519();

let ip = Ipv4Addr::new(192,168,0,1);
let enr = EnrBuilder::new("v4").ip(ip.into()).tcp(8000).build(&key).unwrap();

assert_eq!(enr.ip(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(enr.id(), Some("v4".into()));

Modifying an Enr

ENR fields can be added and modified using the getters/setters on Enr. A custom field can be added using insert and retrieved with get.

use enr::{EnrBuilder, secp256k1::SecretKey, Enr};
use std::net::Ipv4Addr;
use rand::thread_rng;

// generate a random secp256k1 key
let mut rng = thread_rng();
let key = SecretKey::random(&mut rng);

let ip = Ipv4Addr::new(192,168,0,1);
let mut enr = EnrBuilder::new("v4").ip(ip.into()).tcp(8000).build(&key).unwrap();

enr.set_tcp(8001, &key);
// set a custom key
enr.insert("custom_key", vec![0,0,1], &key);

// encode to base64
let base_64_string = enr.to_base64();

// decode from base64
let decoded_enr: Enr = base_64_string.parse().unwrap();

assert_eq!(decoded_enr.ip(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(decoded_enr.id(), Some("v4".into()));
assert_eq!(decoded_enr.tcp(), Some(8001));
assert_eq!(decoded_enr.get("custom_key"), Some(&vec![0,0,1]));

Libp2p key conversion, with the libp2p feature flag

use enr::{EnrBuilder, CombinedKey};
use std::net::Ipv4Addr;
use std::convert::TryInto;

// with the `libp2p` feature flag, one can also use a libp2p key
let libp2p_key = libp2p_core::identity::Keypair::generate_secp256k1();
let key: CombinedKey = libp2p_key.try_into().expect("supports secp256k1");

let ip = Ipv4Addr::new(192,168,0,1);
let enr = EnrBuilder::new("v4").ip(ip.into()).tcp(8000).build(&key).unwrap();

assert_eq!(enr.ip(), Some("192.168.0.1".parse().unwrap()));
assert_eq!(enr.id(), Some("v4".into()));

Encoding/Decoding ENR's of various key types

use enr::{EnrBuilder, secp256k1::SecretKey, Enr, ed25519_dalek::Keypair, CombinedKey};
use std::net::Ipv4Addr;
use rand::thread_rng;
use rand::Rng;

// generate a random secp256k1 key
let mut rng = thread_rng();
let key = SecretKey::random(&mut rng);
let ip = Ipv4Addr::new(192,168,0,1);
let enr_secp256k1 = EnrBuilder::new("v4").ip(ip.into()).tcp(8000).build(&key).unwrap();

// encode to base64
let base64_string_secp256k1 = enr_secp256k1.to_base64();

// generate a random ed25519 key
let key = Keypair::generate(&mut rng);
let enr_ed25519 = EnrBuilder::new("v4").ip(ip.into()).tcp(8000).build(&key).unwrap();

// encode to base64
let base64_string_ed25519 = enr_ed25519.to_base64();

// decode base64 strings of varying key types
// decode the secp256k1 with default Enr
let decoded_enr_secp256k1: Enr = base64_string_secp256k1.parse().unwrap();
// decode ed25519 ENRs
let decoded_enr_ed25519: Enr<Keypair> = base64_string_ed25519.parse().unwrap();

// use the combined key to be able to decode either
let decoded_enr: Enr<CombinedKey> = base64_string_secp256k1.parse().unwrap();
let decoded_enr: Enr<CombinedKey> = base64_string_ed25519.parse().unwrap();

Re-exports

pub use keys::secp256k1;
pub use keys::ed25519_dalek;

Structs

Enr

The ENR, allowing for arbitrary signing algorithms. The default signing algorithm is secp256k1 using the libsecp256k1 library.

EnrBuilder

The base builder for generating ENR records with arbitrary signing algorithms.

NodeId

The NodeId of an ENR (a 32 byte identifier).

Enums

CombinedKey

A standard implementation of the EnrKey trait used to sign and modify ENR records. The variants here represent the currently supported in-built signing schemes.

CombinedPublicKey

A combined implementation of EnrPublicKey which has support for Secp256k1 and Ed25519 for ENR signature verification.

EnrError

An error type for handling various ENR operations.

Traits

EnrKey

The trait required for a key to sign and modify an ENR record.

EnrPublicKey

The trait required for a PublicKey to verify an ENR record.