1#![cfg_attr(not(feature = "std"), no_std)]
14
15#[cfg(not(feature = "std"))]
16extern crate alloc;
17
18#[cfg(feature = "std")]
19mod rstd {
20 pub use std::collections::BTreeMap;
21}
22
23#[cfg(not(feature = "std"))]
24mod rstd {
25 pub use alloc::collections::BTreeMap;
26 pub use alloc::vec::Vec;
27}
28
29use core::cmp;
30use core::iter::once;
31use rstd::*;
32
33use hash_db::Hasher;
34use rlp::RlpStream;
35
36fn shared_prefix_len<T: Eq>(first: &[T], second: &[T]) -> usize {
37 first.iter().zip(second.iter()).position(|(f, s)| f != s).unwrap_or_else(|| cmp::min(first.len(), second.len()))
38}
39
40pub fn ordered_trie_root<H, I>(input: I) -> H::Out
53where
54 I: IntoIterator,
55 I::Item: AsRef<[u8]>,
56 H: Hasher,
57 <H as hash_db::Hasher>::Out: cmp::Ord,
58{
59 trie_root::<H, _, _, _>(input.into_iter().enumerate().map(|(i, v)| (rlp::encode(&i), v)))
60}
61
62pub fn trie_root<H, I, A, B>(input: I) -> H::Out
80where
81 I: IntoIterator<Item = (A, B)>,
82 A: AsRef<[u8]> + Ord,
83 B: AsRef<[u8]>,
84 H: Hasher,
85 <H as hash_db::Hasher>::Out: cmp::Ord,
86{
87 let input = input.into_iter().collect::<BTreeMap<_, _>>();
89
90 let mut nibbles = Vec::with_capacity(input.keys().map(|k| k.as_ref().len()).sum::<usize>() * 2);
91 let mut lens = Vec::with_capacity(input.len() + 1);
92 lens.push(0);
93 for k in input.keys() {
94 for &b in k.as_ref() {
95 nibbles.push(b >> 4);
96 nibbles.push(b & 0x0F);
97 }
98 lens.push(nibbles.len());
99 }
100
101 let input = input.into_iter().zip(lens.windows(2)).map(|((_, v), w)| (&nibbles[w[0]..w[1]], v)).collect::<Vec<_>>();
103
104 let mut stream = RlpStream::new();
105 hash256rlp::<H, _, _>(&input, 0, &mut stream);
106 H::hash(&stream.out())
107}
108
109pub fn sec_trie_root<H, I, A, B>(input: I) -> H::Out
127where
128 I: IntoIterator<Item = (A, B)>,
129 A: AsRef<[u8]>,
130 B: AsRef<[u8]>,
131 H: Hasher,
132 <H as hash_db::Hasher>::Out: cmp::Ord,
133{
134 trie_root::<H, _, _, _>(input.into_iter().map(|(k, v)| (H::hash(k.as_ref()), v)))
135}
136
137fn hex_prefix_encode<'a>(nibbles: &'a [u8], leaf: bool) -> impl Iterator<Item = u8> + 'a {
157 let inlen = nibbles.len();
158 let oddness_factor = inlen % 2;
159
160 let first_byte = {
161 let mut bits = ((inlen as u8 & 1) + (2 * leaf as u8)) << 4;
162 if oddness_factor == 1 {
163 bits += nibbles[0];
164 }
165 bits
166 };
167 once(first_byte).chain(nibbles[oddness_factor..].chunks(2).map(|ch| ch[0] << 4 | ch[1]))
168}
169
170fn hash256rlp<H, A, B>(input: &[(A, B)], pre_len: usize, stream: &mut RlpStream)
171where
172 A: AsRef<[u8]>,
173 B: AsRef<[u8]>,
174 H: Hasher,
175{
176 let inlen = input.len();
177
178 if inlen == 0 {
180 stream.append_empty_data();
181 return;
182 }
183
184 let key: &[u8] = &input[0].0.as_ref();
186 let value: &[u8] = &input[0].1.as_ref();
187
188 if inlen == 1 {
191 stream.begin_list(2);
192 stream.append_iter(hex_prefix_encode(&key[pre_len..], true));
193 stream.append(&value);
194 return;
195 }
196
197 let shared_prefix = input
199 .iter()
200 .skip(1)
202 .fold(key.len(), |acc, &(ref k, _)| cmp::min(shared_prefix_len(key, k.as_ref()), acc));
204
205 if shared_prefix > pre_len {
209 stream.begin_list(2);
210 stream.append_iter(hex_prefix_encode(&key[pre_len..shared_prefix], false));
211 hash256aux::<H, _, _>(input, shared_prefix, stream);
212 return;
213 }
214
215 stream.begin_list(17);
218
219 let mut begin = if pre_len == key.len() { 1 } else { 0 };
221
222 for i in 0..16 {
224 let len = input.iter().skip(begin).take_while(|pair| pair.0.as_ref()[pre_len] == i).count();
226
227 match len {
230 0 => {
231 stream.append_empty_data();
232 }
233 _ => hash256aux::<H, _, _>(&input[begin..(begin + len)], pre_len + 1, stream),
234 }
235 begin += len;
236 }
237
238 if pre_len == key.len() {
240 stream.append(&value);
241 } else {
242 stream.append_empty_data();
243 }
244}
245
246fn hash256aux<H, A, B>(input: &[(A, B)], pre_len: usize, stream: &mut RlpStream)
247where
248 A: AsRef<[u8]>,
249 B: AsRef<[u8]>,
250 H: Hasher,
251{
252 let mut s = RlpStream::new();
253 hash256rlp::<H, _, _>(input, pre_len, &mut s);
254 let out = s.out();
255 match out.len() {
256 0..=31 => stream.append_raw(&out, 1),
257 _ => stream.append(&H::hash(&out).as_ref()),
258 };
259}
260
261#[cfg(test)]
262mod tests {
263 use super::{hex_prefix_encode, shared_prefix_len, trie_root};
264 use ethereum_types::H256;
265 use hex_literal::hex;
266 use keccak_hasher::KeccakHasher;
267
268 #[test]
269 fn test_hex_prefix_encode() {
270 let v = vec![0, 0, 1, 2, 3, 4, 5];
271 let e = vec![0x10, 0x01, 0x23, 0x45];
272 let h = hex_prefix_encode(&v, false).collect::<Vec<_>>();
273 assert_eq!(h, e);
274
275 let v = vec![0, 1, 2, 3, 4, 5];
276 let e = vec![0x00, 0x01, 0x23, 0x45];
277 let h = hex_prefix_encode(&v, false).collect::<Vec<_>>();
278 assert_eq!(h, e);
279
280 let v = vec![0, 1, 2, 3, 4, 5];
281 let e = vec![0x20, 0x01, 0x23, 0x45];
282 let h = hex_prefix_encode(&v, true).collect::<Vec<_>>();
283 assert_eq!(h, e);
284
285 let v = vec![1, 2, 3, 4, 5];
286 let e = vec![0x31, 0x23, 0x45];
287 let h = hex_prefix_encode(&v, true).collect::<Vec<_>>();
288 assert_eq!(h, e);
289
290 let v = vec![1, 2, 3, 4];
291 let e = vec![0x00, 0x12, 0x34];
292 let h = hex_prefix_encode(&v, false).collect::<Vec<_>>();
293 assert_eq!(h, e);
294
295 let v = vec![4, 1];
296 let e = vec![0x20, 0x41];
297 let h = hex_prefix_encode(&v, true).collect::<Vec<_>>();
298 assert_eq!(h, e);
299 }
300
301 #[test]
302 fn simple_test() {
303 assert_eq!(
304 trie_root::<KeccakHasher, _, _, _>(vec![(
305 b"A",
306 b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" as &[u8]
307 )]),
308 H256::from(hex!("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")).as_ref(),
309 );
310 }
311
312 #[test]
313 fn test_triehash_out_of_order() {
314 assert_eq!(
315 trie_root::<KeccakHasher, _, _, _>(vec![
316 (vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
317 (vec![0x81u8, 0x23], vec![0x81u8, 0x23]),
318 (vec![0xf1u8, 0x23], vec![0xf1u8, 0x23]),
319 ]),
320 trie_root::<KeccakHasher, _, _, _>(vec![
321 (vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
322 (vec![0xf1u8, 0x23], vec![0xf1u8, 0x23]), (vec![0x81u8, 0x23], vec![0x81u8, 0x23]),
324 ]),
325 );
326 }
327
328 #[test]
329 fn test_shared_prefix() {
330 let a = vec![1, 2, 3, 4, 5, 6];
331 let b = vec![4, 2, 3, 4, 5, 6];
332 assert_eq!(shared_prefix_len(&a, &b), 0);
333 }
334
335 #[test]
336 fn test_shared_prefix2() {
337 let a = vec![1, 2, 3, 3, 5];
338 let b = vec![1, 2, 3];
339 assert_eq!(shared_prefix_len(&a, &b), 3);
340 }
341
342 #[test]
343 fn test_shared_prefix3() {
344 let a = vec![1, 2, 3, 4, 5, 6];
345 let b = vec![1, 2, 3, 4, 5, 6];
346 assert_eq!(shared_prefix_len(&a, &b), 6);
347 }
348}