Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9ccf26e
In progress, runtime io must switch to future proof root +
cheme Nov 18, 2019
a0f3818
Switch interface, sr-io seems ok, rpc could use similar interface to
cheme Nov 19, 2019
41c5020
test from previous implementation.
cheme Nov 20, 2019
6eb0414
fix proving test.
cheme Nov 20, 2019
e8e72fc
Restore Keyspacedb from other branch, only apply to child trie.
cheme Nov 20, 2019
88ffbc4
Removing unneeded child_info from child root (child info are stored
cheme Nov 20, 2019
435fcb2
Switch rpc to use same format as ext: more future proof.
cheme Nov 20, 2019
b8c7e37
use root from child info for trie backend essence.
cheme Nov 20, 2019
ee43955
Breaking long lines.
cheme Nov 20, 2019
fe285ae
Merge branch 'master' into child_uuid_step1
cheme Nov 21, 2019
a8818d9
Update doc and clean pr a bit.
cheme Nov 21, 2019
9873dcb
Merge branch 'master' into child_uuid_step1
cheme Nov 23, 2019
609a847
Merge branch 'master' into child_uuid_step1
cheme Nov 25, 2019
7254f6c
Merge branch 'master' into child_uuid_step1
cheme Nov 27, 2019
cac9330
fix error type
cheme Nov 27, 2019
c3b943c
Merge branch 'master' into child_uuid_step1
cheme Nov 28, 2019
c05bc80
Restore removed doc on merge and update sr-io doc.
cheme Nov 28, 2019
cd1e343
Merge branch 'master' into child_uuid_step1
cheme Nov 29, 2019
bdff843
Switch child storage api to use directly unique id, if managed id
cheme Nov 29, 2019
9ce77bb
Clean deprecated host interface from child.
cheme Nov 29, 2019
92c7864
Removing assertion on child info (can fail depending on root
cheme Nov 29, 2019
fc91068
merging child info in the overlay when possible.
cheme Nov 29, 2019
cdabca3
child iteration by prefix using child_info.
cheme Nov 29, 2019
783f389
Merge branch 'master' into child_uuid_step1
cheme Dec 2, 2019
d4c7334
Using ChainInfo in frame support. ChainInfo gets redesign to avoid
cheme Dec 2, 2019
64f4084
Add length of root to the data of child info.
cheme Dec 2, 2019
a87bd48
comments
cheme Dec 2, 2019
68712f9
Encode compact.
cheme Dec 2, 2019
3db467e
Remove child info with root.
cheme Dec 3, 2019
a7425cc
Merge branch 'master' into child_uuid_step1
cheme Dec 3, 2019
8e2b8b9
Fix try_update condition.
cheme Dec 3, 2019
5d74151
Comment Ext child root caching.
cheme Dec 3, 2019
0ba3da5
Replace tuples by struct with field
cheme Dec 5, 2019
d924187
remove StorageTuple alias.
cheme Dec 5, 2019
43da346
Merge branch 'master' into child_uuid_step1
cheme Dec 5, 2019
ead5856
Fix doc tests, and remove StorageOverlay and ChildStorageOverlay
cheme Dec 6, 2019
9e05542
Merge branch 'master' into child_uuid_step1
cheme Dec 8, 2019
6f107d0
Merge branch 'master' into child_uuid_step1
cheme Dec 10, 2019
17dd44d
Merge branch 'master' into child_uuid_step1
cheme Dec 11, 2019
0aaeefa
Merge branch 'master' into child_uuid_step1
cheme Dec 11, 2019
489c9f9
Merge branch 'master' into child_uuid_step1
cheme Dec 11, 2019
c58b539
Merge branch 'master' into child_uuid_step1
cheme Dec 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Restore Keyspacedb from other branch, only apply to child trie.
  • Loading branch information
cheme committed Nov 20, 2019
commit e8e72fcfc194262a7980aea561d3eeed99eae905
9 changes: 9 additions & 0 deletions primitives/core/storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ impl<'a> ChildInfo<'a> {
}
}

/// Return byte sequence (keyspace) that can be use for underlying db to isolate keys.
pub fn keyspace(&self) -> &[u8] {
match self {
ChildInfo::Default(ChildTrie {
root: _root,
unique_id,
}) => &unique_id[..],
}
}
}

