Child trie api changes BREAKING (#4857)

Co-Authored-By: thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
cheme
2020-04-20 15:21:22 +02:00
committed by GitHub
parent 7d9aa81bfc
commit 4ffcf98d8d
64 changed files with 1514 additions and 1655 deletions
@@ -22,7 +22,7 @@ use std::sync::Arc;
use log::{debug, warn};
use hash_db::{self, Hasher, EMPTY_PREFIX, Prefix};
use sp_trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue,
default_child_trie_root, read_trie_value, read_child_trie_value,
empty_child_trie_root, read_trie_value, read_child_trie_value,
for_keys_in_child_trie, KeySpacedDB, TrieDBIterator};
use sp_trie::trie_types::{TrieDB, TrieError, Layout};
use crate::{backend::Consolidate, StorageKey, StorageValue};
@@ -71,15 +71,19 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
self.next_storage_key_from_root(&self.root, None, key)
}
/// Access the root of the child storage in its parent trie
fn child_root(&self, child_info: &ChildInfo) -> Result<Option<StorageValue>, String> {
self.storage(child_info.prefixed_storage_key().as_slice())
}
/// Return the next key in the child trie i.e. the minimum key that is strictly superior to
/// `key` in lexicographic order.
pub fn next_child_storage_key(
&self,
storage_key: &[u8],
child_info: ChildInfo,
child_info: &ChildInfo,
key: &[u8],
) -> Result<Option<StorageKey>, String> {
let child_root = match self.storage(storage_key)? {
let child_root = match self.child_root(child_info)? {
Some(child_root) => child_root,
None => return Ok(None),
};
@@ -87,7 +91,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
let mut hash = H::Out::default();
if child_root.len() != hash.as_ref().len() {
return Err(format!("Invalid child storage hash at {:?}", storage_key));
return Err(format!("Invalid child storage hash at {:?}", child_info.storage_key()));
}
// note: child_root and hash must be same size, panics otherwise.
hash.as_mut().copy_from_slice(&child_root[..]);
@@ -99,7 +103,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
fn next_storage_key_from_root(
&self,
root: &H::Out,
child_info: Option<ChildInfo>,
child_info: Option<&ChildInfo>,
key: &[u8],
) -> Result<Option<StorageKey>, String> {
let mut read_overlay = S::Overlay::default();
@@ -161,12 +165,11 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
/// Get the value of child storage at given key.
pub fn child_storage(
&self,
storage_key: &[u8],
child_info: ChildInfo,
child_info: &ChildInfo,
key: &[u8],
) -> Result<Option<StorageValue>, String> {
let root = self.storage(storage_key)?
.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key).encode());
let root = self.child_root(child_info)?
.unwrap_or(empty_child_trie_root::<Layout<H>>().encode());
let mut read_overlay = S::Overlay::default();
let eph = Ephemeral {
@@ -176,19 +179,18 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
let map_e = |e| format!("Trie lookup error: {}", e);
read_child_trie_value::<Layout<H>, _>(storage_key, child_info.keyspace(), &eph, &root, key)
read_child_trie_value::<Layout<H>, _>(child_info.keyspace(), &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],
child_info: ChildInfo,
child_info: &ChildInfo,
f: F,
) {
let root = match self.storage(storage_key) {
Ok(v) => v.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key).encode()),
let root = match self.child_root(child_info) {
Ok(v) => v.unwrap_or(empty_child_trie_root::<Layout<H>>().encode()),
Err(e) => {
debug!(target: "trie", "Error while iterating child storage: {}", e);
return;
@@ -202,7 +204,6 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
};
if let Err(e) = for_keys_in_child_trie::<Layout<H>, _, Ephemeral<S, H>>(
storage_key,
child_info.keyspace(),
&eph,
&root,
@@ -215,13 +216,12 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
/// Execute given closure for all keys starting with prefix.
pub fn for_child_keys_with_prefix<F: FnMut(&[u8])>(
&self,
storage_key: &[u8],
child_info: ChildInfo,
child_info: &ChildInfo,
prefix: &[u8],
mut f: F,
) {
let root_vec = match self.storage(storage_key) {
Ok(v) => v.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key).encode()),
let root_vec = match self.child_root(child_info) {
Ok(v) => v.unwrap_or(empty_child_trie_root::<Layout<H>>().encode()),
Err(e) => {
debug!(target: "trie", "Error while iterating child storage: {}", e);
return;
@@ -242,7 +242,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> where H::Out:
root: &H::Out,
prefix: &[u8],
mut f: F,
child_info: Option<ChildInfo>,
child_info: Option<&ChildInfo>,
) {
let mut read_overlay = S::Overlay::default();
let eph = Ephemeral {
@@ -436,7 +436,8 @@ mod test {
#[test]
fn next_storage_key_and_next_child_storage_key_work() {
let child_info = ChildInfo::new_default(b"uniqueid");
let child_info = ChildInfo::new_default(b"MyChild");
let child_info = &child_info;
// Contains values
let mut root_1 = H256::default();
// Contains child trie
@@ -460,7 +461,8 @@ mod test {
}
{
let mut trie = TrieDBMut::new(&mut mdb, &mut root_2);
trie.insert(b"MyChild", root_1.as_ref()).expect("insert failed");
trie.insert(child_info.prefixed_storage_key().as_slice(), root_1.as_ref())
.expect("insert failed");
};
let essence_1 = TrieBackendEssence::new(mdb, root_1);
@@ -475,19 +477,19 @@ mod test {
let essence_2 = TrieBackendEssence::new(mdb, root_2);
assert_eq!(
essence_2.next_child_storage_key(b"MyChild", child_info, b"2"), Ok(Some(b"3".to_vec()))
essence_2.next_child_storage_key(child_info, b"2"), Ok(Some(b"3".to_vec()))
);
assert_eq!(
essence_2.next_child_storage_key(b"MyChild", child_info, b"3"), Ok(Some(b"4".to_vec()))
essence_2.next_child_storage_key(child_info, b"3"), Ok(Some(b"4".to_vec()))
);
assert_eq!(
essence_2.next_child_storage_key(b"MyChild", child_info, b"4"), Ok(Some(b"6".to_vec()))
essence_2.next_child_storage_key(child_info, b"4"), Ok(Some(b"6".to_vec()))
);
assert_eq!(
essence_2.next_child_storage_key(b"MyChild", child_info, b"5"), Ok(Some(b"6".to_vec()))
essence_2.next_child_storage_key(child_info, b"5"), Ok(Some(b"6".to_vec()))
);
assert_eq!(
essence_2.next_child_storage_key(b"MyChild", child_info, b"6"), Ok(None)
essence_2.next_child_storage_key(child_info, b"6"), Ok(None)
);
}
}