sp_trie/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie").
19
20#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24pub mod accessed_nodes_tracker;
25#[cfg(feature = "std")]
26pub mod cache;
27mod error;
28mod node_codec;
29mod node_header;
30#[cfg(feature = "std")]
31pub mod recorder;
32pub mod recorder_ext;
33mod storage_proof;
34mod trie_codec;
35mod trie_stream;
36
37#[cfg(feature = "std")]
38pub mod proof_size_extension;
39
40use alloc::{borrow::Borrow, boxed::Box, vec, vec::Vec};
41use core::marker::PhantomData;
42/// Our `NodeCodec`-specific error.
43pub use error::Error;
44/// Various re-exports from the `hash-db` crate.
45pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX};
46use hash_db::{Hasher, Prefix};
47/// Various re-exports from the `memory-db` crate.
48pub use memory_db::{prefixed_key, HashKey, KeyFunction, PrefixedKey};
49/// The Substrate format implementation of `NodeCodec`.
50pub use node_codec::NodeCodec;
51pub use storage_proof::{CompactProof, StorageProof, StorageProofError};
52/// Trie codec reexport, mainly child trie support
53/// for trie compact proof.
54pub use trie_codec::{decode_compact, encode_compact, Error as CompactProofError};
55use trie_db::proof::{generate_proof, verify_proof};
56/// Various re-exports from the `trie-db` crate.
57pub use trie_db::{
58	nibble_ops,
59	node::{NodePlan, ValuePlan},
60	triedb::{TrieDBDoubleEndedIterator, TrieDBKeyDoubleEndedIterator},
61	CError, DBValue, Query, Recorder, Trie, TrieCache, TrieConfiguration, TrieDBIterator,
62	TrieDBKeyIterator, TrieDBNodeDoubleEndedIterator, TrieDBRawIterator, TrieLayout, TrieMut,
63	TrieRecorder,
64};
65pub use trie_db::{proof::VerifyError, MerkleValue};
66/// The Substrate format implementation of `TrieStream`.
67pub use trie_stream::TrieStream;
68
69/// Raw storage proof type (just raw trie nodes).
70pub type RawStorageProof = Vec<Vec<u8>>;
71
72/// substrate trie layout
73pub struct LayoutV0<H>(PhantomData<H>);
74
75/// substrate trie layout, with external value nodes.
76pub struct LayoutV1<H>(PhantomData<H>);
77
78impl<H> TrieLayout for LayoutV0<H>
79where
80	H: Hasher,
81{
82	const USE_EXTENSION: bool = false;
83	const ALLOW_EMPTY: bool = true;
84	const MAX_INLINE_VALUE: Option<u32> = None;
85
86	type Hash = H;
87	type Codec = NodeCodec<Self::Hash>;
88}
89
90impl<H> TrieConfiguration for LayoutV0<H>
91where
92	H: Hasher,
93{
94	fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out
95	where
96		I: IntoIterator<Item = (A, B)>,
97		A: AsRef<[u8]> + Ord,
98		B: AsRef<[u8]>,
99	{
100		trie_root::trie_root_no_extension::<H, TrieStream, _, _, _>(input, Self::MAX_INLINE_VALUE)
101	}
102
103	fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
104	where
105		I: IntoIterator<Item = (A, B)>,
106		A: AsRef<[u8]> + Ord,
107		B: AsRef<[u8]>,
108	{
109		trie_root::unhashed_trie_no_extension::<H, TrieStream, _, _, _>(
110			input,
111			Self::MAX_INLINE_VALUE,
112		)
113	}
114
115	fn encode_index(input: u32) -> Vec<u8> {
116		codec::Encode::encode(&codec::Compact(input))
117	}
118}
119
120impl<H> TrieLayout for LayoutV1<H>
121where
122	H: Hasher,
123{
124	const USE_EXTENSION: bool = false;
125	const ALLOW_EMPTY: bool = true;
126	const MAX_INLINE_VALUE: Option<u32> = Some(sp_core::storage::TRIE_VALUE_NODE_THRESHOLD);
127
128	type Hash = H;
129	type Codec = NodeCodec<Self::Hash>;
130}
131
132impl<H> TrieConfiguration for LayoutV1<H>
133where
134	H: Hasher,
135{
136	fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out
137	where
138		I: IntoIterator<Item = (A, B)>,
139		A: AsRef<[u8]> + Ord,
140		B: AsRef<[u8]>,
141	{
142		trie_root::trie_root_no_extension::<H, TrieStream, _, _, _>(input, Self::MAX_INLINE_VALUE)
143	}
144
145	fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
146	where
147		I: IntoIterator<Item = (A, B)>,
148		A: AsRef<[u8]> + Ord,
149		B: AsRef<[u8]>,
150	{
151		trie_root::unhashed_trie_no_extension::<H, TrieStream, _, _, _>(
152			input,
153			Self::MAX_INLINE_VALUE,
154		)
155	}
156
157	fn encode_index(input: u32) -> Vec<u8> {
158		codec::Encode::encode(&codec::Compact(input))
159	}
160}
161
162/// Type that is able to provide a [`trie_db::TrieRecorder`].
163///
164/// Types implementing this trait can be used to maintain recorded state
165/// across operations on different [`trie_db::TrieDB`] instances.
166pub trait TrieRecorderProvider<H: Hasher> {
167	/// Recorder type that is going to be returned by implementors of this trait.
168	type Recorder<'a>: trie_db::TrieRecorder<H::Out> + 'a
169	where
170		Self: 'a;
171
172	/// Create a [`StorageProof`] derived from the internal state.
173	fn drain_storage_proof(self) -> Option<StorageProof>;
174
175	/// Provide a recorder implementing [`trie_db::TrieRecorder`].
176	fn as_trie_recorder(&self, storage_root: H::Out) -> Self::Recorder<'_>;
177}
178
179/// Type that is able to provide a proof size estimation.
180pub trait ProofSizeProvider {
181	/// Returns the storage proof size.
182	fn estimate_encoded_size(&self) -> usize;
183}
184
185/// TrieDB error over `TrieConfiguration` trait.
186pub type TrieError<L> = trie_db::TrieError<TrieHash<L>, CError<L>>;
187/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
188pub trait AsHashDB<H: Hasher>: hash_db::AsHashDB<H, trie_db::DBValue> {}
189impl<H: Hasher, T: hash_db::AsHashDB<H, trie_db::DBValue>> AsHashDB<H> for T {}
190/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
191pub type HashDB<'a, H> = dyn hash_db::HashDB<H, trie_db::DBValue> + 'a;
192/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
193/// This uses a `KeyFunction` for prefixing keys internally (avoiding
194/// key conflict for non random keys).
195pub type PrefixedMemoryDB<H> = memory_db::MemoryDB<H, memory_db::PrefixedKey<H>, trie_db::DBValue>;
196/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
197/// This uses a noops `KeyFunction` (key addressing must be hashed or using
198/// an encoding scheme that avoid key conflict).
199pub type MemoryDB<H> = memory_db::MemoryDB<H, memory_db::HashKey<H>, trie_db::DBValue>;
200/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
201pub type GenericMemoryDB<H, KF> = memory_db::MemoryDB<H, KF, trie_db::DBValue>;
202
203/// Persistent trie database read-access interface for a given hasher.
204pub type TrieDB<'a, 'cache, L> = trie_db::TrieDB<'a, 'cache, L>;
205/// Builder for creating a [`TrieDB`].
206pub type TrieDBBuilder<'a, 'cache, L> = trie_db::TrieDBBuilder<'a, 'cache, L>;
207/// Persistent trie database write-access interface for a given hasher.
208pub type TrieDBMut<'a, L> = trie_db::TrieDBMut<'a, L>;
209/// Builder for creating a [`TrieDBMut`].
210pub type TrieDBMutBuilder<'a, L> = trie_db::TrieDBMutBuilder<'a, L>;
211/// Querying interface, as in `trie_db` but less generic.
212pub type Lookup<'a, 'cache, L, Q> = trie_db::Lookup<'a, 'cache, L, Q>;
213/// Hash type for a trie layout.
214pub type TrieHash<L> = <<L as TrieLayout>::Hash as Hasher>::Out;
215/// This module is for non generic definition of trie type.
216/// Only the `Hasher` trait is generic in this case.
217pub mod trie_types {
218	use super::*;
219
220	/// Persistent trie database read-access interface for a given hasher.
221	///
222	/// Read only V1 and V0 are compatible, thus we always use V1.
223	pub type TrieDB<'a, 'cache, H> = super::TrieDB<'a, 'cache, LayoutV1<H>>;
224	/// Builder for creating a [`TrieDB`].
225	pub type TrieDBBuilder<'a, 'cache, H> = super::TrieDBBuilder<'a, 'cache, LayoutV1<H>>;
226	/// Persistent trie database write-access interface for a given hasher.
227	pub type TrieDBMutV0<'a, H> = super::TrieDBMut<'a, LayoutV0<H>>;
228	/// Builder for creating a [`TrieDBMutV0`].
229	pub type TrieDBMutBuilderV0<'a, H> = super::TrieDBMutBuilder<'a, LayoutV0<H>>;
230	/// Persistent trie database write-access interface for a given hasher.
231	pub type TrieDBMutV1<'a, H> = super::TrieDBMut<'a, LayoutV1<H>>;
232	/// Builder for creating a [`TrieDBMutV1`].
233	pub type TrieDBMutBuilderV1<'a, H> = super::TrieDBMutBuilder<'a, LayoutV1<H>>;
234	/// Querying interface, as in `trie_db` but less generic.
235	pub type Lookup<'a, 'cache, H, Q> = trie_db::Lookup<'a, 'cache, LayoutV1<H>, Q>;
236	/// As in `trie_db`, but less generic, error type for the crate.
237	pub type TrieError<H> = trie_db::TrieError<H, super::Error<H>>;
238}
239
240/// Create a proof for a subset of keys in a trie.
241///
242/// The `keys` may contain any set of keys regardless of each one of them is included
243/// in the `db`.
244///
245/// For a key `K` that is included in the `db` a proof of inclusion is generated.
246/// For a key `K` that is not included in the `db` a proof of non-inclusion is generated.
247/// These can be later checked in `verify_trie_proof`.
248pub fn generate_trie_proof<'a, L, I, K, DB>(
249	db: &DB,
250	root: TrieHash<L>,
251	keys: I,
252) -> Result<Vec<Vec<u8>>, Box<TrieError<L>>>
253where
254	L: TrieConfiguration,
255	I: IntoIterator<Item = &'a K>,
256	K: 'a + AsRef<[u8]>,
257	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
258{
259	generate_proof::<_, L, _, _>(db, &root, keys)
260}
261
262/// Verify a set of key-value pairs against a trie root and a proof.
263///
264/// Checks a set of keys with optional values for inclusion in the proof that was generated by
265/// `generate_trie_proof`.
266/// If the value in the pair is supplied (`(key, Some(value))`), this key-value pair will be
267/// checked for inclusion in the proof.
268/// If the value is omitted (`(key, None)`), this key will be checked for non-inclusion in the
269/// proof.
270pub fn verify_trie_proof<'a, L, I, K, V>(
271	root: &TrieHash<L>,
272	proof: &[Vec<u8>],
273	items: I,
274) -> Result<(), VerifyError<TrieHash<L>, CError<L>>>
275where
276	L: TrieConfiguration,
277	I: IntoIterator<Item = &'a (K, Option<V>)>,
278	K: 'a + AsRef<[u8]>,
279	V: 'a + AsRef<[u8]>,
280{
281	verify_proof::<L, _, _, _>(root, proof, items)
282}
283
284/// Determine a trie root given a hash DB and delta values.
285pub fn delta_trie_root<L: TrieConfiguration, I, A, B, DB, V>(
286	db: &mut DB,
287	mut root: TrieHash<L>,
288	delta: I,
289	recorder: Option<&mut dyn trie_db::TrieRecorder<TrieHash<L>>>,
290	cache: Option<&mut dyn TrieCache<L::Codec>>,
291) -> Result<TrieHash<L>, Box<TrieError<L>>>
292where
293	I: IntoIterator<Item = (A, B)>,
294	A: Borrow<[u8]>,
295	B: Borrow<Option<V>>,
296	V: Borrow<[u8]>,
297	DB: hash_db::HashDB<L::Hash, trie_db::DBValue>,
298{
299	{
300		let mut trie = TrieDBMutBuilder::<L>::from_existing(db, &mut root)
301			.with_optional_cache(cache)
302			.with_optional_recorder(recorder)
303			.build();
304
305		let mut delta = delta.into_iter().collect::<Vec<_>>();
306		delta.sort_by(|l, r| l.0.borrow().cmp(r.0.borrow()));
307
308		for (key, change) in delta {
309			match change.borrow() {
310				Some(val) => trie.insert(key.borrow(), val.borrow())?,
311				None => trie.remove(key.borrow())?,
312			};
313		}
314	}
315
316	Ok(root)
317}
318
319/// Read a value from the trie.
320pub fn read_trie_value<L: TrieLayout, DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>>(
321	db: &DB,
322	root: &TrieHash<L>,
323	key: &[u8],
324	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
325	cache: Option<&mut dyn TrieCache<L::Codec>>,
326) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
327	TrieDBBuilder::<L>::new(db, root)
328		.with_optional_cache(cache)
329		.with_optional_recorder(recorder)
330		.build()
331		.get(key)
332}
333
334/// Read the [`trie_db::MerkleValue`] of the node that is the closest descendant for
335/// the provided key.
336pub fn read_trie_first_descendant_value<L: TrieLayout, DB>(
337	db: &DB,
338	root: &TrieHash<L>,
339	key: &[u8],
340	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
341	cache: Option<&mut dyn TrieCache<L::Codec>>,
342) -> Result<Option<MerkleValue<TrieHash<L>>>, Box<TrieError<L>>>
343where
344	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
345{
346	TrieDBBuilder::<L>::new(db, root)
347		.with_optional_cache(cache)
348		.with_optional_recorder(recorder)
349		.build()
350		.lookup_first_descendant(key)
351}
352
353/// Read a value from the trie with given Query.
354pub fn read_trie_value_with<
355	L: TrieLayout,
356	Q: Query<L::Hash, Item = Vec<u8>>,
357	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
358>(
359	db: &DB,
360	root: &TrieHash<L>,
361	key: &[u8],
362	query: Q,
363) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
364	TrieDBBuilder::<L>::new(db, root).build().get_with(key, query)
365}
366
367/// Determine the empty trie root.
368pub fn empty_trie_root<L: TrieConfiguration>() -> <L::Hash as Hasher>::Out {
369	L::trie_root::<_, Vec<u8>, Vec<u8>>(core::iter::empty())
370}
371
372/// Determine the empty child trie root.
373pub fn empty_child_trie_root<L: TrieConfiguration>() -> <L::Hash as Hasher>::Out {
374	L::trie_root::<_, Vec<u8>, Vec<u8>>(core::iter::empty())
375}
376
377/// Determine a child trie root given its ordered contents, closed form. H is the default hasher,
378/// but a generic implementation may ignore this type parameter and use other hashers.
379pub fn child_trie_root<L: TrieConfiguration, I, A, B>(input: I) -> <L::Hash as Hasher>::Out
380where
381	I: IntoIterator<Item = (A, B)>,
382	A: AsRef<[u8]> + Ord,
383	B: AsRef<[u8]>,
384{
385	L::trie_root(input)
386}
387
388/// Determine a child trie root given a hash DB and delta values. H is the default hasher,
389/// but a generic implementation may ignore this type parameter and use other hashers.
390pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB, RD, V>(
391	keyspace: &[u8],
392	db: &mut DB,
393	root_data: RD,
394	delta: I,
395	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
396	cache: Option<&mut dyn TrieCache<L::Codec>>,
397) -> Result<<L::Hash as Hasher>::Out, Box<TrieError<L>>>
398where
399	I: IntoIterator<Item = (A, B)>,
400	A: Borrow<[u8]>,
401	B: Borrow<Option<V>>,
402	V: Borrow<[u8]>,
403	RD: AsRef<[u8]>,
404	DB: hash_db::HashDB<L::Hash, trie_db::DBValue>,
405{
406	let mut root = TrieHash::<L>::default();
407	// root is fetched from DB, not writable by runtime, so it's always valid.
408	root.as_mut().copy_from_slice(root_data.as_ref());
409
410	let mut db = KeySpacedDBMut::new(db, keyspace);
411	delta_trie_root::<L, _, _, _, _, _>(&mut db, root, delta, recorder, cache)
412}
413
414/// Read a value from the child trie.
415pub fn read_child_trie_value<L: TrieConfiguration, DB>(
416	keyspace: &[u8],
417	db: &DB,
418	root: &TrieHash<L>,
419	key: &[u8],
420	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
421	cache: Option<&mut dyn TrieCache<L::Codec>>,
422) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
423where
424	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
425{
426	let db = KeySpacedDB::new(db, keyspace);
427	TrieDBBuilder::<L>::new(&db, &root)
428		.with_optional_recorder(recorder)
429		.with_optional_cache(cache)
430		.build()
431		.get(key)
432		.map(|x| x.map(|val| val.to_vec()))
433}
434
435/// Read a hash from the child trie.
436pub fn read_child_trie_hash<L: TrieConfiguration, DB>(
437	keyspace: &[u8],
438	db: &DB,
439	root: &TrieHash<L>,
440	key: &[u8],
441	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
442	cache: Option<&mut dyn TrieCache<L::Codec>>,
443) -> Result<Option<TrieHash<L>>, Box<TrieError<L>>>
444where
445	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
446{
447	let db = KeySpacedDB::new(db, keyspace);
448	TrieDBBuilder::<L>::new(&db, &root)
449		.with_optional_recorder(recorder)
450		.with_optional_cache(cache)
451		.build()
452		.get_hash(key)
453}
454
455/// Read the [`trie_db::MerkleValue`] of the node that is the closest descendant for
456/// the provided child key.
457pub fn read_child_trie_first_descendant_value<L: TrieConfiguration, DB>(
458	keyspace: &[u8],
459	db: &DB,
460	root: &TrieHash<L>,
461	key: &[u8],
462	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
463	cache: Option<&mut dyn TrieCache<L::Codec>>,
464) -> Result<Option<MerkleValue<TrieHash<L>>>, Box<TrieError<L>>>
465where
466	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
467{
468	let db = KeySpacedDB::new(db, keyspace);
469	TrieDBBuilder::<L>::new(&db, &root)
470		.with_optional_recorder(recorder)
471		.with_optional_cache(cache)
472		.build()
473		.lookup_first_descendant(key)
474}
475
476/// Read a value from the child trie with given query.
477pub fn read_child_trie_value_with<L, Q, DB>(
478	keyspace: &[u8],
479	db: &DB,
480	root_slice: &[u8],
481	key: &[u8],
482	query: Q,
483) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
484where
485	L: TrieConfiguration,
486	Q: Query<L::Hash, Item = DBValue>,
487	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
488{
489	let mut root = TrieHash::<L>::default();
490	// root is fetched from DB, not writable by runtime, so it's always valid.
491	root.as_mut().copy_from_slice(root_slice);
492
493	let db = KeySpacedDB::new(db, keyspace);
494	TrieDBBuilder::<L>::new(&db, &root)
495		.build()
496		.get_with(key, query)
497		.map(|x| x.map(|val| val.to_vec()))
498}
499
500/// `HashDB` implementation that append a encoded prefix (unique id bytes) in addition to the
501/// prefix of every key value.
502pub struct KeySpacedDB<'a, DB: ?Sized, H>(&'a DB, &'a [u8], PhantomData<H>);
503
504/// `HashDBMut` implementation that append a encoded prefix (unique id bytes) in addition to the
505/// prefix of every key value.
506///
507/// Mutable variant of `KeySpacedDB`, see [`KeySpacedDB`].
508pub struct KeySpacedDBMut<'a, DB: ?Sized, H>(&'a mut DB, &'a [u8], PhantomData<H>);
509
510/// Utility function used to merge some byte data (keyspace) and `prefix` data
511/// before calling key value database primitives.
512fn keyspace_as_prefix_alloc(ks: &[u8], prefix: Prefix) -> (Vec<u8>, Option<u8>) {
513	let mut result = vec![0; ks.len() + prefix.0.len()];
514	result[..ks.len()].copy_from_slice(ks);
515	result[ks.len()..].copy_from_slice(prefix.0);
516	(result, prefix.1)
517}
518
519impl<'a, DB: ?Sized, H> KeySpacedDB<'a, DB, H> {
520	/// instantiate new keyspaced db
521	#[inline]
522	pub fn new(db: &'a DB, ks: &'a [u8]) -> Self {
523		KeySpacedDB(db, ks, PhantomData)
524	}
525}
526
527impl<'a, DB: ?Sized, H> KeySpacedDBMut<'a, DB, H> {
528	/// instantiate new keyspaced db
529	pub fn new(db: &'a mut DB, ks: &'a [u8]) -> Self {
530		KeySpacedDBMut(db, ks, PhantomData)
531	}
532}
533
534impl<'a, DB, H, T> hash_db::HashDBRef<H, T> for KeySpacedDB<'a, DB, H>
535where
536	DB: hash_db::HashDBRef<H, T> + ?Sized,
537	H: Hasher,
538	T: From<&'static [u8]>,
539{
540	fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
541		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
542		self.0.get(key, (&derived_prefix.0, derived_prefix.1))
543	}
544
545	fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
546		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
547		self.0.contains(key, (&derived_prefix.0, derived_prefix.1))
548	}
549}
550
551impl<'a, DB, H, T> hash_db::HashDB<H, T> for KeySpacedDBMut<'a, DB, H>
552where
553	DB: hash_db::HashDB<H, T>,
554	H: Hasher,
555	T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
556{
557	fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
558		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
559		self.0.get(key, (&derived_prefix.0, derived_prefix.1))
560	}
561
562	fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
563		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
564		self.0.contains(key, (&derived_prefix.0, derived_prefix.1))
565	}
566
567	fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out {
568		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
569		self.0.insert((&derived_prefix.0, derived_prefix.1), value)
570	}
571
572	fn emplace(&mut self, key: H::Out, prefix: Prefix, value: T) {
573		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
574		self.0.emplace(key, (&derived_prefix.0, derived_prefix.1), value)
575	}
576
577	fn remove(&mut self, key: &H::Out, prefix: Prefix) {
578		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
579		self.0.remove(key, (&derived_prefix.0, derived_prefix.1))
580	}
581}
582
583impl<'a, DB, H, T> hash_db::AsHashDB<H, T> for KeySpacedDBMut<'a, DB, H>
584where
585	DB: hash_db::HashDB<H, T>,
586	H: Hasher,
587	T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
588{
589	fn as_hash_db(&self) -> &dyn hash_db::HashDB<H, T> {
590		self
591	}
592
593	fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn hash_db::HashDB<H, T> + 'b) {
594		&mut *self
595	}
596}
597
598/// Constants used into trie simplification codec.
599mod trie_constants {
600	const FIRST_PREFIX: u8 = 0b_00 << 6;
601	pub const LEAF_PREFIX_MASK: u8 = 0b_01 << 6;
602	pub const BRANCH_WITHOUT_MASK: u8 = 0b_10 << 6;
603	pub const BRANCH_WITH_MASK: u8 = 0b_11 << 6;
604	pub const EMPTY_TRIE: u8 = FIRST_PREFIX | (0b_00 << 4);
605	pub const ALT_HASHING_LEAF_PREFIX_MASK: u8 = FIRST_PREFIX | (0b_1 << 5);
606	pub const ALT_HASHING_BRANCH_WITH_MASK: u8 = FIRST_PREFIX | (0b_01 << 4);
607	pub const ESCAPE_COMPACT_HEADER: u8 = EMPTY_TRIE | 0b_00_01;
608}
609
610#[cfg(test)]
611mod tests {
612	use super::*;
613	use codec::{Compact, Decode, Encode};
614	use hash_db::{HashDB, Hasher};
615	use sp_core::Blake2Hasher;
616	use trie_db::{DBValue, NodeCodec as NodeCodecT, Trie, TrieMut};
617	use trie_standardmap::{Alphabet, StandardMap, ValueMode};
618
619	type LayoutV0 = super::LayoutV0<Blake2Hasher>;
620	type LayoutV1 = super::LayoutV1<Blake2Hasher>;
621
622	type MemoryDBMeta<H> = memory_db::MemoryDB<H, memory_db::HashKey<H>, trie_db::DBValue>;
623
624	pub fn create_trie<L: TrieLayout>(
625		data: &[(&[u8], &[u8])],
626	) -> (MemoryDB<L::Hash>, trie_db::TrieHash<L>) {
627		let mut db = MemoryDB::default();
628		let mut root = Default::default();
629
630		{
631			let mut trie = trie_db::TrieDBMutBuilder::<L>::new(&mut db, &mut root).build();
632			for (k, v) in data {
633				trie.insert(k, v).expect("Inserts data");
634			}
635		}
636
637		let mut recorder = Recorder::<L>::new();
638		{
639			let trie = trie_db::TrieDBBuilder::<L>::new(&mut db, &mut root)
640				.with_recorder(&mut recorder)
641				.build();
642			for (k, _v) in data {
643				trie.get(k).unwrap();
644			}
645		}
646
647		(db, root)
648	}
649
650	pub fn create_storage_proof<L: TrieLayout>(
651		data: &[(&[u8], &[u8])],
652	) -> (RawStorageProof, trie_db::TrieHash<L>) {
653		let (db, root) = create_trie::<L>(data);
654
655		let mut recorder = Recorder::<L>::new();
656		{
657			let trie = trie_db::TrieDBBuilder::<L>::new(&db, &root)
658				.with_recorder(&mut recorder)
659				.build();
660			for (k, _v) in data {
661				trie.get(k).unwrap();
662			}
663		}
664
665		(recorder.drain().into_iter().map(|record| record.data).collect(), root)
666	}
667
668	fn hashed_null_node<T: TrieConfiguration>() -> TrieHash<T> {
669		<T::Codec as NodeCodecT>::hashed_null_node()
670	}
671
672	fn check_equivalent<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {
673		{
674			let closed_form = T::trie_root(input.clone());
675			let d = T::trie_root_unhashed(input.clone());
676			println!("Data: {:#x?}, {:#x?}", d, Blake2Hasher::hash(&d[..]));
677			let persistent = {
678				let mut memdb = MemoryDBMeta::default();
679				let mut root = Default::default();
680				let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
681				for (x, y) in input.iter().rev() {
682					t.insert(x, y).unwrap();
683				}
684				*t.root()
685			};
686			assert_eq!(closed_form, persistent);
687		}
688	}
689
690	fn check_iteration<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {
691		let mut memdb = MemoryDBMeta::default();
692		let mut root = Default::default();
693		{
694			let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
695			for (x, y) in input.clone() {
696				t.insert(x, y).unwrap();
697			}
698		}
699		{
700			let t = TrieDBBuilder::<T>::new(&memdb, &root).build();
701			assert_eq!(
702				input.iter().map(|(i, j)| (i.to_vec(), j.to_vec())).collect::<Vec<_>>(),
703				t.iter()
704					.unwrap()
705					.map(|x| x.map(|y| (y.0, y.1.to_vec())).unwrap())
706					.collect::<Vec<_>>()
707			);
708		}
709	}
710
711	fn check_input(input: &Vec<(&[u8], &[u8])>) {
712		check_equivalent::<LayoutV0>(input);
713		check_iteration::<LayoutV0>(input);
714		check_equivalent::<LayoutV1>(input);
715		check_iteration::<LayoutV1>(input);
716	}
717
718	#[test]
719	fn default_trie_root() {
720		let mut db = MemoryDB::default();
721		let mut root = TrieHash::<LayoutV1>::default();
722		let mut empty = TrieDBMutBuilder::<LayoutV1>::new(&mut db, &mut root).build();
723		empty.commit();
724		let root1 = empty.root().as_ref().to_vec();
725		let root2: Vec<u8> = LayoutV1::trie_root::<_, Vec<u8>, Vec<u8>>(std::iter::empty())
726			.as_ref()
727			.iter()
728			.cloned()
729			.collect();
730
731		assert_eq!(root1, root2);
732	}
733
734	#[test]
735	fn empty_is_equivalent() {
736		let input: Vec<(&[u8], &[u8])> = vec![];
737		check_input(&input);
738	}
739
740	#[test]
741	fn leaf_is_equivalent() {
742		let input: Vec<(&[u8], &[u8])> = vec![(&[0xaa][..], &[0xbb][..])];
743		check_input(&input);
744	}
745
746	#[test]
747	fn branch_is_equivalent() {
748		let input: Vec<(&[u8], &[u8])> =
749			vec![(&[0xaa][..], &[0x10][..]), (&[0xba][..], &[0x11][..])];
750		check_input(&input);
751	}
752
753	#[test]
754	fn extension_and_branch_is_equivalent() {
755		let input: Vec<(&[u8], &[u8])> =
756			vec![(&[0xaa][..], &[0x10][..]), (&[0xab][..], &[0x11][..])];
757		check_input(&input);
758	}
759
760	#[test]
761	fn standard_is_equivalent() {
762		let st = StandardMap {
763			alphabet: Alphabet::All,
764			min_key: 32,
765			journal_key: 0,
766			value_mode: ValueMode::Random,
767			count: 1000,
768		};
769		let mut d = st.make();
770		d.sort_by(|(a, _), (b, _)| a.cmp(b));
771		let dr = d.iter().map(|v| (&v.0[..], &v.1[..])).collect();
772		check_input(&dr);
773	}
774
775	#[test]
776	fn extension_and_branch_with_value_is_equivalent() {
777		let input: Vec<(&[u8], &[u8])> = vec![
778			(&[0xaa][..], &[0xa0][..]),
779			(&[0xaa, 0xaa][..], &[0xaa][..]),
780			(&[0xaa, 0xbb][..], &[0xab][..]),
781		];
782		check_input(&input);
783	}
784
785	#[test]
786	fn bigger_extension_and_branch_with_value_is_equivalent() {
787		let input: Vec<(&[u8], &[u8])> = vec![
788			(&[0xaa][..], &[0xa0][..]),
789			(&[0xaa, 0xaa][..], &[0xaa][..]),
790			(&[0xaa, 0xbb][..], &[0xab][..]),
791			(&[0xbb][..], &[0xb0][..]),
792			(&[0xbb, 0xbb][..], &[0xbb][..]),
793			(&[0xbb, 0xcc][..], &[0xbc][..]),
794		];
795		check_input(&input);
796	}
797
798	#[test]
799	fn single_long_leaf_is_equivalent() {
800		let input: Vec<(&[u8], &[u8])> = vec![
801			(
802				&[0xaa][..],
803				&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
804			),
805			(&[0xba][..], &[0x11][..]),
806		];
807		check_input(&input);
808	}
809
810	#[test]
811	fn two_long_leaves_is_equivalent() {
812		let input: Vec<(&[u8], &[u8])> = vec![
813			(
814				&[0xaa][..],
815				&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
816			),
817			(
818				&[0xba][..],
819				&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
820			),
821		];
822		check_input(&input);
823	}
824
825	fn populate_trie<'db, T: TrieConfiguration>(
826		db: &'db mut dyn HashDB<T::Hash, DBValue>,
827		root: &'db mut TrieHash<T>,
828		v: &[(Vec<u8>, Vec<u8>)],
829	) -> TrieDBMut<'db, T> {
830		let mut t = TrieDBMutBuilder::<T>::new(db, root).build();
831		for i in 0..v.len() {
832			let key: &[u8] = &v[i].0;
833			let val: &[u8] = &v[i].1;
834			t.insert(key, val).unwrap();
835		}
836		t
837	}
838
839	fn unpopulate_trie<T: TrieConfiguration>(t: &mut TrieDBMut<'_, T>, v: &[(Vec<u8>, Vec<u8>)]) {
840		for i in v {
841			let key: &[u8] = &i.0;
842			t.remove(key).unwrap();
843		}
844	}
845
846	#[test]
847	fn random_should_work() {
848		random_should_work_inner::<LayoutV1>();
849		random_should_work_inner::<LayoutV0>();
850	}
851	fn random_should_work_inner<L: TrieConfiguration>() {
852		let mut seed = <Blake2Hasher as Hasher>::Out::zero();
853		for test_i in 0..10_000 {
854			if test_i % 50 == 0 {
855				println!("{:?} of 10000 stress tests done", test_i);
856			}
857			let x = StandardMap {
858				alphabet: Alphabet::Custom(b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_".to_vec()),
859				min_key: 5,
860				journal_key: 0,
861				value_mode: ValueMode::Index,
862				count: 100,
863			}
864			.make_with(seed.as_fixed_bytes_mut());
865
866			let real = L::trie_root(x.clone());
867			let mut memdb = MemoryDB::default();
868			let mut root = Default::default();
869
870			let mut memtrie = populate_trie::<L>(&mut memdb, &mut root, &x);
871
872			memtrie.commit();
873			if *memtrie.root() != real {
874				println!("TRIE MISMATCH");
875				println!();
876				println!("{:?} vs {:?}", memtrie.root(), real);
877				for i in &x {
878					println!("{:#x?} -> {:#x?}", i.0, i.1);
879				}
880			}
881			assert_eq!(*memtrie.root(), real);
882			unpopulate_trie::<L>(&mut memtrie, &x);
883			memtrie.commit();
884			let hashed_null_node = hashed_null_node::<L>();
885			if *memtrie.root() != hashed_null_node {
886				println!("- TRIE MISMATCH");
887				println!();
888				println!("{:?} vs {:?}", memtrie.root(), hashed_null_node);
889				for i in &x {
890					println!("{:#x?} -> {:#x?}", i.0, i.1);
891				}
892			}
893			assert_eq!(*memtrie.root(), hashed_null_node);
894		}
895	}
896
897	fn to_compact(n: u8) -> u8 {
898		Compact(n).encode()[0]
899	}
900
901	#[test]
902	fn codec_trie_empty() {
903		let input: Vec<(&[u8], &[u8])> = vec![];
904		let trie = LayoutV1::trie_root_unhashed(input);
905		println!("trie: {:#x?}", trie);
906		assert_eq!(trie, vec![0x0]);
907	}
908
909	#[test]
910	fn codec_trie_single_tuple() {
911		let input = vec![(vec![0xaa], vec![0xbb])];
912		let trie = LayoutV1::trie_root_unhashed(input);
913		println!("trie: {:#x?}", trie);
914		assert_eq!(
915			trie,
916			vec![
917				0x42,          // leaf 0x40 (2^6) with (+) key of 2 nibbles (0x02)
918				0xaa,          // key data
919				to_compact(1), // length of value in bytes as Compact
920				0xbb           // value data
921			]
922		);
923	}
924
925	#[test]
926	fn codec_trie_two_tuples_disjoint_keys() {
927		let input = vec![(&[0x48, 0x19], &[0xfe]), (&[0x13, 0x14], &[0xff])];
928		let trie = LayoutV1::trie_root_unhashed(input);
929		println!("trie: {:#x?}", trie);
930		let mut ex = Vec::<u8>::new();
931		ex.push(0x80); // branch, no value (0b_10..) no nibble
932		ex.push(0x12); // slots 1 & 4 are taken from 0-7
933		ex.push(0x00); // no slots from 8-15
934		ex.push(to_compact(0x05)); // first slot: LEAF, 5 bytes long.
935		ex.push(0x43); // leaf 0x40 with 3 nibbles
936		ex.push(0x03); // first nibble
937		ex.push(0x14); // second & third nibble
938		ex.push(to_compact(0x01)); // 1 byte data
939		ex.push(0xff); // value data
940		ex.push(to_compact(0x05)); // second slot: LEAF, 5 bytes long.
941		ex.push(0x43); // leaf with 3 nibbles
942		ex.push(0x08); // first nibble
943		ex.push(0x19); // second & third nibble
944		ex.push(to_compact(0x01)); // 1 byte data
945		ex.push(0xfe); // value data
946
947		assert_eq!(trie, ex);
948	}
949
950	#[test]
951	fn iterator_works() {
952		iterator_works_inner::<LayoutV1>();
953		iterator_works_inner::<LayoutV0>();
954	}
955	fn iterator_works_inner<Layout: TrieConfiguration>() {
956		let pairs = vec![
957			(
958				array_bytes::hex2bytes_unchecked("0103000000000000000464"),
959				array_bytes::hex2bytes_unchecked("0400000000"),
960			),
961			(
962				array_bytes::hex2bytes_unchecked("0103000000000000000469"),
963				array_bytes::hex2bytes_unchecked("0401000000"),
964			),
965		];
966
967		let mut mdb = MemoryDB::default();
968		let mut root = Default::default();
969		let _ = populate_trie::<Layout>(&mut mdb, &mut root, &pairs);
970
971		let trie = TrieDBBuilder::<Layout>::new(&mdb, &root).build();
972
973		let iter = trie.iter().unwrap();
974		let mut iter_pairs = Vec::new();
975		for pair in iter {
976			let (key, value) = pair.unwrap();
977			iter_pairs.push((key, value));
978		}
979
980		assert_eq!(pairs, iter_pairs);
981	}
982
983	#[test]
984	fn proof_non_inclusion_works() {
985		let pairs = vec![
986			(array_bytes::hex2bytes_unchecked("0102"), array_bytes::hex2bytes_unchecked("01")),
987			(array_bytes::hex2bytes_unchecked("0203"), array_bytes::hex2bytes_unchecked("0405")),
988		];
989
990		let mut memdb = MemoryDB::default();
991		let mut root = Default::default();
992		populate_trie::<LayoutV1>(&mut memdb, &mut root, &pairs);
993
994		let non_included_key: Vec<u8> = array_bytes::hex2bytes_unchecked("0909");
995		let proof =
996			generate_trie_proof::<LayoutV1, _, _, _>(&memdb, root, &[non_included_key.clone()])
997				.unwrap();
998
999		// Verifying that the K was not included into the trie should work.
1000		assert!(verify_trie_proof::<LayoutV1, _, _, Vec<u8>>(
1001			&root,
1002			&proof,
1003			&[(non_included_key.clone(), None)],
1004		)
1005		.is_ok());
1006
1007		// Verifying that the K was included into the trie should fail.
1008		assert!(verify_trie_proof::<LayoutV1, _, _, Vec<u8>>(
1009			&root,
1010			&proof,
1011			&[(non_included_key, Some(array_bytes::hex2bytes_unchecked("1010")))],
1012		)
1013		.is_err());
1014	}
1015
1016	#[test]
1017	fn proof_inclusion_works() {
1018		let pairs = vec![
1019			(array_bytes::hex2bytes_unchecked("0102"), array_bytes::hex2bytes_unchecked("01")),
1020			(array_bytes::hex2bytes_unchecked("0203"), array_bytes::hex2bytes_unchecked("0405")),
1021		];
1022
1023		let mut memdb = MemoryDB::default();
1024		let mut root = Default::default();
1025		populate_trie::<LayoutV1>(&mut memdb, &mut root, &pairs);
1026
1027		let proof =
1028			generate_trie_proof::<LayoutV1, _, _, _>(&memdb, root, &[pairs[0].0.clone()]).unwrap();
1029
1030		// Check that a K, V included into the proof are verified.
1031		assert!(verify_trie_proof::<LayoutV1, _, _, _>(
1032			&root,
1033			&proof,
1034			&[(pairs[0].0.clone(), Some(pairs[0].1.clone()))]
1035		)
1036		.is_ok());
1037
1038		// Absence of the V is not verified with the proof that has K, V included.
1039		assert!(verify_trie_proof::<LayoutV1, _, _, Vec<u8>>(
1040			&root,
1041			&proof,
1042			&[(pairs[0].0.clone(), None)]
1043		)
1044		.is_err());
1045
1046		// K not included into the trie is not verified.
1047		assert!(verify_trie_proof::<LayoutV1, _, _, _>(
1048			&root,
1049			&proof,
1050			&[(array_bytes::hex2bytes_unchecked("4242"), Some(pairs[0].1.clone()))]
1051		)
1052		.is_err());
1053
1054		// K included into the trie but not included into the proof is not verified.
1055		assert!(verify_trie_proof::<LayoutV1, _, _, _>(
1056			&root,
1057			&proof,
1058			&[(pairs[1].0.clone(), Some(pairs[1].1.clone()))]
1059		)
1060		.is_err());
1061	}
1062
1063	#[test]
1064	fn generate_storage_root_with_proof_works_independently_from_the_delta_order() {
1065		let proof = StorageProof::decode(&mut &include_bytes!("../test-res/proof")[..]).unwrap();
1066		let storage_root =
1067			sp_core::H256::decode(&mut &include_bytes!("../test-res/storage_root")[..]).unwrap();
1068		// Delta order that is "invalid" so that it would require a different proof.
1069		let invalid_delta = Vec::<(Vec<u8>, Option<Vec<u8>>)>::decode(
1070			&mut &include_bytes!("../test-res/invalid-delta-order")[..],
1071		)
1072		.unwrap();
1073		// Delta order that is "valid"
1074		let valid_delta = Vec::<(Vec<u8>, Option<Vec<u8>>)>::decode(
1075			&mut &include_bytes!("../test-res/valid-delta-order")[..],
1076		)
1077		.unwrap();
1078
1079		let proof_db = proof.into_memory_db::<Blake2Hasher>();
1080		let first_storage_root = delta_trie_root::<LayoutV0, _, _, _, _, _>(
1081			&mut proof_db.clone(),
1082			storage_root,
1083			valid_delta,
1084			None,
1085			None,
1086		)
1087		.unwrap();
1088		let second_storage_root = delta_trie_root::<LayoutV0, _, _, _, _, _>(
1089			&mut proof_db.clone(),
1090			storage_root,
1091			invalid_delta,
1092			None,
1093			None,
1094		)
1095		.unwrap();
1096
1097		assert_eq!(first_storage_root, second_storage_root);
1098	}
1099
1100	#[test]
1101	fn big_key() {
1102		let check = |keysize: usize| {
1103			let mut memdb = PrefixedMemoryDB::<Blake2Hasher>::default();
1104			let mut root = Default::default();
1105			let mut t = TrieDBMutBuilder::<LayoutV1>::new(&mut memdb, &mut root).build();
1106			t.insert(&vec![0x01u8; keysize][..], &[0x01u8, 0x23]).unwrap();
1107			std::mem::drop(t);
1108			let t = TrieDBBuilder::<LayoutV1>::new(&memdb, &root).build();
1109			assert_eq!(t.get(&vec![0x01u8; keysize][..]).unwrap(), Some(vec![0x01u8, 0x23]));
1110		};
1111		check(u16::MAX as usize / 2); // old limit
1112		check(u16::MAX as usize / 2 + 1); // value over old limit still works
1113	}
1114
1115	#[test]
1116	fn node_with_no_children_fail_decoding() {
1117		let branch = NodeCodec::<Blake2Hasher>::branch_node_nibbled(
1118			b"some_partial".iter().copied(),
1119			24,
1120			vec![None; 16].into_iter(),
1121			Some(trie_db::node::Value::Inline(b"value"[..].into())),
1122		);
1123		assert!(NodeCodec::<Blake2Hasher>::decode(branch.as_slice()).is_err());
1124	}
1125}