mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 17:41:08 +00:00
Trie simplification. (#2815)
* switch to simple codec, trie broken for now * Actualy use trie_root_noext * align some hash, failing test on EMCH comment * Fix trie code over layout instead of hash, revert legacy code for legacy mainnet ?? * stub behind LayOut * fix no_std * temp solution for legacy trie behind feature legacy-key in various crate * use remote project * rc client db need prefix * update trie deps * bum spec runtime version * Removing legacy as default. * Switch mode to non legacy. * bump runtime version * Remove legacy trie compatibility features. * fix warning * bump version * change hash on new test. * Move dependency (#11 trie PR) patched to a parity repo. Bench reverted to correct hasher. Some renaming and doc improvments. * ChildBitmap renaming to BitMap. * Renaming of LayOut to Layout. * formatting. * Removing abreviation such as _ix nb_ or bm. * Update deps and apply renaming 'Buff' -> 'Buffer'. * Align to latest trie crates naming changes. * Update trie dependency. * Update trie dependency. * change block_import test hash * update trie deps (trie use new scale codec but it does not seems to be an issue). * update to use latest trie version (no mgmt of multiple radix). * tabify * Restoring test to 10 000. * Use published crate, trie bench is currently down until publishing (require another pr to update version). * Update trie-bench.
This commit is contained in:
@@ -24,7 +24,8 @@ use log::warn;
|
||||
use hash_db::Hasher;
|
||||
use crate::trie_backend::TrieBackend;
|
||||
use crate::trie_backend_essence::TrieBackendStorage;
|
||||
use trie::{TrieDBMut, TrieMut, MemoryDB, trie_root, child_trie_root, default_child_trie_root};
|
||||
use trie::{TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration};
|
||||
use trie::trie_types::{TrieDBMut, Layout};
|
||||
|
||||
/// A state backend is used to read state data and can have changes committed
|
||||
/// to it.
|
||||
@@ -315,7 +316,7 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
|
||||
.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), Some(v.clone()))));
|
||||
|
||||
let transaction: Vec<_> = delta.into_iter().collect();
|
||||
let root = trie_root::<H, _, _, _>(existing_pairs.chain(transaction.iter().cloned())
|
||||
let root = Layout::<H>::trie_root(existing_pairs.chain(transaction.iter().cloned())
|
||||
.collect::<HashMap<_, _>>()
|
||||
.into_iter()
|
||||
.filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val)))
|
||||
@@ -338,7 +339,7 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
|
||||
.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), Some(v.clone()))));
|
||||
|
||||
let transaction: Vec<_> = delta.into_iter().collect();
|
||||
let root = child_trie_root::<H, _, _, _>(
|
||||
let root = child_trie_root::<Layout<H>, _, _, _>(
|
||||
&storage_key,
|
||||
existing_pairs.chain(transaction.iter().cloned())
|
||||
.collect::<HashMap<_, _>>()
|
||||
@@ -348,7 +349,7 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
|
||||
|
||||
let full_transaction = transaction.into_iter().map(|(k, v)| (Some(storage_key.clone()), k, v)).collect();
|
||||
|
||||
let is_default = root == default_child_trie_root::<H>(&storage_key);
|
||||
let is_default = root == default_child_trie_root::<Layout<H>>(&storage_key);
|
||||
|
||||
(root, is_default, full_transaction)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
use crate::backend::{Backend, InMemory};
|
||||
use hash_db::Hasher;
|
||||
use trie::trie_root;
|
||||
use trie::TrieConfiguration;
|
||||
use trie::trie_types::Layout;
|
||||
use primitives::offchain;
|
||||
use primitives::storage::well_known_keys::is_child_storage_key;
|
||||
use super::{ChildStorageKey, Externalities};
|
||||
@@ -149,7 +150,7 @@ impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
|
||||
fn chain_id(&self) -> u64 { 42 }
|
||||
|
||||
fn storage_root(&mut self) -> H::Out {
|
||||
trie_root::<H, _, _, _>(self.top.clone())
|
||||
Layout::<H>::trie_root(self.top.clone())
|
||||
}
|
||||
|
||||
fn child_storage_root(&mut self, storage_key: ChildStorageKey<H>) -> Vec<u8> {
|
||||
@@ -186,7 +187,8 @@ mod tests {
|
||||
ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
|
||||
ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
|
||||
ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
|
||||
const ROOT: [u8; 32] = hex!("0b41e488cccbd67d1f1089592c2c235f5c5399b053f7fe9152dd4b5f279914cd");
|
||||
const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa");
|
||||
|
||||
assert_eq!(ext.storage_root(), H256::from(ROOT));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use parity_codec::{Decode, Encode};
|
||||
use hash_db::{HashDB, Hasher};
|
||||
use hash_db::{HashDB, Hasher, EMPTY_PREFIX};
|
||||
use num_traits::One;
|
||||
use trie::{Recorder, MemoryDB};
|
||||
use crate::changes_trie::{AnchorBlockId, Configuration, RootsStorage, Storage, BlockNumber};
|
||||
@@ -115,7 +115,7 @@ pub fn key_changes_proof_check<S: RootsStorage<H, Number>, H: Hasher, Number: Bl
|
||||
|
||||
let mut proof_db = MemoryDB::<H>::default();
|
||||
for item in proof {
|
||||
proof_db.insert(&[], &item);
|
||||
proof_db.insert(EMPTY_PREFIX, &item);
|
||||
}
|
||||
|
||||
let proof_db = InMemoryStorage::with_db(proof_db);
|
||||
|
||||
@@ -46,14 +46,15 @@ pub use self::storage::InMemoryStorage;
|
||||
pub use self::changes_iterator::{key_changes, key_changes_proof, key_changes_proof_check};
|
||||
pub use self::prune::{prune, oldest_non_pruned_trie};
|
||||
|
||||
use hash_db::Hasher;
|
||||
use hash_db::{Hasher, Prefix};
|
||||
use crate::backend::Backend;
|
||||
use num_traits::{One, Zero};
|
||||
use parity_codec::{Decode, Encode};
|
||||
use primitives;
|
||||
use crate::changes_trie::build::prepare_input;
|
||||
use crate::overlayed_changes::OverlayedChanges;
|
||||
use trie::{MemoryDB, TrieDBMut, TrieMut, DBValue};
|
||||
use trie::{MemoryDB, DBValue, TrieMut};
|
||||
use trie::trie_types::TrieDBMut;
|
||||
|
||||
/// Changes that are made outside of extrinsics are marked with this index;
|
||||
pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff;
|
||||
@@ -108,7 +109,7 @@ pub trait RootsStorage<H: Hasher, Number: BlockNumber>: Send + Sync {
|
||||
/// Changes trie storage. Provides access to trie roots and trie nodes.
|
||||
pub trait Storage<H: Hasher, Number: BlockNumber>: RootsStorage<H, Number> {
|
||||
/// Get a trie node.
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String>;
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
|
||||
}
|
||||
|
||||
/// Changes trie storage -> trie backend essence adapter.
|
||||
@@ -117,7 +118,7 @@ pub struct TrieBackendStorageAdapter<'a, H: Hasher, Number: BlockNumber>(pub &'a
|
||||
impl<'a, H: Hasher, N: BlockNumber> crate::TrieBackendStorage<H> for TrieBackendStorageAdapter<'a, H, N> {
|
||||
type Overlay = trie::MemoryDB<H>;
|
||||
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
|
||||
self.0.get(key, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Changes trie storage utilities.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use hash_db::Hasher;
|
||||
use hash_db::{Hasher, Prefix};
|
||||
use trie::DBValue;
|
||||
use trie::MemoryDB;
|
||||
use parking_lot::RwLock;
|
||||
@@ -101,7 +101,7 @@ impl<H: Hasher, Number: BlockNumber> InMemoryStorage<H, Number> {
|
||||
pub fn remove_from_storage(&self, keys: &HashSet<H::Out>) {
|
||||
let mut data = self.data.write();
|
||||
for key in keys {
|
||||
data.mdb.remove_and_purge(key, &[]);
|
||||
data.mdb.remove_and_purge(key, hash_db::EMPTY_PREFIX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ impl<H: Hasher, Number: BlockNumber> RootsStorage<H, Number> for InMemoryStorage
|
||||
}
|
||||
|
||||
impl<H: Hasher, Number: BlockNumber> Storage<H, Number> for InMemoryStorage<H, Number> {
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
|
||||
MemoryDB::<H>::get(&self.data.read().mdb, key, prefix)
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ impl<'a, H, Number, S> TrieBackendStorage<H> for TrieBackendAdapter<'a, H, Numbe
|
||||
{
|
||||
type Overlay = MemoryDB<H>;
|
||||
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
|
||||
self.storage.get(key, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ use hash_db::Hasher;
|
||||
use primitives::offchain;
|
||||
use primitives::storage::well_known_keys::is_child_storage_key;
|
||||
use trie::{MemoryDB, default_child_trie_root};
|
||||
use trie::trie_types::Layout;
|
||||
|
||||
const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime";
|
||||
|
||||
@@ -297,7 +298,7 @@ where
|
||||
self
|
||||
.storage(storage_key.as_ref())
|
||||
.unwrap_or(
|
||||
default_child_trie_root::<H>(storage_key.as_ref())
|
||||
default_child_trie_root::<Layout<H>>(storage_key.as_ref())
|
||||
)
|
||||
} else {
|
||||
let storage_key = storage_key.as_ref();
|
||||
@@ -394,8 +395,10 @@ mod tests {
|
||||
let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]);
|
||||
let backend = TestBackend::default();
|
||||
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
|
||||
let root = hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into();
|
||||
|
||||
assert_eq!(ext.storage_changes_root(Default::default()).unwrap(),
|
||||
Some(hex!("5b829920b9c8d554a19ee2a1ba593c4f2ee6fc32822d083e04236d693e8358d5").into()));
|
||||
Some(root));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -405,7 +408,9 @@ mod tests {
|
||||
let storage = TestChangesTrieStorage::with_blocks(vec![(99, Default::default())]);
|
||||
let backend = TestBackend::default();
|
||||
let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None);
|
||||
let root = hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into();
|
||||
|
||||
assert_eq!(ext.storage_changes_root(Default::default()).unwrap(),
|
||||
Some(hex!("bcf494e41e29a15c9ae5caa053fe3cb8b446ee3e02a254efbdec7a19235b76e4").into()));
|
||||
Some(root));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ mod trie_backend;
|
||||
mod trie_backend_essence;
|
||||
|
||||
use overlayed_changes::OverlayedChangeSet;
|
||||
pub use trie::{TrieMut, TrieDBMut, DBValue, MemoryDB};
|
||||
pub use trie::{TrieMut, DBValue, MemoryDB};
|
||||
pub use trie::trie_types::{Layout, TrieDBMut};
|
||||
pub use testing::TestExternalities;
|
||||
pub use basic::BasicExternalities;
|
||||
pub use ext::Ext;
|
||||
@@ -71,7 +72,7 @@ pub struct ChildStorageKey<'a, H: Hasher> {
|
||||
|
||||
impl<'a, H: Hasher> ChildStorageKey<'a, H> {
|
||||
fn new(storage_key: Cow<'a, [u8]>) -> Option<Self> {
|
||||
if !trie::is_child_trie_key_valid::<H>(&storage_key) {
|
||||
if !trie::is_child_trie_key_valid::<Layout<H>>(&storage_key) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
@@ -372,7 +372,8 @@ mod tests {
|
||||
Some(&changes_trie_storage),
|
||||
crate::NeverOffchainExt::new(),
|
||||
);
|
||||
const ROOT: [u8; 32] = hex!("0b41e488cccbd67d1f1089592c2c235f5c5399b053f7fe9152dd4b5f279914cd");
|
||||
const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa");
|
||||
|
||||
assert_eq!(ext.storage_root(), H256::from(ROOT));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use log::debug;
|
||||
use hash_db::Hasher;
|
||||
use hash_db::HashDB;
|
||||
use hash_db::{Hasher, HashDB, EMPTY_PREFIX};
|
||||
use trie::{
|
||||
MemoryDB, PrefixedMemoryDB, TrieError, default_child_trie_root,
|
||||
MemoryDB, PrefixedMemoryDB, default_child_trie_root,
|
||||
read_trie_value_with, read_child_trie_value_with, record_all_keys
|
||||
};
|
||||
pub use trie::Recorder;
|
||||
pub use trie::trie_types::{Layout, TrieError};
|
||||
use crate::trie_backend::TrieBackend;
|
||||
use crate::trie_backend_essence::{Ephemeral, TrieBackendEssence, TrieBackendStorage};
|
||||
use crate::{Error, ExecutionError, Backend};
|
||||
@@ -50,11 +50,21 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H>
|
||||
|
||||
let map_e = |e| format!("Trie lookup error: {}", e);
|
||||
|
||||
read_trie_value_with::<H, _, Ephemeral<S, H>>(&eph, self.backend.root(), key, &mut *self.proof_recorder).map_err(map_e)
|
||||
read_trie_value_with::<Layout<H>, _, Ephemeral<S, H>>(
|
||||
&eph,
|
||||
self.backend.root(),
|
||||
key,
|
||||
&mut *self.proof_recorder
|
||||
).map_err(map_e)
|
||||
}
|
||||
|
||||
pub fn child_storage(&mut self, storage_key: &[u8], key: &[u8]) -> Result<Option<Vec<u8>>, String> {
|
||||
let root = self.storage(storage_key)?.unwrap_or(default_child_trie_root::<H>(storage_key));
|
||||
pub fn child_storage(
|
||||
&mut self,
|
||||
storage_key: &[u8],
|
||||
key: &[u8]
|
||||
) -> Result<Option<Vec<u8>>, String> {
|
||||
let root = self.storage(storage_key)?
|
||||
.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key));
|
||||
|
||||
let mut read_overlay = S::Overlay::default();
|
||||
let eph = Ephemeral::new(
|
||||
@@ -64,7 +74,13 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H>
|
||||
|
||||
let map_e = |e| format!("Trie lookup error: {}", e);
|
||||
|
||||
read_child_trie_value_with(storage_key, &eph, &root, key, &mut *self.proof_recorder).map_err(map_e)
|
||||
read_child_trie_value_with::<Layout<H>, _, _>(
|
||||
storage_key,
|
||||
&eph,
|
||||
&root,
|
||||
key,
|
||||
&mut *self.proof_recorder
|
||||
).map_err(map_e)
|
||||
}
|
||||
|
||||
pub fn record_all_keys(&mut self) {
|
||||
@@ -76,7 +92,7 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H>
|
||||
|
||||
let mut iter = move || -> Result<(), Box<TrieError<H::Out>>> {
|
||||
let root = self.backend.root();
|
||||
record_all_keys::<H, _>(&eph, root, &mut *self.proof_recorder)
|
||||
record_all_keys::<Layout<H>, _>(&eph, root, &mut *self.proof_recorder)
|
||||
};
|
||||
|
||||
if let Err(e) = iter() {
|
||||
@@ -199,7 +215,7 @@ where
|
||||
{
|
||||
let db = create_proof_check_backend_storage(proof);
|
||||
|
||||
if db.contains(&root, &[]) {
|
||||
if db.contains(&root, EMPTY_PREFIX) {
|
||||
Ok(TrieBackend::new(db, root))
|
||||
} else {
|
||||
Err(Box::new(ExecutionError::InvalidProof))
|
||||
@@ -215,7 +231,7 @@ where
|
||||
{
|
||||
let mut db = MemoryDB::default();
|
||||
for item in proof {
|
||||
db.insert(&[], &item);
|
||||
db.insert(EMPTY_PREFIX, &item);
|
||||
}
|
||||
db
|
||||
}
|
||||
@@ -307,7 +323,7 @@ mod tests {
|
||||
let mut in_memory = in_memory.update(contents);
|
||||
let in_memory_root = in_memory.full_storage_root::<_, Vec<_>, _>(
|
||||
::std::iter::empty(),
|
||||
in_memory.child_storage_keys().map(|k|(k.to_vec(), Vec::new()))
|
||||
in_memory.child_storage_keys().map(|k|(k.to_vec(), Vec::new()))
|
||||
).0;
|
||||
(0..64).for_each(|i| assert_eq!(
|
||||
in_memory.storage(&[i]).unwrap().unwrap(),
|
||||
|
||||
@@ -277,7 +277,7 @@ mod tests {
|
||||
ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
|
||||
ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
|
||||
ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
|
||||
const ROOT: [u8; 32] = hex!("cc65c26c37ebd4abcdeb3f1ecd727527051620779a2f6c809bac0f8a87dbb816");
|
||||
const ROOT: [u8; 32] = hex!("2a340d3dfd52f5992c6b117e9e45f479e6da5afffafeb26ab619cf137a95aeb8");
|
||||
assert_eq!(ext.storage_root(), H256::from(ROOT));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
use log::{warn, debug};
|
||||
use hash_db::Hasher;
|
||||
use trie::{TrieDB, TrieError, Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root};
|
||||
use trie::{Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root};
|
||||
use trie::trie_types::{TrieDB, TrieError, Layout};
|
||||
use crate::trie_backend_essence::{TrieBackendEssence, TrieBackendStorage, Ephemeral};
|
||||
use crate::Backend;
|
||||
|
||||
@@ -137,7 +138,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
|
||||
&mut write_overlay,
|
||||
);
|
||||
|
||||
match delta_trie_root::<H, _, _, _, _>(&mut eph, root, delta) {
|
||||
match delta_trie_root::<Layout<H>, _, _, _, _>(&mut eph, root, delta) {
|
||||
Ok(ret) => root = ret,
|
||||
Err(e) => warn!(target: "trie", "Failed to write to trie: {}", e),
|
||||
}
|
||||
@@ -151,11 +152,11 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
H::Out: Ord
|
||||
{
|
||||
let default_root = default_child_trie_root::<H>(storage_key);
|
||||
let default_root = default_child_trie_root::<Layout<H>>(storage_key);
|
||||
|
||||
let mut write_overlay = S::Overlay::default();
|
||||
let mut root = match self.storage(storage_key) {
|
||||
Ok(value) => value.unwrap_or(default_child_trie_root::<H>(storage_key)),
|
||||
Ok(value) => value.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key)),
|
||||
Err(e) => {
|
||||
warn!(target: "trie", "Failed to read child storage root: {}", e);
|
||||
default_root.clone()
|
||||
@@ -168,7 +169,12 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
|
||||
&mut write_overlay,
|
||||
);
|
||||
|
||||
match child_delta_trie_root::<H, _, _, _, _>(storage_key, &mut eph, root.clone(), delta) {
|
||||
match child_delta_trie_root::<Layout<H>, _, _, _, _>(
|
||||
storage_key,
|
||||
&mut eph,
|
||||
root.clone(),
|
||||
delta
|
||||
) {
|
||||
Ok(ret) => root = ret,
|
||||
Err(e) => warn!(target: "trie", "Failed to write to trie: {}", e),
|
||||
}
|
||||
@@ -189,7 +195,8 @@ pub mod tests {
|
||||
use std::collections::HashSet;
|
||||
use primitives::{Blake2Hasher, H256};
|
||||
use parity_codec::Encode;
|
||||
use trie::{TrieMut, TrieDBMut, PrefixedMemoryDB};
|
||||
use trie::{TrieMut, PrefixedMemoryDB};
|
||||
use trie::trie_types::TrieDBMut;
|
||||
use super::*;
|
||||
|
||||
fn test_db() -> (PrefixedMemoryDB<Blake2Hasher>, H256) {
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
use log::{debug, warn};
|
||||
use hash_db::{self, Hasher};
|
||||
use trie::{
|
||||
TrieDB, Trie, MemoryDB, PrefixedMemoryDB, DBValue, TrieError,
|
||||
default_child_trie_root, read_trie_value, read_child_trie_value, for_keys_in_child_trie,
|
||||
};
|
||||
use hash_db::{self, Hasher, EMPTY_PREFIX, Prefix};
|
||||
use trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue,
|
||||
default_child_trie_root, read_trie_value, read_child_trie_value,
|
||||
for_keys_in_child_trie};
|
||||
use trie::trie_types::{TrieDB, TrieError, Layout};
|
||||
use crate::backend::Consolidate;
|
||||
|
||||
/// Patricia trie-based storage trait.
|
||||
pub trait Storage<H: Hasher>: Send + Sync {
|
||||
/// Get a trie node.
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String>;
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
|
||||
}
|
||||
|
||||
/// Patricia trie-based pairs storage essence.
|
||||
@@ -73,12 +73,13 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
|
||||
|
||||
let map_e = |e| format!("Trie lookup error: {}", e);
|
||||
|
||||
read_trie_value(&eph, &self.root, key).map_err(map_e)
|
||||
read_trie_value::<Layout<H>, _>(&eph, &self.root, key).map_err(map_e)
|
||||
}
|
||||
|
||||
/// Get the value of child storage at given key.
|
||||
pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result<Option<Vec<u8>>, String> {
|
||||
let root = self.storage(storage_key)?.unwrap_or(default_child_trie_root::<H>(storage_key));
|
||||
let root = self.storage(storage_key)?
|
||||
.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key));
|
||||
|
||||
let mut read_overlay = S::Overlay::default();
|
||||
let eph = Ephemeral {
|
||||
@@ -88,13 +89,13 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
|
||||
|
||||
let map_e = |e| format!("Trie lookup error: {}", e);
|
||||
|
||||
read_child_trie_value(storage_key, &eph, &root, key).map_err(map_e)
|
||||
read_child_trie_value::<Layout<H>, _>(storage_key, &eph, &root, key).map_err(map_e)
|
||||
}
|
||||
|
||||
/// Retrieve all entries keys of child storage and call `f` for each of those keys.
|
||||
pub fn for_keys_in_child_storage<F: FnMut(&[u8])>(&self, storage_key: &[u8], f: F) {
|
||||
let root = match self.storage(storage_key) {
|
||||
Ok(v) => v.unwrap_or(default_child_trie_root::<H>(storage_key)),
|
||||
Ok(v) => v.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key)),
|
||||
Err(e) => {
|
||||
debug!(target: "trie", "Error while iterating child storage: {}", e);
|
||||
return;
|
||||
@@ -107,7 +108,12 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
|
||||
overlay: &mut read_overlay,
|
||||
};
|
||||
|
||||
if let Err(e) = for_keys_in_child_trie::<H, _, Ephemeral<S, H>>(storage_key, &eph, &root, f) {
|
||||
if let Err(e) = for_keys_in_child_trie::<Layout<H>, _, Ephemeral<S, H>>(
|
||||
storage_key,
|
||||
&eph,
|
||||
&root,
|
||||
f,
|
||||
) {
|
||||
debug!(target: "trie", "Error while iterating child storage: {}", e);
|
||||
}
|
||||
}
|
||||
@@ -186,10 +192,10 @@ impl<'a,
|
||||
for Ephemeral<'a, S, H>
|
||||
{
|
||||
fn get(&self, key: &H::Out) -> Option<DBValue> {
|
||||
if let Some(val) = hash_db::HashDB::get(self.overlay, key, &[]) {
|
||||
if let Some(val) = hash_db::HashDB::get(self.overlay, key, EMPTY_PREFIX) {
|
||||
Some(val)
|
||||
} else {
|
||||
match self.storage.get(&key, &[]) {
|
||||
match self.storage.get(&key, EMPTY_PREFIX) {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
warn!(target: "trie", "Failed to read from DB: {}", e);
|
||||
@@ -200,15 +206,15 @@ impl<'a,
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H::Out) -> bool {
|
||||
hash_db::HashDB::get(self, key, &[]).is_some()
|
||||
hash_db::HashDB::get(self, key, EMPTY_PREFIX).is_some()
|
||||
}
|
||||
|
||||
fn emplace(&mut self, key: H::Out, value: DBValue) {
|
||||
hash_db::HashDB::emplace(self.overlay, key, &[], value)
|
||||
hash_db::HashDB::emplace(self.overlay, key, EMPTY_PREFIX, value)
|
||||
}
|
||||
|
||||
fn remove(&mut self, key: &H::Out) {
|
||||
hash_db::HashDB::remove(self.overlay, key, &[])
|
||||
hash_db::HashDB::remove(self.overlay, key, EMPTY_PREFIX)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +234,7 @@ impl<'a,
|
||||
> hash_db::HashDB<H, DBValue>
|
||||
for Ephemeral<'a, S, H>
|
||||
{
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Option<DBValue> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<DBValue> {
|
||||
if let Some(val) = hash_db::HashDB::get(self.overlay, key, prefix) {
|
||||
Some(val)
|
||||
} else {
|
||||
@@ -242,19 +248,19 @@ impl<'a,
|
||||
}
|
||||
}
|
||||
|
||||
fn contains(&self, key: &H::Out, prefix: &[u8]) -> bool {
|
||||
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
|
||||
hash_db::HashDB::get(self, key, prefix).is_some()
|
||||
}
|
||||
|
||||
fn insert(&mut self, prefix: &[u8], value: &[u8]) -> H::Out {
|
||||
fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out {
|
||||
hash_db::HashDB::insert(self.overlay, prefix, value)
|
||||
}
|
||||
|
||||
fn emplace(&mut self, key: H::Out, prefix: &[u8], value: DBValue) {
|
||||
fn emplace(&mut self, key: H::Out, prefix: Prefix, value: DBValue) {
|
||||
hash_db::HashDB::emplace(self.overlay, key, prefix, value)
|
||||
}
|
||||
|
||||
fn remove(&mut self, key: &H::Out, prefix: &[u8]) {
|
||||
fn remove(&mut self, key: &H::Out, prefix: Prefix) {
|
||||
hash_db::HashDB::remove(self.overlay, key, prefix)
|
||||
}
|
||||
}
|
||||
@@ -265,8 +271,8 @@ impl<'a,
|
||||
> hash_db::HashDBRef<H, DBValue>
|
||||
for Ephemeral<'a, S, H>
|
||||
{
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Option<DBValue> { hash_db::HashDB::get(self, key, prefix) }
|
||||
fn contains(&self, key: &H::Out, prefix: &[u8]) -> bool { hash_db::HashDB::contains(self, key, prefix) }
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<DBValue> { hash_db::HashDB::get(self, key, prefix) }
|
||||
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { hash_db::HashDB::contains(self, key, prefix) }
|
||||
}
|
||||
|
||||
/// Key-value pairs storage that is used by trie backend essence.
|
||||
@@ -274,14 +280,14 @@ pub trait TrieBackendStorage<H: Hasher>: Send + Sync {
|
||||
/// Type of in-memory overlay.
|
||||
type Overlay: hash_db::HashDB<H, DBValue> + Default + Consolidate;
|
||||
/// Get the value stored at key.
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String>;
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
|
||||
}
|
||||
|
||||
// This implementation is used by normal storage trie clients.
|
||||
impl<H: Hasher> TrieBackendStorage<H> for Arc<dyn Storage<H>> {
|
||||
type Overlay = PrefixedMemoryDB<H>;
|
||||
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
|
||||
Storage::<H>::get(self.deref(), key, prefix)
|
||||
}
|
||||
}
|
||||
@@ -290,7 +296,7 @@ impl<H: Hasher> TrieBackendStorage<H> for Arc<dyn Storage<H>> {
|
||||
impl<H: Hasher> TrieBackendStorage<H> for PrefixedMemoryDB<H> {
|
||||
type Overlay = PrefixedMemoryDB<H>;
|
||||
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
|
||||
Ok(hash_db::HashDB::get(self, key, prefix))
|
||||
}
|
||||
}
|
||||
@@ -298,7 +304,7 @@ impl<H: Hasher> TrieBackendStorage<H> for PrefixedMemoryDB<H> {
|
||||
impl<H: Hasher> TrieBackendStorage<H> for MemoryDB<H> {
|
||||
type Overlay = MemoryDB<H>;
|
||||
|
||||
fn get(&self, key: &H::Out, prefix: &[u8]) -> Result<Option<DBValue>, String> {
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String> {
|
||||
Ok(hash_db::HashDB::get(self, key, prefix))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user