@@ -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,45 @@ 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 payload_len = self . choices . iter ( ) . fold ( value_len, |acc, child| {
20+ acc + RLPEncode :: length ( child. compute_hash_ref ( ) )
21+ } ) ;
22+
23+ encode_length ( payload_len, buf) ;
24+ for child in self . choices . iter ( ) {
25+ match child. compute_hash_ref ( ) {
26+ NodeHash :: Hashed ( hash) => hash. 0 . encode ( buf) ,
27+ NodeHash :: Inline ( ( _, 0 ) ) => buf. put_u8 ( RLP_NULL ) ,
28+ NodeHash :: Inline ( ( encoded, len) ) => buf. put_slice ( & encoded[ ..* len as usize ] ) ,
29+ }
30+ }
31+ <[ u8 ] as RLPEncode >:: encode ( & self . value , buf) ;
32+ }
33+
34+ // Duplicated to prealloc the buffer and avoid calculating the payload length twice
35+ fn encode_to_vec ( & self ) -> Vec < u8 > {
36+ let value_len = <[ u8 ] as RLPEncode >:: length ( & self . value ) ;
37+ let choices_len = self . choices . iter ( ) . fold ( 0 , |acc, child| {
38+ acc + RLPEncode :: length ( child. compute_hash_ref ( ) )
39+ } ) ;
40+ let payload_len = choices_len + value_len;
41+
42+ let mut buf: Vec < u8 > = Vec :: with_capacity ( payload_len + 3 ) ; // 3 byte prefix headroom
43+
44+ encode_length ( payload_len, & mut buf) ;
1845 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 ( ) )
46+ match child. compute_hash_ref ( ) {
47+ NodeHash :: Hashed ( hash) => hash. 0 . encode ( & mut buf) ,
48+ NodeHash :: Inline ( ( _, 0 ) ) => buf. push ( RLP_NULL ) ,
49+ NodeHash :: Inline ( ( encoded, len) ) => {
50+ buf. extend_from_slice ( & encoded[ ..* len as usize ] )
2351 }
24- _ => encoder = encoder. encode_bytes ( & [ ] ) ,
2552 }
2653 }
27- encoder = encoder. encode_bytes ( & self . value ) ;
28- encoder. finish ( ) ;
54+ <[ u8 ] as RLPEncode >:: encode ( & self . value , & mut buf) ;
55+
56+ buf
2957 }
3058}
3159
0 commit comments