From e68f9f26aa7a22ebacb6a09763784aa97bc04928 Mon Sep 17 00:00:00 2001 From: AurelienFT Date: Sun, 19 Nov 2023 23:49:39 +0100 Subject: [PATCH 1/2] Add DB type generic in trie that use database to allow getting it through .db and .db_mut and get the real db lock --- hash-db/src/lib.rs | 8 +-- test-support/reference-trie/src/lib.rs | 53 ++++++++------- test-support/trie-bench/src/lib.rs | 17 +++-- test-support/trie-standardmap/src/lib.rs | 5 +- trie-db/src/fatdb.rs | 53 +++++++++------ trie-db/src/fatdbmut.rs | 22 +++--- trie-db/src/iterator.rs | 57 +++++++++++----- trie-db/src/lib.rs | 49 ++++++++------ trie-db/src/lookup.rs | 5 +- trie-db/src/node.rs | 5 +- trie-db/src/proof/generate.rs | 2 +- trie-db/src/proof/verify.rs | 25 ++++--- trie-db/src/sectriedb.rs | 17 +++-- trie-db/src/sectriedbmut.rs | 18 ++--- trie-db/src/trie_codec.rs | 9 +-- trie-db/src/triedb.rs | 86 ++++++++++++++---------- trie-db/src/triedbmut.rs | 62 +++++++++-------- trie-db/test/src/iterator.rs | 30 +++++---- trie-eip1186/src/eip1186.rs | 7 +- 19 files changed, 309 insertions(+), 221 deletions(-) diff --git a/hash-db/src/lib.rs b/hash-db/src/lib.rs index 4825aada..c5cbebf4 100644 --- a/hash-db/src/lib.rs +++ b/hash-db/src/lib.rs @@ -157,8 +157,8 @@ pub trait HashDBRef { fn contains(&self, key: &H::Out, prefix: Prefix) -> bool; } -impl<'a, H: Hasher, T> HashDBRef for &'a dyn HashDB { - fn get(&self, key: &H::Out, prefix: Prefix) -> Option { +impl<'a, H: Hasher, V, T: HashDB> HashDBRef for &T { + fn get(&self, key: &H::Out, prefix: Prefix) -> Option { HashDB::get(*self, key, prefix) } fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { @@ -166,8 +166,8 @@ impl<'a, H: Hasher, T> HashDBRef for &'a dyn HashDB { } } -impl<'a, H: Hasher, T> HashDBRef for &'a mut dyn HashDB { - fn get(&self, key: &H::Out, prefix: Prefix) -> Option { +impl<'a, H: Hasher, V, T: HashDB> HashDBRef for &mut T { + fn get(&self, key: &H::Out, prefix: Prefix) -> Option { HashDB::get(*self, key, prefix) } fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { diff --git a/test-support/reference-trie/src/lib.rs b/test-support/reference-trie/src/lib.rs index be626801..e7d95798 100644 --- a/test-support/reference-trie/src/lib.rs +++ b/test-support/reference-trie/src/lib.rs @@ -174,20 +174,21 @@ impl Bitmap { } } -pub type RefTrieDB<'a, 'cache> = trie_db::TrieDB<'a, 'cache, ExtensionLayout>; -pub type RefTrieDBBuilder<'a, 'cache> = trie_db::TrieDBBuilder<'a, 'cache, ExtensionLayout>; -pub type RefTrieDBMut<'a> = trie_db::TrieDBMut<'a, ExtensionLayout>; -pub type RefTrieDBMutBuilder<'a> = trie_db::TrieDBMutBuilder<'a, ExtensionLayout>; -pub type RefTrieDBMutNoExt<'a> = trie_db::TrieDBMut<'a, NoExtensionLayout>; -pub type RefTrieDBMutNoExtBuilder<'a> = trie_db::TrieDBMutBuilder<'a, NoExtensionLayout>; -pub type RefTrieDBMutAllowEmpty<'a> = trie_db::TrieDBMut<'a, AllowEmptyLayout>; -pub type RefTrieDBMutAllowEmptyBuilder<'a> = trie_db::TrieDBMutBuilder<'a, AllowEmptyLayout>; +pub type RefTrieDB<'a, 'cache, DB> = trie_db::TrieDB<'a, 'cache, ExtensionLayout, DB>; +pub type RefTrieDBBuilder<'a, 'cache, DB> = trie_db::TrieDBBuilder<'a, 'cache, ExtensionLayout, DB>; +pub type RefTrieDBMut<'a, DB> = trie_db::TrieDBMut<'a, ExtensionLayout, DB>; +pub type RefTrieDBMutBuilder<'a, DB> = trie_db::TrieDBMutBuilder<'a, ExtensionLayout, DB>; +pub type RefTrieDBMutNoExt<'a, DB> = trie_db::TrieDBMut<'a, NoExtensionLayout, DB>; +pub type RefTrieDBMutNoExtBuilder<'a, DB> = trie_db::TrieDBMutBuilder<'a, NoExtensionLayout, DB>; +pub type RefTrieDBMutAllowEmpty<'a, DB> = trie_db::TrieDBMut<'a, AllowEmptyLayout, DB>; +pub type RefTrieDBMutAllowEmptyBuilder<'a, DB> = + trie_db::TrieDBMutBuilder<'a, AllowEmptyLayout, DB>; pub type RefTestTrieDBCache = TestTrieCache; pub type RefTestTrieDBCacheNoExt = TestTrieCache; -pub type RefFatDB<'a, 'cache> = trie_db::FatDB<'a, 'cache, ExtensionLayout>; -pub type RefFatDBMut<'a> = trie_db::FatDBMut<'a, ExtensionLayout>; -pub type RefSecTrieDB<'a, 'cache> = trie_db::SecTrieDB<'a, 'cache, ExtensionLayout>; -pub type RefSecTrieDBMut<'a> = trie_db::SecTrieDBMut<'a, ExtensionLayout>; +pub type RefFatDB<'a, 'cache, DB> = trie_db::FatDB<'a, 'cache, ExtensionLayout, DB>; +pub type RefFatDBMut<'a, DB> = trie_db::FatDBMut<'a, ExtensionLayout, DB>; +pub type RefSecTrieDB<'a, 'cache, DB> = trie_db::SecTrieDB<'a, 'cache, ExtensionLayout, DB>; +pub type RefSecTrieDBMut<'a, DB> = trie_db::SecTrieDBMut<'a, ExtensionLayout, DB>; pub type RefLookup<'a, 'cache, Q> = trie_db::Lookup<'a, 'cache, ExtensionLayout, Q>; pub type RefLookupNoExt<'a, 'cache, Q> = trie_db::Lookup<'a, 'cache, NoExtensionLayout, Q>; @@ -914,7 +915,7 @@ where let root_new = calc_root_build::(data.clone(), &mut hashdb); let root = { let mut root = Default::default(); - let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); for i in 0..data.len() { t.insert(&data[i].0[..], &data[i].1[..]).unwrap(); } @@ -923,16 +924,16 @@ where }; if root_new != root { { - let db: &dyn hash_db::HashDB<_, _> = &hashdb; - let t = TrieDBBuilder::::new(&db, &root_new).build(); + let db: &DB = &hashdb; + let t = TrieDBBuilder::::new(&db, &root_new).build(); println!("{:?}", t); for a in t.iter().unwrap() { println!("a:{:x?}", a); } } { - let db: &dyn hash_db::HashDB<_, _> = &memdb; - let t = TrieDBBuilder::::new(&db, &root).build(); + let db: &DB = &memdb; + let t = TrieDBBuilder::::new(&db, &root).build(); println!("{:?}", t); for a in t.iter().unwrap() { println!("a:{:x?}", a); @@ -953,7 +954,7 @@ pub fn compare_root>( let root_new = reference_trie_root_iter_build::(data.clone()); let root = { let mut root = Default::default(); - let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); for i in 0..data.len() { t.insert(&data[i].0[..], &data[i].1[..]).unwrap(); } @@ -1028,7 +1029,7 @@ pub fn compare_implementations_unordered( let mut b_map = std::collections::btree_map::BTreeMap::new(); let root = { let mut root = Default::default(); - let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); for i in 0..data.len() { t.insert(&data[i].0[..], &data[i].1[..]).unwrap(); b_map.insert(data[i].0.clone(), data[i].1.clone()); @@ -1043,16 +1044,16 @@ pub fn compare_implementations_unordered( if root != root_new { { - let db: &dyn hash_db::HashDB<_, _> = &memdb; - let t = TrieDBBuilder::::new(&db, &root).build(); + let db: &DB = &memdb; + let t: trie_db::TrieDB<'_, '_, T, &DB> = TrieDBBuilder::::new(&db, &root).build(); println!("{:?}", t); for a in t.iter().unwrap() { println!("a:{:?}", a); } } { - let db: &dyn hash_db::HashDB<_, _> = &hashdb; - let t = TrieDBBuilder::::new(&db, &root_new).build(); + let db: &DB = &hashdb; + let t = TrieDBBuilder::::new(&db, &root_new).build(); println!("{:?}", t); for a in t.iter().unwrap() { println!("a:{:?}", a); @@ -1076,13 +1077,13 @@ pub fn compare_insert_remove>( let mut root = Default::default(); let mut a = 0; { - let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); t.commit(); } while a < data.len() { // new triemut every 3 element root = { - let mut t = TrieDBMutBuilder::::from_existing(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::::from_existing(&mut memdb, &mut root).build(); for _ in 0..3 { if data[a].0 { // remove @@ -1103,7 +1104,7 @@ pub fn compare_insert_remove>( *t.root() }; } - let mut t = TrieDBMutBuilder::::from_existing(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::::from_existing(&mut memdb, &mut root).build(); // we are testing the RefTrie code here so we do not sort or check uniqueness // before. assert_eq!(*t.root(), calc_root::(data2)); diff --git a/test-support/trie-bench/src/lib.rs b/test-support/trie-bench/src/lib.rs index afa45849..65ca34fe 100644 --- a/test-support/trie-bench/src/lib.rs +++ b/test-support/trie-bench/src/lib.rs @@ -59,9 +59,12 @@ fn benchmark( bench_list, |b, d: &TrieInsertionList| { b.iter(&mut || { - let mut memdb = MemoryDB::<_, HashKey, _>::new(L::Codec::empty_node()); + let mut memdb = MemoryDB::new(L::Codec::empty_node()); let mut root = >::default(); - let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::, _>>::new( + &mut memdb, &mut root, + ) + .build(); for i in d.0.iter() { t.insert(&i.0, &i.1).unwrap(); } @@ -72,16 +75,20 @@ fn benchmark( BenchmarkId::new("Iter", bench_size), bench_list, |b, d: &TrieInsertionList| { - let mut memdb = MemoryDB::<_, HashKey<_>, _>::new(L::Codec::empty_node()); + let mut memdb = MemoryDB::new(L::Codec::empty_node()); let mut root = >::default(); { - let mut t = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + let mut t = TrieDBMutBuilder::, _>>::new( + &mut memdb, &mut root, + ) + .build(); for i in d.0.iter() { t.insert(&i.0, &i.1).unwrap(); } } b.iter(&mut || { - let t = TrieDBBuilder::::new(&memdb, &root).build(); + let t = TrieDBBuilder::, _>>::new(&memdb, &root) + .build(); for n in t.iter().unwrap() { black_box(n).unwrap(); } diff --git a/test-support/trie-standardmap/src/lib.rs b/test-support/trie-standardmap/src/lib.rs index 8e01ad12..813cba68 100644 --- a/test-support/trie-standardmap/src/lib.rs +++ b/test-support/trie-standardmap/src/lib.rs @@ -116,8 +116,9 @@ impl StandardMap { let v = match self.value_mode { ValueMode::Mirror => k.clone(), ValueMode::Random => Self::random_value(seed), - ValueMode::Index => - vec![index as u8, (index >> 8) as u8, (index >> 16) as u8, (index >> 24) as u8], + ValueMode::Index => { + vec![index as u8, (index >> 8) as u8, (index >> 16) as u8, (index >> 24) as u8] + }, }; d.push((k, v)) } diff --git a/trie-db/src/fatdb.rs b/trie-db/src/fatdb.rs index f3a3fc43..9c9fdc5a 100644 --- a/trie-db/src/fatdb.rs +++ b/trie-db/src/fatdb.rs @@ -24,21 +24,23 @@ use crate::{rstd::boxed::Box, MerkleValue, TrieDBBuilder}; /// Additionaly it stores inserted hash-key mappings for later retrieval. /// /// Use it as a `Trie` or `TrieMut` trait object. -pub struct FatDB<'db, 'cache, L> +pub struct FatDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef { - raw: TrieDB<'db, 'cache, L>, + raw: TrieDB<'db, 'cache, L, DB>, } -impl<'db, 'cache, L> FatDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> FatDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { /// Create a new trie with the backing database `db` and empty `root` /// Initialise to the state entailed by the genesis block. /// This guarantees the trie is built correctly. - pub fn new(db: &'db dyn HashDBRef, root: &'db TrieHash) -> Self { + pub fn new(db: &'db DB, root: &'db TrieHash) -> Self { FatDB { raw: TrieDBBuilder::new(db, root).build() } } @@ -48,9 +50,10 @@ where } } -impl<'db, 'cache, L> Trie for FatDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> Trie for FatDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn root(&self) -> &TrieHash { self.raw.root() @@ -86,7 +89,7 @@ where TrieHash, CError, > { - FatDBIterator::::new(&self.raw).map(|iter| Box::new(iter) as Box<_>) + FatDBIterator::::new(&self.raw).map(|iter| Box::new(iter) as Box<_>) } fn key_iter<'a>( @@ -96,32 +99,35 @@ where TrieHash, CError, > { - FatDBKeyIterator::::new(&self.raw).map(|iter| Box::new(iter) as Box<_>) + FatDBKeyIterator::::new(&self.raw).map(|iter| Box::new(iter) as Box<_>) } } /// Iterator over inserted pairs of key values. -pub struct FatDBIterator<'db, 'cache, L> +pub struct FatDBIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { - trie_iterator: TrieDBIterator<'db, 'cache, L>, - trie: &'db TrieDB<'db, 'cache, L>, + trie_iterator: TrieDBIterator<'db, 'cache, L, DB>, + trie: &'db TrieDB<'db, 'cache, L, DB>, } -impl<'db, 'cache, L> FatDBIterator<'db, 'cache, L> +impl<'db, 'cache, L, DB> FatDBIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { /// Creates new iterator. - pub fn new(trie: &'db TrieDB<'db, 'cache, L>) -> Result, CError> { + pub fn new(trie: &'db TrieDB<'db, 'cache, L, DB>) -> Result, CError> { Ok(FatDBIterator { trie_iterator: TrieDBIterator::new(trie)?, trie }) } } -impl<'db, 'cache, L> TrieIterator for FatDBIterator<'db, 'cache, L> +impl<'db, 'cache, L, DB> TrieIterator for FatDBIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash, CError> { let hashed_key = L::Hash::hash(key); @@ -129,9 +135,10 @@ where } } -impl<'db, 'cache, L> Iterator for FatDBIterator<'db, 'cache, L> +impl<'db, 'cache, L, DB> Iterator for FatDBIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { type Item = TrieItem, CError>; @@ -149,27 +156,30 @@ where } /// Iterator over inserted keys. -pub struct FatDBKeyIterator<'db, 'cache, L> +pub struct FatDBKeyIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { - trie_iterator: TrieDBKeyIterator<'db, 'cache, L>, - trie: &'db TrieDB<'db, 'cache, L>, + trie_iterator: TrieDBKeyIterator<'db, 'cache, L, DB>, + trie: &'db TrieDB<'db, 'cache, L, DB>, } -impl<'db, 'cache, L> FatDBKeyIterator<'db, 'cache, L> +impl<'db, 'cache, L, DB> FatDBKeyIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { /// Creates new iterator. - pub fn new(trie: &'db TrieDB<'db, 'cache, L>) -> Result, CError> { + pub fn new(trie: &'db TrieDB<'db, 'cache, L, DB>) -> Result, CError> { Ok(FatDBKeyIterator { trie_iterator: TrieDBKeyIterator::new(trie)?, trie }) } } -impl<'db, 'cache, L> TrieIterator for FatDBKeyIterator<'db, 'cache, L> +impl<'db, 'cache, L, DB> TrieIterator for FatDBKeyIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash, CError> { let hashed_key = L::Hash::hash(key); @@ -177,9 +187,10 @@ where } } -impl<'db, 'cache, L> Iterator for FatDBKeyIterator<'db, 'cache, L> +impl<'db, 'cache, L, DB> Iterator for FatDBKeyIterator<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { type Item = TrieKeyItem, CError>; diff --git a/trie-db/src/fatdbmut.rs b/trie-db/src/fatdbmut.rs index fa7a8f07..fa4b7b89 100644 --- a/trie-db/src/fatdbmut.rs +++ b/trie-db/src/fatdbmut.rs @@ -22,48 +22,48 @@ use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; /// Additionaly it stores inserted hash-key mappings for later retrieval. /// /// Use it as a `Trie` or `TrieMut` trait object. -pub struct FatDBMut<'db, L> +pub struct FatDBMut<'db, L, DB> where L: TrieLayout, + DB: HashDB, { - raw: TrieDBMut<'db, L>, + raw: TrieDBMut<'db, L, DB>, } -impl<'db, L> FatDBMut<'db, L> +impl<'db, L, DB> FatDBMut<'db, L, DB> where L: TrieLayout, + DB: HashDB, { /// Create a new trie with the backing database `db` and empty `root` /// Initialise to the state entailed by the genesis block. /// This guarantees the trie is built correctly. - pub fn new(db: &'db mut dyn HashDB, root: &'db mut TrieHash) -> Self { + pub fn new(db: &'db mut DB, root: &'db mut TrieHash) -> Self { FatDBMut { raw: TrieDBMutBuilder::new(db, root).build() } } /// Create a new trie with the backing database `db` and `root`. /// /// Returns an error if root does not exist. - pub fn from_existing( - db: &'db mut dyn HashDB, - root: &'db mut TrieHash, - ) -> Self { + pub fn from_existing(db: &'db mut DB, root: &'db mut TrieHash) -> Self { FatDBMut { raw: TrieDBMutBuilder::from_existing(db, root).build() } } /// Get the backing database. - pub fn db(&self) -> &dyn HashDB { + pub fn db(&self) -> &DB { self.raw.db() } /// Get the backing database. - pub fn db_mut(&mut self) -> &mut dyn HashDB { + pub fn db_mut(&mut self) -> &mut DB { self.raw.db_mut() } } -impl<'db, L> TrieMut for FatDBMut<'db, L> +impl<'db, L, DB> TrieMut for FatDBMut<'db, L, DB> where L: TrieLayout, + DB: HashDB, { fn root(&mut self) -> &TrieHash { self.raw.root() diff --git a/trie-db/src/iterator.rs b/trie-db/src/iterator.rs index ca382b70..c88da008 100644 --- a/trie-db/src/iterator.rs +++ b/trie-db/src/iterator.rs @@ -19,7 +19,7 @@ use crate::{ triedb::TrieDB, TrieError, TrieItem, TrieKeyItem, }; -use hash_db::{Hasher, Prefix, EMPTY_PREFIX}; +use hash_db::{HashDBRef, Hasher, Prefix, EMPTY_PREFIX}; use crate::rstd::{boxed::Box, sync::Arc, vec::Vec}; @@ -71,7 +71,9 @@ impl TrieDBRawIterator { } /// Create a new iterator. - pub fn new(db: &TrieDB) -> Result, CError> { + pub fn new( + db: &TrieDB>, + ) -> Result, CError> { let mut r = TrieDBRawIterator { trail: Vec::with_capacity(8), key_nibbles: NibbleVec::new() }; let (root_node, root_hash) = db.get_raw_or_lookup( @@ -85,7 +87,10 @@ impl TrieDBRawIterator { } /// Create a new iterator, but limited to a given prefix. - pub fn new_prefixed(db: &TrieDB, prefix: &[u8]) -> Result, CError> { + pub fn new_prefixed( + db: &TrieDB>, + prefix: &[u8], + ) -> Result, CError> { let mut iter = TrieDBRawIterator::new(db)?; iter.prefix(db, prefix)?; @@ -96,7 +101,7 @@ impl TrieDBRawIterator { /// It then do a seek operation from prefixed context (using `seek` lose /// prefix context by default). pub fn new_prefixed_then_seek( - db: &TrieDB, + db: &TrieDB>, prefix: &[u8], start_at: &[u8], ) -> Result, CError> { @@ -113,7 +118,7 @@ impl TrieDBRawIterator { /// Fetch value by hash at a current node height pub(crate) fn fetch_value( - db: &TrieDB, + db: &TrieDB>, key: &[u8], prefix: Prefix, ) -> Result, CError> { @@ -130,7 +135,7 @@ impl TrieDBRawIterator { /// where we limit iteration to 'key' as a prefix. pub(crate) fn seek( &mut self, - db: &TrieDB, + db: &TrieDB>, key: &[u8], ) -> Result, CError> { self.trail.clear(); @@ -267,7 +272,11 @@ impl TrieDBRawIterator { /// Advance the iterator into a prefix, no value out of the prefix will be accessed /// or returned after this operation. - fn prefix(&mut self, db: &TrieDB, prefix: &[u8]) -> Result<(), TrieHash, CError> { + fn prefix( + &mut self, + db: &TrieDB>, + prefix: &[u8], + ) -> Result<(), TrieHash, CError> { if self.seek(db, prefix)? { if let Some(v) = self.trail.pop() { self.trail.clear(); @@ -284,7 +293,7 @@ impl TrieDBRawIterator { /// or returned after this operation. fn prefix_then_seek( &mut self, - db: &TrieDB, + db: &TrieDB>, prefix: &[u8], seek: &[u8], ) -> Result<(), TrieHash, CError> { @@ -351,7 +360,7 @@ impl TrieDBRawIterator { /// Must be called with the same `db` as when the iterator was created. pub(crate) fn next_raw_item( &mut self, - db: &TrieDB, + db: &TrieDB>, ) -> Option< Result< (&NibbleVec, Option<&TrieHash>, &Arc>), @@ -450,7 +459,10 @@ impl TrieDBRawIterator { /// Fetches the next trie item. /// /// Must be called with the same `db` as when the iterator was created. - pub fn next_item(&mut self, db: &TrieDB) -> Option, CError>> { + pub fn next_item( + &mut self, + db: &TrieDB>, + ) -> Option, CError>> { while let Some(raw_item) = self.next_raw_item(db) { let (prefix, _, node) = match raw_item { Ok(raw_item) => raw_item, @@ -499,7 +511,10 @@ impl TrieDBRawIterator { /// Fetches the next key. /// /// Must be called with the same `db` as when the iterator was created. - pub fn next_key(&mut self, db: &TrieDB) -> Option, CError>> { + pub fn next_key( + &mut self, + db: &TrieDB>, + ) -> Option, CError>> { while let Some(raw_item) = self.next_raw_item(db) { let (prefix, _, node) = match raw_item { Ok(raw_item) => raw_item, @@ -537,19 +552,21 @@ impl TrieDBRawIterator { } /// Iterator for going through all nodes in the trie in pre-order traversal order. -pub struct TrieDBNodeIterator<'a, 'cache, L: TrieLayout> { - db: &'a TrieDB<'a, 'cache, L>, +pub struct TrieDBNodeIterator<'a, 'cache, L: TrieLayout, DB: HashDBRef> { + db: &'a TrieDB<'a, 'cache, L, DB>, raw_iter: TrieDBRawIterator, } -impl<'a, 'cache, L: TrieLayout> TrieDBNodeIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> + TrieDBNodeIterator<'a, 'cache, L, DB> +{ /// Create a new iterator. - pub fn new(db: &'a TrieDB<'a, 'cache, L>) -> Result, CError> { + pub fn new(db: &'a TrieDB<'a, 'cache, L, DB>) -> Result, CError> { Ok(Self { raw_iter: TrieDBRawIterator::new(db)?, db }) } /// Restore an iterator from a raw iterator. - pub fn from_raw(db: &'a TrieDB<'a, 'cache, L>, raw_iter: TrieDBRawIterator) -> Self { + pub fn from_raw(db: &'a TrieDB<'a, 'cache, L, DB>, raw_iter: TrieDBRawIterator) -> Self { Self { db, raw_iter } } @@ -589,13 +606,17 @@ impl<'a, 'cache, L: TrieLayout> TrieDBNodeIterator<'a, 'cache, L> { } } -impl<'a, 'cache, L: TrieLayout> TrieIterator for TrieDBNodeIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> TrieIterator + for TrieDBNodeIterator<'a, 'cache, L, DB> +{ fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash, CError> { self.raw_iter.seek(self.db, key).map(|_| ()) } } -impl<'a, 'cache, L: TrieLayout> Iterator for TrieDBNodeIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> Iterator + for TrieDBNodeIterator<'a, 'cache, L, DB> +{ type Item = Result<(NibbleVec, Option>, Arc>), TrieHash, CError>; diff --git a/trie-db/src/lib.rs b/trie-db/src/lib.rs index 5ddab42f..03cdf86c 100644 --- a/trie-db/src/lib.rs +++ b/trie-db/src/lib.rs @@ -119,10 +119,12 @@ where fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TrieError::InvalidStateRoot(ref root) => write!(f, "Invalid state root: {:?}", root), - TrieError::IncompleteDatabase(ref missing) => - write!(f, "Database missing expected key: {:?}", missing), - TrieError::ValueAtIncompleteKey(ref bytes, ref extra) => - write!(f, "Value found in trie at incomplete key {:?} + {:?}", bytes, extra), + TrieError::IncompleteDatabase(ref missing) => { + write!(f, "Database missing expected key: {:?}", missing) + }, + TrieError::ValueAtIncompleteKey(ref bytes, ref extra) => { + write!(f, "Value found in trie at incomplete key {:?} + {:?}", bytes, extra) + }, TrieError::DecoderError(ref hash, ref decoder_err) => { write!(f, "Decoding failed for hash {:?}; err: {:?}", hash, decoder_err) }, @@ -384,13 +386,13 @@ pub struct TrieFactory { /// All different kinds of tries. /// This is used to prevent a heap allocation for every created trie. -pub enum TrieKinds<'db, 'cache, L: TrieLayout> { +pub enum TrieKinds<'db, 'cache, L: TrieLayout, DB: HashDBRef> { /// A generic trie db. - Generic(TrieDB<'db, 'cache, L>), + Generic(TrieDB<'db, 'cache, L, DB>), /// A secure trie db. - Secure(SecTrieDB<'db, 'cache, L>), + Secure(SecTrieDB<'db, 'cache, L, DB>), /// A fat trie db. - Fat(FatDB<'db, 'cache, L>), + Fat(FatDB<'db, 'cache, L, DB>), } // wrapper macro for making the match easier to deal with. @@ -404,7 +406,9 @@ macro_rules! wrapper { } } -impl<'db, 'cache, L: TrieLayout> Trie for TrieKinds<'db, 'cache, L> { +impl<'db, 'cache, L: TrieLayout, DB: HashDBRef> Trie + for TrieKinds<'db, 'cache, L, DB> +{ fn root(&self) -> &TrieHash { wrapper!(self, root,) } @@ -464,11 +468,11 @@ impl TrieFactory { } /// Create new immutable instance of Trie. - pub fn readonly<'db, 'cache, L: TrieLayout>( + pub fn readonly<'db, 'cache, L: TrieLayout, DB: HashDBRef>( &self, - db: &'db dyn HashDBRef, + db: &'db DB, root: &'db TrieHash, - ) -> TrieKinds<'db, 'cache, L> { + ) -> TrieKinds<'db, 'cache, L, DB> { match self.spec { TrieSpec::Generic => TrieKinds::Generic(TrieDBBuilder::new(db, root).build()), TrieSpec::Secure => TrieKinds::Secure(SecTrieDB::new(db, root)), @@ -477,28 +481,29 @@ impl TrieFactory { } /// Create new mutable instance of Trie. - pub fn create<'db, L: TrieLayout + 'db>( + pub fn create<'db, L: TrieLayout + 'db, DB: HashDB + 'db>( &self, - db: &'db mut dyn HashDB, + db: &'db mut DB, root: &'db mut TrieHash, ) -> Box + 'db> { match self.spec { - TrieSpec::Generic => Box::new(TrieDBMutBuilder::::new(db, root).build()), - TrieSpec::Secure => Box::new(SecTrieDBMut::::new(db, root)), - TrieSpec::Fat => Box::new(FatDBMut::::new(db, root)), + TrieSpec::Generic => Box::new(TrieDBMutBuilder::::new(db, root).build()), + TrieSpec::Secure => Box::new(SecTrieDBMut::::new(db, root)), + TrieSpec::Fat => Box::new(FatDBMut::::new(db, root)), } } /// Create new mutable instance of trie and check for errors. - pub fn from_existing<'db, L: TrieLayout + 'db>( + pub fn from_existing<'db, L: TrieLayout + 'db, DB: HashDB + 'db>( &self, - db: &'db mut dyn HashDB, + db: &'db mut DB, root: &'db mut TrieHash, ) -> Box + 'db> { match self.spec { - TrieSpec::Generic => Box::new(TrieDBMutBuilder::::from_existing(db, root).build()), - TrieSpec::Secure => Box::new(SecTrieDBMut::::from_existing(db, root)), - TrieSpec::Fat => Box::new(FatDBMut::::from_existing(db, root)), + TrieSpec::Generic => + Box::new(TrieDBMutBuilder::::from_existing(db, root).build()), + TrieSpec::Secure => Box::new(SecTrieDBMut::::from_existing(db, root)), + TrieSpec::Fat => Box::new(FatDBMut::::from_existing(db, root)), } } diff --git a/trie-db/src/lookup.rs b/trie-db/src/lookup.rs index 6f3d1adf..f04a1356 100644 --- a/trie-db/src/lookup.rs +++ b/trie-db/src/lookup.rs @@ -544,7 +544,7 @@ where Some(data.0) }, - Some(CachedValue::Existing { data, hash, .. }) => + Some(CachedValue::Existing { data, hash, .. }) => { if let Some(data) = data.upgrade() { // inline is either when no limit defined or when content // is less than the limit. @@ -562,7 +562,8 @@ where Some(data) } else { lookup_data(&mut self, cache)? - }, + } + }, None => lookup_data(&mut self, cache)?, }; diff --git a/trie-db/src/node.rs b/trie-db/src/node.rs index 19ed9162..da980d67 100644 --- a/trie-db/src/node.rs +++ b/trie-db/src/node.rs @@ -325,7 +325,7 @@ where *returned = true; Some((None, child)) }, - Self::Array(childs, index) => + Self::Array(childs, index) => { if *index >= childs.len() { break None } else { @@ -335,7 +335,8 @@ where if let Some(ref child) = childs[*index - 1] { break Some((Some(*index as u8 - 1), child)) } - }, + } + }, } } } diff --git a/trie-db/src/proof/generate.rs b/trie-db/src/proof/generate.rs index 2db1eafa..66568541 100644 --- a/trie-db/src/proof/generate.rs +++ b/trie-db/src/proof/generate.rs @@ -250,7 +250,7 @@ where // Perform the trie lookup for the next key, recording the sequence of nodes traversed. let mut recorder = Recorder::::new(); let expected_value = { - let trie = TrieDBBuilder::::new(db, root).with_recorder(&mut recorder).build(); + let trie = TrieDBBuilder::::new(db, root).with_recorder(&mut recorder).build(); trie.get(key_bytes)? }; diff --git a/trie-db/src/proof/verify.rs b/trie-db/src/proof/verify.rs index fedd0579..57ce35a9 100644 --- a/trie-db/src/proof/verify.rs +++ b/trie-db/src/proof/verify.rs @@ -55,20 +55,24 @@ pub enum Error { impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { match self { - Error::DuplicateKey(key) => - write!(f, "Duplicate key in input statement: key={:?}", key), + Error::DuplicateKey(key) => { + write!(f, "Duplicate key in input statement: key={:?}", key) + }, Error::ExtraneousNode => write!(f, "Extraneous node found in proof"), - Error::ExtraneousValue(key) => - write!(f, "Extraneous value found in proof should have been omitted: key={:?}", key), + Error::ExtraneousValue(key) => { + write!(f, "Extraneous value found in proof should have been omitted: key={:?}", key) + }, Error::ExtraneousHashReference(hash) => write!( f, "Extraneous hash reference found in proof should have been omitted: hash={:?}", hash ), - Error::InvalidChildReference(data) => - write!(f, "Invalid child reference exceeds hash length: {:?}", data), - Error::ValueMismatch(key) => - write!(f, "Expected value was not found in the trie: key={:?}", key), + Error::InvalidChildReference(data) => { + write!(f, "Invalid child reference exceeds hash length: {:?}", data) + }, + Error::ValueMismatch(key) => { + write!(f, "Expected value was not found in the trie: key={:?}", key) + }, Error::IncompleteProof => write!(f, "Proof is incomplete -- expected more nodes"), Error::RootMismatch(hash) => write!(f, "Computed incorrect root {:?} from proof", hash), Error::DecodeError(err) => write!(f, "Unable to decode proof node: {}", err), @@ -468,8 +472,9 @@ where } let computed_root = match child_ref { ChildReference::Hash(hash) => hash, - ChildReference::Inline(_, _) => - panic!("the bottom item on the stack has is_inline = false; qed"), + ChildReference::Inline(_, _) => { + panic!("the bottom item on the stack has is_inline = false; qed") + }, }; if computed_root != *root { return Err(Error::RootMismatch(computed_root)) diff --git a/trie-db/src/sectriedb.rs b/trie-db/src/sectriedb.rs index 2885c069..da3bc36c 100644 --- a/trie-db/src/sectriedb.rs +++ b/trie-db/src/sectriedb.rs @@ -21,39 +21,42 @@ use hash_db::{HashDBRef, Hasher}; /// A `Trie` implementation which hashes keys and uses a generic `HashDB` backing database. /// /// Use it as a `Trie` trait object. You can use `raw()` to get the backing `TrieDB` object. -pub struct SecTrieDB<'db, 'cache, L> +pub struct SecTrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { - raw: TrieDB<'db, 'cache, L>, + raw: TrieDB<'db, 'cache, L, DB>, } -impl<'db, 'cache, L> SecTrieDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> SecTrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { /// Create a new trie with the backing database `db` and `root`. /// /// Initialise to the state entailed by the genesis block. /// This guarantees the trie is built correctly. - pub fn new(db: &'db dyn HashDBRef, root: &'db TrieHash) -> Self { + pub fn new(db: &'db DB, root: &'db TrieHash) -> Self { SecTrieDB { raw: TrieDBBuilder::new(db, root).build() } } /// Get a reference to the underlying raw `TrieDB` struct. - pub fn raw(&self) -> &TrieDB<'db, 'cache, L> { + pub fn raw(&self) -> &TrieDB<'db, 'cache, L, DB> { &self.raw } /// Get a mutable reference to the underlying raw `TrieDB` struct. - pub fn raw_mut(&mut self) -> &mut TrieDB<'db, 'cache, L> { + pub fn raw_mut(&mut self) -> &mut TrieDB<'db, 'cache, L, DB> { &mut self.raw } } -impl<'db, 'cache, L> Trie for SecTrieDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> Trie for SecTrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn root(&self) -> &TrieHash { self.raw.root() diff --git a/trie-db/src/sectriedbmut.rs b/trie-db/src/sectriedbmut.rs index b56dc55a..23575169 100644 --- a/trie-db/src/sectriedbmut.rs +++ b/trie-db/src/sectriedbmut.rs @@ -22,29 +22,28 @@ use hash_db::{HashDB, Hasher}; /// /// Use it as a `Trie` or `TrieMut` trait object. You can use `raw()` to get the backing `TrieDBMut` /// object. -pub struct SecTrieDBMut<'db, L> +pub struct SecTrieDBMut<'db, L, DB> where L: TrieLayout, + DB: HashDB, { - raw: TrieDBMut<'db, L>, + raw: TrieDBMut<'db, L, DB>, } -impl<'db, L> SecTrieDBMut<'db, L> +impl<'db, L, DB> SecTrieDBMut<'db, L, DB> where L: TrieLayout, + DB: HashDB, { /// Create a new trie with the backing database `db` and empty `root` /// Initialize to the state entailed by the genesis block. /// This guarantees the trie is built correctly. - pub fn new(db: &'db mut dyn HashDB, root: &'db mut TrieHash) -> Self { + pub fn new(db: &'db mut DB, root: &'db mut TrieHash) -> Self { SecTrieDBMut { raw: TrieDBMutBuilder::new(db, root).build() } } /// Create a new trie with the backing database `db` and `root`. - pub fn from_existing( - db: &'db mut dyn HashDB, - root: &'db mut TrieHash, - ) -> Self { + pub fn from_existing(db: &'db mut DB, root: &'db mut TrieHash) -> Self { SecTrieDBMut { raw: TrieDBMutBuilder::from_existing(db, root).build() } } @@ -59,9 +58,10 @@ where } } -impl<'db, L> TrieMut for SecTrieDBMut<'db, L> +impl<'db, L, DB> TrieMut for SecTrieDBMut<'db, L, DB> where L: TrieLayout, + DB: HashDB, { fn root(&mut self) -> &TrieHash { self.raw.root() diff --git a/trie-db/src/trie_codec.rs b/trie-db/src/trie_codec.rs index 9a1f51b3..fb3faed3 100644 --- a/trie-db/src/trie_codec.rs +++ b/trie-db/src/trie_codec.rs @@ -32,7 +32,7 @@ use crate::{ CError, ChildReference, DBValue, NibbleVec, NodeCodec, Result, TrieDB, TrieDBRawIterator, TrieError, TrieHash, TrieLayout, }; -use hash_db::{HashDB, Prefix}; +use hash_db::{HashDB, HashDBRef, Prefix}; const OMIT_VALUE_HASH: crate::node::Value<'static> = crate::node::Value::Inline(&[]); @@ -187,8 +187,8 @@ impl EncoderStackEntry { /// Detached value if included does write a reserved header, /// followed by node encoded with 0 length value and the value /// as a standalone vec. -fn detached_value( - db: &TrieDB, +fn detached_value>( + db: &TrieDB, value: &ValuePlan, node_data: &[u8], node_prefix: Prefix, @@ -216,9 +216,10 @@ fn detached_value( /// /// This function makes the assumption that all child references in an inline trie node are inline /// references. -pub fn encode_compact(db: &TrieDB) -> Result>, TrieHash, CError> +pub fn encode_compact(db: &TrieDB) -> Result>, TrieHash, CError> where L: TrieLayout, + DB: HashDBRef, { let mut output = Vec::new(); diff --git a/trie-db/src/triedb.rs b/trie-db/src/triedb.rs index 310deff3..408e9c2a 100644 --- a/trie-db/src/triedb.rs +++ b/trie-db/src/triedb.rs @@ -30,20 +30,22 @@ use crate::{ use hash_db::{HashDBRef, Prefix, EMPTY_PREFIX}; /// A builder for creating a [`TrieDB`]. -pub struct TrieDBBuilder<'db, 'cache, L: TrieLayout> { - db: &'db dyn HashDBRef, +pub struct TrieDBBuilder<'db, 'cache, L: TrieLayout, DB: HashDBRef> { + db: &'db DB, root: &'db TrieHash, cache: Option<&'cache mut dyn TrieCache>, recorder: Option<&'cache mut dyn TrieRecorder>>, } -impl<'db, 'cache, L: TrieLayout> TrieDBBuilder<'db, 'cache, L> { +impl<'db, 'cache, L: TrieLayout, DB: HashDBRef> + TrieDBBuilder<'db, 'cache, L, DB> +{ /// Create a new trie-db builder with the backing database `db` and `root`. /// /// This doesn't check if `root` exists in the given `db`. If `root` doesn't exist it will fail /// when trying to lookup any key. #[inline] - pub fn new(db: &'db dyn HashDBRef, root: &'db TrieHash) -> Self { + pub fn new(db: &'db DB, root: &'db TrieHash) -> Self { Self { db, root, cache: None, recorder: None } } @@ -85,7 +87,7 @@ impl<'db, 'cache, L: TrieLayout> TrieDBBuilder<'db, 'cache, L> { /// Build the [`TrieDB`]. #[inline] - pub fn build(self) -> TrieDB<'db, 'cache, L> { + pub fn build(self) -> TrieDB<'db, 'cache, L, DB> { TrieDB { db: self.db, root: self.root, @@ -117,19 +119,21 @@ impl<'db, 'cache, L: TrieLayout> TrieDBBuilder<'db, 'cache, L> { /// assert!(t.contains(b"foo").unwrap()); /// assert_eq!(t.get(b"foo").unwrap().unwrap(), b"bar".to_vec()); /// ``` -pub struct TrieDB<'db, 'cache, L> +pub struct TrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { - db: &'db dyn HashDBRef, + db: &'db DB, root: &'db TrieHash, cache: Option>>, recorder: Option>>>, } -impl<'db, 'cache, L> TrieDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> TrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { /// Get the backing database. pub fn db(&'db self) -> &'db dyn HashDBRef { @@ -212,9 +216,10 @@ where } } -impl<'db, 'cache, L> Trie for TrieDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> Trie for TrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn root(&self) -> &TrieHash { self.root @@ -292,20 +297,22 @@ where // This is for pretty debug output only #[cfg(feature = "std")] -struct TrieAwareDebugNode<'db, 'cache, 'a, L> +struct TrieAwareDebugNode<'db, 'cache, 'a, L, DB> where L: TrieLayout, + DB: HashDBRef, { - trie: &'db TrieDB<'db, 'cache, L>, + trie: &'db TrieDB<'db, 'cache, L, DB>, node_key: NodeHandle<'a>, partial_key: NibbleVec, index: Option, } #[cfg(feature = "std")] -impl<'db, 'cache, 'a, L> fmt::Debug for TrieAwareDebugNode<'db, 'cache, 'a, L> +impl<'db, 'cache, 'a, L, DB> fmt::Debug for TrieAwareDebugNode<'db, 'cache, 'a, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.trie.get_raw_or_lookup( @@ -342,7 +349,7 @@ where disp.finish() }, Node::Branch(ref nodes, ref value) => { - let nodes: Vec> = nodes + let nodes: Vec> = nodes .into_iter() .enumerate() .filter_map(|(i, n)| n.map(|n| (i, n))) @@ -363,7 +370,7 @@ where disp.finish() }, Node::NibbledBranch(slice, nodes, value) => { - let nodes: Vec> = nodes + let nodes: Vec> = nodes .iter() .enumerate() .filter_map(|(i, n)| n.map(|n| (i, n))) @@ -400,9 +407,10 @@ where } #[cfg(feature = "std")] -impl<'db, 'cache, L> fmt::Debug for TrieDB<'db, 'cache, L> +impl<'db, 'cache, L, DB> fmt::Debug for TrieDB<'db, 'cache, L, DB> where L: TrieLayout, + DB: HashDBRef, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("TrieDB") @@ -420,26 +428,26 @@ where } /// Iterator for going through all values in the trie in pre-order traversal order. -pub struct TrieDBIterator<'a, 'cache, L: TrieLayout> { - db: &'a TrieDB<'a, 'cache, L>, +pub struct TrieDBIterator<'a, 'cache, L: TrieLayout, DB: HashDBRef> { + db: &'a TrieDB<'a, 'cache, L, DB>, raw_iter: TrieDBRawIterator, } /// Iterator for going through all of key with values in the trie in pre-order traversal order. -pub struct TrieDBKeyIterator<'a, 'cache, L: TrieLayout> { - db: &'a TrieDB<'a, 'cache, L>, +pub struct TrieDBKeyIterator<'a, 'cache, L: TrieLayout, DB: HashDBRef> { + db: &'a TrieDB<'a, 'cache, L, DB>, raw_iter: TrieDBRawIterator, } -impl<'a, 'cache, L: TrieLayout> TrieDBIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> TrieDBIterator<'a, 'cache, L, DB> { /// Create a new iterator. - pub fn new(db: &'a TrieDB<'a, 'cache, L>) -> Result, CError> { + pub fn new(db: &'a TrieDB<'a, 'cache, L, DB>) -> Result, CError> { Ok(Self { db, raw_iter: TrieDBRawIterator::new(db)? }) } /// Create a new iterator, but limited to a given prefix. pub fn new_prefixed( - db: &'a TrieDB<'a, 'cache, L>, + db: &'a TrieDB<'a, 'cache, L, DB>, prefix: &[u8], ) -> Result, CError> { Ok(Self { db, raw_iter: TrieDBRawIterator::new_prefixed(db, prefix)? }) @@ -449,7 +457,7 @@ impl<'a, 'cache, L: TrieLayout> TrieDBIterator<'a, 'cache, L> { /// It then do a seek operation from prefixed context (using `seek` lose /// prefix context by default). pub fn new_prefixed_then_seek( - db: &'a TrieDB<'a, 'cache, L>, + db: &'a TrieDB<'a, 'cache, L, DB>, prefix: &[u8], start_at: &[u8], ) -> Result, CError> { @@ -457,7 +465,7 @@ impl<'a, 'cache, L: TrieLayout> TrieDBIterator<'a, 'cache, L> { } /// Restore an iterator from a raw iterator. - pub fn from_raw(db: &'a TrieDB<'a, 'cache, L>, raw_iter: TrieDBRawIterator) -> Self { + pub fn from_raw(db: &'a TrieDB<'a, 'cache, L, DB>, raw_iter: TrieDBRawIterator) -> Self { Self { db, raw_iter } } @@ -467,22 +475,26 @@ impl<'a, 'cache, L: TrieLayout> TrieDBIterator<'a, 'cache, L> { } } -impl<'a, 'cache, L: TrieLayout> TrieIterator for TrieDBIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> TrieIterator + for TrieDBIterator<'a, 'cache, L, DB> +{ /// Position the iterator on the first element with key >= `key` fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash, CError> { self.raw_iter.seek(self.db, key).map(|_| ()) } } -impl<'a, 'cache, L: TrieLayout> TrieDBKeyIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> + TrieDBKeyIterator<'a, 'cache, L, DB> +{ /// Create a new iterator. - pub fn new(db: &'a TrieDB<'a, 'cache, L>) -> Result, CError> { + pub fn new(db: &'a TrieDB<'a, 'cache, L, DB>) -> Result, CError> { Ok(Self { db, raw_iter: TrieDBRawIterator::new(db)? }) } /// Create a new iterator, but limited to a given prefix. pub fn new_prefixed( - db: &'a TrieDB<'a, 'cache, L>, + db: &'a TrieDB<'a, 'cache, L, DB>, prefix: &[u8], ) -> Result, CError> { Ok(Self { db, raw_iter: TrieDBRawIterator::new_prefixed(db, prefix)? }) @@ -492,15 +504,15 @@ impl<'a, 'cache, L: TrieLayout> TrieDBKeyIterator<'a, 'cache, L> { /// It then do a seek operation from prefixed context (using `seek` lose /// prefix context by default). pub fn new_prefixed_then_seek( - db: &'a TrieDB<'a, 'cache, L>, + db: &'a TrieDB<'a, 'cache, L, DB>, prefix: &[u8], start_at: &[u8], - ) -> Result, TrieHash, CError> { + ) -> Result, TrieHash, CError> { Ok(Self { db, raw_iter: TrieDBRawIterator::new_prefixed_then_seek(db, prefix, start_at)? }) } /// Restore an iterator from a raw iterator. - pub fn from_raw(db: &'a TrieDB<'a, 'cache, L>, raw_iter: TrieDBRawIterator) -> Self { + pub fn from_raw(db: &'a TrieDB<'a, 'cache, L, DB>, raw_iter: TrieDBRawIterator) -> Self { Self { db, raw_iter } } @@ -510,14 +522,18 @@ impl<'a, 'cache, L: TrieLayout> TrieDBKeyIterator<'a, 'cache, L> { } } -impl<'a, 'cache, L: TrieLayout> TrieIterator for TrieDBKeyIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> TrieIterator + for TrieDBKeyIterator<'a, 'cache, L, DB> +{ /// Position the iterator on the first element with key >= `key` fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash, CError> { self.raw_iter.seek(self.db, key).map(|_| ()) } } -impl<'a, 'cache, L: TrieLayout> Iterator for TrieDBIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> Iterator + for TrieDBIterator<'a, 'cache, L, DB> +{ type Item = TrieItem, CError>; fn next(&mut self) -> Option { @@ -525,7 +541,9 @@ impl<'a, 'cache, L: TrieLayout> Iterator for TrieDBIterator<'a, 'cache, L> { } } -impl<'a, 'cache, L: TrieLayout> Iterator for TrieDBKeyIterator<'a, 'cache, L> { +impl<'a, 'cache, L: TrieLayout, DB: HashDBRef> Iterator + for TrieDBKeyIterator<'a, 'cache, L, DB> +{ type Item = TrieKeyItem, CError>; fn next(&mut self) -> Option { diff --git a/trie-db/src/triedbmut.rs b/trie-db/src/triedbmut.rs index 797bd8f8..666627b4 100644 --- a/trie-db/src/triedbmut.rs +++ b/trie-db/src/triedbmut.rs @@ -27,7 +27,7 @@ use crate::{ TrieLayout, TrieMut, TrieRecorder, }; -use hash_db::{HashDB, Hasher, Prefix, EMPTY_PREFIX}; +use hash_db::{HashDB, HashDBRef, Hasher, Prefix, EMPTY_PREFIX}; #[cfg(feature = "std")] use std::collections::HashSet as Set; @@ -173,8 +173,9 @@ impl Value { Value::Inline(value) => EncodedValue::Inline(&value), Value::Node(hash) => EncodedValue::Node(hash.as_ref()), Value::NewNode(Some(hash), _value) => EncodedValue::Node(hash.as_ref()), - Value::NewNode(None, _value) => - unreachable!("New external value are always added before encoding anode"), + Value::NewNode(None, _value) => { + unreachable!("New external value are always added before encoding anode") + }, }; value } @@ -190,7 +191,7 @@ impl Value { Value::Inline(value) => value.to_vec(), Value::NewNode(_, value) => value.to_vec(), Value::Node(hash) => - if let Some(value) = db.get(hash, prefix) { + if let Some(value) = HashDB::get(db, hash, prefix) { recorder.as_ref().map(|r| { r.borrow_mut().record(TrieAccess::Value { hash: *hash, @@ -263,13 +264,16 @@ where fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { Self::Empty => write!(fmt, "Empty"), - Self::Leaf((ref a, ref b), ref c) => - write!(fmt, "Leaf({:?}, {:?})", (a, ToHex(&*b)), c), - Self::Extension((ref a, ref b), ref c) => - write!(fmt, "Extension({:?}, {:?})", (a, ToHex(&*b)), c), + Self::Leaf((ref a, ref b), ref c) => { + write!(fmt, "Leaf({:?}, {:?})", (a, ToHex(&*b)), c) + }, + Self::Extension((ref a, ref b), ref c) => { + write!(fmt, "Extension({:?}, {:?})", (a, ToHex(&*b)), c) + }, Self::Branch(ref a, ref b) => write!(fmt, "Branch({:?}, {:?}", a, b), - Self::NibbledBranch((ref a, ref b), ref c, ref d) => - write!(fmt, "NibbledBranch({:?}, {:?}, {:?})", (a, ToHex(&*b)), c, d), + Self::NibbledBranch((ref a, ref b), ref c, ref d) => { + write!(fmt, "NibbledBranch({:?}, {:?}, {:?})", (a, ToHex(&*b)), c, d) + }, } } } @@ -443,8 +447,9 @@ impl Node { Node::NibbledBranch(k.into(), children, val.as_ref().map(Into::into)) }, - NodeOwned::Value(_, _) => - unreachable!("`NodeOwned::Value` can only be returned for the hash of a value."), + NodeOwned::Value(_, _) => { + unreachable!("`NodeOwned::Value` can only be returned for the hash of a value.") + }, } } @@ -640,17 +645,17 @@ impl<'a, L: TrieLayout> Index<&'a StorageHandle> for NodeStorage { } /// A builder for creating a [`TrieDBMut`]. -pub struct TrieDBMutBuilder<'db, L: TrieLayout> { - db: &'db mut dyn HashDB, +pub struct TrieDBMutBuilder<'db, L: TrieLayout, DB: HashDB> { + db: &'db mut DB, root: &'db mut TrieHash, cache: Option<&'db mut dyn TrieCache>, recorder: Option<&'db mut dyn TrieRecorder>>, } -impl<'db, L: TrieLayout> TrieDBMutBuilder<'db, L> { +impl<'db, L: TrieLayout, DB: HashDB> TrieDBMutBuilder<'db, L, DB> { /// Create a builder for constructing a new trie with the backing database `db` and empty /// `root`. - pub fn new(db: &'db mut dyn HashDB, root: &'db mut TrieHash) -> Self { + pub fn new(db: &'db mut DB, root: &'db mut TrieHash) -> Self { *root = L::Codec::hashed_null_node(); Self { root, db, cache: None, recorder: None } @@ -660,10 +665,7 @@ impl<'db, L: TrieLayout> TrieDBMutBuilder<'db, L> { /// /// This doesn't check if `root` exists in the given `db`. If `root` doesn't exist it will fail /// when trying to lookup any key. - pub fn from_existing( - db: &'db mut dyn HashDB, - root: &'db mut TrieHash, - ) -> Self { + pub fn from_existing(db: &'db mut DB, root: &'db mut TrieHash) -> Self { Self { db, root, cache: None, recorder: None } } @@ -700,7 +702,7 @@ impl<'db, L: TrieLayout> TrieDBMutBuilder<'db, L> { } /// Build the [`TrieDBMut`]. - pub fn build(self) -> TrieDBMut<'db, L> { + pub fn build(self) -> TrieDBMut<'db, L, DB> { let root_handle = NodeHandle::Hash(*self.root); TrieDBMut { @@ -743,12 +745,13 @@ impl<'db, L: TrieLayout> TrieDBMutBuilder<'db, L> { /// t.remove(b"foo").unwrap(); /// assert!(!t.contains(b"foo").unwrap()); /// ``` -pub struct TrieDBMut<'a, L> +pub struct TrieDBMut<'a, L, DB> where L: TrieLayout, + DB: HashDB, { storage: NodeStorage, - db: &'a mut dyn HashDB, + db: &'a mut DB, root: &'a mut TrieHash, root_handle: NodeHandle>, death_row: Set<(TrieHash, (BackingByteVec, Option))>, @@ -761,17 +764,18 @@ where recorder: Option>>>, } -impl<'a, L> TrieDBMut<'a, L> +impl<'a, L, DB> TrieDBMut<'a, L, DB> where L: TrieLayout, + DB: HashDB, { /// Get the backing database. - pub fn db(&self) -> &dyn HashDB { + pub fn db(&self) -> &DB { self.db } /// Get the backing database mutably. - pub fn db_mut(&mut self) -> &mut dyn HashDB { + pub fn db_mut(&mut self) -> &mut DB { self.db } @@ -2030,9 +2034,10 @@ where } } -impl<'a, L> TrieMut for TrieDBMut<'a, L> +impl<'a, L, DB> TrieMut for TrieDBMut<'a, L, DB> where L: TrieLayout, + DB: HashDB, { fn root(&mut self) -> &TrieHash { self.commit(); @@ -2108,9 +2113,10 @@ where } } -impl<'a, L> Drop for TrieDBMut<'a, L> +impl<'a, L, DB> Drop for TrieDBMut<'a, L, DB> where L: TrieLayout, + DB: HashDB, { fn drop(&mut self) { self.commit(); diff --git a/trie-db/test/src/iterator.rs b/trie-db/test/src/iterator.rs index e36ef6d0..864f335b 100644 --- a/trie-db/test/src/iterator.rs +++ b/trie-db/test/src/iterator.rs @@ -68,8 +68,9 @@ fn iterator_works_internal() { Some(Ok((prefix, Some(_), node))) => { assert_eq!(prefix, nibble_vec(hex!(""), 0)); match node.node() { - Node::Extension(partial, _) => - assert_eq!(partial, NibbleSlice::new_offset(&hex!("00")[..], 1)), + Node::Extension(partial, _) => { + assert_eq!(partial, NibbleSlice::new_offset(&hex!("00")[..], 1)) + }, _ => panic!("unexpected node"), } }, @@ -102,8 +103,9 @@ fn iterator_works_internal() { Some(Ok((prefix, None, node))) => { assert_eq!(prefix, nibble_vec(hex!("0120"), 3)); match node.node() { - Node::Leaf(partial, _) => - assert_eq!(partial, NibbleSlice::new_offset(&hex!("03")[..], 1)), + Node::Leaf(partial, _) => { + assert_eq!(partial, NibbleSlice::new_offset(&hex!("03")[..], 1)) + }, _ => panic!("unexpected node"), } }, @@ -129,8 +131,9 @@ fn iterator_works_internal() { Some(Ok((prefix, Some(_), node))) => { assert_eq!(prefix, nibble_vec(hex!(""), 0)); match node.node() { - Node::NibbledBranch(partial, _, _) => - assert_eq!(partial, NibbleSlice::new_offset(&hex!("00")[..], 1)), + Node::NibbledBranch(partial, _, _) => { + assert_eq!(partial, NibbleSlice::new_offset(&hex!("00")[..], 1)) + }, _ => panic!("unexpected node"), } }, @@ -144,8 +147,9 @@ fn iterator_works_internal() { } assert_eq!(prefix, nibble_vec(hex!("01"), 2)); match node.node() { - Node::NibbledBranch(partial, _, _) => - assert_eq!(partial, NibbleSlice::new(&hex!("")[..])), + Node::NibbledBranch(partial, _, _) => { + assert_eq!(partial, NibbleSlice::new(&hex!("")[..])) + }, _ => panic!("unexpected node"), } }, @@ -159,8 +163,9 @@ fn iterator_works_internal() { } assert_eq!(prefix, nibble_vec(hex!("0120"), 3)); match node.node() { - Node::Leaf(partial, _) => - assert_eq!(partial, NibbleSlice::new_offset(&hex!("03")[..], 1)), + Node::Leaf(partial, _) => { + assert_eq!(partial, NibbleSlice::new_offset(&hex!("03")[..], 1)) + }, _ => panic!("unexpected node"), } }, @@ -371,8 +376,9 @@ fn prefix_works_internal() { } assert_eq!(prefix, nibble_vec(hex!("01"), 2)); match node.node() { - Node::NibbledBranch(partial, _, _) => - assert_eq!(partial, NibbleSlice::new_offset(&hex!("")[..], 0)), + Node::NibbledBranch(partial, _, _) => { + assert_eq!(partial, NibbleSlice::new_offset(&hex!("")[..], 0)) + }, _ => panic!("unexpected node"), } }, diff --git a/trie-eip1186/src/eip1186.rs b/trie-eip1186/src/eip1186.rs index 37ad106d..8a864e0c 100644 --- a/trie-eip1186/src/eip1186.rs +++ b/trie-eip1186/src/eip1186.rs @@ -8,18 +8,19 @@ use trie_db::{ }; /// Generate an eip-1186 compatible proof for key-value pairs in a trie given a key. -pub fn generate_proof( - db: &dyn HashDBRef, +pub fn generate_proof( + db: &DB, root: &TrieHash, key: &[u8], ) -> TrieResult<(Vec>, Option>), TrieHash, CError> where L: TrieLayout, + DB: HashDBRef, { let mut recorder = Recorder::::new(); let item = { - let trie = TrieDBBuilder::::new(db, root).with_recorder(&mut recorder).build(); + let trie = TrieDBBuilder::::new(db, root).with_recorder(&mut recorder).build(); trie.get(key)? }; From c7ac2be1648736debf8aa6710029bc1ee3f4f9fe Mon Sep 17 00:00:00 2001 From: AurelienFT Date: Fri, 1 Dec 2023 14:02:56 +0100 Subject: [PATCH 2/2] Remove storage of leaf value node --- trie-db/src/triedbmut.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trie-db/src/triedbmut.rs b/trie-db/src/triedbmut.rs index 666627b4..958f40fc 100644 --- a/trie-db/src/triedbmut.rs +++ b/trie-db/src/triedbmut.rs @@ -1987,7 +1987,7 @@ where let mov = prefix.append_optional_slice_and_nibble(o_slice, o_index); match node { NodeToEncode::Node(value) => { - let value_hash = self.db.insert(prefix.as_prefix(), value); + let value_hash = L::Hash::hash(value); self.cache_value(prefix.inner(), value, value_hash);