/// Type of child, this can be different child usage
Expand Down
2 changes: 2 additions & 0 deletions primitives/state-machine/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,8 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
let mut root_map = None;
for (child_info, map) in &self.inner {
if let Some((storage_key, _child_info)) = child_info.as_ref() {
// no need to use child_info at this point because we use a MemoryDB for
// proof (with PrefixedMemoryDB it would be needed).
let ch = insert_into_memory_db::<H, _>(&mut mdb, map.clone().into_iter())?;
new_child_roots.push((storage_key.clone(), ch.as_ref().into()));
} else {
Expand Down
3 changes: 1 addition & 2 deletions primitives/state-machine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,8 +1143,7 @@ mod tests {
println!("test duplicate for {:?} {:?}", k, value);
}
}
// TODO EMCH revert this condition when implemented!!!
assert!(duplicate);
assert!(!duplicate);
}

#[test]
Expand Down
2 changes: 2 additions & 0 deletions primitives/state-machine/src/proving_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H>
pub fn child_storage(
&mut self,
storage_key: &[u8],
child_info: ChildInfo,
key: &[u8]
) -> Result<Option<Vec<u8>>, String> {
let root = self.storage(storage_key)?
Expand All @@ -158,6 +159,7 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H>

read_child_trie_value_with::<Layout<H>, _, _>(
storage_key,
child_info.keyspace(),
&eph,
&root,
key,
Expand Down
15 changes: 8 additions & 7 deletions primitives/state-machine/src/trie_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
fn child_storage(
&self,
storage_key: &[u8],
_child_info: ChildInfo,
child_info: ChildInfo,
key: &[u8],
) -> Result<Option<Vec<u8>>, Self::Error> {
self.essence.child_storage(storage_key, key)
self.essence.child_storage(storage_key, child_info, key)
}

fn for_keys_with_prefix<F: FnMut(&[u8])>(&self, prefix: &[u8], f: F) {
Expand All @@ -95,10 +95,10 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
fn for_keys_in_child_storage<F: FnMut(&[u8])>(
&self,
storage_key: &[u8],
_child_info: ChildInfo,
child_info: ChildInfo,
f: F,
) {
self.essence.for_keys_in_child_storage(storage_key, f)
self.essence.for_keys_in_child_storage(storage_key, child_info, f)
}

fn for_child_keys_with_prefix<F: FnMut(&[u8])>(
Expand Down Expand Up @@ -179,7 +179,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
fn child_storage_root<I>(
&self,
storage_key: &[u8],
_child_info: ChildInfo,
child_info: ChildInfo,
delta: I,
) -> (Vec<u8>, bool, Self::Transaction)
where
Expand All @@ -205,6 +205,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where

match child_delta_trie_root::<Layout<H>, _, _, _, _>(
storage_key,
child_info.keyspace(),
&mut eph,
root.clone(),
delta
Expand All @@ -229,7 +230,7 @@ pub mod tests {
use std::collections::HashSet;
use primitives::{Blake2Hasher, H256};
use codec::Encode;
use trie::{TrieMut, PrefixedMemoryDB, trie_types::TrieDBMut};
use trie::{TrieMut, PrefixedMemoryDB, trie_types::TrieDBMut, KeySpacedDBMut};
use super::*;

const CHILD_KEY_1: &[u8] = b":child_storage:default:sub1";
Expand All @@ -241,7 +242,7 @@ pub mod tests {
let mut root = H256::default();
let mut mdb = PrefixedMemoryDB::<Blake2Hasher>::default();
{
// TODO EMCH let mut mdb = KeySpacedDBMut::new(&mut mdb, Some(&keyspace1));
let mut mdb = KeySpacedDBMut::new(&mut mdb, CHILD_UUID_1);
let mut trie = TrieDBMut::new(&mut mdb, &mut root);
trie.insert(b"value3", &[142]).expect("insert failed");
trie.insert(b"value4", &[124]).expect("insert failed");
Expand Down
19 changes: 16 additions & 3 deletions primitives/state-machine/src/trie_backend_essence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue,
for_keys_in_child_trie};
use trie::trie_types::{TrieDB, TrieError, Layout};
use crate::backend::Consolidate;
use primitives::storage::ChildInfo;

/// Patricia trie-based storage trait.
pub trait Storage<H: Hasher>: Send + Sync {
Expand Down Expand Up @@ -77,7 +78,12 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {
}

/// Get the value of child storage at given key.
pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result<Option<Vec<u8>>, String> {
pub fn child_storage(
&self,
storage_key: &[u8],
child_info: ChildInfo,
key: &[u8],
) -> Result<Option<Vec<u8>>, String> {
let root = self.storage(storage_key)?
.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key));

Expand All @@ -89,11 +95,17 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {

let map_e = |e| format!("Trie lookup error: {}", e);

read_child_trie_value::<Layout<H>, _>(storage_key, &eph, &root, key).map_err(map_e)
read_child_trie_value::<Layout<H>, _>(storage_key, 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], f: F) {
pub fn for_keys_in_child_storage<F: FnMut(&[u8])>(
&self,
storage_key: &[u8],
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)),
Err(e) => {
Expand All @@ -110,6 +122,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> TrieBackendEssence<S, H> {

if let Err(e) = for_keys_in_child_trie::<Layout<H>, _, Ephemeral<S, H>>(
storage_key,
child_info.keyspace(),
&eph,
&root,
f,
Expand Down
115 changes: 110 additions & 5 deletions primitives/trie/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ mod node_codec;
mod trie_stream;

use rstd::boxed::Box;
use rstd::marker::PhantomData;
use rstd::vec::Vec;
use hash_db::Hasher;
use hash_db::{Hasher, Prefix};
/// Our `NodeCodec`-specific error.
pub use error::Error;
/// The Substrate format implementation of `TrieStream`.
Expand Down Expand Up @@ -186,6 +187,7 @@ pub fn child_trie_root<L: TrieConfiguration, I, A, B>(_storage_key: &[u8], input
/// but a generic implementation may ignore this type parameter and use other hashers.
pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB>(
_storage_key: &[u8],
keyspace: &[u8],
db: &mut DB,
root_vec: Vec<u8>,
delta: I
Expand All @@ -202,7 +204,8 @@ pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB>(
root.as_mut().copy_from_slice(&root_vec);

{
let mut trie = TrieDBMut::<L>::from_existing(&mut *db, &mut root)?;
let mut db = KeySpacedDBMut::new(&mut *db, keyspace);
let mut trie = TrieDBMut::<L>::from_existing(&mut db, &mut root)?;

for (key, change) in delta {
match change {
Expand All @@ -218,6 +221,7 @@ pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB>(
/// Call `f` for all keys in a child trie.
pub fn for_keys_in_child_trie<L: TrieConfiguration, F: FnMut(&[u8]), DB>(
_storage_key: &[u8],
keyspace: &[u8],
db: &DB,
root_slice: &[u8],
mut f: F
Expand All @@ -230,7 +234,8 @@ pub fn for_keys_in_child_trie<L: TrieConfiguration, F: FnMut(&[u8]), DB>(
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);

let trie = TrieDB::<L>::new(&*db, &root)?;
let db = KeySpacedDB::new(&*db, keyspace);
let trie = TrieDB::<L>::new(&db, &root)?;
let iter = trie.iter()?;

for x in iter {
Expand Down Expand Up @@ -267,6 +272,7 @@ pub fn record_all_keys<L: TrieConfiguration, DB>(
/// Read a value from the child trie.
pub fn read_child_trie_value<L: TrieConfiguration, DB>(
_storage_key: &[u8],
keyspace: &[u8],
db: &DB,
root_slice: &[u8],
key: &[u8]
Expand All @@ -279,12 +285,14 @@ pub fn read_child_trie_value<L: TrieConfiguration, DB>(
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);

Ok(TrieDB::<L>::new(&*db, &root)?.get(key).map(|x| x.map(|val| val.to_vec()))?)
let db = KeySpacedDB::new(&*db, keyspace);
Ok(TrieDB::<L>::new(&db, &root)?.get(key).map(|x| x.map(|val| val.to_vec()))?)
}

/// Read a value from the child trie with given query.
pub fn read_child_trie_value_with<L: TrieConfiguration, Q: Query<L::Hash, Item=DBValue>, DB>(
_storage_key: &[u8],
keyspace: &[u8],
db: &DB,
root_slice: &[u8],
key: &[u8],
Expand All @@ -298,7 +306,104 @@ pub fn read_child_trie_value_with<L: TrieConfiguration, Q: Query<L::Hash, Item=D
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);

Ok(TrieDB::<L>::new(&*db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?)
let db = KeySpacedDB::new(&*db, keyspace);
Ok(TrieDB::<L>::new(&db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))?)
}

/// `HashDB` implementation that append a encoded prefix (unique id bytes) in addition to the
/// prefix of every key value.
pub struct KeySpacedDB<'a, DB, H>(&'a DB, &'a [u8], PhantomData<H>);

/// `HashDBMut` implementation that append a encoded prefix (unique id bytes) in addition to the
/// prefix of every key value.
///
/// Mutable variant of `KeySpacedDB`, see [`KeySpacedDB`].
pub struct KeySpacedDBMut<'a, DB, H>(&'a mut DB, &'a [u8], PhantomData<H>);

/// Utility function used to merge some byte data (keyspace) and `prefix` data
/// before calling key value database primitives.
fn keyspace_as_prefix_alloc(ks: &[u8], prefix: Prefix) -> (Vec<u8>, Option<u8>) {
let mut result = rstd::vec![0; ks.len() + prefix.0.len()];
result[..ks.len()].copy_from_slice(ks);
result[ks.len()..].copy_from_slice(prefix.0);
(result, prefix.1)
}

impl<'a, DB, H> KeySpacedDB<'a, DB, H> where
H: Hasher,
{
/// instantiate new keyspaced db
pub fn new(db: &'a DB, ks: &'a [u8]) -> Self {
KeySpacedDB(db, ks, PhantomData)
}
}

impl<'a, DB, H> KeySpacedDBMut<'a, DB, H> where
H: Hasher,
{
/// instantiate new keyspaced db
pub fn new(db: &'a mut DB, ks: &'a [u8]) -> Self {
KeySpacedDBMut(db, ks, PhantomData)
}
}

impl<'a, DB, H, T> hash_db::HashDBRef<H, T> for KeySpacedDB<'a, DB, H> where
DB: hash_db::HashDBRef<H, T>,
H: Hasher,
T: From<&'static [u8]>,
{
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.get(key, (&derived_prefix.0, derived_prefix.1))
}

fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.contains(key, (&derived_prefix.0, derived_prefix.1))
}
}

impl<'a, DB, H, T> hash_db::HashDB<H, T> for KeySpacedDBMut<'a, DB, H> where
DB: hash_db::HashDB<H, T>,
H: Hasher,
T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
{
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.get(key, (&derived_prefix.0, derived_prefix.1))
}

fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.contains(key, (&derived_prefix.0, derived_prefix.1))
}

fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.insert((&derived_prefix.0, derived_prefix.1), value)
}

fn emplace(&mut self, key: H::Out, prefix: Prefix, value: T) {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.emplace(key, (&derived_prefix.0, derived_prefix.1), value)
}

fn remove(&mut self, key: &H::Out, prefix: Prefix) {
let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
self.0.remove(key, (&derived_prefix.0, derived_prefix.1))
}
}

impl<'a, DB, H, T> hash_db::AsHashDB<H, T> for KeySpacedDBMut<'a, DB, H> where
DB: hash_db::HashDB<H, T>,
H: Hasher,
T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
{
fn as_hash_db(&self) -> &dyn hash_db::HashDB<H, T> { &*self }

fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn hash_db::HashDB<H, T> + 'b) {
&mut *self
}
}

/// Constants used into trie simplification codec.
Expand Down