Skip to main content

reference_trie/
lib.rs

1// Copyright 2017, 2021 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Reference implementation of a streamer.
16
17use 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
46/// Reference hasher is a keccak hasher.
47pub type RefHasher = keccak_hasher::KeccakHasher;
48
49/// Apply a test method on every test layouts.
50#[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/// Apply a test method on every test layouts.
84#[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/// Trie layout using extension nodes.
96#[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
109/// Trie layout without extension nodes, allowing
110/// generic hasher.
111pub 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/// Trie that allows empty values.
134#[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
147/// Trie layout without extension nodes.
148pub type NoExtensionLayout = GenericNoExtensionLayout<RefHasher>;
149
150/// Children bitmap codec for radix 16 trie.
151pub 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); // latest value for uniqueness
218	}
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
265// Constant use with no extensino trie codec.
266const 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
273/// Create a leaf/extension node, encoding a number of nibbles. Note that this
274/// cannot handle a number of nibbles that is zero or greater than 125 and if
275/// you attempt to do so *IT WILL PANIC*.
276fn 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
295/// Encoding of branch header and children bitmap (for trie stream radix 16).
296/// For stream variant with extension.
297fn 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
303/// Encoding of branch header and children bitmap for any radix.
304/// For codec/stream variant with extension.
305fn 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
315/// Encoding of children bitmap (for trie stream radix 16).
316/// For stream variant without extension.
317fn 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/// Reference implementation of a `TrieStream` with extension nodes.
330#[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			// should not happen
362			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/// A node header.
387#[derive(Copy, Clone, PartialEq, Eq, Debug)]
388enum NodeHeader {
389	Null,
390	Branch(bool),
391	Extension(usize),
392	Leaf(usize),
393}
394
395/// A node header no extension.
396#[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
417/// Encode and allocate node type header (type and size), and partial value.
418/// It uses an iterator over encoded partial bytes as input.
419fn 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			// do not allow any special encoding
504			_ => Err("Unknown type of node".into()),
505		}
506	}
507}
508
509/// Simple reference implementation of a `NodeCodec`.
510#[derive(Default, Clone)]
511pub struct ReferenceNodeCodec<H>(PhantomData<H>);
512
513/// Simple reference implementation of a `NodeCodec`.
514/// Even if implementation follows initial specification of
515/// https://github.com/w3f/polkadot-re-spec/issues/8, this may
516/// not follow it in the future, it is mainly the testing codec without extension node.
517#[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
597// NOTE: what we'd really like here is:
598// `impl<H: Hasher> NodeCodec<H> for RlpNodeCodec<H> where <KeccakHasher as Hasher>::Out: Decodable`
599// but due to the current limitations of Rust const evaluation we can't do
600// `const HASHED_NULL_NODE: <KeccakHasher as Hasher>::Out = <KeccakHasher as Hasher>::Out( … … )`.
601// Perhaps one day soon?
602impl<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				// check that the padding is valid (if any)
775				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				// check that the padding is valid (if any)
815				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
909/// Compare trie builder and in memory trie.
910pub 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	// compare db content for key fuzzing
946	assert!(memdb == hashdb);
947}
948
949/// Compare trie builder and trie root implementations.
950pub 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
967/// Compare trie builder and trie root unhashed implementations.
968pub 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
979/// Compare trie builder and trie root unhashed implementations.
980/// This uses the variant without extension nodes.
981pub 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
992/// Trie builder root calculation utility.
993pub 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
1005/// Trie builder trie building utility.
1006pub 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
1019/// `compare_implementations_no_extension` for unordered input (trie_root does
1020/// ordering before running when trie_build expect correct ordering).
1021pub 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
1067/// Testing utility that uses some periodic removal over
1068/// its input test data.
1069pub 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		// new triemut every 3 element
1085		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					// remove
1090					t.remove(&data[a].1[..]).unwrap();
1091					data2.remove(&data[a].1[..]);
1092				} else {
1093					// add
1094					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	// we are testing the RefTrie code here so we do not sort or check uniqueness
1109	// before.
1110	assert_eq!(*t.root(), calc_root::<T, _, _, _>(data2));
1111}
1112
1113/// Example trie cache implementation.
1114///
1115/// Should not be used for anything in production.
1116pub struct TestTrieCache<L: TrieLayout> {
1117	/// In a real implementation we need to make sure that this is unique per trie root.
1118	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	/// Clear the value cache.
1124	pub fn clear_value_cache(&mut self) {
1125		self.value_cache.clear();
1126	}
1127
1128	/// Clear the node cache.
1129	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		// + 1 for 0 added byte of nibble encode
1204		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
1241// This is a bit redundant with other iterator fuzzer
1242fn 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	// Populate DB with full trie from entries.
1250	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	// Lookup items in trie while recording traversed nodes.
1263	let trie = TrieDBBuilder::<L>::new(&db, &root).build();
1264	// standard iter
1265	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	// - the first 2/3 are added to the trie.
1319	// - the last 1/3 is not added to the trie and use for random seek and prefix.
1320	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	// enc = (minkeylen, maxkeylen (min max up to 32), datas)
1333	// fix data len 2 bytes
1334	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}