mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 00:31:07 +00:00
Multiple storage root support (#902)
* Implement a non generic version of child delta trie * Use delta_trie_root in state_machine * Expand InMemory backend to support multi-storage * Create Consolidate trait * Fix all crate compile and remove unused OverlayedChanges::drain * Implement child storage root support and overlay changes * Add child storage reader * Add child storage writer * Implement child storage cleaning * Fix light backend compile * Add all required ext functions for wasm executor * Add ext def to io * Add all io functions * Fix nostd compile * Add simple test * Remove unnecessary vec copy in child_storage_root_transaction * Use values_mut/for_each to make it shorter * Use extend to shorter a for loop * Move record_all_keys to trie so it's easier to generic them later * space -> tab * Remove to_owned in debug format * Clean out all to_owned * Break debug_trace to multiple lines * Remove 0.. * UserError copy/paste typo * Replace Vec::from_raw_parts by slice::from_raw_parts * Use iter::empty() * Wrap some long lines * Wrap a missing line * Remove unnecessary map https://github.com/paritytech/substrate/pull/856#discussion_r226222663 * Call ext_free after from_raw_parts * Fix tests in other crates
This commit is contained in:
@@ -97,33 +97,62 @@ pub trait Externalities<H: Hasher> {
|
||||
/// Read storage of current contract being called.
|
||||
fn storage(&self, key: &[u8]) -> Option<Vec<u8>>;
|
||||
|
||||
/// Read child storage of current contract being called.
|
||||
fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option<Vec<u8>>;
|
||||
|
||||
/// Set storage entry `key` of current contract being called (effective immediately).
|
||||
fn set_storage(&mut self, key: Vec<u8>, value: Vec<u8>) {
|
||||
self.place_storage(key, Some(value));
|
||||
}
|
||||
|
||||
/// Set child storage entry `key` of current contract being called (effective immediately).
|
||||
fn set_child_storage(&mut self, storage_key: Vec<u8>, key: Vec<u8>, value: Vec<u8>) -> bool {
|
||||
self.place_child_storage(storage_key, key, Some(value))
|
||||
}
|
||||
|
||||
/// Clear a storage entry (`key`) of current contract being called (effective immediately).
|
||||
fn clear_storage(&mut self, key: &[u8]) {
|
||||
self.place_storage(key.to_vec(), None);
|
||||
}
|
||||
|
||||
/// Clear a storage entry (`key`) of current contract being called (effective immediately).
|
||||
/// Clear a child storage entry (`key`) of current contract being called (effective immediately).
|
||||
fn clear_child_storage(&mut self, storage_key: &[u8], key: &[u8]) -> bool {
|
||||
self.place_child_storage(storage_key.to_vec(), key.to_vec(), None)
|
||||
}
|
||||
|
||||
/// Whether a storage entry exists.
|
||||
fn exists_storage(&self, key: &[u8]) -> bool {
|
||||
self.storage(key).is_some()
|
||||
}
|
||||
|
||||
/// Whether a child storage entry exists.
|
||||
fn exists_child_storage(&self, storage_key: &[u8], key: &[u8]) -> bool {
|
||||
self.child_storage(storage_key, key).is_some()
|
||||
}
|
||||
|
||||
/// Clear an entire child storage.
|
||||
fn kill_child_storage(&mut self, storage_key: &[u8]);
|
||||
|
||||
/// Clear storage entries which keys are start with the given prefix.
|
||||
fn clear_prefix(&mut self, prefix: &[u8]);
|
||||
|
||||
/// Set or clear a storage entry (`key`) of current contract being called (effective immediately).
|
||||
fn place_storage(&mut self, key: Vec<u8>, value: Option<Vec<u8>>);
|
||||
|
||||
/// Set or clear a child storage entry. Return whether the operation succeeds.
|
||||
fn place_child_storage(&mut self, storage_key: Vec<u8>, key: Vec<u8>, value: Option<Vec<u8>>) -> bool;
|
||||
|
||||
/// Get the identity of the chain.
|
||||
fn chain_id(&self) -> u64;
|
||||
|
||||
/// Get the trie root of the current storage map.
|
||||
/// Get the trie root of the current storage map. This will also update all child storage keys in the top-level storage map.
|
||||
fn storage_root(&mut self) -> H::Out where H::Out: Ord;
|
||||
|
||||
/// Get the trie root of a child storage map. This will also update the value of the child storage keys in the top-level storage map. If the storage root equals default hash as defined by trie, the key in top-level storage map will be removed.
|
||||
///
|
||||
/// Returns None if key provided is not a storage key. This can due to not being started with CHILD_STORAGE_KEY_PREFIX, or the trie implementation regards the key as invalid.
|
||||
fn child_storage_root(&mut self, storage_key: &[u8]) -> Option<Vec<u8>>;
|
||||
|
||||
/// Get the change trie root of the current storage overlay at given block.
|
||||
fn storage_changes_root(&mut self, block: u64) -> Option<H::Out> where H::Out: Ord;
|
||||
}
|
||||
@@ -477,6 +506,7 @@ where
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use codec::Encode;
|
||||
use overlayed_changes::OverlayedValue;
|
||||
use super::*;
|
||||
use super::backend::InMemory;
|
||||
use super::ext::Ext;
|
||||
@@ -600,12 +630,12 @@ mod tests {
|
||||
let backend = InMemory::<Blake2Hasher>::from(initial).try_into_trie_backend().unwrap();
|
||||
let mut overlay = OverlayedChanges {
|
||||
committed: map![
|
||||
b"aba".to_vec() => Some(b"1312".to_vec()).into(),
|
||||
b"bab".to_vec() => Some(b"228".to_vec()).into()
|
||||
b"aba".to_vec() => OverlayedValue::from(Some(b"1312".to_vec())),
|
||||
b"bab".to_vec() => OverlayedValue::from(Some(b"228".to_vec()))
|
||||
],
|
||||
prospective: map![
|
||||
b"abd".to_vec() => Some(b"69".to_vec()).into(),
|
||||
b"bbd".to_vec() => Some(b"42".to_vec()).into()
|
||||
b"abd".to_vec() => OverlayedValue::from(Some(b"69".to_vec())),
|
||||
b"bbd".to_vec() => OverlayedValue::from(Some(b"42".to_vec()))
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
@@ -631,6 +661,19 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_child_storage_works() {
|
||||
let backend = InMemory::<Blake2Hasher>::default().try_into_trie_backend().unwrap();
|
||||
let changes_trie_storage = InMemoryChangesTrieStorage::new();
|
||||
let mut overlay = OverlayedChanges::default();
|
||||
let mut ext = Ext::new(&mut overlay, &backend, Some(&changes_trie_storage));
|
||||
|
||||
assert!(ext.set_child_storage(b":child_storage:testchild".to_vec(), b"abc".to_vec(), b"def".to_vec()));
|
||||
assert_eq!(ext.child_storage(b":child_storage:testchild", b"abc"), Some(b"def".to_vec()));
|
||||
ext.kill_child_storage(b":child_storage:testchild");
|
||||
assert_eq!(ext.child_storage(b":child_storage:testchild", b"abc"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prove_read_and_proof_check_works() {
|
||||
// fetch read proof from 'remote' full node
|
||||
|
||||
Reference in New Issue
Block a user