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