1use tetcore_std::marker::PhantomData;
21use tetcore_std::ops::Range;
22use tetcore_std::vec::Vec;
23use tetcore_std::borrow::Borrow;
24use codec::{Encode, Decode, Input, Compact};
25use tetsy_hash_db::Hasher;
26use tetsy_trie_db::{self, node::{NibbleSlicePlan, NodePlan, NodeHandlePlan}, ChildReference,
27 nibble_ops, Partial, NodeCodec as NodeCodecT};
28use crate::error::Error;
29use crate::trie_constants;
30use super::{node_header::{NodeHeader, NodeKind}};
31
32struct ByteSliceInput<'a> {
36 data: &'a [u8],
37 offset: usize,
38}
39
40impl<'a> ByteSliceInput<'a> {
41 fn new(data: &'a [u8]) -> Self {
42 ByteSliceInput {
43 data,
44 offset: 0,
45 }
46 }
47
48 fn take(&mut self, count: usize) -> Result<Range<usize>, codec::Error> {
49 if self.offset + count > self.data.len() {
50 return Err("out of data".into());
51 }
52
53 let range = self.offset..(self.offset + count);
54 self.offset += count;
55 Ok(range)
56 }
57}
58
59impl<'a> Input for ByteSliceInput<'a> {
60 fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
61 let remaining = if self.offset <= self.data.len() {
62 Some(self.data.len() - self.offset)
63 } else {
64 None
65 };
66 Ok(remaining)
67 }
68
69 fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> {
70 let range = self.take(into.len())?;
71 into.copy_from_slice(&self.data[range]);
72 Ok(())
73 }
74
75 fn read_byte(&mut self) -> Result<u8, codec::Error> {
76 if self.offset + 1 > self.data.len() {
77 return Err("out of data".into());
78 }
79
80 let byte = self.data[self.offset];
81 self.offset += 1;
82 Ok(byte)
83 }
84}
85
86#[derive(Default, Clone)]
88pub struct NodeCodec<H>(PhantomData<H>);
89
90impl<H: Hasher> NodeCodecT for NodeCodec<H> {
91 type Error = Error;
92 type HashOut = H::Out;
93
94 fn hashed_null_node() -> <H as Hasher>::Out {
95 H::hash(<Self as NodeCodecT>::empty_node())
96 }
97
98 fn decode_plan(data: &[u8]) -> tetcore_std::result::Result<NodePlan, Self::Error> {
99 let mut input = ByteSliceInput::new(data);
100 match NodeHeader::decode(&mut input)? {
101 NodeHeader::Null => Ok(NodePlan::Empty),
102 NodeHeader::Branch(has_value, nibble_count) => {
103 let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
104 if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
106 return Err(Error::BadFormat);
107 }
108 let partial = input.take(
109 (nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
110 )?;
111 let partial_padding = nibble_ops::number_padding(nibble_count);
112 let bitmap_range = input.take(BITMAP_LENGTH)?;
113 let bitmap = Bitmap::decode(&data[bitmap_range])?;
114 let value = if has_value {
115 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
116 Some(input.take(count)?)
117 } else {
118 None
119 };
120 let mut children = [
121 None, None, None, None, None, None, None, None,
122 None, None, None, None, None, None, None, None,
123 ];
124 for i in 0..nibble_ops::NIBBLE_LENGTH {
125 if bitmap.value_at(i) {
126 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
127 let range = input.take(count)?;
128 children[i] = Some(if count == H::LENGTH {
129 NodeHandlePlan::Hash(range)
130 } else {
131 NodeHandlePlan::Inline(range)
132 });
133 }
134 }
135 Ok(NodePlan::NibbledBranch {
136 partial: NibbleSlicePlan::new(partial, partial_padding),
137 value,
138 children,
139 })
140 }
141 NodeHeader::Leaf(nibble_count) => {
142 let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
143 if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
145 return Err(Error::BadFormat);
146 }
147 let partial = input.take(
148 (nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
149 )?;
150 let partial_padding = nibble_ops::number_padding(nibble_count);
151 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
152 Ok(NodePlan::Leaf {
153 partial: NibbleSlicePlan::new(partial, partial_padding),
154 value: input.take(count)?,
155 })
156 }
157 }
158 }
159
160 fn is_empty_node(data: &[u8]) -> bool {
161 data == <Self as NodeCodecT>::empty_node()
162 }
163
164 fn empty_node() -> &'static [u8] {
165 &[trie_constants::EMPTY_TRIE]
166 }
167
168 fn leaf_node(partial: Partial, value: &[u8]) -> Vec<u8> {
169 let mut output = partial_encode(partial, NodeKind::Leaf);
170 value.encode_to(&mut output);
171 output
172 }
173
174 fn extension_node(
175 _partial: impl Iterator<Item = u8>,
176 _nbnibble: usize,
177 _child: ChildReference<<H as Hasher>::Out>,
178 ) -> Vec<u8> {
179 unreachable!()
180 }
181
182 fn branch_node(
183 _children: impl Iterator<Item = impl Borrow<Option<ChildReference<<H as Hasher>::Out>>>>,
184 _maybe_value: Option<&[u8]>,
185 ) -> Vec<u8> {
186 unreachable!()
187 }
188
189 fn branch_node_nibbled(
190 partial: impl Iterator<Item = u8>,
191 number_nibble: usize,
192 children: impl Iterator<Item = impl Borrow<Option<ChildReference<<H as Hasher>::Out>>>>,
193 maybe_value: Option<&[u8]>,
194 ) -> Vec<u8> {
195 let mut output = if maybe_value.is_some() {
196 partial_from_iterator_encode(partial, number_nibble, NodeKind::BranchWithValue)
197 } else {
198 partial_from_iterator_encode(partial, number_nibble, NodeKind::BranchNoValue)
199 };
200 let bitmap_index = output.len();
201 let mut bitmap: [u8; BITMAP_LENGTH] = [0; BITMAP_LENGTH];
202 (0..BITMAP_LENGTH).for_each(|_|output.push(0));
203 if let Some(value) = maybe_value {
204 value.encode_to(&mut output);
205 };
206 Bitmap::encode(children.map(|maybe_child| match maybe_child.borrow() {
207 Some(ChildReference::Hash(h)) => {
208 h.as_ref().encode_to(&mut output);
209 true
210 }
211 &Some(ChildReference::Inline(inline_data, len)) => {
212 inline_data.as_ref()[..len].encode_to(&mut output);
213 true
214 }
215 None => false,
216 }), bitmap.as_mut());
217 output[bitmap_index..bitmap_index + BITMAP_LENGTH]
218 .copy_from_slice(&bitmap[..BITMAP_LENGTH]);
219 output
220 }
221
222}
223
224fn partial_from_iterator_encode<I: Iterator<Item = u8>>(
229 partial: I,
230 nibble_count: usize,
231 node_kind: NodeKind,
232) -> Vec<u8> {
233 let nibble_count = tetcore_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count);
234
235 let mut output = Vec::with_capacity(3 + (nibble_count / nibble_ops::NIBBLE_PER_BYTE));
236 match node_kind {
237 NodeKind::Leaf => NodeHeader::Leaf(nibble_count).encode_to(&mut output),
238 NodeKind::BranchWithValue => NodeHeader::Branch(true, nibble_count).encode_to(&mut output),
239 NodeKind::BranchNoValue => NodeHeader::Branch(false, nibble_count).encode_to(&mut output),
240 };
241 output.extend(partial);
242 output
243}
244
245fn partial_encode(partial: Partial, node_kind: NodeKind) -> Vec<u8> {
248 let number_nibble_encoded = (partial.0).0 as usize;
249 let nibble_count = partial.1.len() * nibble_ops::NIBBLE_PER_BYTE + number_nibble_encoded;
250
251 let nibble_count = tetcore_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibble_count);
252
253 let mut output = Vec::with_capacity(3 + partial.1.len());
254 match node_kind {
255 NodeKind::Leaf => NodeHeader::Leaf(nibble_count).encode_to(&mut output),
256 NodeKind::BranchWithValue => NodeHeader::Branch(true, nibble_count).encode_to(&mut output),
257 NodeKind::BranchNoValue => NodeHeader::Branch(false, nibble_count).encode_to(&mut output),
258 };
259 if number_nibble_encoded > 0 {
260 output.push(nibble_ops::pad_right((partial.0).1));
261 }
262 output.extend_from_slice(&partial.1[..]);
263 output
264}
265
266const BITMAP_LENGTH: usize = 2;
267
268pub(crate) struct Bitmap(u16);
273
274impl Bitmap {
275 pub fn decode(data: &[u8]) -> Result<Self, Error> {
276 Ok(Bitmap(u16::decode(&mut &data[..])?))
277 }
278
279 pub fn value_at(&self, i: usize) -> bool {
280 self.0 & (1u16 << i) != 0
281 }
282
283 pub fn encode<I: Iterator<Item = bool>>(has_children: I , dest: &mut [u8]) {
284 let mut bitmap: u16 = 0;
285 let mut cursor: u16 = 1;
286 for v in has_children {
287 if v { bitmap |= cursor }
288 cursor <<= 1;
289 }
290 dest[0] = (bitmap % 256) as u8;
291 dest[1] = (bitmap / 256) as u8;
292 }
293}