1#![cfg_attr(not(feature = "std"), no_std)]
15
16#[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
83pub type DBValue = Vec<u8>;
85
86#[derive(PartialEq, Eq, Clone, Debug)]
91pub enum TrieError<T, E> {
92 InvalidStateRoot(T),
94 IncompleteDatabase(T),
96 ValueAtIncompleteKey(Vec<u8>, u8),
100 DecoderError(T, E),
102 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
140pub type Result<T, H, E> = crate::rstd::result::Result<T, Box<TrieError<H, E>>>;
143
144pub type TrieItem<U, E> = Result<(Vec<u8>, DBValue), U, E>;
146
147pub type TrieKeyItem<U, E> = Result<Vec<u8>, U, E>;
149
150pub trait Query<H: Hasher> {
152 type Item;
154
155 fn decode(self, data: &[u8]) -> Self::Item;
157}
158
159#[cfg_attr(feature = "std", derive(Debug))]
165pub enum TrieAccess<'a, H> {
166 NodeOwned { hash: H, node_owned: &'a NodeOwned<H> },
168 EncodedNode { hash: H, encoded_node: rstd::borrow::Cow<'a, [u8]> },
170 Value { hash: H, value: rstd::borrow::Cow<'a, [u8]>, full_key: &'a [u8] },
176 InlineValue { full_key: &'a [u8] },
183 Hash { full_key: &'a [u8] },
187 NonExisting { full_key: &'a [u8] },
191}
192
193#[derive(Debug, Clone, Copy, PartialEq, Eq)]
195pub enum RecordedForKey {
196 Value,
205 Hash,
216 None,
220}
221
222impl RecordedForKey {
223 pub fn is_none(&self) -> bool {
225 matches!(self, Self::None)
226 }
227}
228
229pub trait TrieRecorder<H> {
234 fn record<'a>(&mut self, access: TrieAccess<'a, H>);
239
240 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
256pub trait Trie<L: TrieLayout> {
258 fn root(&self) -> &TrieHash<L>;
260
261 fn is_empty(&self) -> bool {
263 *self.root() == L::Codec::hashed_null_node()
264 }
265
266 fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
268 self.get(key).map(|x| x.is_some())
269 }
270
271 fn get_hash(&self, key: &[u8]) -> Result<Option<TrieHash<L>>, TrieHash<L>, CError<L>>;
273
274 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 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 fn lookup_first_descendant(
294 &self,
295 key: &[u8],
296 ) -> Result<Option<MerkleValue<TrieHash<L>>>, TrieHash<L>, CError<L>>;
297
298 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 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
317pub trait TrieMut<L: TrieLayout> {
319 fn root(&mut self) -> &TrieHash<L>;
321
322 fn is_empty(&self) -> bool;
324
325 fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
327 self.get(key).map(|x| x.is_some())
328 }
329
330 fn get<'a, 'key>(&'a self, key: &'key [u8]) -> Result<Option<DBValue>, TrieHash<L>, CError<L>>
332 where
333 'a: 'key;
334
335 fn insert(
338 &mut self,
339 key: &[u8],
340 value: &[u8],
341 ) -> Result<Option<Value<L>>, TrieHash<L>, CError<L>>;
342
343 fn remove(&mut self, key: &[u8]) -> Result<Option<Value<L>>, TrieHash<L>, CError<L>>;
346}
347
348pub trait TrieIterator<L: TrieLayout>: Iterator {
350 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>>;
352}
353
354#[derive(PartialEq, Clone)]
356#[cfg_attr(feature = "std", derive(Debug))]
357pub enum TrieSpec {
358 Generic,
360 Secure,
362 Fat,
364}
365
366impl Default for TrieSpec {
367 fn default() -> TrieSpec {
368 TrieSpec::Secure
369 }
370}
371
372#[derive(Default, Clone)]
374pub struct TrieFactory {
375 spec: TrieSpec,
376}
377
378pub enum TrieKinds<'db, 'cache, L: TrieLayout> {
381 Generic(TrieDB<'db, 'cache, L>),
383 Secure(SecTrieDB<'db, 'cache, L>),
385 Fat(FatDB<'db, 'cache, L>),
387}
388
389macro_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 pub fn new(spec: TrieSpec) -> Self {
456 TrieFactory { spec }
457 }
458
459 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 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 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 pub fn is_fat(&self) -> bool {
500 self.spec == TrieSpec::Fat
501 }
502}
503
504pub trait TrieLayout {
508 const USE_EXTENSION: bool;
512 const ALLOW_EMPTY: bool = false;
514 const MAX_INLINE_VALUE: Option<u32>;
517
518 type Hash: Hasher;
520 type Codec: NodeCodec<HashOut = <Self::Hash as Hasher>::Out>;
522}
523
524pub trait TrieConfiguration: Sized + TrieLayout {
528 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 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 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 fn encode_index(input: u32) -> Vec<u8> {
565 input.to_be_bytes().to_vec()
567 }
568 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
581pub type TrieHash<L> = <<L as TrieLayout>::Hash as Hasher>::Out;
583pub type CError<L> = <<L as TrieLayout>::Codec as NodeCodec>::Error;
585
586#[derive(Clone, Debug)]
588pub enum CachedValue<H> {
589 NonExisting,
591 ExistingHash(H),
593 Existing {
595 hash: H,
597 data: BytesWeak,
603 },
604}
605
606impl<H: Copy> CachedValue<H> {
607 pub fn data(&self) -> Option<Option<Bytes>> {
613 match self {
614 Self::Existing { data, .. } => Some(data.upgrade()),
615 _ => None,
616 }
617 }
618
619 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
654pub trait TrieCache<NC: NodeCodec> {
671 fn lookup_value_for_key(&mut self, key: &[u8]) -> Option<&CachedValue<NC::HashOut>>;
685
686 fn cache_value_for_key(&mut self, key: &[u8], value: CachedValue<NC::HashOut>);
694
695 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 fn get_node(&mut self, hash: &NC::HashOut) -> Option<&NodeOwned<NC::HashOut>>;
710}
711
712#[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#[derive(Clone, Debug)]
750pub struct BytesWeak(rstd::sync::Weak<[u8]>);
751
752impl BytesWeak {
753 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#[derive(Clone, Debug, PartialEq, Eq)]
772pub enum MerkleValue<H> {
773 Node(Vec<u8>),
778 Hash(H),
780}