Fix key collision for child trie (#4162)

* In progress, runtime io must switch to future proof root +
child_specific (unique id) + u32 type.

* Switch interface, sr-io seems ok, rpc could use similar interface to
sr-io, genesis json broken if there is child trie in existing encoding
genesis.

* test from previous implementation.

* fix proving test.

* Restore Keyspacedb from other branch, only apply to child trie.

* Removing unneeded child_info from child root (child info are stored
if things changed, otherwhise the root does not change).

* Switch rpc to use same format as ext: more future proof.

* use root from child info for trie backend essence.

* Breaking long lines.

* Update doc and clean pr a bit.

* fix error type

* Restore removed doc on merge and update sr-io doc.

* Switch child storage api to use directly unique id, if managed id
where to be put in place, the api will change at this time.

* Clean deprecated host interface from child.

* Removing assertion on child info (can fail depending on root
memoization).

* merging child info in the overlay when possible.

* child iteration by prefix using child_info.

* Using ChainInfo in frame support. ChainInfo gets redesign to avoid
buffers allocation on every calls.

* Add length of root to the data of child info.

* comments

* Encode compact.

* Remove child info with root.

* Fix try_update condition.

* Comment Ext child root caching.

* Replace tuples by struct with field

* remove StorageTuple alias.

* Fix doc tests, and remove StorageOverlay and ChildStorageOverlay
aliases.
This commit is contained in:
cheme
2019-12-14 03:11:19 +01:00
committed by Gavin Wood
parent 7121837f84
commit 0ece5d9e17
53 changed files with 2121 additions and 918 deletions
+34 -9
View File
@@ -21,7 +21,7 @@ use self::error::Error;
use std::sync::Arc;
use assert_matches::assert_matches;
use futures01::stream::Stream;
use primitives::storage::well_known_keys;
use primitives::storage::{well_known_keys, ChildInfo};
use primitives::hash::H256;
use sp_io::hashing::blake2_256;
use test_client::{
@@ -30,6 +30,8 @@ use test_client::{
runtime,
};
const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"unique_id");
#[test]
fn should_return_storage() {
const KEY: &[u8] = b":mock";
@@ -40,12 +42,14 @@ fn should_return_storage() {
let mut core = tokio::runtime::Runtime::new().unwrap();
let client = TestClientBuilder::new()
.add_extra_storage(KEY.to_vec(), VALUE.to_vec())
.add_extra_child_storage(STORAGE_KEY.to_vec(), KEY.to_vec(), CHILD_VALUE.to_vec())
.add_extra_child_storage(STORAGE_KEY.to_vec(), CHILD_INFO, KEY.to_vec(), CHILD_VALUE.to_vec())
.build();
let genesis_hash = client.genesis_hash();
let client = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor())));
let key = StorageKey(KEY.to_vec());
let storage_key = StorageKey(STORAGE_KEY.to_vec());
let (child_info, child_type) = CHILD_INFO.info();
let child_info = StorageKey(child_info.to_vec());
assert_eq!(
client.storage(key.clone(), Some(genesis_hash).into()).wait()
@@ -63,7 +67,7 @@ fn should_return_storage() {
);
assert_eq!(
core.block_on(
client.child_storage(storage_key, key, Some(genesis_hash).into())
client.child_storage(storage_key, child_info, child_type, key, Some(genesis_hash).into())
.map(|x| x.map(|x| x.0.len()))
).unwrap().unwrap() as usize,
CHILD_VALUE.len(),
@@ -73,27 +77,48 @@ fn should_return_storage() {
#[test]
fn should_return_child_storage() {
let (child_info, child_type) = CHILD_INFO.info();
let child_info = StorageKey(child_info.to_vec());
let core = tokio::runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::TestClientBuilder::new()
.add_child_storage("test", "key", vec![42_u8])
.add_child_storage("test", "key", CHILD_INFO, vec![42_u8])
.build());
let genesis_hash = client.genesis_hash();
let client = new_full(client, Subscriptions::new(Arc::new(core.executor())));
let child_key = StorageKey(well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect());
let child_key = StorageKey(
well_known_keys::CHILD_STORAGE_KEY_PREFIX.iter().chain(b"test").cloned().collect()
);
let key = StorageKey(b"key".to_vec());
assert_matches!(
client.child_storage(child_key.clone(), key.clone(), Some(genesis_hash).into()).wait(),
client.child_storage(
child_key.clone(),
child_info.clone(),
child_type,
key.clone(),
Some(genesis_hash).into(),
).wait(),
Ok(Some(StorageData(ref d))) if d[0] == 42 && d.len() == 1
);
assert_matches!(
client.child_storage_hash(child_key.clone(), key.clone(), Some(genesis_hash).into())
.wait().map(|x| x.is_some()),
client.child_storage_hash(
child_key.clone(),
child_info.clone(),
child_type,
key.clone(),
Some(genesis_hash).into(),
).wait().map(|x| x.is_some()),
Ok(true)
);
assert_matches!(
client.child_storage_size(child_key.clone(), key.clone(), None).wait(),
client.child_storage_size(
child_key.clone(),
child_info.clone(),
child_type,
key.clone(),
None,
).wait(),
Ok(Some(1))
);
}