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 value_len = <[u8] as RLPEncode>::length(&self.value);
31 let payload_len = self.choices.iter().fold(value_len, |acc, child| {
32 acc + RLPEncode::length(child.compute_hash_ref(&NativeCrypto))
33 });
34
35 encode_length(payload_len, buf);
36 for child in self.choices.iter() {
37 match child.compute_hash_ref(&NativeCrypto) {
38 NodeHash::Hashed(hash) => hash.0.encode(buf),
39 NodeHash::Inline((_, 0)) => buf.put_u8(RLP_NULL),
40 NodeHash::Inline((encoded, len)) => buf.put_slice(&encoded[..*len as usize]),
41 }
42 }
43 <[u8] as RLPEncode>::encode(&self.value, buf);
44 }
45
46 fn encode_to_vec(&self) -> Vec<u8> {
48 let value_len = <[u8] as RLPEncode>::length(&self.value);
49 let choices_len = self.choices.iter().fold(0, |acc, child| {
50 acc + RLPEncode::length(child.compute_hash_ref(&NativeCrypto))
51 });
52 let payload_len = choices_len + value_len;
53
54 let mut buf: Vec<u8> = Vec::with_capacity(payload_len + 3); encode_length(payload_len, &mut buf);
57 for child in self.choices.iter() {
58 match child.compute_hash_ref(&NativeCrypto) {
59 NodeHash::Hashed(hash) => hash.0.encode(&mut buf),
60 NodeHash::Inline((_, 0)) => buf.push(RLP_NULL),
61 NodeHash::Inline((encoded, len)) => {
62 buf.extend_from_slice(&encoded[..*len as usize])
63 }
64 }
65 }
66 <[u8] as RLPEncode>::encode(&self.value, &mut buf);
67
68 buf
69 }
70}
71
72impl RLPEncode for ExtensionNode {
73 fn encode(&self, buf: &mut dyn bytes::BufMut) {
74 let mut encoder = Encoder::new(buf).encode_bytes(&self.prefix.encode_compact());
75 encoder = self.child.compute_hash(&NativeCrypto).encode(encoder);
76 encoder.finish();
77 }
78}
79
80impl RLPEncode for LeafNode {
81 fn encode(&self, buf: &mut dyn bytes::BufMut) {
82 Encoder::new(buf)
83 .encode_bytes(&self.partial.encode_compact())
84 .encode_bytes(&self.value)
85 .finish()
86 }
87}
88
89impl RLPEncode for Node {
90 fn encode(&self, buf: &mut dyn bytes::BufMut) {
91 match self {
92 Node::Branch(n) => n.encode(buf),
93 Node::Extension(n) => n.encode(buf),
94 Node::Leaf(n) => n.encode(buf),
95 }
96 }
97}
98
99impl RLPDecode for Node {
100 fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
101 let mut rlp_items_len = 0;
102 let mut rlp_items: [Option<&[u8]>; 17] = Default::default();
103 let mut decoder = Decoder::new(rlp)?;
104 let mut item;
105 while !decoder.is_done() && rlp_items_len < 17 {
109 (item, decoder) = decoder.get_encoded_item_ref()?;
110 rlp_items[rlp_items_len] = Some(item);
111 rlp_items_len += 1;
112 }
113 if !decoder.is_done() {
114 return Err(RLPDecodeError::Custom(
115 "Invalid arg count for Node, expected 2 or 17, got more than 17".to_string(),
116 ));
117 }
118 let node = match rlp_items_len {
120 2 => {
122 let (path, _) = decode_bytes(rlp_items[0].expect("we already checked the length"))?;
123 let path = Nibbles::decode_compact(path);
124 if path.is_leaf() {
125 let (value, _) =
127 decode_bytes(rlp_items[1].expect("we already checked the length"))?;
128 LeafNode {
129 partial: path,
130 value: value.to_vec(),
131 }
132 .into()
133 } else {
134 ExtensionNode {
136 prefix: path,
137 child: decode_child(rlp_items[1].expect("we already checked the length"))
138 .into(),
139 }
140 .into()
141 }
142 }
143 17 => {
145 let choices = array::from_fn(|i| {
146 decode_child(rlp_items[i].expect("we already checked the length")).into()
147 });
148 let (value, _) =
149 decode_bytes(rlp_items[16].expect("we already checked the length"))?;
150 BranchNode {
151 choices,
152 value: value.to_vec(),
153 }
154 .into()
155 }
156 n => {
157 return Err(RLPDecodeError::Custom(format!(
158 "Invalid arg count for Node, expected 2 or 17, got {n}"
159 )));
160 }
161 };
162 Ok((node, decoder.finish()?))
163 }
164}
165
166fn decode_child(rlp: &[u8]) -> NodeHash {
167 match decode_bytes(rlp) {
168 Ok((hash, &[])) if hash.len() == 32 => NodeHash::from_slice(hash),
169 Ok((&[], &[])) => NodeHash::default(),
170 _ => NodeHash::from_slice(rlp),
171 }
172}