@@ -3,8 +3,9 @@ use std::array;
33// Contains RLP encoding and decoding implementations for Trie Nodes
44// This encoding is only used to store the nodes in the DB, it is not the encoding used for hash computation
55use ethrex_rlp:: {
6+ constants:: RLP_NULL ,
67 decode:: { RLPDecode , decode_bytes} ,
7- encode:: RLPEncode ,
8+ encode:: { RLPEncode , encode_length } ,
89 error:: RLPDecodeError ,
910 structs:: { Decoder , Encoder } ,
1011} ;
@@ -14,18 +15,44 @@ use crate::{Nibbles, NodeHash};
1415
1516impl RLPEncode for BranchNode {
1617 fn encode ( & self , buf : & mut dyn bytes:: BufMut ) {
17- let mut encoder = Encoder :: new ( buf) ;
18+ let value_len = <[ u8 ] as RLPEncode >:: length ( & self . value ) ;
19+ let choices_len = self . choices . iter ( ) . fold ( 0 , |acc, child| {
20+ acc + RLPEncode :: length ( child. compute_hash_ref ( ) )
21+ } ) ;
22+ let payload_len = choices_len + value_len;
23+
24+ encode_length ( payload_len, buf) ;
1825 for child in self . choices . iter ( ) {
19- match child. compute_hash ( ) {
20- NodeHash :: Hashed ( hash) => encoder = encoder. encode_bytes ( & hash. 0 ) ,
21- child @ NodeHash :: Inline ( raw) if raw. 1 != 0 => {
22- encoder = encoder. encode_raw ( child. as_ref ( ) )
23- }
24- _ => encoder = encoder. encode_bytes ( & [ ] ) ,
26+ match child. compute_hash_ref ( ) {
27+ NodeHash :: Hashed ( hash) => hash. 0 . encode ( buf) ,
28+ NodeHash :: Inline ( ( _, 0 ) ) => buf. put_u8 ( RLP_NULL ) ,
29+ NodeHash :: Inline ( ( encoded, len) ) => buf. put_slice ( & encoded[ ..* len as usize ] ) ,
2530 }
2631 }
27- encoder = encoder. encode_bytes ( & self . value ) ;
28- encoder. finish ( ) ;
32+ <[ u8 ] as RLPEncode >:: encode ( & self . value , buf) ;
33+ }
34+
35+ // Duplicated to prealloc the buffer and avoid calculating the payload length twice
36+ fn encode_to_vec ( & self ) -> Vec < u8 > {
37+ let value_len = <[ u8 ] as RLPEncode >:: length ( & self . value ) ;
38+ let choices_len = self . choices . iter ( ) . fold ( 0 , |acc, child| {
39+ acc + RLPEncode :: length ( child. compute_hash_ref ( ) )
40+ } ) ;
41+ let payload_len = choices_len + value_len;
42+
43+ let mut buf: Vec < u8 > = Vec :: with_capacity ( payload_len + 3 ) ; // 3 byte prefix headroom
44+
45+ encode_length ( payload_len, & mut buf) ;
46+ for child in self . choices . iter ( ) {
47+ match child. compute_hash_ref ( ) {
48+ NodeHash :: Hashed ( hash) => hash. 0 . encode ( & mut buf) ,
49+ NodeHash :: Inline ( ( _, 0 ) ) => buf. push ( RLP_NULL ) ,
50+ NodeHash :: Inline ( ( encoded, len) ) => buf. extend_from_slice ( & encoded[ ..* len as usize ] ) ,
51+ }
52+ }
53+ <[ u8 ] as RLPEncode >:: encode ( & self . value , & mut buf) ;
54+
55+ buf
2956 }
3057}
3158
0 commit comments