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