1use hashbrown::{hash_map::Entry, HashMap};
18use parity_scale_codec::{Compact, Decode, Encode, Error as CodecError, Input, Output};
19use std::{borrow::Borrow, fmt, iter::once, marker::PhantomData, ops::Range};
20use trie_db::{
21 nibble_ops,
22 node::{NibbleSlicePlan, NodeHandlePlan, NodeOwned, NodePlan, Value, ValuePlan},
23 trie_visit,
24 triedbmut::ChildReference,
25 DBValue, NodeCodec, Trie, TrieBuilder, TrieConfiguration, TrieDBBuilder, TrieDBMutBuilder,
26 TrieHash, TrieLayout, TrieMut, TrieRoot,
27};
28pub use trie_root::TrieStream;
29use trie_root::{Hasher, Value as TrieStreamValue};
30
31mod substrate;
32mod substrate_like;
33pub mod trie_db_0_31_decoder;
34pub mod node {
35 pub use trie_db::node::Node;
36}
37
38pub use substrate_like::{
39 trie_constants, HashedValueNoExt, HashedValueNoExtThreshold,
40 NodeCodec as ReferenceNodeCodecNoExtMeta, ReferenceTrieStreamNoExt,
41};
42
43pub use paste::paste;
44pub use substrate::{LayoutV0 as SubstrateV0, LayoutV1 as SubstrateV1};
45
46pub type RefHasher = keccak_hasher::KeccakHasher;
48
49#[macro_export]
51macro_rules! test_layouts {
52 ($test:ident, $test_internal:ident) => {
53 #[test]
54 fn $test() {
55 eprintln!("Running with layout `HashedValueNoExtThreshold`");
56 $test_internal::<$crate::HashedValueNoExtThreshold<1>>();
57 eprintln!("Running with layout `HashedValueNoExt`");
58 $test_internal::<$crate::HashedValueNoExt>();
59 eprintln!("Running with layout `NoExtensionLayout`");
60 $test_internal::<$crate::NoExtensionLayout>();
61 eprintln!("Running with layout `ExtensionLayout`");
62 $test_internal::<$crate::ExtensionLayout>();
63 }
64 };
65}
66
67#[macro_export]
68macro_rules! test_layouts_substrate {
69 ($test:ident) => {
70 $crate::paste! {
71 #[test]
72 fn [<$test _substrate_v0>]() {
73 $test::<$crate::SubstrateV0<$crate::RefHasher>>();
74 }
75 #[test]
76 fn [<$test _substrate_v1>]() {
77 $test::<$crate::SubstrateV1<$crate::RefHasher>>();
78 }
79 }
80 };
81}
82
83#[macro_export]
85macro_rules! test_layouts_no_meta {
86 ($test:ident, $test_internal:ident) => {
87 #[test]
88 fn $test() {
89 $test_internal::<$crate::NoExtensionLayout>();
90 $test_internal::<$crate::ExtensionLayout>();
91 }
92 };
93}
94
95#[derive(Default, Clone)]
97pub struct ExtensionLayout;
98
99impl TrieLayout for ExtensionLayout {
100 const USE_EXTENSION: bool = true;
101 const ALLOW_EMPTY: bool = false;
102 const MAX_INLINE_VALUE: Option<u32> = None;
103 type Hash = RefHasher;
104 type Codec = ReferenceNodeCodec<RefHasher>;
105}
106
107impl TrieConfiguration for ExtensionLayout {}
108
109pub struct GenericNoExtensionLayout<H>(PhantomData<H>);
112
113impl<H> Default for GenericNoExtensionLayout<H> {
114 fn default() -> Self {
115 GenericNoExtensionLayout(PhantomData)
116 }
117}
118
119impl<H> Clone for GenericNoExtensionLayout<H> {
120 fn clone(&self) -> Self {
121 GenericNoExtensionLayout(PhantomData)
122 }
123}
124
125impl<H: Hasher> TrieLayout for GenericNoExtensionLayout<H> {
126 const USE_EXTENSION: bool = false;
127 const ALLOW_EMPTY: bool = false;
128 const MAX_INLINE_VALUE: Option<u32> = None;
129 type Hash = H;
130 type Codec = ReferenceNodeCodecNoExt<H>;
131}
132
133#[derive(Default, Clone)]
135pub struct AllowEmptyLayout;
136
137impl TrieLayout for AllowEmptyLayout {
138 const USE_EXTENSION: bool = true;
139 const ALLOW_EMPTY: bool = true;
140 const MAX_INLINE_VALUE: Option<u32> = None;
141 type Hash = RefHasher;
142 type Codec = ReferenceNodeCodec<RefHasher>;
143}
144
145impl<H: Hasher> TrieConfiguration for GenericNoExtensionLayout<H> {}
146
147pub type NoExtensionLayout = GenericNoExtensionLayout<RefHasher>;
149
150pub struct Bitmap(u16);
152
153const BITMAP_LENGTH: usize = 2;
154
155impl Bitmap {
156 fn decode(data: &[u8]) -> Result<Self, CodecError> {
157 Ok(u16::decode(&mut &data[..]).map(|v| Bitmap(v))?)
158 }
159
160 fn value_at(&self, i: usize) -> bool {
161 self.0 & (1u16 << i) != 0
162 }
163
164 fn encode<I: Iterator<Item = bool>>(has_children: I, output: &mut [u8]) {
165 let mut bitmap: u16 = 0;
166 let mut cursor: u16 = 1;
167 for v in has_children {
168 if v {
169 bitmap |= cursor
170 }
171 cursor <<= 1;
172 }
173 output[0] = (bitmap % 256) as u8;
174 output[1] = (bitmap / 256) as u8;
175 }
176}
177
178pub type RefTrieDB<'a, 'cache> = trie_db::TrieDB<'a, 'cache, ExtensionLayout>;
179pub type RefTrieDBBuilder<'a, 'cache> = trie_db::TrieDBBuilder<'a, 'cache, ExtensionLayout>;
180pub type RefTrieDBMut<'a> = trie_db::TrieDBMut<'a, ExtensionLayout>;
181pub type RefTrieDBMutBuilder<'a> = trie_db::TrieDBMutBuilder<'a, ExtensionLayout>;
182pub type RefTrieDBMutNoExt<'a> = trie_db::TrieDBMut<'a, NoExtensionLayout>;
183pub type RefTrieDBMutNoExtBuilder<'a> = trie_db::TrieDBMutBuilder<'a, NoExtensionLayout>;
184pub type RefTrieDBMutAllowEmpty<'a> = trie_db::TrieDBMut<'a, AllowEmptyLayout>;
185pub type RefTrieDBMutAllowEmptyBuilder<'a> = trie_db::TrieDBMutBuilder<'a, AllowEmptyLayout>;
186pub type RefTestTrieDBCache = TestTrieCache<ExtensionLayout>;
187pub type RefTestTrieDBCacheNoExt = TestTrieCache<NoExtensionLayout>;
188pub type RefFatDB<'a, 'cache> = trie_db::FatDB<'a, 'cache, ExtensionLayout>;
189pub type RefFatDBMut<'a> = trie_db::FatDBMut<'a, ExtensionLayout>;
190pub type RefSecTrieDB<'a, 'cache> = trie_db::SecTrieDB<'a, 'cache, ExtensionLayout>;
191pub type RefSecTrieDBMut<'a> = trie_db::SecTrieDBMut<'a, ExtensionLayout>;
192pub type RefLookup<'a, 'cache, Q> = trie_db::Lookup<'a, 'cache, ExtensionLayout, Q>;
193pub type RefLookupNoExt<'a, 'cache, Q> = trie_db::Lookup<'a, 'cache, NoExtensionLayout, Q>;
194
195pub fn reference_trie_root<T: TrieLayout, I, A, B>(input: I) -> <T::Hash as Hasher>::Out
196where
197 I: IntoIterator<Item = (A, B)>,
198 A: AsRef<[u8]> + Ord + fmt::Debug,
199 B: AsRef<[u8]> + fmt::Debug,
200{
201 if T::USE_EXTENSION {
202 trie_root::trie_root::<T::Hash, ReferenceTrieStream, _, _, _>(input, T::MAX_INLINE_VALUE)
203 } else {
204 trie_root::trie_root_no_extension::<T::Hash, ReferenceTrieStreamNoExt, _, _, _>(
205 input,
206 T::MAX_INLINE_VALUE,
207 )
208 }
209}
210
211fn data_sorted_unique<I, A: Ord, B>(input: I) -> Vec<(A, B)>
212where
213 I: IntoIterator<Item = (A, B)>,
214{
215 let mut m = std::collections::BTreeMap::new();
216 for (k, v) in input {
217 let _ = m.insert(k, v); }
219 m.into_iter().collect()
220}
221
222pub fn reference_trie_root_iter_build<T, I, A, B>(input: I) -> <T::Hash as Hasher>::Out
223where
224 T: TrieLayout,
225 I: IntoIterator<Item = (A, B)>,
226 A: AsRef<[u8]> + Ord + fmt::Debug,
227 B: AsRef<[u8]> + fmt::Debug,
228{
229 let mut cb = trie_db::TrieRoot::<T>::default();
230 trie_visit::<T, _, _, _, _>(data_sorted_unique(input), &mut cb);
231 cb.root.unwrap_or_default()
232}
233
234fn reference_trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
235where
236 I: IntoIterator<Item = (A, B)>,
237 A: AsRef<[u8]> + Ord + fmt::Debug,
238 B: AsRef<[u8]> + fmt::Debug,
239{
240 trie_root::unhashed_trie::<RefHasher, ReferenceTrieStream, _, _, _>(input, Default::default())
241}
242
243fn reference_trie_root_unhashed_no_extension<I, A, B>(input: I) -> Vec<u8>
244where
245 I: IntoIterator<Item = (A, B)>,
246 A: AsRef<[u8]> + Ord + fmt::Debug,
247 B: AsRef<[u8]> + fmt::Debug,
248{
249 trie_root::unhashed_trie_no_extension::<RefHasher, ReferenceTrieStreamNoExt, _, _, _>(
250 input,
251 Default::default(),
252 )
253}
254
255const EMPTY_TRIE: u8 = 0;
256const LEAF_NODE_OFFSET: u8 = 1;
257const EXTENSION_NODE_OFFSET: u8 = 128;
258const BRANCH_NODE_NO_VALUE: u8 = 254;
259const BRANCH_NODE_WITH_VALUE: u8 = 255;
260const LEAF_NODE_OVER: u8 = EXTENSION_NODE_OFFSET - LEAF_NODE_OFFSET;
261const EXTENSION_NODE_OVER: u8 = BRANCH_NODE_NO_VALUE - EXTENSION_NODE_OFFSET;
262const LEAF_NODE_LAST: u8 = EXTENSION_NODE_OFFSET - 1;
263const EXTENSION_NODE_LAST: u8 = BRANCH_NODE_NO_VALUE - 1;
264
265const NIBBLE_SIZE_BOUND_NO_EXT: usize = u16::max_value() as usize;
267const FIRST_PREFIX: u8 = 0b_00 << 6;
268const LEAF_PREFIX_MASK_NO_EXT: u8 = 0b_01 << 6;
269const BRANCH_WITHOUT_MASK_NO_EXT: u8 = 0b_10 << 6;
270const BRANCH_WITH_MASK_NO_EXT: u8 = 0b_11 << 6;
271const EMPTY_TRIE_NO_EXT: u8 = FIRST_PREFIX | 0b_00;
272
273fn fuse_nibbles_node<'a>(nibbles: &'a [u8], leaf: bool) -> impl Iterator<Item = u8> + 'a {
277 debug_assert!(
278 nibbles.len() < LEAF_NODE_OVER.min(EXTENSION_NODE_OVER) as usize,
279 "nibbles length too long. what kind of size of key are you trying to include in the trie!?!"
280 );
281 let first_byte =
282 if leaf { LEAF_NODE_OFFSET } else { EXTENSION_NODE_OFFSET } + nibbles.len() as u8;
283
284 once(first_byte)
285 .chain(if nibbles.len() % 2 == 1 { Some(nibbles[0]) } else { None })
286 .chain(nibbles[nibbles.len() % 2..].chunks(2).map(|ch| ch[0] << 4 | ch[1]))
287}
288
289enum NodeKindNoExt {
290 Leaf,
291 BranchNoValue,
292 BranchWithValue,
293}
294
295fn branch_node(has_value: bool, has_children: impl Iterator<Item = bool>) -> [u8; 3] {
298 let mut result = [0, 0, 0];
299 branch_node_buffered(has_value, has_children, &mut result[..]);
300 result
301}
302
303fn branch_node_buffered<I: Iterator<Item = bool>>(
306 has_value: bool,
307 has_children: I,
308 output: &mut [u8],
309) {
310 let first = if has_value { BRANCH_NODE_WITH_VALUE } else { BRANCH_NODE_NO_VALUE };
311 output[0] = first;
312 Bitmap::encode(has_children, &mut output[1..]);
313}
314
315fn branch_node_bit_mask(has_children: impl Iterator<Item = bool>) -> (u8, u8) {
318 let mut bitmap: u16 = 0;
319 let mut cursor: u16 = 1;
320 for v in has_children {
321 if v {
322 bitmap |= cursor
323 }
324 cursor <<= 1;
325 }
326 ((bitmap % 256) as u8, (bitmap / 256) as u8)
327}
328
329#[derive(Default, Clone)]
331pub struct ReferenceTrieStream {
332 buffer: Vec<u8>,
333}
334
335impl TrieStream for ReferenceTrieStream {
336 fn new() -> Self {
337 ReferenceTrieStream { buffer: Vec::new() }
338 }
339
340 fn append_empty_data(&mut self) {
341 self.buffer.push(EMPTY_TRIE);
342 }
343
344 fn append_leaf(&mut self, key: &[u8], value: TrieStreamValue) {
345 if let TrieStreamValue::Inline(value) = value {
346 self.buffer.extend(fuse_nibbles_node(key, true));
347 value.encode_to(&mut self.buffer);
348 } else {
349 unreachable!("This stream do not allow external value node")
350 }
351 }
352
353 fn begin_branch(
354 &mut self,
355 maybe_key: Option<&[u8]>,
356 maybe_value: Option<TrieStreamValue>,
357 has_children: impl Iterator<Item = bool>,
358 ) {
359 self.buffer.extend(&branch_node(!matches!(maybe_value, None), has_children));
360 if let Some(partial) = maybe_key {
361 self.buffer.extend(fuse_nibbles_node(partial, false));
363 }
364 if let Some(TrieStreamValue::Inline(value)) = maybe_value {
365 value.encode_to(&mut self.buffer);
366 }
367 }
368
369 fn append_extension(&mut self, key: &[u8]) {
370 self.buffer.extend(fuse_nibbles_node(key, false));
371 }
372
373 fn append_substream<H: Hasher>(&mut self, other: Self) {
374 let data = other.out();
375 match data.len() {
376 0..=31 => data.encode_to(&mut self.buffer),
377 _ => H::hash(&data).as_ref().encode_to(&mut self.buffer),
378 }
379 }
380
381 fn out(self) -> Vec<u8> {
382 self.buffer
383 }
384}
385
386#[derive(Copy, Clone, PartialEq, Eq, Debug)]
388enum NodeHeader {
389 Null,
390 Branch(bool),
391 Extension(usize),
392 Leaf(usize),
393}
394
395#[derive(Copy, Clone, PartialEq, Eq, Debug)]
397enum NodeHeaderNoExt {
398 Null,
399 Branch(bool, usize),
400 Leaf(usize),
401}
402
403impl Encode for NodeHeader {
404 fn encode_to<T: Output + ?Sized>(&self, output: &mut T) {
405 match self {
406 NodeHeader::Null => output.push_byte(EMPTY_TRIE),
407 NodeHeader::Branch(true) => output.push_byte(BRANCH_NODE_WITH_VALUE),
408 NodeHeader::Branch(false) => output.push_byte(BRANCH_NODE_NO_VALUE),
409 NodeHeader::Leaf(nibble_count) =>
410 output.push_byte(LEAF_NODE_OFFSET + *nibble_count as u8),
411 NodeHeader::Extension(nibble_count) =>
412 output.push_byte(EXTENSION_NODE_OFFSET + *nibble_count as u8),
413 }
414 }
415}
416
417fn size_and_prefix_iterator(size: usize, prefix: u8) -> impl Iterator<Item = u8> {
420 let size = ::std::cmp::min(NIBBLE_SIZE_BOUND_NO_EXT, size);
421
422 let l1 = std::cmp::min(62, size);
423 let (first_byte, mut rem) =
424 if size == l1 { (once(prefix + l1 as u8), 0) } else { (once(prefix + 63), size - l1) };
425 let next_bytes = move || {
426 if rem > 0 {
427 if rem < 256 {
428 let result = rem - 1;
429 rem = 0;
430 Some(result as u8)
431 } else {
432 rem = rem.saturating_sub(255);
433 Some(255)
434 }
435 } else {
436 None
437 }
438 };
439 first_byte.chain(::std::iter::from_fn(next_bytes))
440}
441
442fn encode_size_and_prefix(size: usize, prefix: u8, out: &mut (impl Output + ?Sized)) {
443 for b in size_and_prefix_iterator(size, prefix) {
444 out.push_byte(b)
445 }
446}
447
448fn decode_size<I: Input>(first: u8, input: &mut I) -> Result<usize, CodecError> {
449 let mut result = (first & 255u8 >> 2) as usize;
450 if result < 63 {
451 return Ok(result)
452 }
453 result -= 1;
454 while result <= NIBBLE_SIZE_BOUND_NO_EXT {
455 let n = input.read_byte()? as usize;
456 if n < 255 {
457 return Ok(result + n + 1)
458 }
459 result += 255;
460 }
461 Err("Size limit reached for a nibble slice".into())
462}
463
464impl Encode for NodeHeaderNoExt {
465 fn encode_to<T: Output + ?Sized>(&self, output: &mut T) {
466 match self {
467 NodeHeaderNoExt::Null => output.push_byte(EMPTY_TRIE_NO_EXT),
468 NodeHeaderNoExt::Branch(true, nibble_count) =>
469 encode_size_and_prefix(*nibble_count, BRANCH_WITH_MASK_NO_EXT, output),
470 NodeHeaderNoExt::Branch(false, nibble_count) =>
471 encode_size_and_prefix(*nibble_count, BRANCH_WITHOUT_MASK_NO_EXT, output),
472 NodeHeaderNoExt::Leaf(nibble_count) =>
473 encode_size_and_prefix(*nibble_count, LEAF_PREFIX_MASK_NO_EXT, output),
474 }
475 }
476}
477
478impl Decode for NodeHeader {
479 fn decode<I: Input>(input: &mut I) -> Result<Self, CodecError> {
480 Ok(match input.read_byte()? {
481 EMPTY_TRIE => NodeHeader::Null,
482 BRANCH_NODE_NO_VALUE => NodeHeader::Branch(false),
483 BRANCH_NODE_WITH_VALUE => NodeHeader::Branch(true),
484 i @ LEAF_NODE_OFFSET..=LEAF_NODE_LAST =>
485 NodeHeader::Leaf((i - LEAF_NODE_OFFSET) as usize),
486 i @ EXTENSION_NODE_OFFSET..=EXTENSION_NODE_LAST =>
487 NodeHeader::Extension((i - EXTENSION_NODE_OFFSET) as usize),
488 })
489 }
490}
491
492impl Decode for NodeHeaderNoExt {
493 fn decode<I: Input>(input: &mut I) -> Result<Self, CodecError> {
494 let i = input.read_byte()?;
495 if i == EMPTY_TRIE_NO_EXT {
496 return Ok(NodeHeaderNoExt::Null)
497 }
498 match i & (0b11 << 6) {
499 LEAF_PREFIX_MASK_NO_EXT => Ok(NodeHeaderNoExt::Leaf(decode_size(i, input)?)),
500 BRANCH_WITHOUT_MASK_NO_EXT =>
501 Ok(NodeHeaderNoExt::Branch(false, decode_size(i, input)?)),
502 BRANCH_WITH_MASK_NO_EXT => Ok(NodeHeaderNoExt::Branch(true, decode_size(i, input)?)),
503 _ => Err("Unknown type of node".into()),
505 }
506 }
507}
508
509#[derive(Default, Clone)]
511pub struct ReferenceNodeCodec<H>(PhantomData<H>);
512
513#[derive(Default, Clone)]
518pub struct ReferenceNodeCodecNoExt<H>(PhantomData<H>);
519
520fn partial_from_iterator_to_key<I: Iterator<Item = u8>>(
521 partial: I,
522 nibble_count: usize,
523 offset: u8,
524 over: u8,
525) -> Vec<u8> {
526 assert!(nibble_count < over as usize);
527 let mut output = Vec::with_capacity(1 + (nibble_count / nibble_ops::NIBBLE_PER_BYTE));
528 output.push(offset + nibble_count as u8);
529 output.extend(partial);
530 output
531}
532
533fn partial_from_iterator_encode<I: Iterator<Item = u8>>(
534 partial: I,
535 nibble_count: usize,
536 node_kind: NodeKindNoExt,
537) -> Vec<u8> {
538 let nibble_count = ::std::cmp::min(NIBBLE_SIZE_BOUND_NO_EXT, nibble_count);
539
540 let mut output = Vec::with_capacity(3 + (nibble_count / nibble_ops::NIBBLE_PER_BYTE));
541 match node_kind {
542 NodeKindNoExt::Leaf => NodeHeaderNoExt::Leaf(nibble_count).encode_to(&mut output),
543 NodeKindNoExt::BranchWithValue =>
544 NodeHeaderNoExt::Branch(true, nibble_count).encode_to(&mut output),
545 NodeKindNoExt::BranchNoValue =>
546 NodeHeaderNoExt::Branch(false, nibble_count).encode_to(&mut output),
547 };
548 output.extend(partial);
549 output
550}
551
552struct ByteSliceInput<'a> {
553 data: &'a [u8],
554 offset: usize,
555}
556
557impl<'a> ByteSliceInput<'a> {
558 fn new(data: &'a [u8]) -> Self {
559 ByteSliceInput { data, offset: 0 }
560 }
561
562 fn take(&mut self, count: usize) -> Result<Range<usize>, CodecError> {
563 if self.offset + count > self.data.len() {
564 return Err("out of data".into())
565 }
566
567 let range = self.offset..(self.offset + count);
568 self.offset += count;
569 Ok(range)
570 }
571}
572
573impl<'a> Input for ByteSliceInput<'a> {
574 fn remaining_len(&mut self) -> Result<Option<usize>, CodecError> {
575 let remaining =
576 if self.offset <= self.data.len() { Some(self.data.len() - self.offset) } else { None };
577 Ok(remaining)
578 }
579
580 fn read(&mut self, into: &mut [u8]) -> Result<(), CodecError> {
581 let range = self.take(into.len())?;
582 into.copy_from_slice(&self.data[range]);
583 Ok(())
584 }
585
586 fn read_byte(&mut self) -> Result<u8, CodecError> {
587 if self.offset + 1 > self.data.len() {
588 return Err("out of data".into())
589 }
590
591 let byte = self.data[self.offset];
592 self.offset += 1;
593 Ok(byte)
594 }
595}
596
597impl<H: Hasher> NodeCodec for ReferenceNodeCodec<H> {
603 type Error = CodecError;
604 type HashOut = H::Out;
605
606 fn hashed_null_node() -> <H as Hasher>::Out {
607 H::hash(<Self as NodeCodec>::empty_node())
608 }
609
610 fn decode_plan(data: &[u8]) -> ::std::result::Result<NodePlan, Self::Error> {
611 let mut input = ByteSliceInput::new(data);
612 match NodeHeader::decode(&mut input)? {
613 NodeHeader::Null => Ok(NodePlan::Empty),
614 NodeHeader::Branch(has_value) => {
615 let bitmap_range = input.take(BITMAP_LENGTH)?;
616 let bitmap = Bitmap::decode(&data[bitmap_range])?;
617
618 let value = if has_value {
619 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
620 Some(ValuePlan::Inline(input.take(count)?))
621 } else {
622 None
623 };
624 let mut children = [
625 None, None, None, None, None, None, None, None, None, None, None, None, None,
626 None, None, None,
627 ];
628 for i in 0..nibble_ops::NIBBLE_LENGTH {
629 if bitmap.value_at(i) {
630 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
631 let range = input.take(count)?;
632 children[i] = Some(if count == H::LENGTH {
633 NodeHandlePlan::Hash(range)
634 } else {
635 NodeHandlePlan::Inline(range)
636 });
637 }
638 }
639 Ok(NodePlan::Branch { value, children })
640 },
641 NodeHeader::Extension(nibble_count) => {
642 let partial = input.take(
643 (nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) /
644 nibble_ops::NIBBLE_PER_BYTE,
645 )?;
646 let partial_padding = nibble_ops::number_padding(nibble_count);
647 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
648 let range = input.take(count)?;
649 let child = if count == H::LENGTH {
650 NodeHandlePlan::Hash(range)
651 } else {
652 NodeHandlePlan::Inline(range)
653 };
654 Ok(NodePlan::Extension {
655 partial: NibbleSlicePlan::new(partial, partial_padding),
656 child,
657 })
658 },
659 NodeHeader::Leaf(nibble_count) => {
660 let partial = input.take(
661 (nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) /
662 nibble_ops::NIBBLE_PER_BYTE,
663 )?;
664 let partial_padding = nibble_ops::number_padding(nibble_count);
665 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
666 let value = input.take(count)?;
667 Ok(NodePlan::Leaf {
668 partial: NibbleSlicePlan::new(partial, partial_padding),
669 value: ValuePlan::Inline(value),
670 })
671 },
672 }
673 }
674
675 fn is_empty_node(data: &[u8]) -> bool {
676 data == <Self as NodeCodec>::empty_node()
677 }
678
679 fn empty_node() -> &'static [u8] {
680 &[EMPTY_TRIE]
681 }
682
683 fn leaf_node(partial: impl Iterator<Item = u8>, number_nibble: usize, value: Value) -> Vec<u8> {
684 let mut output =
685 partial_from_iterator_to_key(partial, number_nibble, LEAF_NODE_OFFSET, LEAF_NODE_OVER);
686 match value {
687 Value::Inline(value) => {
688 Compact(value.len() as u32).encode_to(&mut output);
689 output.extend_from_slice(value);
690 },
691 _ => unimplemented!("unsupported"),
692 }
693 output
694 }
695
696 fn extension_node(
697 partial: impl Iterator<Item = u8>,
698 number_nibble: usize,
699 child: ChildReference<Self::HashOut>,
700 ) -> Vec<u8> {
701 let mut output = partial_from_iterator_to_key(
702 partial,
703 number_nibble,
704 EXTENSION_NODE_OFFSET,
705 EXTENSION_NODE_OVER,
706 );
707 match child {
708 ChildReference::Hash(h) => h.as_ref().encode_to(&mut output),
709 ChildReference::Inline(inline_data, len) =>
710 (&AsRef::<[u8]>::as_ref(&inline_data)[..len]).encode_to(&mut output),
711 };
712 output
713 }
714
715 fn branch_node(
716 children: impl Iterator<Item = impl Borrow<Option<ChildReference<Self::HashOut>>>>,
717 maybe_value: Option<Value>,
718 ) -> Vec<u8> {
719 let mut output = vec![0; BITMAP_LENGTH + 1];
720 let mut prefix: [u8; 3] = [0; 3];
721 let have_value = match maybe_value {
722 Some(Value::Inline(value)) => {
723 Compact(value.len() as u32).encode_to(&mut output);
724 output.extend_from_slice(value);
725 true
726 },
727 None => false,
728 _ => unimplemented!("unsupported"),
729 };
730 let has_children = children.map(|maybe_child| match maybe_child.borrow() {
731 Some(ChildReference::Hash(h)) => {
732 h.as_ref().encode_to(&mut output);
733 true
734 },
735 &Some(ChildReference::Inline(inline_data, len)) => {
736 inline_data.as_ref()[..len].encode_to(&mut output);
737 true
738 },
739 None => false,
740 });
741 branch_node_buffered(have_value, has_children, prefix.as_mut());
742 output[0..BITMAP_LENGTH + 1].copy_from_slice(prefix.as_ref());
743 output
744 }
745
746 fn branch_node_nibbled(
747 _partial: impl Iterator<Item = u8>,
748 _number_nibble: usize,
749 _children: impl Iterator<Item = impl Borrow<Option<ChildReference<Self::HashOut>>>>,
750 _maybe_value: Option<Value>,
751 ) -> Vec<u8> {
752 unreachable!("codec with extension branch")
753 }
754}
755
756impl<H: Hasher> NodeCodec for ReferenceNodeCodecNoExt<H> {
757 type Error = CodecError;
758 type HashOut = <H as Hasher>::Out;
759
760 fn hashed_null_node() -> <H as Hasher>::Out {
761 H::hash(<Self as NodeCodec>::empty_node())
762 }
763
764 fn decode_plan(data: &[u8]) -> Result<NodePlan, Self::Error> {
765 if data.len() < 1 {
766 return Err(CodecError::from("Empty encoded node."))
767 }
768 let mut input = ByteSliceInput::new(data);
769
770 Ok(match NodeHeaderNoExt::decode(&mut input)? {
771 NodeHeaderNoExt::Null => NodePlan::Empty,
772 NodeHeaderNoExt::Branch(has_value, nibble_count) => {
773 let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
774 if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
776 return Err(CodecError::from("Bad format"))
777 }
778 let partial = input.take(
779 (nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) /
780 nibble_ops::NIBBLE_PER_BYTE,
781 )?;
782 let partial_padding = nibble_ops::number_padding(nibble_count);
783 let bitmap_range = input.take(BITMAP_LENGTH)?;
784 let bitmap = Bitmap::decode(&data[bitmap_range])?;
785 let value = if has_value {
786 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
787 Some(ValuePlan::Inline(input.take(count)?))
788 } else {
789 None
790 };
791 let mut children = [
792 None, None, None, None, None, None, None, None, None, None, None, None, None,
793 None, None, None,
794 ];
795 for i in 0..nibble_ops::NIBBLE_LENGTH {
796 if bitmap.value_at(i) {
797 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
798 let range = input.take(count)?;
799 children[i] = Some(if count == H::LENGTH {
800 NodeHandlePlan::Hash(range)
801 } else {
802 NodeHandlePlan::Inline(range)
803 });
804 }
805 }
806 NodePlan::NibbledBranch {
807 partial: NibbleSlicePlan::new(partial, partial_padding),
808 value,
809 children,
810 }
811 },
812 NodeHeaderNoExt::Leaf(nibble_count) => {
813 let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
814 if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
816 return Err(CodecError::from("Bad format"))
817 }
818 let partial = input.take(
819 (nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) /
820 nibble_ops::NIBBLE_PER_BYTE,
821 )?;
822 let partial_padding = nibble_ops::number_padding(nibble_count);
823 let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
824 let value = ValuePlan::Inline(input.take(count)?);
825
826 NodePlan::Leaf { partial: NibbleSlicePlan::new(partial, partial_padding), value }
827 },
828 })
829 }
830
831 fn is_empty_node(data: &[u8]) -> bool {
832 data == <Self as NodeCodec>::empty_node()
833 }
834
835 fn empty_node() -> &'static [u8] {
836 &[EMPTY_TRIE_NO_EXT]
837 }
838
839 fn leaf_node(partial: impl Iterator<Item = u8>, number_nibble: usize, value: Value) -> Vec<u8> {
840 let mut output = partial_from_iterator_encode(partial, number_nibble, NodeKindNoExt::Leaf);
841 match value {
842 Value::Inline(value) => {
843 Compact(value.len() as u32).encode_to(&mut output);
844 output.extend_from_slice(value);
845 },
846 Value::Node(..) => unimplemented!("No support for inner hashed value"),
847 }
848 output
849 }
850
851 fn extension_node(
852 _partial: impl Iterator<Item = u8>,
853 _nbnibble: usize,
854 _child: ChildReference<<H as Hasher>::Out>,
855 ) -> Vec<u8> {
856 unreachable!("no extension codec")
857 }
858
859 fn branch_node(
860 _children: impl Iterator<Item = impl Borrow<Option<ChildReference<<H as Hasher>::Out>>>>,
861 _maybe_value: Option<Value>,
862 ) -> Vec<u8> {
863 unreachable!("no extension codec")
864 }
865
866 fn branch_node_nibbled(
867 partial: impl Iterator<Item = u8>,
868 number_nibble: usize,
869 children: impl Iterator<Item = impl Borrow<Option<ChildReference<Self::HashOut>>>>,
870 maybe_value: Option<Value>,
871 ) -> Vec<u8> {
872 let mut output = if maybe_value.is_none() {
873 partial_from_iterator_encode(partial, number_nibble, NodeKindNoExt::BranchNoValue)
874 } else {
875 partial_from_iterator_encode(partial, number_nibble, NodeKindNoExt::BranchWithValue)
876 };
877 let bitmap_index = output.len();
878 let mut bitmap: [u8; BITMAP_LENGTH] = [0; BITMAP_LENGTH];
879 (0..BITMAP_LENGTH).for_each(|_| output.push(0));
880 match maybe_value {
881 Some(Value::Inline(value)) => {
882 Compact(value.len() as u32).encode_to(&mut output);
883 output.extend_from_slice(value);
884 },
885 Some(Value::Node(..)) => unimplemented!("No support for inner hashed value"),
886 None => (),
887 }
888
889 Bitmap::encode(
890 children.map(|maybe_child| match maybe_child.borrow() {
891 Some(ChildReference::Hash(h)) => {
892 h.as_ref().encode_to(&mut output);
893 true
894 },
895 &Some(ChildReference::Inline(inline_data, len)) => {
896 inline_data.as_ref()[..len].encode_to(&mut output);
897 true
898 },
899 None => false,
900 }),
901 bitmap.as_mut(),
902 );
903 output[bitmap_index..bitmap_index + BITMAP_LENGTH]
904 .copy_from_slice(&bitmap.as_ref()[..BITMAP_LENGTH]);
905 output
906 }
907}
908
909pub fn compare_implementations<T, DB>(data: Vec<(Vec<u8>, Vec<u8>)>, mut memdb: DB, mut hashdb: DB)
911where
912 T: TrieLayout,
913 DB: hash_db::HashDB<T::Hash, DBValue> + Eq,
914{
915 let root_new = calc_root_build::<T, _, _, _, _>(data.clone(), &mut hashdb);
916 let root = {
917 let mut root = Default::default();
918 let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
919 for i in 0..data.len() {
920 t.insert(&data[i].0[..], &data[i].1[..]).unwrap();
921 }
922 t.commit();
923 *t.root()
924 };
925 if root_new != root {
926 {
927 let db: &dyn hash_db::HashDB<_, _> = &hashdb;
928 let t = TrieDBBuilder::<T>::new(&db, &root_new).build();
929 println!("{:?}", t);
930 for a in t.iter().unwrap() {
931 println!("a:{:x?}", a);
932 }
933 }
934 {
935 let db: &dyn hash_db::HashDB<_, _> = &memdb;
936 let t = TrieDBBuilder::<T>::new(&db, &root).build();
937 println!("{:?}", t);
938 for a in t.iter().unwrap() {
939 println!("a:{:x?}", a);
940 }
941 }
942 }
943
944 assert_eq!(root, root_new);
945 assert!(memdb == hashdb);
947}
948
949pub fn compare_root<T: TrieLayout, DB: hash_db::HashDB<T::Hash, DBValue>>(
951 data: Vec<(Vec<u8>, Vec<u8>)>,
952 mut memdb: DB,
953) {
954 let root_new = reference_trie_root_iter_build::<T, _, _, _>(data.clone());
955 let root = {
956 let mut root = Default::default();
957 let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
958 for i in 0..data.len() {
959 t.insert(&data[i].0[..], &data[i].1[..]).unwrap();
960 }
961 *t.root()
962 };
963
964 assert_eq!(root, root_new);
965}
966
967pub fn compare_unhashed(data: Vec<(Vec<u8>, Vec<u8>)>) {
969 let root_new = {
970 let mut cb = trie_db::TrieRootUnhashed::<ExtensionLayout>::default();
971 trie_visit::<ExtensionLayout, _, _, _, _>(data.clone().into_iter(), &mut cb);
972 cb.root.unwrap_or(Default::default())
973 };
974 let root = reference_trie_root_unhashed(data);
975
976 assert_eq!(root, root_new);
977}
978
979pub fn compare_unhashed_no_extension(data: Vec<(Vec<u8>, Vec<u8>)>) {
982 let root_new = {
983 let mut cb = trie_db::TrieRootUnhashed::<NoExtensionLayout>::default();
984 trie_visit::<NoExtensionLayout, _, _, _, _>(data.clone().into_iter(), &mut cb);
985 cb.root.unwrap_or(Default::default())
986 };
987 let root = reference_trie_root_unhashed_no_extension(data);
988
989 assert_eq!(root, root_new);
990}
991
992pub fn calc_root<T, I, A, B>(data: I) -> <T::Hash as Hasher>::Out
994where
995 T: TrieLayout,
996 I: IntoIterator<Item = (A, B)>,
997 A: AsRef<[u8]> + Ord + fmt::Debug,
998 B: AsRef<[u8]> + fmt::Debug,
999{
1000 let mut cb = TrieRoot::<T>::default();
1001 trie_visit::<T, _, _, _, _>(data.into_iter(), &mut cb);
1002 cb.root.unwrap_or_default()
1003}
1004
1005pub fn calc_root_build<T, I, A, B, DB>(data: I, hashdb: &mut DB) -> <T::Hash as Hasher>::Out
1007where
1008 T: TrieLayout,
1009 I: IntoIterator<Item = (A, B)>,
1010 A: AsRef<[u8]> + Ord + fmt::Debug,
1011 B: AsRef<[u8]> + fmt::Debug,
1012 DB: hash_db::HashDB<T::Hash, DBValue>,
1013{
1014 let mut cb = TrieBuilder::<T, DB>::new(hashdb);
1015 trie_visit::<T, _, _, _, _>(data.into_iter(), &mut cb);
1016 cb.root.unwrap_or_default()
1017}
1018
1019pub fn compare_implementations_unordered<T, DB>(
1022 data: Vec<(Vec<u8>, Vec<u8>)>,
1023 mut memdb: DB,
1024 mut hashdb: DB,
1025) where
1026 T: TrieLayout,
1027 DB: hash_db::HashDB<T::Hash, DBValue> + Eq,
1028{
1029 let mut b_map = std::collections::btree_map::BTreeMap::new();
1030 let root = {
1031 let mut root = Default::default();
1032 let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
1033 for i in 0..data.len() {
1034 t.insert(&data[i].0[..], &data[i].1[..]).unwrap();
1035 b_map.insert(data[i].0.clone(), data[i].1.clone());
1036 }
1037 *t.root()
1038 };
1039 let root_new = {
1040 let mut cb = TrieBuilder::<T, DB>::new(&mut hashdb);
1041 trie_visit::<T, _, _, _, _>(b_map.into_iter(), &mut cb);
1042 cb.root.unwrap_or_default()
1043 };
1044
1045 if root != root_new {
1046 {
1047 let db: &dyn hash_db::HashDB<_, _> = &memdb;
1048 let t = TrieDBBuilder::<T>::new(&db, &root).build();
1049 println!("{:?}", t);
1050 for a in t.iter().unwrap() {
1051 println!("a:{:?}", a);
1052 }
1053 }
1054 {
1055 let db: &dyn hash_db::HashDB<_, _> = &hashdb;
1056 let t = TrieDBBuilder::<T>::new(&db, &root_new).build();
1057 println!("{:?}", t);
1058 for a in t.iter().unwrap() {
1059 println!("a:{:?}", a);
1060 }
1061 }
1062 }
1063
1064 assert_eq!(root, root_new);
1065}
1066
1067pub fn compare_insert_remove<T, DB: hash_db::HashDB<T::Hash, DBValue>>(
1070 data: Vec<(bool, Vec<u8>, Vec<u8>)>,
1071 mut memdb: DB,
1072) where
1073 T: TrieLayout,
1074 DB: hash_db::HashDB<T::Hash, DBValue> + Eq,
1075{
1076 let mut data2 = std::collections::BTreeMap::new();
1077 let mut root = Default::default();
1078 let mut a = 0;
1079 {
1080 let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
1081 t.commit();
1082 }
1083 while a < data.len() {
1084 root = {
1086 let mut t = TrieDBMutBuilder::<T>::from_existing(&mut memdb, &mut root).build();
1087 for _ in 0..3 {
1088 if data[a].0 {
1089 t.remove(&data[a].1[..]).unwrap();
1091 data2.remove(&data[a].1[..]);
1092 } else {
1093 t.insert(&data[a].1[..], &data[a].2[..]).unwrap();
1095 data2.insert(&data[a].1[..], &data[a].2[..]);
1096 }
1097
1098 a += 1;
1099 if a == data.len() {
1100 break
1101 }
1102 }
1103 t.commit();
1104 *t.root()
1105 };
1106 }
1107 let mut t = TrieDBMutBuilder::<T>::from_existing(&mut memdb, &mut root).build();
1108 assert_eq!(*t.root(), calc_root::<T, _, _, _>(data2));
1111}
1112
1113pub struct TestTrieCache<L: TrieLayout> {
1117 value_cache: HashMap<Vec<u8>, trie_db::CachedValue<TrieHash<L>>>,
1119 node_cache: HashMap<TrieHash<L>, NodeOwned<TrieHash<L>>>,
1120}
1121
1122impl<L: TrieLayout> TestTrieCache<L> {
1123 pub fn clear_value_cache(&mut self) {
1125 self.value_cache.clear();
1126 }
1127
1128 pub fn clear_node_cache(&mut self) {
1130 self.node_cache.clear();
1131 }
1132}
1133
1134impl<L: TrieLayout> Default for TestTrieCache<L> {
1135 fn default() -> Self {
1136 Self { value_cache: Default::default(), node_cache: Default::default() }
1137 }
1138}
1139
1140impl<L: TrieLayout> trie_db::TrieCache<L::Codec> for TestTrieCache<L> {
1141 fn lookup_value_for_key(&mut self, key: &[u8]) -> Option<&trie_db::CachedValue<TrieHash<L>>> {
1142 self.value_cache.get(key)
1143 }
1144
1145 fn cache_value_for_key(&mut self, key: &[u8], value: trie_db::CachedValue<TrieHash<L>>) {
1146 self.value_cache.insert(key.to_vec(), value);
1147 }
1148
1149 fn get_or_insert_node(
1150 &mut self,
1151 hash: TrieHash<L>,
1152 fetch_node: &mut dyn FnMut() -> trie_db::Result<
1153 NodeOwned<TrieHash<L>>,
1154 TrieHash<L>,
1155 trie_db::CError<L>,
1156 >,
1157 ) -> trie_db::Result<&NodeOwned<TrieHash<L>>, TrieHash<L>, trie_db::CError<L>> {
1158 match self.node_cache.entry(hash) {
1159 Entry::Occupied(e) => Ok(e.into_mut()),
1160 Entry::Vacant(e) => {
1161 let node = (*fetch_node)()?;
1162 Ok(e.insert(node))
1163 },
1164 }
1165 }
1166
1167 fn get_node(&mut self, hash: &TrieHash<L>) -> Option<&NodeOwned<TrieHash<L>>> {
1168 self.node_cache.get(hash)
1169 }
1170}
1171
1172#[cfg(test)]
1173mod tests {
1174 use super::*;
1175 use trie_db::{nibble_ops::NIBBLE_PER_BYTE, node::Node};
1176
1177 const _: fn() -> () = || {
1178 #[allow(dead_code)]
1179 struct AssertTrieDBRawIteratorIsSendAndSync
1180 where
1181 trie_db::TrieDBRawIterator<NoExtensionLayout>: Send + Sync;
1182 };
1183
1184 #[test]
1185 fn test_encoding_simple_trie() {
1186 for prefix in
1187 [LEAF_PREFIX_MASK_NO_EXT, BRANCH_WITHOUT_MASK_NO_EXT, BRANCH_WITH_MASK_NO_EXT].iter()
1188 {
1189 for i in (0..1000).chain(NIBBLE_SIZE_BOUND_NO_EXT - 2..NIBBLE_SIZE_BOUND_NO_EXT + 2) {
1190 let mut output = Vec::new();
1191 encode_size_and_prefix(i, *prefix, &mut output);
1192 let input = &mut &output[..];
1193 let first = input.read_byte().unwrap();
1194 assert_eq!(first & (0b11 << 6), *prefix);
1195 let v = decode_size(first, input);
1196 assert_eq!(Ok(std::cmp::min(i, NIBBLE_SIZE_BOUND_NO_EXT)), v);
1197 }
1198 }
1199 }
1200
1201 #[test]
1202 fn too_big_nibble_length() {
1203 let input = vec![0u8; (NIBBLE_SIZE_BOUND_NO_EXT as usize + 1) / 2 + 1];
1205 let enc = <ReferenceNodeCodecNoExt<RefHasher> as NodeCodec>::leaf_node(
1206 input.iter().cloned(),
1207 input.len() * NIBBLE_PER_BYTE,
1208 Value::Inline(&[1]),
1209 );
1210 let dec = <ReferenceNodeCodecNoExt<RefHasher> as NodeCodec>::decode(&enc).unwrap();
1211 let o_sl = if let Node::Leaf(sl, _) = dec { Some(sl) } else { None };
1212 assert!(o_sl.is_some());
1213 }
1214
1215 #[test]
1216 fn size_encode_limit_values() {
1217 let sizes = [0, 1, 62, 63, 64, 317, 318, 319, 572, 573, 574];
1218 let encs = [
1219 vec![0],
1220 vec![1],
1221 vec![0x3e],
1222 vec![0x3f, 0],
1223 vec![0x3f, 1],
1224 vec![0x3f, 0xfe],
1225 vec![0x3f, 0xff, 0],
1226 vec![0x3f, 0xff, 1],
1227 vec![0x3f, 0xff, 0xfe],
1228 vec![0x3f, 0xff, 0xff, 0],
1229 vec![0x3f, 0xff, 0xff, 1],
1230 ];
1231 for i in 0..sizes.len() {
1232 let mut enc = Vec::new();
1233 encode_size_and_prefix(sizes[i], 0, &mut enc);
1234 assert_eq!(enc, encs[i]);
1235 let s_dec = decode_size(encs[i][0], &mut &encs[i][1..]);
1236 assert_eq!(s_dec, Ok(sizes[i]));
1237 }
1238 }
1239}
1240
1241fn test_iterator<L, DB>(entries: Vec<(Vec<u8>, Vec<u8>)>, keys: Vec<Vec<u8>>, prefix: bool)
1243where
1244 L: TrieLayout,
1245 DB: hash_db::HashDB<L::Hash, DBValue> + hash_db::HashDBRef<L::Hash, DBValue> + Default,
1246{
1247 let mut ref_tree = std::collections::BTreeMap::new();
1248
1249 let (db, root) = {
1251 let mut db = DB::default();
1252 let mut root = Default::default();
1253 {
1254 let mut trie = TrieDBMutBuilder::<L>::new(&mut db, &mut root).build();
1255 for (key, value) in entries.into_iter() {
1256 trie.insert(&key, &value).unwrap();
1257 ref_tree.insert(key, value);
1258 }
1259 }
1260 (db, root)
1261 };
1262 let trie = TrieDBBuilder::<L>::new(&db, &root).build();
1264 let mut iter = trie_db::triedb::TrieDBDoubleEndedIterator::new(&trie).unwrap();
1266 let mut iter_ref = ref_tree.iter();
1267 let mut iter_ref2 = ref_tree.iter();
1268
1269 loop {
1270 let n = iter.next();
1271 let nb = iter.next_back();
1272 let n_ref = iter_ref.next();
1273 let nb_ref = iter_ref2.next_back();
1274 assert_eq!(n.as_ref().map(|v| v.as_ref().map(|v| (&v.0, &v.1)).unwrap()), n_ref);
1275 assert_eq!(nb.as_ref().map(|v| v.as_ref().map(|v| (&v.0, &v.1)).unwrap()), nb_ref);
1276 if n_ref.is_none() && nb_ref.is_none() {
1277 break;
1278 }
1279 }
1280 for key in keys {
1281 use trie_db::TrieIterator;
1282 let mut iter = if prefix {
1283 trie_db::triedb::TrieDBDoubleEndedIterator::new_prefixed(&trie, &key).unwrap()
1284 } else {
1285 trie_db::triedb::TrieDBDoubleEndedIterator::new(&trie).unwrap()
1286 };
1287 if !prefix {
1288 iter.seek(&key).unwrap();
1289 }
1290 let mut iter_ref =
1291 ref_tree
1292 .iter()
1293 .filter(|k| if prefix { k.0.starts_with(&key) } else { k.0 >= &key });
1294 let mut iter_ref2 =
1295 ref_tree
1296 .iter()
1297 .filter(|k| if prefix { k.0.starts_with(&key) } else { k.0 <= &key });
1298 loop {
1299 let n = iter.next();
1300 let nb = iter.next_back();
1301 let n_ref = iter_ref.next();
1302 let nb_ref = iter_ref2.next_back();
1303 assert_eq!(n.as_ref().map(|v| v.as_ref().map(|v| (&v.0, &v.1)).unwrap()), n_ref);
1304 assert_eq!(nb.as_ref().map(|v| v.as_ref().map(|v| (&v.0, &v.1)).unwrap()), nb_ref);
1305 if n_ref.is_none() && nb_ref.is_none() {
1306 break;
1307 }
1308 }
1309 }
1310}
1311
1312pub fn fuzz_double_iter<T, DB>(input: &[u8], prefix: bool)
1313where
1314 T: TrieLayout,
1315 DB: hash_db::HashDB<T::Hash, DBValue> + hash_db::HashDBRef<T::Hash, DBValue> + Default,
1316{
1317 let mut data = fuzz_to_data(input);
1318 let mut keys = data[(data.len() / 3)..].iter().map(|(key, _)| key.clone()).collect::<Vec<_>>();
1321 data.truncate(data.len() * 2 / 3);
1322
1323 let data = data_sorted_unique(data);
1324 keys.sort();
1325 keys.dedup();
1326
1327 test_iterator::<T, DB>(data, keys, prefix);
1328}
1329
1330pub fn fuzz_to_data(input: &[u8]) -> Vec<(Vec<u8>, Vec<u8>)> {
1331 let mut result = Vec::new();
1332 let mut minkeylen = if let Some(v) = input.get(0) {
1335 let mut v = *v & 31u8;
1336 v = v + 1;
1337 v
1338 } else {
1339 return result
1340 };
1341 let mut maxkeylen = if let Some(v) = input.get(1) {
1342 let mut v = *v & 31u8;
1343 v = v + 1;
1344 v
1345 } else {
1346 return result
1347 };
1348
1349 if maxkeylen < minkeylen {
1350 let v = minkeylen;
1351 minkeylen = maxkeylen;
1352 maxkeylen = v;
1353 }
1354 let mut ix = 2;
1355 loop {
1356 let keylen = if let Some(v) = input.get(ix) {
1357 let mut v = *v & 31u8;
1358 v = v + 1;
1359 v = std::cmp::max(minkeylen, v);
1360 v = std::cmp::min(maxkeylen, v);
1361 v as usize
1362 } else {
1363 break
1364 };
1365 let key = if input.len() > ix + keylen { input[ix..ix + keylen].to_vec() } else { break };
1366 ix += keylen;
1367 let val = if input.len() > ix + 2 { input[ix..ix + 2].to_vec() } else { break };
1368 result.push((key, val));
1369 }
1370 result
1371}