mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 08:07:58 +00:00
Move Externalities into its own crate (#3775)
* Move `Externalities` into `substrate-externalities` - `Externalities` now support generic extensions - Split of `primtives-storage` for storage primitive types * Move the externalities scoping into `substrate-externalities` * Fix compilation * Review feedback * Adds macro for declaring extensions * Fix benchmarks * Introduce `ExtensionStore` trait * Last review comments * Implement it for `ExtensionStore`
This commit is contained in:
@@ -16,15 +16,14 @@
|
||||
|
||||
//! Basic implementation for Externalities.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
use std::{collections::HashMap, any::{TypeId, Any}, iter::FromIterator};
|
||||
use crate::backend::{Backend, InMemory};
|
||||
use hash_db::Hasher;
|
||||
use trie::{TrieConfiguration, default_child_trie_root};
|
||||
use trie::trie_types::Layout;
|
||||
use primitives::{
|
||||
storage::well_known_keys::is_child_storage_key, child_storage_key::ChildStorageKey, offchain,
|
||||
traits::Externalities,
|
||||
storage::{well_known_keys::is_child_storage_key, ChildStorageKey},
|
||||
traits::Externalities, Blake2Hasher, hash::H256,
|
||||
};
|
||||
use log::warn;
|
||||
|
||||
@@ -88,21 +87,37 @@ impl From<HashMap<Vec<u8>, Vec<u8>>> for BasicExternalities {
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
|
||||
impl Externalities for BasicExternalities {
|
||||
fn storage(&self, key: &[u8]) -> Option<Vec<u8>> {
|
||||
self.top.get(key).cloned()
|
||||
}
|
||||
|
||||
fn storage_hash(&self, key: &[u8]) -> Option<H256> {
|
||||
self.storage(key).map(|v| Blake2Hasher::hash(&v))
|
||||
}
|
||||
|
||||
fn original_storage(&self, key: &[u8]) -> Option<Vec<u8>> {
|
||||
Externalities::<H>::storage(self, key)
|
||||
self.storage(key)
|
||||
}
|
||||
|
||||
fn original_storage_hash(&self, key: &[u8]) -> Option<H256> {
|
||||
self.storage_hash(key)
|
||||
}
|
||||
|
||||
fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
|
||||
self.children.get(storage_key.as_ref()).and_then(|child| child.get(key)).cloned()
|
||||
}
|
||||
|
||||
fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<H256> {
|
||||
self.child_storage(storage_key, key).map(|v| Blake2Hasher::hash(&v))
|
||||
}
|
||||
|
||||
fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<H256> {
|
||||
self.child_storage_hash(storage_key, key)
|
||||
}
|
||||
|
||||
fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
|
||||
Externalities::<H>::child_storage(self, storage_key, key)
|
||||
Externalities::child_storage(self, storage_key, key)
|
||||
}
|
||||
|
||||
fn place_storage(&mut self, key: Vec<u8>, maybe_value: Option<Vec<u8>>) {
|
||||
@@ -155,16 +170,15 @@ impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
|
||||
|
||||
fn chain_id(&self) -> u64 { 42 }
|
||||
|
||||
fn storage_root(&mut self) -> H::Out {
|
||||
fn storage_root(&mut self) -> H256 {
|
||||
let mut top = self.top.clone();
|
||||
let keys: Vec<_> = self.children.keys().map(|k| k.to_vec()).collect();
|
||||
// Single child trie implementation currently allows using the same child
|
||||
// empty root for all child trie. Using null storage key until multiple
|
||||
// type of child trie support.
|
||||
let empty_hash = default_child_trie_root::<Layout<H>>(&[]);
|
||||
let empty_hash = default_child_trie_root::<Layout<Blake2Hasher>>(&[]);
|
||||
for storage_key in keys {
|
||||
let child_root = Externalities::<H>::child_storage_root(
|
||||
self,
|
||||
let child_root = self.child_storage_root(
|
||||
ChildStorageKey::from_slice(storage_key.as_slice())
|
||||
.expect("Map only feed by valid keys; qed"),
|
||||
);
|
||||
@@ -175,30 +189,27 @@ impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
|
||||
}
|
||||
}
|
||||
|
||||
Layout::<H>::trie_root(self.top.clone())
|
||||
Layout::<Blake2Hasher>::trie_root(self.top.clone())
|
||||
}
|
||||
|
||||
fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec<u8> {
|
||||
if let Some(child) = self.children.get(storage_key.as_ref()) {
|
||||
let delta = child.clone().into_iter().map(|(k, v)| (k, Some(v)));
|
||||
|
||||
InMemory::<H>::default().child_storage_root(storage_key.as_ref(), delta).0
|
||||
InMemory::<Blake2Hasher>::default().child_storage_root(storage_key.as_ref(), delta).0
|
||||
} else {
|
||||
default_child_trie_root::<Layout<H>>(storage_key.as_ref())
|
||||
default_child_trie_root::<Layout<Blake2Hasher>>(storage_key.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
fn storage_changes_root(&mut self, _parent: H::Out) -> Result<Option<H::Out>, ()> {
|
||||
fn storage_changes_root(&mut self, _parent: H256) -> Result<Option<H256>, ()> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn offchain(&mut self) -> Option<&mut dyn offchain::Externalities> {
|
||||
warn!("Call to non-existent offchain externalities set.");
|
||||
None
|
||||
}
|
||||
|
||||
fn keystore(&self) -> Option<primitives::traits::BareCryptoStorePtr> {
|
||||
warn!("Call to non-existent keystore.");
|
||||
impl externalities::ExtensionStore for BasicExternalities {
|
||||
fn extension_by_type_id(&mut self, _: TypeId) -> Option<&mut dyn Any> {
|
||||
warn!("Extensions are not supported by `BasicExternalities`.");
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -206,14 +217,13 @@ impl<H: Hasher> Externalities<H> for BasicExternalities where H::Out: Ord {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use primitives::{Blake2Hasher, H256, map};
|
||||
use primitives::{H256, map};
|
||||
use primitives::storage::well_known_keys::CODE;
|
||||
use hex_literal::hex;
|
||||
|
||||
#[test]
|
||||
fn commit_should_work() {
|
||||
let mut ext = BasicExternalities::default();
|
||||
let ext = &mut ext as &mut dyn Externalities<Blake2Hasher>;
|
||||
ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
|
||||
ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
|
||||
ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
|
||||
@@ -225,7 +235,6 @@ mod tests {
|
||||
#[test]
|
||||
fn set_and_retrieve_code() {
|
||||
let mut ext = BasicExternalities::default();
|
||||
let ext = &mut ext as &mut dyn Externalities<Blake2Hasher>;
|
||||
|
||||
let code = vec![1, 2, 3];
|
||||
ext.set_storage(CODE.to_vec(), code.clone());
|
||||
@@ -246,8 +255,6 @@ mod tests {
|
||||
]
|
||||
);
|
||||
|
||||
let ext = &mut ext as &mut dyn Externalities<Blake2Hasher>;
|
||||
|
||||
let child = || ChildStorageKey::from_vec(child_storage.clone()).unwrap();
|
||||
|
||||
assert_eq!(ext.child_storage(child(), b"doe"), Some(b"reindeer".to_vec()));
|
||||
|
||||
Reference in New Issue
Block a user