Skip to content
This repository was archived by the owner on Nov 20, 2023. It is now read-only.

Commit 128002e

Browse files
authored
Port to bytes, rlp 0.5 (#25)
1 parent 074fe32 commit 128002e

File tree

9 files changed

+50
-45
lines changed

9 files changed

+50
-45
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ exclude = [
1717
[dependencies]
1818
base64 = "0.12.1"
1919
bs58 = "0.3.1"
20+
bytes = "1"
2021
hex = "0.4.2"
2122
log = "0.4.8"
2223
rand = "0.7.3"
23-
rlp = "0.4.5"
24+
rlp = "0.5"
2425
zeroize = "1.1.0"
2526
libsecp256k1 = { version = "0.3.5", optional = true }
2627
sha3 = "0.9"

src/builder.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{Enr, EnrError, EnrKey, EnrPublicKey, Key, NodeId, MAX_ENR_SIZE};
2+
use bytes::{Bytes, BytesMut};
23
use rlp::RlpStream;
34
use std::{collections::BTreeMap, marker::PhantomData, net::IpAddr};
45

@@ -12,7 +13,7 @@ pub struct EnrBuilder<K: EnrKey> {
1213

1314
/// The key-value pairs for the ENR record.
1415
/// Values are stored as RLP encoded bytes.
15-
content: BTreeMap<Key, Vec<u8>>,
16+
content: BTreeMap<Key, Bytes>,
1617

1718
/// Pins the generic key types.
1819
phantom: PhantomData<K>,
@@ -39,11 +40,11 @@ impl<K: EnrKey> EnrBuilder<K> {
3940

4041
/// Adds an arbitrary key-value to the `ENRBuilder`.
4142
pub fn add_value(&mut self, key: impl AsRef<[u8]>, value: &[u8]) -> &mut Self {
42-
self.add_value_rlp(key, rlp::encode(&value))
43+
self.add_value_rlp(key, rlp::encode(&value).freeze())
4344
}
4445

4546
/// Adds an arbitrary key-value where the value is raw RLP encoded bytes.
46-
pub fn add_value_rlp(&mut self, key: impl AsRef<[u8]>, rlp: Vec<u8>) -> &mut Self {
47+
pub fn add_value_rlp(&mut self, key: impl AsRef<[u8]>, rlp: Bytes) -> &mut Self {
4748
self.content.insert(key.as_ref().to_vec(), rlp);
4849
self
4950
}
@@ -97,16 +98,16 @@ impl<K: EnrKey> EnrBuilder<K> {
9798
}
9899

99100
/// Generates the rlp-encoded form of the ENR specified by the builder config.
100-
fn rlp_content(&self) -> Vec<u8> {
101-
let mut stream = RlpStream::new();
101+
fn rlp_content(&self) -> BytesMut {
102+
let mut stream = RlpStream::new_with_buffer(BytesMut::with_capacity(MAX_ENR_SIZE));
102103
stream.begin_list(self.content.len() * 2 + 1);
103104
stream.append(&self.seq);
104105
for (k, v) in &self.content {
105106
stream.append(k);
106107
// The values are stored as raw RLP encoded bytes
107108
stream.append_raw(v, 1);
108109
}
109-
stream.drain()
110+
stream.out()
110111
}
111112

112113
/// Signs record based on the identity scheme. Currently only "v4" is supported.
@@ -144,7 +145,7 @@ impl<K: EnrKey> EnrBuilder<K> {
144145
}
145146
}
146147

147-
self.add_value_rlp("id", rlp::encode(&self.id.as_bytes()));
148+
self.add_value_rlp("id", rlp::encode(&self.id.as_bytes()).freeze());
148149

149150
self.add_public_key(&key.public());
150151
let rlp_content = self.rlp_content();

src/keys/combined.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! Currently only `secp256k1` and `ed25519` key types are supported.
55
66
use super::{ed25519_dalek as ed25519, EnrKey, EnrPublicKey, SigningError};
7+
use bytes::Bytes;
78
pub use k256;
89
use rand::RngCore;
910
use rlp::DecoderError;
@@ -66,7 +67,7 @@ impl EnrKey for CombinedKey {
6667
}
6768

6869
/// Decodes the raw bytes of an ENR's content into a public key if possible.
69-
fn enr_to_public(content: &BTreeMap<Key, Vec<u8>>) -> Result<Self::PublicKey, DecoderError> {
70+
fn enr_to_public(content: &BTreeMap<Key, Bytes>) -> Result<Self::PublicKey, DecoderError> {
7071
k256::ecdsa::SigningKey::enr_to_public(content)
7172
.map(CombinedPublicKey::Secp256k1)
7273
.or_else(|_| ed25519::Keypair::enr_to_public(content).map(CombinedPublicKey::from))

src/keys/ed25519.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::{
33
EnrKey, EnrKeyUnambiguous, EnrPublicKey, SigningError,
44
};
55
use crate::Key;
6+
use bytes::Bytes;
67
use rlp::DecoderError;
78
use std::{collections::BTreeMap, convert::TryFrom};
89

@@ -26,7 +27,7 @@ impl EnrKey for ed25519::Keypair {
2627
}
2728

2829
/// Decodes the raw bytes of an ENR's content into a public key if possible.
29-
fn enr_to_public(content: &BTreeMap<Key, Vec<u8>>) -> Result<Self::PublicKey, DecoderError> {
30+
fn enr_to_public(content: &BTreeMap<Key, Bytes>) -> Result<Self::PublicKey, DecoderError> {
3031
let pubkey_bytes = content
3132
.get(ENR_KEY.as_bytes())
3233
.ok_or(DecoderError::Custom("Unknown signature"))?;

src/keys/k256_key.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use super::{EnrKey, EnrKeyUnambiguous, EnrPublicKey, SigningError};
44
use crate::Key;
5+
use bytes::Bytes;
56
use k256::{
67
ecdsa::{
78
signature::{DigestVerifier, RandomizedDigestSigner, Signature as _},
@@ -35,7 +36,7 @@ impl EnrKey for SigningKey {
3536
self.verify_key()
3637
}
3738

38-
fn enr_to_public(content: &BTreeMap<Key, Vec<u8>>) -> Result<Self::PublicKey, DecoderError> {
39+
fn enr_to_public(content: &BTreeMap<Key, Bytes>) -> Result<Self::PublicKey, DecoderError> {
3940
let pubkey_bytes = content
4041
.get(ENR_KEY.as_bytes())
4142
.ok_or(DecoderError::Custom("Unknown signature"))?;

src/keys/libsecp256k1.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use super::{secp256k1, EnrKey, EnrKeyUnambiguous, EnrPublicKey, SigningError};
44
use crate::{digest, Key};
5+
use bytes::Bytes;
56
use rlp::DecoderError;
67
use std::collections::BTreeMap;
78

@@ -30,7 +31,7 @@ impl EnrKey for secp256k1::SecretKey {
3031
}
3132

3233
/// Decodes the raw bytes of an ENR's content into a public key if possible.
33-
fn enr_to_public(content: &BTreeMap<Key, Vec<u8>>) -> Result<Self::PublicKey, DecoderError> {
34+
fn enr_to_public(content: &BTreeMap<Key, Bytes>) -> Result<Self::PublicKey, DecoderError> {
3435
let pubkey_bytes = content
3536
.get(ENR_KEY.as_bytes())
3637
.ok_or(DecoderError::Custom("Unknown signature"))?;

src/keys/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub use k256;
3131
pub use secp256k1;
3232

3333
use crate::Key;
34+
use bytes::Bytes;
3435
use rlp::DecoderError;
3536
use std::{
3637
collections::BTreeMap,
@@ -54,7 +55,7 @@ pub trait EnrKey: Send + Sync + Unpin + 'static {
5455
/// `EnrPublicKey`. It takes the ENR's `BTreeMap` and returns a public key.
5556
///
5657
/// Note: This specifies the supported key schemes for an ENR.
57-
fn enr_to_public(content: &BTreeMap<Key, Vec<u8>>) -> Result<Self::PublicKey, DecoderError>;
58+
fn enr_to_public(content: &BTreeMap<Key, Bytes>) -> Result<Self::PublicKey, DecoderError>;
5859
}
5960

6061
/// Trait for keys that are uniquely represented

src/keys/rust_secp256k1.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{EnrKey, EnrKeyUnambiguous, EnrPublicKey, SigningError};
22
use crate::{digest, Key};
3+
use bytes::Bytes;
34
use c_secp256k1::SECP256K1;
45
use rlp::DecoderError;
56
use std::collections::BTreeMap;
@@ -23,7 +24,7 @@ impl EnrKey for c_secp256k1::SecretKey {
2324
Self::PublicKey::from_secret_key(SECP256K1, self)
2425
}
2526

26-
fn enr_to_public(content: &BTreeMap<Key, Vec<u8>>) -> Result<Self::PublicKey, DecoderError> {
27+
fn enr_to_public(content: &BTreeMap<Key, Bytes>) -> Result<Self::PublicKey, DecoderError> {
2728
let pubkey_bytes = content
2829
.get(ENR_KEY.as_bytes())
2930
.ok_or(DecoderError::Custom("Unknown signature"))?;

src/lib.rs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ mod builder;
180180
mod keys;
181181
mod node_id;
182182

183+
use bytes::{Bytes, BytesMut};
183184
use log::debug;
184185
use rlp::{DecoderError, Rlp, RlpStream};
185186
use std::collections::BTreeMap;
@@ -227,7 +228,7 @@ pub struct Enr<K: EnrKey> {
227228
/// Key-value contents of the ENR. A BTreeMap is used to get the keys in sorted order, which is
228229
/// important for verifying the signature of the ENR.
229230
/// Everything is stored as raw RLP bytes.
230-
content: BTreeMap<Key, Vec<u8>>,
231+
content: BTreeMap<Key, Bytes>,
231232

232233
/// The signature of the ENR record, stored as bytes.
233234
signature: Vec<u8>,
@@ -261,13 +262,13 @@ impl<K: EnrKey> Enr<K> {
261262
}
262263

263264
/// Reads a custom key from the record if it exists as raw RLP bytes.
264-
pub fn get_raw_rlp(&self, key: impl AsRef<[u8]>) -> Option<&Vec<u8>> {
265-
self.content.get(key.as_ref())
265+
pub fn get_raw_rlp(&self, key: impl AsRef<[u8]>) -> Option<&[u8]> {
266+
self.content.get(key.as_ref()).map(AsRef::as_ref)
266267
}
267268

268269
/// Returns an iterator over all key/value pairs in the ENR.
269-
pub fn iter(&self) -> impl Iterator<Item = (&Key, &Vec<u8>)> {
270-
self.content.iter()
270+
pub fn iter(&self) -> impl Iterator<Item = (&Key, &[u8])> {
271+
self.content.iter().map(|(k, v)| (k, v.as_ref()))
271272
}
272273

273274
/// Returns the IPv4 address of the ENR record if it is defined.
@@ -430,18 +431,10 @@ impl<K: EnrKey> Enr<K> {
430431
}
431432
}
432433

433-
/// RLP encodes the ENR into a byte array.
434-
#[must_use]
435-
pub fn encode(&self) -> Vec<u8> {
436-
let mut s = RlpStream::new();
437-
s.append(self);
438-
s.drain()
439-
}
440-
441434
/// Provides the URL-safe base64 encoded "text" version of the ENR prefixed by "enr:".
442435
#[must_use]
443436
pub fn to_base64(&self) -> String {
444-
let hex = base64::encode_config(&self.encode(), base64::URL_SAFE_NO_PAD);
437+
let hex = base64::encode_config(&rlp::encode(self), base64::URL_SAFE_NO_PAD);
445438
format!("enr:{}", hex)
446439
}
447440

@@ -480,8 +473,8 @@ impl<K: EnrKey> Enr<K> {
480473
key: impl AsRef<[u8]>,
481474
value: &[u8],
482475
enr_key: &K,
483-
) -> Result<Option<Vec<u8>>, EnrError> {
484-
self.insert_raw_rlp(key, rlp::encode(&value), enr_key)
476+
) -> Result<Option<Bytes>, EnrError> {
477+
self.insert_raw_rlp(key, rlp::encode(&value).freeze(), enr_key)
485478
}
486479

487480
/// Adds or modifies a key/value to the ENR record. A `EnrKey` is required to re-sign the record once
@@ -491,11 +484,11 @@ impl<K: EnrKey> Enr<K> {
491484
pub fn insert_raw_rlp(
492485
&mut self,
493486
key: impl AsRef<[u8]>,
494-
value: Vec<u8>,
487+
value: Bytes,
495488
enr_key: &K,
496-
) -> Result<Option<Vec<u8>>, EnrError> {
489+
) -> Result<Option<Bytes>, EnrError> {
497490
// currently only support "v4" identity schemes
498-
if key.as_ref() == b"id" && value != b"v4" {
491+
if key.as_ref() == b"id" && &*value != b"v4" {
499492
return Err(EnrError::UnsupportedIdentityScheme);
500493
}
501494

@@ -504,7 +497,7 @@ impl<K: EnrKey> Enr<K> {
504497
let public_key = enr_key.public();
505498
let previous_key = self.content.insert(
506499
public_key.enr_key(),
507-
rlp::encode(&public_key.encode().as_ref()),
500+
rlp::encode(&public_key.encode().as_ref()).freeze(),
508501
);
509502

510503
// check the size of the record
@@ -640,27 +633,31 @@ impl<K: EnrKey> Enr<K> {
640633

641634
let (prev_ip, prev_port) = match socket.ip() {
642635
IpAddr::V4(addr) => (
643-
self.content
644-
.insert("ip".into(), rlp::encode(&(&addr.octets() as &[u8]))),
636+
self.content.insert(
637+
"ip".into(),
638+
rlp::encode(&(&addr.octets() as &[u8])).freeze(),
639+
),
645640
self.content.insert(
646641
port_string.clone(),
647-
rlp::encode(&(&socket.port().to_be_bytes() as &[u8])),
642+
rlp::encode(&(&socket.port().to_be_bytes() as &[u8])).freeze(),
648643
),
649644
),
650645
IpAddr::V6(addr) => (
651-
self.content
652-
.insert("ip6".into(), rlp::encode(&(&addr.octets() as &[u8]))),
646+
self.content.insert(
647+
"ip6".into(),
648+
rlp::encode(&(&addr.octets() as &[u8])).freeze(),
649+
),
653650
self.content.insert(
654651
port_v6_string.clone(),
655-
rlp::encode(&(&socket.port().to_be_bytes() as &[u8])),
652+
rlp::encode(&(&socket.port().to_be_bytes() as &[u8])).freeze(),
656653
),
657654
),
658655
};
659656

660657
let public_key = key.public();
661658
let previous_key = self.content.insert(
662659
public_key.enr_key(),
663-
rlp::encode(&public_key.encode().as_ref()),
660+
rlp::encode(&public_key.encode().as_ref()).freeze(),
664661
);
665662

666663
// check the size and revert on failure
@@ -726,8 +723,8 @@ impl<K: EnrKey> Enr<K> {
726723
// Private Functions //
727724

728725
/// Evaluates the RLP-encoding of the content of the ENR record.
729-
fn rlp_content(&self) -> Vec<u8> {
730-
let mut stream = RlpStream::new();
726+
fn rlp_content(&self) -> BytesMut {
727+
let mut stream = RlpStream::new_with_buffer(BytesMut::with_capacity(MAX_ENR_SIZE));
731728
stream.begin_list(self.content.len() * 2 + 1);
732729
stream.append(&self.seq);
733730
for (k, v) in &self.content {
@@ -736,7 +733,7 @@ impl<K: EnrKey> Enr<K> {
736733
// Values are raw RLP encoded data
737734
stream.append_raw(v, 1);
738735
}
739-
stream.drain()
736+
stream.out()
740737
}
741738

742739
/// Signs the ENR record based on the identity scheme. Currently only "v4" is supported.
@@ -892,7 +889,7 @@ impl<K: EnrKey> rlp::Decodable for Enr<K> {
892889
return Err(DecoderError::Custom("Unsorted keys"));
893890
}
894891
prev = Some(key.clone());
895-
content.insert(key, value.into());
892+
content.insert(key, Bytes::copy_from_slice(value));
896893
}
897894

898895
// verify we know the signature type

0 commit comments

Comments
 (0)