mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 12:11:09 +00:00
Don't clone values when calculating storage root (#6108)
* Don't clone values when calculating storage root Instead of cloning all the keys and values of the overlay when calculating the storage root, we pass all the values by reference. This should probably bring some performance improvements when calculating the storage root. * no cow version (#6113) Co-authored-by: cheme <emericchevalier.pro@gmail.com>
This commit is contained in:
@@ -79,12 +79,12 @@ impl<B: BlockT> BenchmarkingState<B> {
|
||||
};
|
||||
|
||||
state.reopen()?;
|
||||
let child_delta = genesis.children_default.into_iter().map(|(_storage_key, child_content)| (
|
||||
child_content.child_info,
|
||||
child_content.data.into_iter().map(|(k, v)| (k, Some(v))),
|
||||
let child_delta = genesis.children_default.iter().map(|(_storage_key, child_content)| (
|
||||
&child_content.child_info,
|
||||
child_content.data.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))),
|
||||
));
|
||||
let (root, transaction): (B::Hash, _) = state.state.borrow_mut().as_mut().unwrap().full_storage_root(
|
||||
genesis.top.into_iter().map(|(k, v)| (k, Some(v))),
|
||||
genesis.top.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))),
|
||||
child_delta,
|
||||
);
|
||||
state.genesis = transaction.clone().drain();
|
||||
@@ -193,19 +193,18 @@ impl<B: BlockT> StateBackend<HashFor<B>> for BenchmarkingState<B> {
|
||||
}
|
||||
}
|
||||
|
||||
fn storage_root<I>(&self, delta: I) -> (B::Hash, Self::Transaction) where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
|
||||
{
|
||||
fn storage_root<'a>(
|
||||
&self,
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, Self::Transaction) where B::Hash: Ord {
|
||||
self.state.borrow().as_ref().map_or(Default::default(), |s| s.storage_root(delta))
|
||||
}
|
||||
|
||||
fn child_storage_root<I>(
|
||||
fn child_storage_root<'a>(
|
||||
&self,
|
||||
child_info: &ChildInfo,
|
||||
delta: I,
|
||||
) -> (B::Hash, bool, Self::Transaction) where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
{
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord {
|
||||
self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_storage_root(child_info, delta))
|
||||
}
|
||||
|
||||
|
||||
@@ -212,21 +212,18 @@ impl<B: BlockT> StateBackend<HashFor<B>> for RefTrackingState<B> {
|
||||
self.state.for_child_keys_with_prefix(child_info, prefix, f)
|
||||
}
|
||||
|
||||
fn storage_root<I>(&self, delta: I) -> (B::Hash, Self::Transaction)
|
||||
where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>
|
||||
{
|
||||
fn storage_root<'a>(
|
||||
&self,
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, Self::Transaction) where B::Hash: Ord {
|
||||
self.state.storage_root(delta)
|
||||
}
|
||||
|
||||
fn child_storage_root<I>(
|
||||
fn child_storage_root<'a>(
|
||||
&self,
|
||||
child_info: &ChildInfo,
|
||||
delta: I,
|
||||
) -> (B::Hash, bool, Self::Transaction)
|
||||
where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
{
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord {
|
||||
self.state.child_storage_root(child_info, delta)
|
||||
}
|
||||
|
||||
@@ -605,26 +602,25 @@ impl<Block: BlockT> sc_client_api::backend::BlockImportOperation<Block> for Bloc
|
||||
&mut self,
|
||||
storage: Storage,
|
||||
) -> ClientResult<Block::Hash> {
|
||||
|
||||
if storage.top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) {
|
||||
if storage.top.keys().any(|k| well_known_keys::is_child_storage_key(&k)) {
|
||||
return Err(sp_blockchain::Error::GenesisInvalid.into());
|
||||
}
|
||||
|
||||
let child_delta = storage.children_default.into_iter().map(|(_storage_key, child_content)|(
|
||||
child_content.child_info,
|
||||
child_content.data.into_iter().map(|(k, v)| (k, Some(v))),
|
||||
let child_delta = storage.children_default.iter().map(|(_storage_key, child_content)|(
|
||||
&child_content.child_info,
|
||||
child_content.data.iter().map(|(k, v)| (&k[..], Some(&v[..]))),
|
||||
));
|
||||
|
||||
let mut changes_trie_config: Option<ChangesTrieConfiguration> = None;
|
||||
let (root, transaction) = self.old_state.full_storage_root(
|
||||
storage.top.into_iter().map(|(k, v)| {
|
||||
if k == well_known_keys::CHANGES_TRIE_CONFIG {
|
||||
storage.top.iter().map(|(k, v)| {
|
||||
if &k[..] == well_known_keys::CHANGES_TRIE_CONFIG {
|
||||
changes_trie_config = Some(
|
||||
Decode::decode(&mut &v[..])
|
||||
.expect("changes trie configuration is encoded properly at genesis")
|
||||
);
|
||||
}
|
||||
(k, Some(v))
|
||||
(&k[..], Some(&v[..]))
|
||||
}),
|
||||
child_delta
|
||||
);
|
||||
@@ -1810,13 +1806,12 @@ pub(crate) mod tests {
|
||||
|
||||
header.state_root = op.old_state.storage_root(storage
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|(x, y)| (x, Some(y)))
|
||||
.map(|(x, y)| (&x[..], Some(&y[..])))
|
||||
).0.into();
|
||||
let hash = header.hash();
|
||||
|
||||
op.reset_storage(Storage {
|
||||
top: storage.iter().cloned().collect(),
|
||||
top: storage.into_iter().collect(),
|
||||
children_default: Default::default(),
|
||||
}).unwrap();
|
||||
op.set_block_data(
|
||||
@@ -1853,7 +1848,10 @@ pub(crate) mod tests {
|
||||
(vec![5, 5, 5], Some(vec![4, 5, 6])),
|
||||
];
|
||||
|
||||
let (root, overlay) = op.old_state.storage_root(storage.iter().cloned());
|
||||
let (root, overlay) = op.old_state.storage_root(
|
||||
storage.iter()
|
||||
.map(|(k, v)| (&k[..], v.as_ref().map(|v| &v[..])))
|
||||
);
|
||||
op.update_db_storage(overlay).unwrap();
|
||||
header.state_root = root.into();
|
||||
|
||||
@@ -1892,17 +1890,11 @@ pub(crate) mod tests {
|
||||
extrinsics_root: Default::default(),
|
||||
};
|
||||
|
||||
let storage: Vec<(_, _)> = vec![];
|
||||
|
||||
header.state_root = op.old_state.storage_root(storage
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|(x, y)| (x, Some(y)))
|
||||
).0.into();
|
||||
header.state_root = op.old_state.storage_root(std::iter::empty()).0.into();
|
||||
let hash = header.hash();
|
||||
|
||||
op.reset_storage(Storage {
|
||||
top: storage.iter().cloned().collect(),
|
||||
top: Default::default(),
|
||||
children_default: Default::default(),
|
||||
}).unwrap();
|
||||
|
||||
|
||||
@@ -621,21 +621,18 @@ impl<S: StateBackend<HashFor<B>>, B: BlockT> StateBackend<HashFor<B>> for Cachin
|
||||
self.state.for_child_keys_with_prefix(child_info, prefix, f)
|
||||
}
|
||||
|
||||
fn storage_root<I>(&self, delta: I) -> (B::Hash, Self::Transaction)
|
||||
where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
{
|
||||
fn storage_root<'a>(
|
||||
&self,
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, Self::Transaction) where B::Hash: Ord {
|
||||
self.state.storage_root(delta)
|
||||
}
|
||||
|
||||
fn child_storage_root<I>(
|
||||
fn child_storage_root<'a>(
|
||||
&self,
|
||||
child_info: &ChildInfo,
|
||||
delta: I,
|
||||
) -> (B::Hash, bool, Self::Transaction)
|
||||
where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
{
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord {
|
||||
self.state.child_storage_root(child_info, delta)
|
||||
}
|
||||
|
||||
@@ -806,21 +803,18 @@ impl<S: StateBackend<HashFor<B>>, B: BlockT> StateBackend<HashFor<B>> for Syncin
|
||||
self.caching_state().for_child_keys_with_prefix(child_info, prefix, f)
|
||||
}
|
||||
|
||||
fn storage_root<I>(&self, delta: I) -> (B::Hash, Self::Transaction)
|
||||
where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
{
|
||||
fn storage_root<'a>(
|
||||
&self,
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, Self::Transaction) where B::Hash: Ord {
|
||||
self.caching_state().storage_root(delta)
|
||||
}
|
||||
|
||||
fn child_storage_root<I>(
|
||||
fn child_storage_root<'a>(
|
||||
&self,
|
||||
child_info: &ChildInfo,
|
||||
delta: I,
|
||||
) -> (B::Hash, bool, Self::Transaction)
|
||||
where
|
||||
I: IntoIterator<Item=(Vec<u8>, Option<Vec<u8>>)>,
|
||||
{
|
||||
delta: impl Iterator<Item=(&'a [u8], Option<&'a [u8]>)>,
|
||||
) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord {
|
||||
self.caching_state().child_storage_root(child_info, delta)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user