1#[cfg(not(feature = "std"))]
2use alloc::{string::ToString, vec::Vec};
3use core::array;
4
5use ethrex_rlp::{
8 constants::RLP_NULL,
9 decode::{RLPDecode, decode_bytes},
10 encode::{RLPEncode, encode_length},
11 error::RLPDecodeError,
12 structs::{Decoder, Encoder},
13};
14
15use ethrex_crypto::NativeCrypto;
16
17use super::node::{BranchNode, ExtensionNode, LeafNode, Node};
18use crate::{Nibbles, NodeHash};
19
20impl RLPEncode for BranchNode {
29 fn encode(&self, buf: &mut dyn bytes::BufMut) {
30 let hashes: [&NodeHash; 16] =
33 array::from_fn(|i| self.choices[i].compute_hash_ref(&NativeCrypto));
34
35 let value_len = <[u8] as RLPEncode>::length(&self.value);
36 let payload_len = hashes
37 .iter()
38 .fold(value_len, |acc, hash| acc + RLPEncode::length(*hash));
39
40 encode_length(payload_len, buf);
41 for hash in hashes {
42 match hash {
43 NodeHash::Hashed(hash) => hash.0.encode(buf),
44 NodeHash::Inline((_, 0)) => buf.put_u8(RLP_NULL),
45 NodeHash::Inline((encoded, len)) => buf.put_slice(&encoded[..*len as usize]),
46 }
47 }
48 <[u8] as RLPEncode>::encode(&self.value, buf);
49 }
50
51 fn encode_to_vec(&self) -> Vec<u8> {
53 let value_len = <[u8] as RLPEncode>::length(&self.value);
54 let choices_len = self.choices.iter().fold(0, |acc, child| {
55 acc + RLPEncode::length(child.compute_hash_ref(&NativeCrypto))
56 });
57 let payload_len = choices_len + value_len;
58
59 let mut buf: Vec<u8> = Vec::with_capacity(payload_len + 3); encode_length(payload_len, &mut buf);
62 for child in self.choices.iter() {
63 match child.compute_hash_ref(&NativeCrypto) {
64 NodeHash::Hashed(hash) => hash.0.encode(&mut buf),
65 NodeHash::Inline((_, 0)) => buf.push(RLP_NULL),
66 NodeHash::Inline((encoded, len)) => {
67 buf.extend_from_slice(&encoded[..*len as usize])
68 }
69 }
70 }
71 <[u8] as RLPEncode>::encode(&self.value, &mut buf);
72
73 buf
74 }
75}
76
77impl BranchNode {
78 pub fn encode_into_vec(&self, buf: &mut Vec<u8>) {
87 let hashes: [&NodeHash; 16] =
88 array::from_fn(|i| self.choices[i].compute_hash_ref(&NativeCrypto));
89
90 let value_len = <[u8] as RLPEncode>::length(&self.value);
91 let payload_len = hashes
92 .iter()
93 .fold(value_len, |acc, hash| acc + RLPEncode::length(*hash));
94
95 encode_length(payload_len, buf);
96 for hash in hashes {
97 match hash {
98 NodeHash::Hashed(hash) => hash.0.encode(&mut *buf),
99 NodeHash::Inline((_, 0)) => buf.push(RLP_NULL),
100 NodeHash::Inline((encoded, len)) => {
101 buf.extend_from_slice(&encoded[..*len as usize])
102 }
103 }
104 }
105 <[u8] as RLPEncode>::encode(&self.value, buf);
106 }
107}
108
109impl RLPEncode for ExtensionNode {
110 fn encode(&self, buf: &mut dyn bytes::BufMut) {
111 let mut encoder = Encoder::new(buf).encode_bytes(&self.prefix.encode_compact());
112 encoder = self.child.compute_hash(&NativeCrypto).encode(encoder);
113 encoder.finish();
114 }
115}
116
117impl RLPEncode for LeafNode {
118 fn encode(&self, buf: &mut dyn bytes::BufMut) {
119 Encoder::new(buf)
120 .encode_bytes(&self.partial.encode_compact())
121 .encode_bytes(&self.value)
122 .finish()
123 }
124}
125
126impl RLPEncode for Node {
127 fn encode(&self, buf: &mut dyn bytes::BufMut) {
128 match self {
129 Node::Branch(n) => n.encode(buf),
130 Node::Extension(n) => n.encode(buf),
131 Node::Leaf(n) => n.encode(buf),
132 }
133 }
134}
135
136impl RLPDecode for Node {
137 fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
138 let mut rlp_items_len = 0;
139 let mut rlp_items: [Option<&[u8]>; 17] = Default::default();
140 let mut decoder = Decoder::new(rlp)?;
141 let mut item;
142 while !decoder.is_done() && rlp_items_len < 17 {
146 (item, decoder) = decoder.get_encoded_item_ref()?;
147 rlp_items[rlp_items_len] = Some(item);
148 rlp_items_len += 1;
149 }
150 if !decoder.is_done() {
151 return Err(RLPDecodeError::Custom(
152 "Invalid arg count for Node, expected 2 or 17, got more than 17".to_string(),
153 ));
154 }
155 let node = match rlp_items_len {
157 2 => {
159 let (path, _) = decode_bytes(rlp_items[0].expect("we already checked the length"))?;
160 let path = Nibbles::decode_compact(path);
161 if path.is_leaf() {
162 let (value, _) =
164 decode_bytes(rlp_items[1].expect("we already checked the length"))?;
165 LeafNode {
166 partial: path,
167 value: value.to_vec(),
168 }
169 .into()
170 } else {
171 ExtensionNode {
173 prefix: path,
174 child: decode_child(rlp_items[1].expect("we already checked the length"))
175 .into(),
176 }
177 .into()
178 }
179 }
180 17 => {
182 let choices = array::from_fn(|i| {
183 decode_child(rlp_items[i].expect("we already checked the length")).into()
184 });
185 let (value, _) =
186 decode_bytes(rlp_items[16].expect("we already checked the length"))?;
187 BranchNode {
188 choices,
189 value: value.to_vec(),
190 }
191 .into()
192 }
193 n => {
194 return Err(RLPDecodeError::Custom(format!(
195 "Invalid arg count for Node, expected 2 or 17, got {n}"
196 )));
197 }
198 };
199 Ok((node, decoder.finish()?))
200 }
201}
202
203fn decode_child(rlp: &[u8]) -> NodeHash {
204 match decode_bytes(rlp) {
205 Ok((hash, &[])) if hash.len() == 32 => NodeHash::from_slice(hash),
206 Ok((&[], &[])) => NodeHash::default(),
207 _ => NodeHash::from_slice(rlp),
208 }
209}