Implement change trie for child trie. (#3122)

* Initial implementation, some redundancy is awkward and there is
some useless computation (but there is a pending pr for that).
Next are tests.

* Minimal tests and fix extend child.

* implement iterator for change child trie.

* prune child trie.

* Fix pruning test.

* bump spec version.

* Avoid empty child trie (could also be checked before)

* tabs.

* Fix child digest overriding each others.

* Restore doc deleted on merge.

* Check correct child value on extrinsics build.

* Revert runtime version update.
This commit is contained in:
cheme
2019-09-02 11:10:42 +02:00
committed by Svyatoslav Nikolsky
parent 06658e0c3c
commit e3d0c60a31
23 changed files with 670 additions and 138 deletions
@@ -55,7 +55,7 @@ pub struct OverlayedChangeSet {
/// Top level storage changes.
pub top: HashMap<Vec<u8>, OverlayedValue>,
/// Child storage changes.
pub children: HashMap<Vec<u8>, (Option<BTreeSet<u32>>, HashMap<Vec<u8>, Option<Vec<u8>>>)>,
pub children: HashMap<Vec<u8>, HashMap<Vec<u8>, OverlayedValue>>,
}
#[cfg(test)]
@@ -117,14 +117,14 @@ impl OverlayedChanges {
/// value has been set.
pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option<Option<&[u8]>> {
if let Some(map) = self.prospective.children.get(storage_key) {
if let Some(val) = map.1.get(key) {
return Some(val.as_ref().map(AsRef::as_ref));
if let Some(val) = map.get(key) {
return Some(val.value.as_ref().map(AsRef::as_ref));
}
}
if let Some(map) = self.committed.children.get(storage_key) {
if let Some(val) = map.1.get(key) {
return Some(val.as_ref().map(AsRef::as_ref));
if let Some(val) = map.get(key) {
return Some(val.value.as_ref().map(AsRef::as_ref));
}
}
@@ -151,10 +151,11 @@ impl OverlayedChanges {
pub(crate) fn set_child_storage(&mut self, storage_key: Vec<u8>, key: Vec<u8>, val: Option<Vec<u8>>) {
let extrinsic_index = self.extrinsic_index();
let map_entry = self.prospective.children.entry(storage_key).or_default();
map_entry.1.insert(key, val);
let entry = map_entry.entry(key).or_default();
entry.value = val;
if let Some(extrinsic) = extrinsic_index {
map_entry.0.get_or_insert_with(Default::default)
entry.extrinsics.get_or_insert_with(Default::default)
.insert(extrinsic);
}
}
@@ -169,16 +170,28 @@ impl OverlayedChanges {
let extrinsic_index = self.extrinsic_index();
let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default();
if let Some(extrinsic) = extrinsic_index {
map_entry.0.get_or_insert_with(Default::default)
.insert(extrinsic);
}
map_entry.values_mut().for_each(|e| {
if let Some(extrinsic) = extrinsic_index {
e.extrinsics.get_or_insert_with(Default::default)
.insert(extrinsic);
}
map_entry.1.values_mut().for_each(|e| *e = None);
e.value = None;
});
if let Some((_, committed_map)) = self.committed.children.get(storage_key) {
for (key, _) in committed_map.iter() {
map_entry.1.insert(key.clone(), None);
if let Some(committed_map) = self.committed.children.get(storage_key) {
for (key, value) in committed_map.iter() {
if !map_entry.contains_key(key) {
map_entry.insert(key.clone(), OverlayedValue {
value: None,
extrinsics: extrinsic_index.map(|i| {
let mut e = value.extrinsics.clone()
.unwrap_or_else(|| BTreeSet::default());
e.insert(i);
e
}),
});
}
}
}
}
@@ -224,12 +237,12 @@ impl OverlayedChanges {
let extrinsic_index = self.extrinsic_index();
let map_entry = self.prospective.children.entry(storage_key.to_vec()).or_default();
for (key, entry) in map_entry.1.iter_mut() {
for (key, entry) in map_entry.iter_mut() {
if key.starts_with(prefix) {
*entry = None;
entry.value = None;
if let Some(extrinsic) = extrinsic_index {
map_entry.0.get_or_insert_with(Default::default)
entry.extrinsics.get_or_insert_with(Default::default)
.insert(extrinsic);
}
}
@@ -238,13 +251,13 @@ impl OverlayedChanges {
if let Some(child_committed) = self.committed.children.get(storage_key) {
// Then do the same with keys from commited changes.
// NOTE that we are making changes in the prospective change set.
for key in child_committed.1.keys() {
for key in child_committed.keys() {
if key.starts_with(prefix) {
let entry = map_entry.1.entry(key.clone()).or_default();
*entry = None;
let entry = map_entry.entry(key.clone()).or_default();
entry.value = None;
if let Some(extrinsic) = extrinsic_index {
map_entry.0.get_or_insert_with(Default::default)
entry.extrinsics.get_or_insert_with(Default::default)
.insert(extrinsic);
}
}
@@ -271,13 +284,16 @@ impl OverlayedChanges {
.extend(prospective_extrinsics);
}
}
for (storage_key, map) in self.prospective.children.drain() {
let entry = self.committed.children.entry(storage_key).or_default();
entry.1.extend(map.1.iter().map(|(k, v)| (k.clone(), v.clone())));
for (storage_key, mut map) in self.prospective.children.drain() {
let map_dest = self.committed.children.entry(storage_key).or_default();
for (key, val) in map.drain() {
let entry = map_dest.entry(key).or_default();
entry.value = val.value;
if let Some(prospective_extrinsics) = map.0 {
entry.0.get_or_insert_with(Default::default)
.extend(prospective_extrinsics);
if let Some(prospective_extrinsics) = val.extrinsics {
entry.extrinsics.get_or_insert_with(Default::default)
.extend(prospective_extrinsics);
}
}
}
}
@@ -293,7 +309,8 @@ impl OverlayedChanges {
){
assert!(self.prospective.is_empty());
(self.committed.top.into_iter().map(|(k, v)| (k, v.value)),
self.committed.children.into_iter().map(|(sk, v)| (sk, v.1.into_iter())))
self.committed.children.into_iter()
.map(|(sk, v)| (sk, v.into_iter().map(|(k, v)| (k, v.value)))))
}
/// Inserts storage entry responsible for current extrinsic index.