mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-02 09:27:24 +00:00
Refactor OverlayedChanges (#5989)
* Hide internal structure of OverlayChanges * Fix tests for OverlayChanges refactor * Do not clone pending changes Discarding prospective changes should be equivalent as a state machine is not to be called with peding changes. This will be replaced by a storage transaction that is rolled back before executing the call the second time removing this constraint. * Doc fixes * Remove overlong line * Revert "Do not clone pending changes" This reverts commit 4799491f4ac16f8517287a0fcf4a3f84ad56f46e. * Deduplicate chield tries returned from child_infos() * Remove redundant type annotation * Avoid changing the storage root in tests * Preserve extrinsic indices in trie build test * Swap order of comitted and prospective in fn child_infos This is only for consistency and does not impact the result. * Rename set_pending to replace_pending for clearity
This commit is contained in:
committed by
GitHub
parent
f275c6ab0b
commit
7a5bdb896b
@@ -30,7 +30,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, ChildInfo};
|
||||
use sp_core::storage::{well_known_keys::EXTRINSIC_INDEX, ChildInfo, ChildType};
|
||||
use sp_core::offchain::storage::OffchainOverlayedChanges;
|
||||
use std::{mem, ops};
|
||||
|
||||
@@ -55,13 +55,13 @@ pub type ChildStorageCollection = Vec<(StorageKey, StorageCollection)>;
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct OverlayedChanges {
|
||||
/// Changes that are not yet committed.
|
||||
pub(crate) prospective: OverlayedChangeSet,
|
||||
prospective: OverlayedChangeSet,
|
||||
/// Committed changes.
|
||||
pub(crate) committed: OverlayedChangeSet,
|
||||
committed: OverlayedChangeSet,
|
||||
/// True if extrinsics stats must be collected.
|
||||
pub(crate) collect_extrinsics: bool,
|
||||
collect_extrinsics: bool,
|
||||
/// Collect statistic on this execution.
|
||||
pub(crate) stats: StateMachineStats,
|
||||
stats: StateMachineStats,
|
||||
}
|
||||
|
||||
/// The storage value, used inside OverlayedChanges.
|
||||
@@ -69,10 +69,10 @@ pub struct OverlayedChanges {
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub struct OverlayedValue {
|
||||
/// Current value. None if value has been deleted.
|
||||
pub value: Option<StorageValue>,
|
||||
value: Option<StorageValue>,
|
||||
/// The set of extrinsic indices where the values has been changed.
|
||||
/// Is filled only if runtime has announced changes trie support.
|
||||
pub extrinsics: Option<BTreeSet<u32>>,
|
||||
extrinsics: Option<BTreeSet<u32>>,
|
||||
}
|
||||
|
||||
/// Prospective or committed overlayed change set.
|
||||
@@ -80,9 +80,9 @@ pub struct OverlayedValue {
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub struct OverlayedChangeSet {
|
||||
/// Top level storage changes.
|
||||
pub top: BTreeMap<StorageKey, OverlayedValue>,
|
||||
top: BTreeMap<StorageKey, OverlayedValue>,
|
||||
/// Child storage changes. The map key is the child storage key without the common prefix.
|
||||
pub children_default: HashMap<StorageKey, (BTreeMap<StorageKey, OverlayedValue>, ChildInfo)>,
|
||||
children_default: HashMap<StorageKey, (BTreeMap<StorageKey, OverlayedValue>, ChildInfo)>,
|
||||
}
|
||||
|
||||
/// A storage changes structure that can be generated by the data collected in [`OverlayedChanges`].
|
||||
@@ -187,6 +187,18 @@ impl FromIterator<(StorageKey, OverlayedValue)> for OverlayedChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
impl OverlayedValue {
|
||||
/// The most recent value contained in this overlay.
|
||||
pub fn value(&self) -> Option<&StorageValue> {
|
||||
self.value.as_ref()
|
||||
}
|
||||
|
||||
/// List of indices of extrinsics which modified the value using this overlay.
|
||||
pub fn extrinsics(&self) -> Option<impl Iterator<Item=&u32>> {
|
||||
self.extrinsics.as_ref().map(|v| v.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl OverlayedChangeSet {
|
||||
/// Whether the change set is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
@@ -499,6 +511,44 @@ impl OverlayedChanges {
|
||||
)
|
||||
}
|
||||
|
||||
/// Get an iterator over all pending and committed child tries in the overlay.
|
||||
pub fn child_infos(&self) -> impl IntoIterator<Item=&ChildInfo> {
|
||||
self.committed.children_default.iter()
|
||||
.chain(self.prospective.children_default.iter())
|
||||
.map(|(_, v)| &v.1).collect::<BTreeSet<_>>()
|
||||
}
|
||||
|
||||
/// Get an iterator over all pending and committed changes.
|
||||
///
|
||||
/// Supplying `None` for `child_info` will only return changes that are in the top
|
||||
/// trie. Specifying some `child_info` will return only the changes in that
|
||||
/// child trie.
|
||||
pub fn changes(&self, child_info: Option<&ChildInfo>)
|
||||
-> impl Iterator<Item=(&StorageKey, &OverlayedValue)>
|
||||
{
|
||||
let (committed, prospective) = if let Some(child_info) = child_info {
|
||||
match child_info.child_type() {
|
||||
ChildType::ParentKeyId => (
|
||||
self.committed.children_default.get(child_info.storage_key()).map(|c| &c.0),
|
||||
self.prospective.children_default.get(child_info.storage_key()).map(|c| &c.0),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
(Some(&self.committed.top), Some(&self.prospective.top))
|
||||
};
|
||||
committed.into_iter().flatten().chain(prospective.into_iter().flatten())
|
||||
}
|
||||
|
||||
/// Return a clone of the currently pending changes.
|
||||
pub fn clone_pending(&self) -> OverlayedChangeSet {
|
||||
self.prospective.clone()
|
||||
}
|
||||
|
||||
/// Replace the currently pending changes.
|
||||
pub fn replace_pending(&mut self, pending: OverlayedChangeSet) {
|
||||
self.prospective = pending;
|
||||
}
|
||||
|
||||
/// Convert this instance with all changes into a [`StorageChanges`] instance.
|
||||
pub fn into_storage_changes<
|
||||
B: Backend<H>, H: Hasher, N: BlockNumber
|
||||
|
||||
Reference in New Issue
Block a user