@@ -180,6 +180,7 @@ mod builder;
180180mod keys;
181181mod node_id;
182182
183+ use bytes:: { Bytes , BytesMut } ;
183184use log:: debug;
184185use rlp:: { DecoderError , Rlp , RlpStream } ;
185186use 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