mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 23:18:01 +00:00
Child trie api changes BREAKING (#4857)
Co-Authored-By: thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
@@ -32,6 +32,7 @@ use crate::{
|
||||
input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex, ChildIndex},
|
||||
},
|
||||
};
|
||||
use sp_core::storage::{ChildInfo, ChildType, PrefixedStorageKey};
|
||||
|
||||
/// Prepare input pairs for building a changes trie of given block.
|
||||
///
|
||||
@@ -105,19 +106,19 @@ fn prepare_extrinsics_input<'a, B, H, Number>(
|
||||
Number: BlockNumber,
|
||||
{
|
||||
|
||||
let mut children_keys = BTreeSet::<StorageKey>::new();
|
||||
let mut children_info = BTreeSet::<ChildInfo>::new();
|
||||
let mut children_result = BTreeMap::new();
|
||||
for (storage_key, _) in changes.prospective.children.iter()
|
||||
.chain(changes.committed.children.iter()) {
|
||||
children_keys.insert(storage_key.clone());
|
||||
for (_storage_key, (_map, child_info)) in changes.prospective.children_default.iter()
|
||||
.chain(changes.committed.children_default.iter()) {
|
||||
children_info.insert(child_info.clone());
|
||||
}
|
||||
for storage_key in children_keys {
|
||||
for child_info in children_info {
|
||||
let child_index = ChildIndex::<Number> {
|
||||
block: block.clone(),
|
||||
storage_key: storage_key.clone(),
|
||||
storage_key: child_info.prefixed_storage_key(),
|
||||
};
|
||||
|
||||
let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(storage_key))?;
|
||||
let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(child_info))?;
|
||||
children_result.insert(child_index, iter);
|
||||
}
|
||||
|
||||
@@ -130,22 +131,22 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>(
|
||||
backend: &'a B,
|
||||
block: &Number,
|
||||
changes: &'a OverlayedChanges,
|
||||
storage_key: Option<StorageKey>,
|
||||
child_info: Option<ChildInfo>,
|
||||
) -> Result<impl Iterator<Item=InputPair<Number>> + 'a, String>
|
||||
where
|
||||
B: Backend<H>,
|
||||
H: Hasher,
|
||||
Number: BlockNumber,
|
||||
{
|
||||
let (committed, prospective, child_info) = if let Some(sk) = storage_key.as_ref() {
|
||||
let child_info = changes.child_info(sk).cloned();
|
||||
(
|
||||
changes.committed.children.get(sk).map(|c| &c.0),
|
||||
changes.prospective.children.get(sk).map(|c| &c.0),
|
||||
child_info,
|
||||
)
|
||||
let (committed, prospective) = if let Some(child_info) = child_info.as_ref() {
|
||||
match child_info.child_type() {
|
||||
ChildType::ParentKeyId => (
|
||||
changes.committed.children_default.get(child_info.storage_key()).map(|c| &c.0),
|
||||
changes.prospective.children_default.get(child_info.storage_key()).map(|c| &c.0),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
(Some(&changes.committed.top), Some(&changes.prospective.top), None)
|
||||
(Some(&changes.committed.top), Some(&changes.prospective.top))
|
||||
};
|
||||
committed.iter().flat_map(|c| c.iter())
|
||||
.chain(prospective.iter().flat_map(|c| c.iter()))
|
||||
@@ -155,13 +156,11 @@ fn prepare_extrinsics_input_inner<'a, B, H, Number>(
|
||||
Entry::Vacant(entry) => {
|
||||
// ignore temporary values (values that have null value at the end of operation
|
||||
// AND are not in storage at the beginning of operation
|
||||
if let Some(sk) = storage_key.as_ref() {
|
||||
if !changes.child_storage(sk, k).map(|v| v.is_some()).unwrap_or_default() {
|
||||
if let Some(child_info) = child_info.as_ref() {
|
||||
if !backend.exists_child_storage(sk, child_info.as_ref(), k)
|
||||
.map_err(|e| format!("{}", e))? {
|
||||
return Ok(map);
|
||||
}
|
||||
if let Some(child_info) = child_info.as_ref() {
|
||||
if !changes.child_storage(child_info, k).map(|v| v.is_some()).unwrap_or_default() {
|
||||
if !backend.exists_child_storage(&child_info, k)
|
||||
.map_err(|e| format!("{}", e))? {
|
||||
return Ok(map);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -281,7 +280,7 @@ fn prepare_digest_input<'a, H, Number>(
|
||||
return Ok((map, child_map));
|
||||
}
|
||||
|
||||
let mut children_roots = BTreeMap::<StorageKey, _>::new();
|
||||
let mut children_roots = BTreeMap::<PrefixedStorageKey, _>::new();
|
||||
{
|
||||
let trie_storage = TrieBackendEssence::<_, H>::new(
|
||||
crate::changes_trie::TrieBackendStorageAdapter(storage),
|
||||
@@ -344,22 +343,20 @@ mod test {
|
||||
use codec::Encode;
|
||||
use sp_core::Blake2Hasher;
|
||||
use sp_core::storage::well_known_keys::EXTRINSIC_INDEX;
|
||||
use sp_core::storage::ChildInfo;
|
||||
use crate::InMemoryBackend;
|
||||
use crate::changes_trie::{RootsStorage, Configuration, storage::InMemoryStorage};
|
||||
use crate::changes_trie::build_cache::{IncompleteCacheAction, IncompleteCachedBuildData};
|
||||
use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet};
|
||||
use super::*;
|
||||
|
||||
const CHILD_INFO_1: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_1");
|
||||
const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2");
|
||||
|
||||
fn prepare_for_build(zero: u64) -> (
|
||||
InMemoryBackend<Blake2Hasher>,
|
||||
InMemoryStorage<Blake2Hasher, u64>,
|
||||
OverlayedChanges,
|
||||
Configuration,
|
||||
) {
|
||||
let child_info_1 = ChildInfo::new_default(b"storage_key1");
|
||||
let child_info_2 = ChildInfo::new_default(b"storage_key2");
|
||||
let backend: InMemoryBackend<_> = vec![
|
||||
(vec![100], vec![255]),
|
||||
(vec![101], vec![255]),
|
||||
@@ -368,8 +365,9 @@ mod test {
|
||||
(vec![104], vec![255]),
|
||||
(vec![105], vec![255]),
|
||||
].into_iter().collect::<std::collections::BTreeMap<_, _>>().into();
|
||||
let child_trie_key1 = b"1".to_vec();
|
||||
let child_trie_key2 = b"2".to_vec();
|
||||
let prefixed_child_trie_key1 = child_info_1.prefixed_storage_key();
|
||||
let child_trie_key1 = child_info_1.storage_key().to_vec();
|
||||
let child_trie_key2 = child_info_2.storage_key().to_vec();
|
||||
let storage = InMemoryStorage::with_inputs(vec![
|
||||
(zero + 1, vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]),
|
||||
@@ -403,7 +401,7 @@ mod test {
|
||||
]),
|
||||
(zero + 9, Vec::new()), (zero + 10, Vec::new()), (zero + 11, Vec::new()), (zero + 12, Vec::new()),
|
||||
(zero + 13, Vec::new()), (zero + 14, Vec::new()), (zero + 15, Vec::new()),
|
||||
], vec![(child_trie_key1.clone(), vec![
|
||||
], vec![(prefixed_child_trie_key1.clone(), vec![
|
||||
(zero + 1, vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![100] }, vec![1, 3]),
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 1, key: vec![101] }, vec![0, 2]),
|
||||
@@ -430,19 +428,19 @@ mod test {
|
||||
extrinsics: Some(vec![0, 1].into_iter().collect())
|
||||
}),
|
||||
].into_iter().collect(),
|
||||
children: vec![
|
||||
children_default: vec![
|
||||
(child_trie_key1.clone(), (vec![
|
||||
(vec![100], OverlayedValue {
|
||||
value: Some(vec![200]),
|
||||
extrinsics: Some(vec![0, 2].into_iter().collect())
|
||||
})
|
||||
].into_iter().collect(), CHILD_INFO_1.to_owned())),
|
||||
].into_iter().collect(), child_info_1.to_owned())),
|
||||
(child_trie_key2, (vec![
|
||||
(vec![100], OverlayedValue {
|
||||
value: Some(vec![200]),
|
||||
extrinsics: Some(vec![0, 2].into_iter().collect())
|
||||
})
|
||||
].into_iter().collect(), CHILD_INFO_2.to_owned())),
|
||||
].into_iter().collect(), child_info_2.to_owned())),
|
||||
].into_iter().collect()
|
||||
},
|
||||
committed: OverlayedChangeSet { top: vec![
|
||||
@@ -459,13 +457,13 @@ mod test {
|
||||
extrinsics: Some(vec![1].into_iter().collect())
|
||||
}),
|
||||
].into_iter().collect(),
|
||||
children: vec![
|
||||
children_default: vec![
|
||||
(child_trie_key1, (vec![
|
||||
(vec![100], OverlayedValue {
|
||||
value: Some(vec![202]),
|
||||
extrinsics: Some(vec![3].into_iter().collect())
|
||||
})
|
||||
].into_iter().collect(), CHILD_INFO_1.to_owned())),
|
||||
].into_iter().collect(), child_info_1.to_owned())),
|
||||
].into_iter().collect(),
|
||||
},
|
||||
collect_extrinsics: true,
|
||||
@@ -487,6 +485,8 @@ mod test {
|
||||
#[test]
|
||||
fn build_changes_trie_nodes_on_non_digest_block() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key();
|
||||
let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key();
|
||||
let (backend, storage, changes, config) = prepare_for_build(zero);
|
||||
let parent = AnchorBlockId { hash: Default::default(), number: zero + 4 };
|
||||
let changes_trie_nodes = prepare_input(
|
||||
@@ -503,11 +503,11 @@ mod test {
|
||||
]);
|
||||
assert_eq!(changes_trie_nodes.1.into_iter()
|
||||
.map(|(k,v)| (k, v.collect::<Vec<_>>())).collect::<Vec<_>>(), vec![
|
||||
(ChildIndex { block: zero + 5u64, storage_key: b"1".to_vec() },
|
||||
(ChildIndex { block: zero + 5u64, storage_key: child_trie_key1 },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5u64, key: vec![100] }, vec![0, 2, 3]),
|
||||
]),
|
||||
(ChildIndex { block: zero + 5, storage_key: b"2".to_vec() },
|
||||
(ChildIndex { block: zero + 5, storage_key: child_trie_key2 },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 5, key: vec![100] }, vec![0, 2]),
|
||||
]),
|
||||
@@ -523,6 +523,8 @@ mod test {
|
||||
#[test]
|
||||
fn build_changes_trie_nodes_on_digest_block_l1() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key();
|
||||
let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key();
|
||||
let (backend, storage, changes, config) = prepare_for_build(zero);
|
||||
let parent = AnchorBlockId { hash: Default::default(), number: zero + 3 };
|
||||
let changes_trie_nodes = prepare_input(
|
||||
@@ -544,7 +546,7 @@ mod test {
|
||||
]);
|
||||
assert_eq!(changes_trie_nodes.1.into_iter()
|
||||
.map(|(k,v)| (k, v.collect::<Vec<_>>())).collect::<Vec<_>>(), vec![
|
||||
(ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() },
|
||||
(ChildIndex { block: zero + 4u64, storage_key: child_trie_key1.clone() },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]),
|
||||
|
||||
@@ -553,7 +555,7 @@ mod test {
|
||||
InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]),
|
||||
InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]),
|
||||
]),
|
||||
(ChildIndex { block: zero + 4, storage_key: b"2".to_vec() },
|
||||
(ChildIndex { block: zero + 4, storage_key: child_trie_key2.clone() },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]),
|
||||
]),
|
||||
@@ -568,6 +570,8 @@ mod test {
|
||||
#[test]
|
||||
fn build_changes_trie_nodes_on_digest_block_l2() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key();
|
||||
let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key();
|
||||
let (backend, storage, changes, config) = prepare_for_build(zero);
|
||||
let parent = AnchorBlockId { hash: Default::default(), number: zero + 15 };
|
||||
let changes_trie_nodes = prepare_input(
|
||||
@@ -590,13 +594,13 @@ mod test {
|
||||
]);
|
||||
assert_eq!(changes_trie_nodes.1.into_iter()
|
||||
.map(|(k,v)| (k, v.collect::<Vec<_>>())).collect::<Vec<_>>(), vec![
|
||||
(ChildIndex { block: zero + 16u64, storage_key: b"1".to_vec() },
|
||||
(ChildIndex { block: zero + 16u64, storage_key: child_trie_key1.clone() },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16u64, key: vec![100] }, vec![0, 2, 3]),
|
||||
|
||||
InputPair::DigestIndex(DigestIndex { block: zero + 16, key: vec![102] }, vec![zero + 4]),
|
||||
]),
|
||||
(ChildIndex { block: zero + 16, storage_key: b"2".to_vec() },
|
||||
(ChildIndex { block: zero + 16, storage_key: child_trie_key2.clone() },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 16, key: vec![100] }, vec![0, 2]),
|
||||
]),
|
||||
@@ -657,6 +661,8 @@ mod test {
|
||||
#[test]
|
||||
fn build_changes_trie_nodes_ignores_temporary_storage_values() {
|
||||
fn test_with_zero(zero: u64) {
|
||||
let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key();
|
||||
let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key();
|
||||
let (backend, storage, mut changes, config) = prepare_for_build(zero);
|
||||
|
||||
// 110: missing from backend, set to None in overlay
|
||||
@@ -685,7 +691,7 @@ mod test {
|
||||
]);
|
||||
assert_eq!(changes_trie_nodes.1.into_iter()
|
||||
.map(|(k,v)| (k, v.collect::<Vec<_>>())).collect::<Vec<_>>(), vec![
|
||||
(ChildIndex { block: zero + 4u64, storage_key: b"1".to_vec() },
|
||||
(ChildIndex { block: zero + 4u64, storage_key: child_trie_key1.clone() },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4u64, key: vec![100] }, vec![0, 2, 3]),
|
||||
|
||||
@@ -694,7 +700,7 @@ mod test {
|
||||
InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![102] }, vec![zero + 2]),
|
||||
InputPair::DigestIndex(DigestIndex { block: zero + 4, key: vec![105] }, vec![zero + 1]),
|
||||
]),
|
||||
(ChildIndex { block: zero + 4, storage_key: b"2".to_vec() },
|
||||
(ChildIndex { block: zero + 4, storage_key: child_trie_key2.clone() },
|
||||
vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: zero + 4, key: vec![100] }, vec![0, 2]),
|
||||
]),
|
||||
@@ -709,6 +715,8 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn cache_is_used_when_changes_trie_is_built() {
|
||||
let child_trie_key1 = ChildInfo::new_default(b"storage_key1").prefixed_storage_key();
|
||||
let child_trie_key2 = ChildInfo::new_default(b"storage_key2").prefixed_storage_key();
|
||||
let (backend, mut storage, changes, config) = prepare_for_build(0);
|
||||
let parent = AnchorBlockId { hash: Default::default(), number: 15 };
|
||||
|
||||
@@ -728,8 +736,8 @@ mod test {
|
||||
let cached_data4 = IncompleteCacheAction::CacheBuildData(IncompleteCachedBuildData::new())
|
||||
.set_digest_input_blocks(vec![1, 2, 3])
|
||||
.insert(None, vec![vec![100], vec![102]].into_iter().collect())
|
||||
.insert(Some(b"1".to_vec()), vec![vec![103], vec![104]].into_iter().collect())
|
||||
.insert(Some(b"2".to_vec()), vec![vec![105], vec![106]].into_iter().collect())
|
||||
.insert(Some(child_trie_key1.clone()), vec![vec![103], vec![104]].into_iter().collect())
|
||||
.insert(Some(child_trie_key2.clone()), vec![vec![105], vec![106]].into_iter().collect())
|
||||
.complete(4, &trie_root4);
|
||||
storage.cache_mut().perform(cached_data4);
|
||||
|
||||
@@ -755,7 +763,10 @@ mod test {
|
||||
.map(|(k, i)| (k, i.collect::<Vec<_>>()))
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
assert_eq!(
|
||||
child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"1".to_vec() }).unwrap(),
|
||||
child_changes_tries_nodes.get(&ChildIndex {
|
||||
block: 16u64,
|
||||
storage_key: child_trie_key1.clone(),
|
||||
}).unwrap(),
|
||||
&vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2, 3]),
|
||||
|
||||
@@ -764,7 +775,7 @@ mod test {
|
||||
],
|
||||
);
|
||||
assert_eq!(
|
||||
child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: b"2".to_vec() }).unwrap(),
|
||||
child_changes_tries_nodes.get(&ChildIndex { block: 16u64, storage_key: child_trie_key2.clone() }).unwrap(),
|
||||
&vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16u64, key: vec![100] }, vec![0, 2]),
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use crate::StorageKey;
|
||||
use sp_core::storage::PrefixedStorageKey;
|
||||
|
||||
/// Changes trie build cache.
|
||||
///
|
||||
@@ -38,7 +39,7 @@ pub struct BuildCache<H, N> {
|
||||
/// The `Option<Vec<u8>>` in inner `HashMap` stands for the child storage key.
|
||||
/// If it is `None`, then the `HashSet` contains keys changed in top-level storage.
|
||||
/// If it is `Some`, then the `HashSet` contains keys changed in child storage, identified by the key.
|
||||
changed_keys: HashMap<H, HashMap<Option<StorageKey>, HashSet<StorageKey>>>,
|
||||
changed_keys: HashMap<H, HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>>,
|
||||
}
|
||||
|
||||
/// The action to perform when block-with-changes-trie is imported.
|
||||
@@ -56,7 +57,7 @@ pub struct CachedBuildData<H, N> {
|
||||
block: N,
|
||||
trie_root: H,
|
||||
digest_input_blocks: Vec<N>,
|
||||
changed_keys: HashMap<Option<StorageKey>, HashSet<StorageKey>>,
|
||||
changed_keys: HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>,
|
||||
}
|
||||
|
||||
/// The action to perform when block-with-changes-trie is imported.
|
||||
@@ -72,7 +73,7 @@ pub(crate) enum IncompleteCacheAction<N> {
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct IncompleteCachedBuildData<N> {
|
||||
digest_input_blocks: Vec<N>,
|
||||
changed_keys: HashMap<Option<StorageKey>, HashSet<StorageKey>>,
|
||||
changed_keys: HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>,
|
||||
}
|
||||
|
||||
impl<H, N> BuildCache<H, N>
|
||||
@@ -89,7 +90,7 @@ impl<H, N> BuildCache<H, N>
|
||||
}
|
||||
|
||||
/// Get cached changed keys for changes trie with given root.
|
||||
pub fn get(&self, root: &H) -> Option<&HashMap<Option<StorageKey>, HashSet<StorageKey>>> {
|
||||
pub fn get(&self, root: &H) -> Option<&HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>> {
|
||||
self.changed_keys.get(&root)
|
||||
}
|
||||
|
||||
@@ -98,7 +99,7 @@ impl<H, N> BuildCache<H, N>
|
||||
pub fn with_changed_keys(
|
||||
&self,
|
||||
root: &H,
|
||||
functor: &mut dyn FnMut(&HashMap<Option<StorageKey>, HashSet<StorageKey>>),
|
||||
functor: &mut dyn FnMut(&HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>),
|
||||
) -> bool {
|
||||
match self.changed_keys.get(&root) {
|
||||
Some(changed_keys) => {
|
||||
@@ -164,7 +165,7 @@ impl<N> IncompleteCacheAction<N> {
|
||||
/// Insert changed keys of given storage into cached data.
|
||||
pub(crate) fn insert(
|
||||
self,
|
||||
storage_key: Option<StorageKey>,
|
||||
storage_key: Option<PrefixedStorageKey>,
|
||||
changed_keys: HashSet<StorageKey>,
|
||||
) -> Self {
|
||||
match self {
|
||||
@@ -200,7 +201,7 @@ impl<N> IncompleteCachedBuildData<N> {
|
||||
|
||||
fn insert(
|
||||
mut self,
|
||||
storage_key: Option<StorageKey>,
|
||||
storage_key: Option<PrefixedStorageKey>,
|
||||
changed_keys: HashSet<StorageKey>,
|
||||
) -> Self {
|
||||
self.changed_keys.insert(storage_key, changed_keys);
|
||||
|
||||
@@ -22,6 +22,7 @@ use std::collections::VecDeque;
|
||||
use codec::{Decode, Encode, Codec};
|
||||
use hash_db::Hasher;
|
||||
use num_traits::Zero;
|
||||
use sp_core::storage::PrefixedStorageKey;
|
||||
use sp_trie::Recorder;
|
||||
use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber};
|
||||
use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue};
|
||||
@@ -40,7 +41,7 @@ pub fn key_changes<'a, H: Hasher, Number: BlockNumber>(
|
||||
begin: Number,
|
||||
end: &'a AnchorBlockId<H::Out, Number>,
|
||||
max: Number,
|
||||
storage_key: Option<&'a [u8]>,
|
||||
storage_key: Option<&'a PrefixedStorageKey>,
|
||||
key: &'a [u8],
|
||||
) -> Result<DrilldownIterator<'a, H, Number>, String> {
|
||||
// we can't query any roots before root
|
||||
@@ -79,7 +80,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>(
|
||||
begin: Number,
|
||||
end: &AnchorBlockId<H::Out, Number>,
|
||||
max: Number,
|
||||
storage_key: Option<&[u8]>,
|
||||
storage_key: Option<&PrefixedStorageKey>,
|
||||
key: &[u8],
|
||||
) -> Result<Vec<Vec<u8>>, String> where H::Out: Codec {
|
||||
// we can't query any roots before root
|
||||
@@ -127,7 +128,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>(
|
||||
begin: Number,
|
||||
end: &AnchorBlockId<H::Out, Number>,
|
||||
max: Number,
|
||||
storage_key: Option<&[u8]>,
|
||||
storage_key: Option<&PrefixedStorageKey>,
|
||||
key: &[u8]
|
||||
) -> Result<Vec<(Number, u32)>, String> where H::Out: Encode {
|
||||
key_changes_proof_check_with_db(
|
||||
@@ -150,7 +151,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>(
|
||||
begin: Number,
|
||||
end: &AnchorBlockId<H::Out, Number>,
|
||||
max: Number,
|
||||
storage_key: Option<&[u8]>,
|
||||
storage_key: Option<&PrefixedStorageKey>,
|
||||
key: &[u8]
|
||||
) -> Result<Vec<(Number, u32)>, String> where H::Out: Encode {
|
||||
// we can't query any roots before root
|
||||
@@ -188,7 +189,7 @@ pub struct DrilldownIteratorEssence<'a, H, Number>
|
||||
Number: BlockNumber,
|
||||
H::Out: 'a,
|
||||
{
|
||||
storage_key: Option<&'a [u8]>,
|
||||
storage_key: Option<&'a PrefixedStorageKey>,
|
||||
key: &'a [u8],
|
||||
roots_storage: &'a dyn RootsStorage<H, Number>,
|
||||
storage: &'a dyn Storage<H, Number>,
|
||||
@@ -238,7 +239,7 @@ impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number>
|
||||
let trie_root = if let Some(storage_key) = self.storage_key {
|
||||
let child_key = ChildIndex {
|
||||
block: block.clone(),
|
||||
storage_key: storage_key.to_vec(),
|
||||
storage_key: storage_key.clone(),
|
||||
}.encode();
|
||||
if let Some(trie_root) = trie_reader(self.storage, trie_root, &child_key)?
|
||||
.and_then(|v| <Vec<u8>>::decode(&mut &v[..]).ok())
|
||||
@@ -382,6 +383,11 @@ mod tests {
|
||||
use sp_runtime::traits::BlakeTwo256;
|
||||
use super::*;
|
||||
|
||||
fn child_key() -> PrefixedStorageKey {
|
||||
let child_info = sp_core::storage::ChildInfo::new_default(&b"1"[..]);
|
||||
child_info.prefixed_storage_key()
|
||||
}
|
||||
|
||||
fn prepare_for_drilldown() -> (Configuration, InMemoryStorage<BlakeTwo256, u64>) {
|
||||
let config = Configuration { digest_interval: 4, digest_levels: 2 };
|
||||
let backend = InMemoryStorage::with_inputs(vec![
|
||||
@@ -418,7 +424,7 @@ mod tests {
|
||||
(16, vec![
|
||||
InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![4, 8]),
|
||||
]),
|
||||
], vec![(b"1".to_vec(), vec![
|
||||
], vec![(child_key(), vec![
|
||||
(1, vec![
|
||||
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![42] }, vec![0]),
|
||||
]),
|
||||
@@ -535,7 +541,7 @@ mod tests {
|
||||
1,
|
||||
&AnchorBlockId { hash: Default::default(), number: 100 },
|
||||
1000,
|
||||
Some(&b"1"[..]),
|
||||
Some(&child_key()),
|
||||
&[42],
|
||||
).and_then(|i| i.collect::<Result<Vec<_>, _>>()).is_err());
|
||||
}
|
||||
@@ -577,7 +583,7 @@ mod tests {
|
||||
let (remote_config, remote_storage) = prepare_for_drilldown();
|
||||
let remote_proof_child = key_changes_proof::<BlakeTwo256, u64>(
|
||||
configuration_range(&remote_config, 0), &remote_storage, 1,
|
||||
&AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]).unwrap();
|
||||
&AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]).unwrap();
|
||||
|
||||
// happens on local light node:
|
||||
|
||||
@@ -592,7 +598,7 @@ mod tests {
|
||||
local_storage.clear_storage();
|
||||
let local_result_child = key_changes_proof_check::<BlakeTwo256, u64>(
|
||||
configuration_range(&local_config, 0), &local_storage, remote_proof_child, 1,
|
||||
&AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&b"1"[..]), &[42]);
|
||||
&AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]);
|
||||
|
||||
// check that drilldown result is the same as if it was happening at the full node
|
||||
assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)]));
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::{
|
||||
StorageKey, StorageValue,
|
||||
changes_trie::BlockNumber
|
||||
};
|
||||
use sp_core::storage::PrefixedStorageKey;
|
||||
|
||||
/// Key of { changed key => set of extrinsic indices } mapping.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -49,7 +50,7 @@ pub struct ChildIndex<Number: BlockNumber> {
|
||||
/// Block at which this key has been inserted in the trie.
|
||||
pub block: Number,
|
||||
/// Storage key this node is responsible for.
|
||||
pub storage_key: StorageKey,
|
||||
pub storage_key: PrefixedStorageKey,
|
||||
}
|
||||
|
||||
/// Value of { changed key => block/digest block numbers } mapping.
|
||||
@@ -178,7 +179,7 @@ impl<Number: BlockNumber> Decode for InputKey<Number> {
|
||||
})),
|
||||
3 => Ok(InputKey::ChildIndex(ChildIndex {
|
||||
block: Decode::decode(input)?,
|
||||
storage_key: Decode::decode(input)?,
|
||||
storage_key: PrefixedStorageKey::new(Decode::decode(input)?),
|
||||
})),
|
||||
_ => Err("Invalid input key variant".into()),
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ use hash_db::{Hasher, Prefix};
|
||||
use num_traits::{One, Zero};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_core;
|
||||
use sp_core::storage::PrefixedStorageKey;
|
||||
use sp_trie::{MemoryDB, DBValue, TrieMut};
|
||||
use sp_trie::trie_types::TrieDBMut;
|
||||
use crate::{
|
||||
@@ -156,7 +157,7 @@ pub trait Storage<H: Hasher, Number: BlockNumber>: RootsStorage<H, Number> {
|
||||
fn with_cached_changed_keys(
|
||||
&self,
|
||||
root: &H::Out,
|
||||
functor: &mut dyn FnMut(&HashMap<Option<StorageKey>, HashSet<StorageKey>>),
|
||||
functor: &mut dyn FnMut(&HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>),
|
||||
) -> bool;
|
||||
/// Get a trie node.
|
||||
fn get(&self, key: &H::Out, prefix: Prefix) -> Result<Option<DBValue>, String>;
|
||||
|
||||
@@ -137,7 +137,8 @@ mod tests {
|
||||
#[test]
|
||||
fn prune_works() {
|
||||
fn prepare_storage() -> InMemoryStorage<BlakeTwo256, u64> {
|
||||
let child_key = ChildIndex { block: 67u64, storage_key: b"1".to_vec() }.encode();
|
||||
let child_info = sp_core::storage::ChildInfo::new_default(&b"1"[..]);
|
||||
let child_key = ChildIndex { block: 67u64, storage_key: child_info.prefixed_storage_key() }.encode();
|
||||
let mut mdb1 = MemoryDB::<BlakeTwo256>::default();
|
||||
let root1 = insert_into_memory_db::<BlakeTwo256, _>(
|
||||
&mut mdb1, vec![(vec![10], vec![20])]).unwrap();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
use std::collections::{BTreeMap, HashSet, HashMap};
|
||||
use hash_db::{Hasher, Prefix, EMPTY_PREFIX};
|
||||
use sp_core::storage::PrefixedStorageKey;
|
||||
use sp_trie::DBValue;
|
||||
use sp_trie::MemoryDB;
|
||||
use parking_lot::RwLock;
|
||||
@@ -96,7 +97,7 @@ impl<H: Hasher, Number: BlockNumber> InMemoryStorage<H, Number> {
|
||||
#[cfg(test)]
|
||||
pub fn with_inputs(
|
||||
mut top_inputs: Vec<(Number, Vec<InputPair<Number>>)>,
|
||||
children_inputs: Vec<(StorageKey, Vec<(Number, Vec<InputPair<Number>>)>)>,
|
||||
children_inputs: Vec<(PrefixedStorageKey, Vec<(Number, Vec<InputPair<Number>>)>)>,
|
||||
) -> Self {
|
||||
let mut mdb = MemoryDB::default();
|
||||
let mut roots = BTreeMap::new();
|
||||
@@ -182,7 +183,7 @@ impl<H: Hasher, Number: BlockNumber> Storage<H, Number> for InMemoryStorage<H, N
|
||||
fn with_cached_changed_keys(
|
||||
&self,
|
||||
root: &H::Out,
|
||||
functor: &mut dyn FnMut(&HashMap<Option<StorageKey>, HashSet<StorageKey>>),
|
||||
functor: &mut dyn FnMut(&HashMap<Option<PrefixedStorageKey>, HashSet<StorageKey>>),
|
||||
) -> bool {
|
||||
self.cache.with_changed_keys(root, functor)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user