Skip to main content

trie_db/
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#![cfg_attr(not(feature = "std"), no_std)]
15
16//! Trie interface and implementation.
17
18#[cfg(not(feature = "std"))]
19extern crate alloc;
20
21#[cfg(feature = "std")]
22mod rstd {
23	pub use std::{
24		borrow, boxed, cmp,
25		collections::{BTreeMap, BTreeSet, VecDeque},
26		convert,
27		error::Error,
28		fmt, hash, iter, marker, mem, ops, result, sync, vec,
29	};
30}
31
32#[cfg(not(feature = "std"))]
33mod rstd {
34	pub use alloc::{
35		borrow, boxed,
36		collections::{btree_map::BTreeMap, btree_set::BTreeSet, VecDeque},
37		rc, sync, vec,
38	};
39	pub use core::{cmp, convert, fmt, hash, iter, marker, mem, ops, result};
40	pub trait Error {}
41	impl<T> Error for T {}
42}
43
44#[cfg(feature = "std")]
45use self::rstd::{fmt, Error};
46
47use self::rstd::{boxed::Box, vec::Vec};
48use hash_db::MaybeDebug;
49pub use iterator::TrieDBNodeDoubleEndedIterator;
50use node::NodeOwned;
51
52pub mod node;
53pub mod proof;
54pub mod recorder;
55pub mod sectriedb;
56pub mod sectriedbmut;
57pub mod triedb;
58pub mod triedbmut;
59
60mod fatdb;
61mod fatdbmut;
62mod iter_build;
63mod iterator;
64mod lookup;
65mod nibble;
66mod node_codec;
67mod trie_codec;
68
69pub use self::{
70	fatdb::{FatDB, FatDBIterator},
71	fatdbmut::FatDBMut,
72	lookup::Lookup,
73	nibble::{nibble_ops, NibbleSlice, NibbleVec},
74	recorder::Recorder,
75	sectriedb::SecTrieDB,
76	sectriedbmut::SecTrieDBMut,
77	triedb::{TrieDB, TrieDBBuilder, TrieDBIterator, TrieDBKeyIterator},
78	triedbmut::{ChildReference, TrieDBMut, TrieDBMutBuilder, Value},
79};
80pub use crate::{
81	iter_build::{trie_visit, ProcessEncodedNode, TrieBuilder, TrieRoot, TrieRootUnhashed},
82	iterator::{TrieDBNodeIterator, TrieDBRawIterator},
83	node_codec::{NodeCodec, Partial},
84	trie_codec::{
85		decode_compact, decode_compact_from_iter, encode_compact, encode_compact_skip_duplicates,
86		SeenHashes,
87	},
88};
89pub use hash_db::{HashDB, HashDBRef, Hasher};
90
91#[cfg(feature = "std")]
92pub use crate::iter_build::TrieRootPrint;
93
94/// Database value
95pub type DBValue = Vec<u8>;
96
97/// Trie Errors.
98///
99/// These borrow the data within them to avoid excessive copying on every
100/// trie operation.
101#[derive(PartialEq, Eq, Clone, Debug)]
102pub enum TrieError<T, E> {
103	/// Attempted to create a trie with a state root not in the DB.
104	InvalidStateRoot(T),
105	/// Trie item not found in the database,
106	IncompleteDatabase(T),
107	/// A value was found in the trie with a nibble key that was not byte-aligned.
108	/// The first parameter is the byte-aligned part of the prefix and the second parameter is the
109	/// remaining nibble.
110	ValueAtIncompleteKey(Vec<u8>, u8),
111	/// Corrupt Trie item.
112	DecoderError(T, E),
113	/// Hash is not value.
114	InvalidHash(T, Vec<u8>),
115}
116
117#[cfg(feature = "std")]
118impl<T, E> fmt::Display for TrieError<T, E>
119where
120	T: MaybeDebug,
121	E: MaybeDebug,
122{
123	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124		match *self {
125			TrieError::InvalidStateRoot(ref root) => write!(f, "Invalid state root: {:?}", root),
126			TrieError::IncompleteDatabase(ref missing) =>
127				write!(f, "Database missing expected key: {:?}", missing),
128			TrieError::ValueAtIncompleteKey(ref bytes, ref extra) =>
129				write!(f, "Value found in trie at incomplete key {:?} + {:?}", bytes, extra),
130			TrieError::DecoderError(ref hash, ref decoder_err) => {
131				write!(f, "Decoding failed for hash {:?}; err: {:?}", hash, decoder_err)
132			},
133			TrieError::InvalidHash(ref hash, ref data) => write!(
134				f,
135				"Encoded node {:?} contains invalid hash reference with length: {}",
136				hash,
137				data.len()
138			),
139		}
140	}
141}
142
143#[cfg(feature = "std")]
144impl<T, E> Error for TrieError<T, E>
145where
146	T: fmt::Debug,
147	E: Error,
148{
149}
150
151/// Trie result type.
152/// Boxed to avoid copying around extra space for the `Hasher`s `Out` on successful queries.
153pub type Result<T, H, E> = crate::rstd::result::Result<T, Box<TrieError<H, E>>>;
154
155/// Trie-Item type used for iterators over trie data.
156pub type TrieItem<U, E> = Result<(Vec<u8>, DBValue), U, E>;
157
158/// Trie-Item type used for iterators over trie key only.
159pub type TrieKeyItem<U, E> = Result<Vec<u8>, U, E>;
160
161/// Description of what kind of query will be made to the trie.
162pub trait Query<H: Hasher> {
163	/// Output item.
164	type Item;
165
166	/// Decode a byte-slice into the desired item.
167	fn decode(self, data: &[u8]) -> Self::Item;
168}
169
170/// Used to report the trie access to the [`TrieRecorder`].
171///
172/// As the trie can use a [`TrieCache`], there are multiple kinds of accesses.
173/// If a cache is used, [`Self::Key`] and [`Self::NodeOwned`] are possible
174/// values. Otherwise only [`Self::EncodedNode`] is a possible value.
175#[cfg_attr(feature = "std", derive(Debug))]
176pub enum TrieAccess<'a, H> {
177	/// The given [`NodeOwned`] was accessed using its `hash`.
178	NodeOwned { hash: H, node_owned: &'a NodeOwned<H> },
179	/// The given `encoded_node` was accessed using its `hash`.
180	EncodedNode { hash: H, encoded_node: rstd::borrow::Cow<'a, [u8]> },
181	/// The given `value` was accessed using its `hash`.
182	///
183	/// The given `full_key` is the key to access this value in the trie.
184	///
185	/// Should map to [`RecordedForKey::Value`] when checking the recorder.
186	Value { hash: H, value: rstd::borrow::Cow<'a, [u8]>, full_key: &'a [u8] },
187	/// A value was accessed that is stored inline a node.
188	///
189	/// As the value is stored inline there is no need to separately record the value as it is part
190	/// of a node. The given `full_key` is the key to access this value in the trie.
191	///
192	/// Should map to [`RecordedForKey::Value`] when checking the recorder.
193	InlineValue { full_key: &'a [u8] },
194	/// The hash of the value for the given `full_key` was accessed.
195	///
196	/// Should map to [`RecordedForKey::Hash`] when checking the recorder.
197	Hash { full_key: &'a [u8] },
198	/// The value/hash for `full_key` was accessed, but it couldn't be found in the trie.
199	///
200	/// Should map to [`RecordedForKey::Value`] when checking the recorder.
201	NonExisting { full_key: &'a [u8] },
202}
203
204/// Result of [`TrieRecorder::trie_nodes_recorded_for_key`].
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
206pub enum RecordedForKey {
207	/// We recorded all trie nodes up to the value for a storage key.
208	///
209	/// This should be returned when the recorder has seen the following [`TrieAccess`]:
210	///
211	/// - [`TrieAccess::Value`]: If we see this [`TrieAccess`], it means we have recorded all the
212	///   trie nodes up to the value.
213	/// - [`TrieAccess::NonExisting`]: If we see this [`TrieAccess`], it means we have recorded all
214	///   the necessary  trie nodes to prove that the value doesn't exist in the trie.
215	Value,
216	/// We recorded all trie nodes up to the value hash for a storage key.
217	///
218	/// If we have a [`RecordedForKey::Value`], it means that we also have the hash of this value.
219	/// This also means that if we first have recorded the hash of a value and then also record the
220	/// value, the access should be upgraded to [`RecordedForKey::Value`].
221	///
222	/// This should be returned when the recorder has seen the following [`TrieAccess`]:
223	///
224	/// - [`TrieAccess::Hash`]: If we see this [`TrieAccess`], it means we have recorded all trie
225	///   nodes to have the hash of the value.
226	Hash,
227	/// We haven't recorded any trie nodes yet for a storage key.
228	///
229	/// This means we have not seen any [`TrieAccess`] referencing the searched key.
230	None,
231}
232
233impl RecordedForKey {
234	/// Is `self` equal to [`Self::None`]?
235	pub fn is_none(&self) -> bool {
236		matches!(self, Self::None)
237	}
238}
239
240/// A trie recorder that can be used to record all kind of [`TrieAccess`]'s.
241///
242/// To build a trie proof a recorder is required that records all trie accesses. These recorded trie
243/// accesses can then be used to create the proof.
244pub trait TrieRecorder<H> {
245	/// Record the given [`TrieAccess`].
246	///
247	/// Depending on the [`TrieAccess`] a call of [`Self::trie_nodes_recorded_for_key`] afterwards
248	/// must return the correct recorded state.
249	fn record<'a>(&mut self, access: TrieAccess<'a, H>);
250
251	/// Check if we have recorded any trie nodes for the given `key`.
252	///
253	/// Returns [`RecordedForKey`] to express the state of the recorded trie nodes.
254	fn trie_nodes_recorded_for_key(&self, key: &[u8]) -> RecordedForKey;
255}
256
257impl<F, T, H: Hasher> Query<H> for F
258where
259	F: for<'a> FnOnce(&'a [u8]) -> T,
260{
261	type Item = T;
262	fn decode(self, value: &[u8]) -> T {
263		(self)(value)
264	}
265}
266
267/// A key-value datastore implemented as a database-backed modified Merkle tree.
268pub trait Trie<L: TrieLayout> {
269	/// Return the root of the trie.
270	fn root(&self) -> &TrieHash<L>;
271
272	/// Is the trie empty?
273	fn is_empty(&self) -> bool {
274		*self.root() == L::Codec::hashed_null_node()
275	}
276
277	/// Does the trie contain a given key?
278	fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
279		self.get(key).map(|x| x.is_some())
280	}
281
282	/// Returns the hash of the value for `key`.
283	fn get_hash(&self, key: &[u8]) -> Result<Option<TrieHash<L>>, TrieHash<L>, CError<L>>;
284
285	/// What is the value of the given key in this trie?
286	fn get(&self, key: &[u8]) -> Result<Option<DBValue>, TrieHash<L>, CError<L>> {
287		self.get_with(key, |v: &[u8]| v.to_vec())
288	}
289
290	/// Search for the key with the given query parameter. See the docs of the `Query`
291	/// trait for more details.
292	fn get_with<Q: Query<L::Hash>>(
293		&self,
294		key: &[u8],
295		query: Q,
296	) -> Result<Option<Q::Item>, TrieHash<L>, CError<L>>;
297
298	/// Look up the [`MerkleValue`] of the node that is the closest descendant for the provided
299	/// key.
300	///
301	/// When the provided key leads to a node, then the merkle value of that node
302	/// is returned. However, if the key does not lead to a node, then the merkle value
303	/// of the closest descendant is returned. `None` if no such descendant exists.
304	fn lookup_first_descendant(
305		&self,
306		key: &[u8],
307	) -> Result<Option<MerkleValue<TrieHash<L>>>, TrieHash<L>, CError<L>>;
308
309	/// Returns a depth-first iterator over the elements of trie.
310	fn iter<'a>(
311		&'a self,
312	) -> Result<
313		Box<dyn TrieIterator<L, Item = TrieItem<TrieHash<L>, CError<L>>> + 'a>,
314		TrieHash<L>,
315		CError<L>,
316	>;
317
318	/// Returns a depth-first iterator over the keys of elemets of trie.
319	fn key_iter<'a>(
320		&'a self,
321	) -> Result<
322		Box<dyn TrieIterator<L, Item = TrieKeyItem<TrieHash<L>, CError<L>>> + 'a>,
323		TrieHash<L>,
324		CError<L>,
325	>;
326}
327
328/// A key-value datastore implemented as a database-backed modified Merkle tree.
329pub trait TrieMut<L: TrieLayout> {
330	/// Return the root of the trie.
331	fn root(&mut self) -> &TrieHash<L>;
332
333	/// Is the trie empty?
334	fn is_empty(&self) -> bool;
335
336	/// Does the trie contain a given key?
337	fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
338		self.get(key).map(|x| x.is_some())
339	}
340
341	/// What is the value of the given key in this trie?
342	fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Result<Option<DBValue>, TrieHash<L>, CError<L>>
343	where
344		'a: 'key;
345
346	/// Insert a `key`/`value` pair into the trie. An empty value is equivalent to removing
347	/// `key` from the trie. Returns the old value associated with this key, if it existed.
348	fn insert(
349		&mut self,
350		key: &[u8],
351		value: &[u8],
352	) -> Result<Option<Value<L>>, TrieHash<L>, CError<L>>;
353
354	/// Remove a `key` from the trie. Equivalent to making it equal to the empty
355	/// value. Returns the old value associated with this key, if it existed.
356	fn remove(&mut self, key: &[u8]) -> Result<Option<Value<L>>, TrieHash<L>, CError<L>>;
357}
358
359/// A trie iterator that also supports random access (`seek()`).
360pub trait TrieIterator<L: TrieLayout>: Iterator {
361	/// Position the iterator on the first element with key >= `key`
362	fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>>;
363}
364
365/// Extending the `TrieIterator` trait with `DoubleEndedIterator` trait.
366pub trait TrieDoubleEndedIterator<L: TrieLayout>: TrieIterator<L> + DoubleEndedIterator {}
367
368/// Trie types
369#[derive(PartialEq, Clone)]
370#[cfg_attr(feature = "std", derive(Debug))]
371pub enum TrieSpec {
372	/// Generic trie.
373	Generic,
374	/// Secure trie.
375	Secure,
376	///	Secure trie with fat database.
377	Fat,
378}
379
380impl Default for TrieSpec {
381	fn default() -> TrieSpec {
382		TrieSpec::Secure
383	}
384}
385
386/// Trie factory.
387#[derive(Default, Clone)]
388pub struct TrieFactory {
389	spec: TrieSpec,
390}
391
392/// All different kinds of tries.
393/// This is used to prevent a heap allocation for every created trie.
394pub enum TrieKinds<'db, 'cache, L: TrieLayout> {
395	/// A generic trie db.
396	Generic(TrieDB<'db, 'cache, L>),
397	/// A secure trie db.
398	Secure(SecTrieDB<'db, 'cache, L>),
399	/// A fat trie db.
400	Fat(FatDB<'db, 'cache, L>),
401}
402
403// wrapper macro for making the match easier to deal with.
404macro_rules! wrapper {
405	($me: ident, $f_name: ident, $($param: ident),*) => {
406		match *$me {
407			TrieKinds::Generic(ref t) => t.$f_name($($param),*),
408			TrieKinds::Secure(ref t) => t.$f_name($($param),*),
409			TrieKinds::Fat(ref t) => t.$f_name($($param),*),
410		}
411	}
412}
413
414impl<'db, 'cache, L: TrieLayout> Trie<L> for TrieKinds<'db, 'cache, L> {
415	fn root(&self) -> &TrieHash<L> {
416		wrapper!(self, root,)
417	}
418
419	fn is_empty(&self) -> bool {
420		wrapper!(self, is_empty,)
421	}
422
423	fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
424		wrapper!(self, contains, key)
425	}
426
427	fn get_hash(&self, key: &[u8]) -> Result<Option<TrieHash<L>>, TrieHash<L>, CError<L>> {
428		wrapper!(self, get_hash, key)
429	}
430
431	fn get_with<Q: Query<L::Hash>>(
432		&self,
433		key: &[u8],
434		query: Q,
435	) -> Result<Option<Q::Item>, TrieHash<L>, CError<L>> {
436		wrapper!(self, get_with, key, query)
437	}
438
439	fn lookup_first_descendant(
440		&self,
441		key: &[u8],
442	) -> Result<Option<MerkleValue<TrieHash<L>>>, TrieHash<L>, CError<L>> {
443		wrapper!(self, lookup_first_descendant, key)
444	}
445
446	fn iter<'a>(
447		&'a self,
448	) -> Result<
449		Box<dyn TrieIterator<L, Item = TrieItem<TrieHash<L>, CError<L>>> + 'a>,
450		TrieHash<L>,
451		CError<L>,
452	> {
453		wrapper!(self, iter,)
454	}
455
456	fn key_iter<'a>(
457		&'a self,
458	) -> Result<
459		Box<dyn TrieIterator<L, Item = TrieKeyItem<TrieHash<L>, CError<L>>> + 'a>,
460		TrieHash<L>,
461		CError<L>,
462	> {
463		wrapper!(self, key_iter,)
464	}
465}
466
467impl TrieFactory {
468	/// Creates new factory.
469	pub fn new(spec: TrieSpec) -> Self {
470		TrieFactory { spec }
471	}
472
473	/// Create new immutable instance of Trie.
474	pub fn readonly<'db, 'cache, L: TrieLayout>(
475		&self,
476		db: &'db dyn HashDBRef<L::Hash, DBValue>,
477		root: &'db TrieHash<L>,
478	) -> TrieKinds<'db, 'cache, L> {
479		match self.spec {
480			TrieSpec::Generic => TrieKinds::Generic(TrieDBBuilder::new(db, root).build()),
481			TrieSpec::Secure => TrieKinds::Secure(SecTrieDB::new(db, root)),
482			TrieSpec::Fat => TrieKinds::Fat(FatDB::new(db, root)),
483		}
484	}
485
486	/// Create new mutable instance of Trie.
487	pub fn create<'db, L: TrieLayout + 'db>(
488		&self,
489		db: &'db mut dyn HashDB<L::Hash, DBValue>,
490		root: &'db mut TrieHash<L>,
491	) -> Box<dyn TrieMut<L> + 'db> {
492		match self.spec {
493			TrieSpec::Generic => Box::new(TrieDBMutBuilder::<L>::new(db, root).build()),
494			TrieSpec::Secure => Box::new(SecTrieDBMut::<L>::new(db, root)),
495			TrieSpec::Fat => Box::new(FatDBMut::<L>::new(db, root)),
496		}
497	}
498
499	/// Create new mutable instance of trie and check for errors.
500	pub fn from_existing<'db, L: TrieLayout + 'db>(
501		&self,
502		db: &'db mut dyn HashDB<L::Hash, DBValue>,
503		root: &'db mut TrieHash<L>,
504	) -> Box<dyn TrieMut<L> + 'db> {
505		match self.spec {
506			TrieSpec::Generic => Box::new(TrieDBMutBuilder::<L>::from_existing(db, root).build()),
507			TrieSpec::Secure => Box::new(SecTrieDBMut::<L>::from_existing(db, root)),
508			TrieSpec::Fat => Box::new(FatDBMut::<L>::from_existing(db, root)),
509		}
510	}
511
512	/// Returns true iff the trie DB is a fat DB (allows enumeration of keys).
513	pub fn is_fat(&self) -> bool {
514		self.spec == TrieSpec::Fat
515	}
516}
517
518/// Trait with definition of trie layout.
519/// Contains all associated trait needed for
520/// a trie definition or implementation.
521pub trait TrieLayout {
522	/// If true, the trie will use extension nodes and
523	/// no partial in branch, if false the trie will only
524	/// use branch and node with partials in both.
525	const USE_EXTENSION: bool;
526	/// If true, the trie will allow empty values into `TrieDBMut`
527	const ALLOW_EMPTY: bool = false;
528	/// Threshold above which an external node should be
529	/// use to store a node value.
530	const MAX_INLINE_VALUE: Option<u32>;
531
532	/// Hasher to use for this trie.
533	type Hash: Hasher;
534	/// Codec to use (needs to match hasher and nibble ops).
535	type Codec: NodeCodec<HashOut = <Self::Hash as Hasher>::Out>;
536}
537
538/// This trait associates a trie definition with preferred methods.
539/// It also contains own default implementations and can be
540/// used to allow switching implementation.
541pub trait TrieConfiguration: Sized + TrieLayout {
542	/// Operation to build a trie db from its ordered iterator over its key/values.
543	fn trie_build<DB, I, A, B>(db: &mut DB, input: I) -> <Self::Hash as Hasher>::Out
544	where
545		DB: HashDB<Self::Hash, DBValue>,
546		I: IntoIterator<Item = (A, B)>,
547		A: AsRef<[u8]> + Ord,
548		B: AsRef<[u8]>,
549	{
550		let mut cb = TrieBuilder::<Self, DB>::new(db);
551		trie_visit::<Self, _, _, _, _>(input.into_iter(), &mut cb);
552		cb.root.unwrap_or_default()
553	}
554	/// Determines a trie root given its ordered contents, closed form.
555	fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out
556	where
557		I: IntoIterator<Item = (A, B)>,
558		A: AsRef<[u8]> + Ord,
559		B: AsRef<[u8]>,
560	{
561		let mut cb = TrieRoot::<Self>::default();
562		trie_visit::<Self, _, _, _, _>(input.into_iter(), &mut cb);
563		cb.root.unwrap_or_default()
564	}
565	/// Determines a trie root node's data given its ordered contents, closed form.
566	fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
567	where
568		I: IntoIterator<Item = (A, B)>,
569		A: AsRef<[u8]> + Ord,
570		B: AsRef<[u8]>,
571	{
572		let mut cb = TrieRootUnhashed::<Self>::default();
573		trie_visit::<Self, _, _, _, _>(input.into_iter(), &mut cb);
574		cb.root.unwrap_or_default()
575	}
576	/// Encoding of index as a key (when reusing general trie for
577	/// indexed trie).
578	fn encode_index(input: u32) -> Vec<u8> {
579		// be for byte ordering
580		input.to_be_bytes().to_vec()
581	}
582	/// A trie root formed from the items, with keys attached according to their
583	/// compact-encoded index (using `parity-codec` crate).
584	fn ordered_trie_root<I, A>(input: I) -> <Self::Hash as Hasher>::Out
585	where
586		I: IntoIterator<Item = A>,
587		A: AsRef<[u8]>,
588	{
589		Self::trie_root(
590			input.into_iter().enumerate().map(|(i, v)| (Self::encode_index(i as u32), v)),
591		)
592	}
593}
594
595/// Alias accessor to hasher hash output type from a `TrieLayout`.
596pub type TrieHash<L> = <<L as TrieLayout>::Hash as Hasher>::Out;
597/// Alias accessor to `NodeCodec` associated `Error` type from a `TrieLayout`.
598pub type CError<L> = <<L as TrieLayout>::Codec as NodeCodec>::Error;
599
600/// A value as cached by the [`TrieCache`].
601#[derive(Clone, Debug)]
602pub enum CachedValue<H> {
603	/// The value doesn't exist in the trie.
604	NonExisting,
605	/// We cached the hash, because we did not yet accessed the data.
606	ExistingHash(H),
607	/// The value exists in the trie.
608	Existing {
609		/// The hash of the value.
610		hash: H,
611		/// The actual data of the value stored as [`BytesWeak`].
612		///
613		/// The original data [`Bytes`] is stored in the trie node
614		/// that is also cached by the [`TrieCache`]. If this node is dropped,
615		/// this data will also not be "upgradeable" anymore.
616		data: BytesWeak,
617	},
618}
619
620impl<H: Copy> CachedValue<H> {
621	/// Returns the data of the value.
622	///
623	/// If a value doesn't exist in the trie or only the value hash is cached, this function returns
624	/// `None`. If the reference to the data couldn't be upgraded (see [`Bytes::upgrade`]), this
625	/// function returns `Some(None)`, aka the data needs to be fetched again from the trie.
626	pub fn data(&self) -> Option<Option<Bytes>> {
627		match self {
628			Self::Existing { data, .. } => Some(data.upgrade()),
629			_ => None,
630		}
631	}
632
633	/// Returns the hash of the value.
634	///
635	/// Returns only `None` when the value doesn't exist.
636	pub fn hash(&self) -> Option<H> {
637		match self {
638			Self::ExistingHash(hash) | Self::Existing { hash, .. } => Some(*hash),
639			Self::NonExisting => None,
640		}
641	}
642}
643
644impl<H> From<(Bytes, H)> for CachedValue<H> {
645	fn from(value: (Bytes, H)) -> Self {
646		Self::Existing { hash: value.1, data: value.0.into() }
647	}
648}
649
650impl<H> From<H> for CachedValue<H> {
651	fn from(value: H) -> Self {
652		Self::ExistingHash(value)
653	}
654}
655
656impl<H> From<Option<(Bytes, H)>> for CachedValue<H> {
657	fn from(value: Option<(Bytes, H)>) -> Self {
658		value.map_or(Self::NonExisting, |v| Self::Existing { hash: v.1, data: v.0.into() })
659	}
660}
661
662impl<H> From<Option<H>> for CachedValue<H> {
663	fn from(value: Option<H>) -> Self {
664		value.map_or(Self::NonExisting, |v| Self::ExistingHash(v))
665	}
666}
667
668/// A cache that can be used to speed-up certain operations when accessing the trie.
669///
670/// The [`TrieDB`]/[`TrieDBMut`] by default are working with the internal hash-db in a non-owning
671/// mode. This means that for every lookup in the trie, every node is always fetched and decoded on
672/// the fly. Fetching and decoding a node always takes some time and can kill the performance of any
673/// application that is doing quite a lot of trie lookups. To circumvent this performance
674/// degradation, a cache can be used when looking up something in the trie. Any cache that should be
675/// used with the [`TrieDB`]/[`TrieDBMut`] needs to implement this trait.
676///
677/// The trait is laying out a two level cache, first the trie nodes cache and then the value cache.
678/// The trie nodes cache, as the name indicates, is for caching trie nodes as [`NodeOwned`]. These
679/// trie nodes are referenced by their hash. The value cache is caching [`CachedValue`]'s and these
680/// are referenced by the key to look them up in the trie. As multiple different tries can have
681/// different values under the same key, it up to the cache implementation to ensure that the
682/// correct value is returned. As each trie has a different root, this root can be used to
683/// differentiate values under the same key.
684pub trait TrieCache<NC: NodeCodec> {
685	/// Lookup value for the given `key`.
686	///
687	/// Returns the `None` if the `key` is unknown or otherwise `Some(_)` with the associated
688	/// value.
689	///
690	/// [`Self::cache_data_for_key`] is used to make the cache aware of data that is associated
691	/// to a `key`.
692	///
693	/// # Attention
694	///
695	/// The cache can be used for different tries, aka with different roots. This means
696	/// that the cache implementation needs to take care of always returning the correct value
697	/// for the current trie root.
698	fn lookup_value_for_key(&mut self, key: &[u8]) -> Option<&CachedValue<NC::HashOut>>;
699
700	/// Cache the given `value` for the given `key`.
701	///
702	/// # Attention
703	///
704	/// The cache can be used for different tries, aka with different roots. This means
705	/// that the cache implementation needs to take care of caching `value` for the current
706	/// trie root.
707	fn cache_value_for_key(&mut self, key: &[u8], value: CachedValue<NC::HashOut>);
708
709	/// Get or insert a [`NodeOwned`].
710	///
711	/// The cache implementation should look up based on the given `hash` if the node is already
712	/// known. If the node is not yet known, the given `fetch_node` function can be used to fetch
713	/// the particular node.
714	///
715	/// Returns the [`NodeOwned`] or an error that happened on fetching the node.
716	fn get_or_insert_node(
717		&mut self,
718		hash: NC::HashOut,
719		fetch_node: &mut dyn FnMut() -> Result<NodeOwned<NC::HashOut>, NC::HashOut, NC::Error>,
720	) -> Result<&NodeOwned<NC::HashOut>, NC::HashOut, NC::Error>;
721
722	/// Get the [`NodeOwned`] that corresponds to the given `hash`.
723	fn get_node(&mut self, hash: &NC::HashOut) -> Option<&NodeOwned<NC::HashOut>>;
724}
725
726/// A container for storing bytes.
727///
728/// This uses a reference counted pointer internally, so it is cheap to clone this object.
729#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
730pub struct Bytes(rstd::sync::Arc<[u8]>);
731
732impl rstd::ops::Deref for Bytes {
733	type Target = [u8];
734
735	fn deref(&self) -> &Self::Target {
736		self.0.deref()
737	}
738}
739
740impl From<Vec<u8>> for Bytes {
741	fn from(bytes: Vec<u8>) -> Self {
742		Self(bytes.into())
743	}
744}
745
746impl From<&[u8]> for Bytes {
747	fn from(bytes: &[u8]) -> Self {
748		Self(bytes.into())
749	}
750}
751
752impl<T: AsRef<[u8]>> PartialEq<T> for Bytes {
753	fn eq(&self, other: &T) -> bool {
754		self.as_ref() == other.as_ref()
755	}
756}
757
758/// A weak reference of [`Bytes`].
759///
760/// A weak reference means that it doesn't prevent [`Bytes`] from being dropped because
761/// it holds a non-owning reference to the associated [`Bytes`] object. With [`Self::upgrade`] it
762/// is possible to upgrade it again to [`Bytes`] if the reference is still valid.
763#[derive(Clone, Debug)]
764pub struct BytesWeak(rstd::sync::Weak<[u8]>);
765
766impl BytesWeak {
767	/// Upgrade to [`Bytes`].
768	///
769	/// Returns `None` when the inner value was already dropped.
770	pub fn upgrade(&self) -> Option<Bytes> {
771		self.0.upgrade().map(Bytes)
772	}
773}
774
775impl From<Bytes> for BytesWeak {
776	fn from(bytes: Bytes) -> Self {
777		Self(rstd::sync::Arc::downgrade(&bytes.0))
778	}
779}
780
781/// Either the `hash` or `value` of a node depending on its size.
782///
783/// If the size of the node `value` is bigger or equal than `MAX_INLINE_VALUE` the `hash` is
784/// returned.
785#[derive(Clone, Debug, PartialEq, Eq)]
786pub enum MerkleValue<H> {
787	/// The merkle value is the node data itself when the
788	/// node data is smaller than `MAX_INLINE_VALUE`.
789	///
790	/// Note: The case of inline nodes.
791	Node(Vec<u8>),
792	/// The merkle value is the hash of the node.
793	Hash(H),
794}