mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-27 09:21:07 +00:00
Child trie api changes BREAKING (#4857)
Co-Authored-By: thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
@@ -29,7 +29,7 @@ use crate::{
|
||||
use std::iter::FromIterator;
|
||||
use std::collections::{HashMap, BTreeMap, BTreeSet};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, OwnedChildInfo, ChildInfo};
|
||||
use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo};
|
||||
use std::{mem, ops};
|
||||
|
||||
use hash_db::Hasher;
|
||||
@@ -79,8 +79,8 @@ pub struct OverlayedValue {
|
||||
pub struct OverlayedChangeSet {
|
||||
/// Top level storage changes.
|
||||
pub top: BTreeMap<StorageKey, OverlayedValue>,
|
||||
/// Child storage changes.
|
||||
pub children: HashMap<StorageKey, (BTreeMap<StorageKey, OverlayedValue>, OwnedChildInfo)>,
|
||||
/// Child storage changes. The map key is the child storage key without the common prefix.
|
||||
pub children_default: HashMap<StorageKey, (BTreeMap<StorageKey, OverlayedValue>, ChildInfo)>,
|
||||
}
|
||||
|
||||
/// A storage changes structure that can be generated by the data collected in [`OverlayedChanges`].
|
||||
@@ -174,7 +174,7 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet {
|
||||
fn from_iter<T: IntoIterator<Item = (StorageKey, OverlayedValue)>>(iter: T) -> Self {
|
||||
Self {
|
||||
top: iter.into_iter().collect(),
|
||||
children: Default::default(),
|
||||
children_default: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,13 +182,13 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet {
|
||||
impl OverlayedChangeSet {
|
||||
/// Whether the change set is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.top.is_empty() && self.children.is_empty()
|
||||
self.top.is_empty() && self.children_default.is_empty()
|
||||
}
|
||||
|
||||
/// Clear the change set.
|
||||
pub fn clear(&mut self) {
|
||||
self.top.clear();
|
||||
self.children.clear();
|
||||
self.children_default.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,8 +219,8 @@ impl OverlayedChanges {
|
||||
/// Returns a double-Option: None if the key is unknown (i.e. and the query should be referred
|
||||
/// to the backend); Some(None) if the key has been deleted. Some(Some(...)) for a key whose
|
||||
/// 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) {
|
||||
pub fn child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> Option<Option<&[u8]>> {
|
||||
if let Some(map) = self.prospective.children_default.get(child_info.storage_key()) {
|
||||
if let Some(val) = map.0.get(key) {
|
||||
let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0);
|
||||
self.stats.tally_read_modified(size_read);
|
||||
@@ -228,7 +228,7 @@ impl OverlayedChanges {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(map) = self.committed.children.get(storage_key) {
|
||||
if let Some(map) = self.committed.children_default.get(child_info.storage_key()) {
|
||||
if let Some(val) = map.0.get(key) {
|
||||
let size_read = val.value.as_ref().map(|x| x.len() as u64).unwrap_or(0);
|
||||
self.stats.tally_read_modified(size_read);
|
||||
@@ -260,15 +260,15 @@ impl OverlayedChanges {
|
||||
/// `None` can be used to delete a value specified by the given key.
|
||||
pub(crate) fn set_child_storage(
|
||||
&mut self,
|
||||
storage_key: StorageKey,
|
||||
child_info: ChildInfo,
|
||||
child_info: &ChildInfo,
|
||||
key: StorageKey,
|
||||
val: Option<StorageValue>,
|
||||
) {
|
||||
let size_write = val.as_ref().map(|x| x.len() as u64).unwrap_or(0);
|
||||
self.stats.tally_write_overlay(size_write);
|
||||
let extrinsic_index = self.extrinsic_index();
|
||||
let map_entry = self.prospective.children.entry(storage_key)
|
||||
let storage_key = child_info.storage_key().to_vec();
|
||||
let map_entry = self.prospective.children_default.entry(storage_key)
|
||||
.or_insert_with(|| (Default::default(), child_info.to_owned()));
|
||||
let updatable = map_entry.1.try_update(child_info);
|
||||
debug_assert!(updatable);
|
||||
@@ -290,11 +290,11 @@ impl OverlayedChanges {
|
||||
/// [`discard_prospective`]: #method.discard_prospective
|
||||
pub(crate) fn clear_child_storage(
|
||||
&mut self,
|
||||
storage_key: &[u8],
|
||||
child_info: ChildInfo,
|
||||
child_info: &ChildInfo,
|
||||
) {
|
||||
let extrinsic_index = self.extrinsic_index();
|
||||
let map_entry = self.prospective.children.entry(storage_key.to_vec())
|
||||
let storage_key = child_info.storage_key();
|
||||
let map_entry = self.prospective.children_default.entry(storage_key.to_vec())
|
||||
.or_insert_with(|| (Default::default(), child_info.to_owned()));
|
||||
let updatable = map_entry.1.try_update(child_info);
|
||||
debug_assert!(updatable);
|
||||
@@ -308,7 +308,7 @@ impl OverlayedChanges {
|
||||
e.value = None;
|
||||
});
|
||||
|
||||
if let Some((committed_map, _child_info)) = self.committed.children.get(storage_key) {
|
||||
if let Some((committed_map, _child_info)) = self.committed.children_default.get(storage_key) {
|
||||
for (key, value) in committed_map.iter() {
|
||||
if !map_entry.0.contains_key(key) {
|
||||
map_entry.0.insert(key.clone(), OverlayedValue {
|
||||
@@ -364,12 +364,12 @@ impl OverlayedChanges {
|
||||
|
||||
pub(crate) fn clear_child_prefix(
|
||||
&mut self,
|
||||
storage_key: &[u8],
|
||||
child_info: ChildInfo,
|
||||
child_info: &ChildInfo,
|
||||
prefix: &[u8],
|
||||
) {
|
||||
let extrinsic_index = self.extrinsic_index();
|
||||
let map_entry = self.prospective.children.entry(storage_key.to_vec())
|
||||
let storage_key = child_info.storage_key();
|
||||
let map_entry = self.prospective.children_default.entry(storage_key.to_vec())
|
||||
.or_insert_with(|| (Default::default(), child_info.to_owned()));
|
||||
let updatable = map_entry.1.try_update(child_info);
|
||||
debug_assert!(updatable);
|
||||
@@ -385,7 +385,7 @@ impl OverlayedChanges {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((child_committed, _child_info)) = self.committed.children.get(storage_key) {
|
||||
if let Some((child_committed, _child_info)) = self.committed.children_default.get(storage_key) {
|
||||
// Then do the same with keys from committed changes.
|
||||
// NOTE that we are making changes in the prospective change set.
|
||||
for key in child_committed.keys() {
|
||||
@@ -422,8 +422,8 @@ impl OverlayedChanges {
|
||||
.extend(prospective_extrinsics);
|
||||
}
|
||||
}
|
||||
for (storage_key, (map, child_info)) in self.prospective.children.drain() {
|
||||
let child_content = self.committed.children.entry(storage_key)
|
||||
for (storage_key, (map, child_info)) in self.prospective.children_default.drain() {
|
||||
let child_content = self.committed.children_default.entry(storage_key)
|
||||
.or_insert_with(|| (Default::default(), child_info));
|
||||
// No update to child info at this point (will be needed for deletion).
|
||||
for (key, val) in map.into_iter() {
|
||||
@@ -445,14 +445,14 @@ impl OverlayedChanges {
|
||||
/// Will panic if there are any uncommitted prospective changes.
|
||||
fn drain_committed(&mut self) -> (
|
||||
impl Iterator<Item=(StorageKey, Option<StorageValue>)>,
|
||||
impl Iterator<Item=(StorageKey, (impl Iterator<Item=(StorageKey, Option<StorageValue>)>, OwnedChildInfo))>,
|
||||
impl Iterator<Item=(StorageKey, (impl Iterator<Item=(StorageKey, Option<StorageValue>)>, ChildInfo))>,
|
||||
) {
|
||||
assert!(self.prospective.is_empty());
|
||||
(
|
||||
std::mem::replace(&mut self.committed.top, Default::default())
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.value)),
|
||||
std::mem::replace(&mut self.committed.children, Default::default())
|
||||
std::mem::replace(&mut self.committed.children_default, Default::default())
|
||||
.into_iter()
|
||||
.map(|(sk, (v, ci))| (sk, (v.into_iter().map(|(k, v)| (k, v.value)), ci))),
|
||||
)
|
||||
@@ -549,21 +549,20 @@ impl OverlayedChanges {
|
||||
) -> H::Out
|
||||
where H::Out: Ord + Encode,
|
||||
{
|
||||
let child_storage_keys = self.prospective.children.keys()
|
||||
.chain(self.committed.children.keys());
|
||||
let child_storage_keys = self.prospective.children_default.keys()
|
||||
.chain(self.committed.children_default.keys());
|
||||
let child_delta_iter = child_storage_keys.map(|storage_key|
|
||||
(
|
||||
storage_key.clone(),
|
||||
self.committed.children.get(storage_key)
|
||||
self.default_child_info(storage_key).cloned()
|
||||
.expect("child info initialized in either committed or prospective"),
|
||||
self.committed.children_default.get(storage_key)
|
||||
.into_iter()
|
||||
.flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))
|
||||
.chain(
|
||||
self.prospective.children.get(storage_key)
|
||||
self.prospective.children_default.get(storage_key)
|
||||
.into_iter()
|
||||
.flat_map(|(map, _)| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))
|
||||
),
|
||||
self.child_info(storage_key).cloned()
|
||||
.expect("child info initialized in either committed or prospective"),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -610,11 +609,11 @@ impl OverlayedChanges {
|
||||
|
||||
/// Get child info for a storage key.
|
||||
/// Take the latest value so prospective first.
|
||||
pub fn child_info(&self, storage_key: &[u8]) -> Option<&OwnedChildInfo> {
|
||||
if let Some((_, ci)) = self.prospective.children.get(storage_key) {
|
||||
pub fn default_child_info(&self, storage_key: &[u8]) -> Option<&ChildInfo> {
|
||||
if let Some((_, ci)) = self.prospective.children_default.get(storage_key) {
|
||||
return Some(&ci);
|
||||
}
|
||||
if let Some((_, ci)) = self.committed.children.get(storage_key) {
|
||||
if let Some((_, ci)) = self.committed.children_default.get(storage_key) {
|
||||
return Some(&ci);
|
||||
}
|
||||
None
|
||||
@@ -654,10 +653,10 @@ impl OverlayedChanges {
|
||||
) -> Option<(&[u8], &OverlayedValue)> {
|
||||
let range = (ops::Bound::Excluded(key), ops::Bound::Unbounded);
|
||||
|
||||
let next_prospective_key = self.prospective.children.get(storage_key)
|
||||
let next_prospective_key = self.prospective.children_default.get(storage_key)
|
||||
.and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v)));
|
||||
|
||||
let next_committed_key = self.committed.children.get(storage_key)
|
||||
let next_committed_key = self.committed.children_default.get(storage_key)
|
||||
.and_then(|(map, _)| map.range::<[u8], _>(range).next().map(|(k, v)| (&k[..], v)));
|
||||
|
||||
match (next_committed_key, next_prospective_key) {
|
||||
@@ -866,39 +865,40 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn next_child_storage_key_change_works() {
|
||||
let child = b"Child1".to_vec();
|
||||
let child_info = ChildInfo::new_default(b"uniqueid");
|
||||
let child_info = ChildInfo::new_default(b"Child1");
|
||||
let child_info = &child_info;
|
||||
let child = child_info.storage_key();
|
||||
let mut overlay = OverlayedChanges::default();
|
||||
overlay.set_child_storage(child.clone(), child_info, vec![20], Some(vec![20]));
|
||||
overlay.set_child_storage(child.clone(), child_info, vec![30], Some(vec![30]));
|
||||
overlay.set_child_storage(child.clone(), child_info, vec![40], Some(vec![40]));
|
||||
overlay.set_child_storage(child_info, vec![20], Some(vec![20]));
|
||||
overlay.set_child_storage(child_info, vec![30], Some(vec![30]));
|
||||
overlay.set_child_storage(child_info, vec![40], Some(vec![40]));
|
||||
overlay.commit_prospective();
|
||||
overlay.set_child_storage(child.clone(), child_info, vec![10], Some(vec![10]));
|
||||
overlay.set_child_storage(child.clone(), child_info, vec![30], None);
|
||||
overlay.set_child_storage(child_info, vec![10], Some(vec![10]));
|
||||
overlay.set_child_storage(child_info, vec![30], None);
|
||||
|
||||
// next_prospective < next_committed
|
||||
let next_to_5 = overlay.next_child_storage_key_change(&child, &[5]).unwrap();
|
||||
let next_to_5 = overlay.next_child_storage_key_change(child, &[5]).unwrap();
|
||||
assert_eq!(next_to_5.0.to_vec(), vec![10]);
|
||||
assert_eq!(next_to_5.1.value, Some(vec![10]));
|
||||
|
||||
// next_committed < next_prospective
|
||||
let next_to_10 = overlay.next_child_storage_key_change(&child, &[10]).unwrap();
|
||||
let next_to_10 = overlay.next_child_storage_key_change(child, &[10]).unwrap();
|
||||
assert_eq!(next_to_10.0.to_vec(), vec![20]);
|
||||
assert_eq!(next_to_10.1.value, Some(vec![20]));
|
||||
|
||||
// next_committed == next_prospective
|
||||
let next_to_20 = overlay.next_child_storage_key_change(&child, &[20]).unwrap();
|
||||
let next_to_20 = overlay.next_child_storage_key_change(child, &[20]).unwrap();
|
||||
assert_eq!(next_to_20.0.to_vec(), vec![30]);
|
||||
assert_eq!(next_to_20.1.value, None);
|
||||
|
||||
// next_committed, no next_prospective
|
||||
let next_to_30 = overlay.next_child_storage_key_change(&child, &[30]).unwrap();
|
||||
let next_to_30 = overlay.next_child_storage_key_change(child, &[30]).unwrap();
|
||||
assert_eq!(next_to_30.0.to_vec(), vec![40]);
|
||||
assert_eq!(next_to_30.1.value, Some(vec![40]));
|
||||
|
||||
overlay.set_child_storage(child.clone(), child_info, vec![50], Some(vec![50]));
|
||||
overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
|
||||
// next_prospective, no next_committed
|
||||
let next_to_40 = overlay.next_child_storage_key_change(&child, &[40]).unwrap();
|
||||
let next_to_40 = overlay.next_child_storage_key_change(child, &[40]).unwrap();
|
||||
assert_eq!(next_to_40.0.to_vec(), vec![50]);
|
||||
assert_eq!(next_to_40.1.value, Some(vec![50]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user