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

Commit 80b3ca8

Browse files
authored
Avoid allocations in RLP decode impl for Enr (#32)
* Use iter rather than collecting * Use ref in `prev`
1 parent 0cde4eb commit 80b3ca8

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/lib.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -851,15 +851,21 @@ impl<K: EnrKey> rlp::Decodable for Enr<K> {
851851
return Err(DecoderError::RlpExpectedToBeList);
852852
}
853853

854-
let mut decoded_list: Vec<Rlp> = rlp.iter().collect();
854+
let mut rlp_iter = rlp.iter();
855855

856-
if decoded_list.is_empty() || decoded_list.len() % 2 != 0 {
856+
if rlp_iter.len() == 0 || rlp_iter.len() % 2 != 0 {
857857
debug!("Failed to decode ENR. List size is not a multiple of 2.");
858858
return Err(DecoderError::Custom("List not a multiple of two"));
859859
}
860860

861-
let signature = decoded_list.remove(0).data()?;
862-
let seq_bytes = decoded_list.remove(0).data()?;
861+
let signature = rlp_iter
862+
.next()
863+
.ok_or(DecoderError::Custom("List is empty"))?
864+
.data()?;
865+
let seq_bytes = rlp_iter
866+
.next()
867+
.ok_or(DecoderError::Custom("List has only one item"))?
868+
.data()?;
863869

864870
if seq_bytes.len() > 8 {
865871
debug!("Failed to decode ENR. Sequence number is not a u64.");
@@ -872,20 +878,22 @@ impl<K: EnrKey> rlp::Decodable for Enr<K> {
872878
let seq = u64::from_be_bytes(seq);
873879

874880
let mut content = BTreeMap::new();
875-
let mut prev: Option<Key> = None;
876-
for _ in 0..decoded_list.len() / 2 {
877-
let key = decoded_list.remove(0).data()?.to_vec();
878-
let item = decoded_list.remove(0);
881+
let mut prev: Option<&[u8]> = None;
882+
while let Some(key) = rlp_iter.next() {
883+
let key = key.data()?;
884+
let item = rlp_iter
885+
.next()
886+
.ok_or(DecoderError::Custom("List not a multiple of 2"))?;
879887

880888
// Sanitize the data
881889
let _ = item.data()?;
882890
let value = item.as_raw();
883891

884-
if prev.is_some() && prev.as_ref() >= Some(&key) {
892+
if prev.is_some() && prev >= Some(key) {
885893
return Err(DecoderError::Custom("Unsorted keys"));
886894
}
887-
prev = Some(key.clone());
888-
content.insert(key, Bytes::copy_from_slice(value));
895+
prev = Some(key);
896+
content.insert(key.to_vec(), Bytes::copy_from_slice(value));
889897
}
890898

891899
// verify we know the signature type

0 commit comments

Comments
 (0)