diff --git a/Cargo.lock b/Cargo.lock index 226cce363e7d5..6ae7d4deabf19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5986,7 +5986,6 @@ name = "substrate-externalities" version = "2.0.0" dependencies = [ "environmental 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", "substrate-primitives-storage 2.0.0", ] diff --git a/bin/node/executor/src/lib.rs b/bin/node/executor/src/lib.rs index b1e5e24ffd328..d85ec452c72c5 100644 --- a/bin/node/executor/src/lib.rs +++ b/bin/node/executor/src/lib.rs @@ -913,7 +913,7 @@ mod tests { None, ).0.unwrap(); - assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(&GENESIS_HASH.encode()).unwrap().is_some()); } #[test] @@ -929,7 +929,7 @@ mod tests { None, ).0.unwrap(); - assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some()); + assert!(t.ext().storage_changes_root(&GENESIS_HASH.encode()).unwrap().is_some()); } #[test] diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index dceffc852a646..253b48e6fa15f 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -174,7 +174,7 @@ impl StateBackend for RefTrackingState { self.state.storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H256, bool, Self::Transaction) where I: IntoIterator, Option>)>, { @@ -193,7 +193,9 @@ impl StateBackend for RefTrackingState { self.state.child_keys(child_key, prefix) } - fn as_trie_backend(&mut self) -> Option<&state_machine::TrieBackend> { + fn as_trie_backend( + &mut self, + ) -> Option<&state_machine::TrieBackend> { self.state.as_trie_backend() } } diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 3febc6b4d4807..38848577868aa 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -568,7 +568,7 @@ impl, B: BlockT> StateBackend for CachingState< self.state.storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord diff --git a/client/executor/src/deprecated_host_interface.rs b/client/executor/src/deprecated_host_interface.rs index 223b13367aa87..f74a9597e57fb 100644 --- a/client/executor/src/deprecated_host_interface.rs +++ b/client/executor/src/deprecated_host_interface.rs @@ -425,7 +425,7 @@ impl_wasm_host_interface! { context.read_memory_into(parent_hash_data, &mut parent_hash[..]) .map_err(|_| "Invalid attempt to get parent_hash in ext_storage_changes_root")?; - if let Some(r) = runtime_io::storage::changes_root(parent_hash) { + if let Some(r) = runtime_io::storage::changes_root(&parent_hash) { context.write_memory(result, &r[..]) .map_err(|_| "Invalid attempt to set memory in ext_storage_changes_root")?; Ok(1) diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index c58f63a1e03de..5014c0581609e 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -26,7 +26,7 @@ use log::{trace, warn}; use codec::Decode; -use primitives::{storage::well_known_keys, traits::Externalities, H256}; +use primitives::{storage::well_known_keys, traits::Externalities}; use runtime_version::RuntimeVersion; use std::{collections::hash_map::{Entry, HashMap}, panic::AssertUnwindSafe}; @@ -82,7 +82,7 @@ pub struct RuntimesCache { /// A cache of runtime instances along with metadata, ready to be reused. /// /// Instances are keyed by the Wasm execution method and the hash of their code. - instances: HashMap<(WasmExecutionMethod, [u8; 32]), Result>, + instances: HashMap<(WasmExecutionMethod, Vec), Result>, } impl RuntimesCache { @@ -128,7 +128,7 @@ impl RuntimesCache { wasm_method: WasmExecutionMethod, default_heap_pages: u64, host_functions: &[&'static dyn Function], - ) -> Result<(&mut (dyn WasmRuntime + 'static), &RuntimeVersion, H256), Error> { + ) -> Result<(&mut (dyn WasmRuntime + 'static), &RuntimeVersion, Vec), Error> { let code_hash = ext .original_storage_hash(well_known_keys::CODE) .ok_or(Error::InvalidCode("`CODE` not found in storage.".into()))?; @@ -138,7 +138,7 @@ impl RuntimesCache { .and_then(|pages| u64::decode(&mut &pages[..]).ok()) .unwrap_or(default_heap_pages); - let result = match self.instances.entry((wasm_method, code_hash.into())) { + let result = match self.instances.entry((wasm_method, code_hash.clone())) { Entry::Occupied(o) => { let result = o.into_mut(); if let Ok(ref mut cached_runtime) = result { @@ -198,10 +198,10 @@ impl RuntimesCache { pub fn invalidate_runtime( &mut self, wasm_method: WasmExecutionMethod, - code_hash: H256, + code_hash: Vec, ) { // Just remove the instance, it will be re-created the next time it is requested. - self.instances.remove(&(wasm_method, code_hash.into())); + self.instances.remove(&(wasm_method, code_hash)); } } diff --git a/client/src/cht.rs b/client/src/cht.rs index dc49069f0afa0..7e0552f2f267a 100644 --- a/client/src/cht.rs +++ b/client/src/cht.rs @@ -92,7 +92,7 @@ pub fn build_proof( where Header: HeaderT, Hasher: hash_db::Hasher, - Hasher::Out: Ord, + Hasher::Out: Ord + codec::Codec, BlocksI: IntoIterator, HashesI: IntoIterator>>, { @@ -119,7 +119,7 @@ pub fn check_proof( where Header: HeaderT, Hasher: hash_db::Hasher, - Hasher::Out: Ord, + Hasher::Out: Ord + codec::Codec, { do_check_proof::( local_root, @@ -148,7 +148,7 @@ pub fn check_proof_on_proving_backend( where Header: HeaderT, Hasher: hash_db::Hasher, - Hasher::Out: Ord, + Hasher::Out: Ord + codec::Codec, { do_check_proof::( local_root, diff --git a/client/src/light/backend.rs b/client/src/light/backend.rs index da21ebf9e8640..2077713ba5481 100644 --- a/client/src/light/backend.rs +++ b/client/src/light/backend.rs @@ -21,7 +21,9 @@ use std::collections::HashMap; use std::sync::Arc; use parking_lot::RwLock; -use state_machine::{Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState, ChangesTrieTransaction}; +use state_machine::{ + Backend as StateBackend, TrieBackend, backend::InMemory as InMemoryState, ChangesTrieTransaction +}; use primitives::offchain::storage::InMemOffchainStorage; use sr_primitives::{generic::BlockId, Justification, StorageOverlay, ChildrenStorageOverlay}; use sr_primitives::traits::{Block as BlockT, NumberFor, Zero, Header}; @@ -341,7 +343,7 @@ impl std::fmt::Debug for GenesisOrUnavailableState { impl StateBackend for GenesisOrUnavailableState where - H::Out: Ord, + H::Out: Ord + codec::Codec, { type Error = ClientError; type Transaction = (); @@ -409,7 +411,7 @@ impl StateBackend for GenesisOrUnavailableState } } - fn child_storage_root(&self, key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)> { @@ -418,7 +420,7 @@ impl StateBackend for GenesisOrUnavailableState let (root, is_equal, _) = state.child_storage_root(key, delta); (root, is_equal, ()) }, - GenesisOrUnavailableState::Unavailable => (H::Out::default().as_ref().to_vec(), true, ()), + GenesisOrUnavailableState::Unavailable => (H::Out::default(), true, ()), } } diff --git a/client/src/light/fetcher.rs b/client/src/light/fetcher.rs index d3f9436262d91..9db6dda172d1b 100644 --- a/client/src/light/fetcher.rs +++ b/client/src/light/fetcher.rs @@ -70,7 +70,7 @@ impl> LightDataChecker { ) -> ClientResult, u32)>> where H: Hasher, - H::Out: Ord, + H::Out: Ord + codec::Codec, { // since we need roots of all changes tries for the range begin..max // => remote node can't use max block greater that one that we have passed @@ -148,7 +148,7 @@ impl> LightDataChecker { ) -> ClientResult<()> where H: Hasher, - H::Out: Ord, + H::Out: Ord + codec::Codec, { // all the checks are sharing the same storage let storage = create_proof_check_backend_storage(remote_roots_proof); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 611ec2ff16093..17fb3fbf0ef22 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -668,13 +668,17 @@ impl Module { } } - let storage_root = T::Hashing::storage_root(); - let storage_changes_root = T::Hashing::storage_changes_root(parent_hash); + let storage_root = T::Hash::decode(&mut &runtime_io::storage::root()[..]) + .expect("Node is configured to use the same hash; qed"); + let storage_changes_root = runtime_io::storage::changes_root(&parent_hash.encode()); // we can't compute changes trie root earlier && put it to the Digest // because it will include all currently existing temporaries. if let Some(storage_changes_root) = storage_changes_root { - let item = generic::DigestItem::ChangesTrieRoot(storage_changes_root); + let item = generic::DigestItem::ChangesTrieRoot( + T::Hash::decode(&mut &storage_changes_root[..]) + .expect("Node is configured to use the same hash; qed") + ); digest.push(item); } diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index 0b806ecee0494..ec4fa9a9a5d29 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -6,7 +6,6 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -primitive-types = { version = "0.6", features = ["codec"] } primitives-storage = { package = "substrate-primitives-storage", path = "../core/storage" } rstd = { package = "sr-std", path = "../sr-std" } environmental = { version = "1.0.2" } diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 4efbc54a4edc9..da3fe16d77945 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -22,8 +22,6 @@ //! //! This crate exposes the main [`Externalities`] trait. -use primitive_types::H256; - use std::any::{Any, TypeId}; use primitives_storage::ChildStorageKey; @@ -42,26 +40,40 @@ pub trait Externalities: ExtensionStore { fn storage(&self, key: &[u8]) -> Option>; /// Get storage value hash. This may be optimized for large values. - fn storage_hash(&self, key: &[u8]) -> Option; + fn storage_hash(&self, key: &[u8]) -> Option>; /// Get child storage value hash. This may be optimized for large values. - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; /// Read original runtime storage, ignoring any overlayed changes. fn original_storage(&self, key: &[u8]) -> Option>; /// Read original runtime child storage, ignoring any overlayed changes. + /// + /// Returns an `Option` that holds the SCALE encoded hash. fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; /// Get original storage value hash, ignoring any overlayed changes. /// This may be optimized for large values. - fn original_storage_hash(&self, key: &[u8]) -> Option; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn original_storage_hash(&self, key: &[u8]) -> Option>; /// Get original child storage value hash, ignoring any overlayed changes. /// This may be optimized for large values. - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option; + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + key: &[u8], + ) -> Option>; /// Read child runtime storage. + /// + /// Returns an `Option` that holds the SCALE encoded hash. fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option>; /// Set storage entry `key` of current contract being called (effective immediately). @@ -107,14 +119,23 @@ pub trait Externalities: ExtensionStore { fn place_storage(&mut self, key: Vec, value: Option>); /// Set or clear a child storage entry. Return whether the operation succeeds. - fn place_child_storage(&mut self, storage_key: ChildStorageKey, key: Vec, value: Option>); + fn place_child_storage( + &mut self, + storage_key: ChildStorageKey, + key: Vec, + value: Option>, + ); /// Get the identity of the chain. fn chain_id(&self) -> u64; /// 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) -> H256; + /// + /// The hash is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn storage_root(&mut self) -> Vec; /// 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. @@ -123,7 +144,12 @@ pub trait Externalities: ExtensionStore { fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec; /// Get the change trie root of the current storage overlay at a block with given parent. - fn storage_changes_root(&mut self, parent: H256) -> Result, ()>; + /// `parent` is expects a SCALE endcoded hash. + /// + /// The hash is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn storage_changes_root(&mut self, parent: &[u8]) -> Result>, ()>; } /// Extension for the [`Externalities`] trait. diff --git a/primitives/sr-io/src/lib.rs b/primitives/sr-io/src/lib.rs index 589b6a1dd1aad..40d52db98b0a8 100644 --- a/primitives/sr-io/src/lib.rs +++ b/primitives/sr-io/src/lib.rs @@ -50,7 +50,7 @@ use primitives::{ }; #[cfg(feature = "std")] -use trie::{TrieConfiguration, trie_types::Layout}; +use ::trie::{TrieConfiguration, trie_types::Layout}; use runtime_interface::{runtime_interface, Pointer}; @@ -186,28 +186,45 @@ pub trait Storage { } /// "Commit" all existing operations and compute the resulting storage root. - fn root(&mut self) -> H256 { + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. + fn root(&mut self) -> Vec { self.storage_root() } /// "Commit" all existing operations and compute the resulting child storage root. + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns the SCALE encoded hash. fn child_root(&mut self, child_storage_key: &[u8]) -> Vec { let storage_key = child_storage_key_or_panic(child_storage_key); self.child_storage_root(storage_key) } /// "Commit" all existing operations and get the resulting storage change root. - fn changes_root(&mut self, parent_hash: [u8; 32]) -> Option { - self.storage_changes_root(parent_hash.into()).ok().and_then(|h| h) + /// `parent_hash` is a SCALE encoded hash. + /// + /// The hashing algorithm is defined by the `Block`. + /// + /// Returns an `Option` that holds the SCALE encoded hash. + fn changes_root(&mut self, parent_hash: &[u8]) -> Option> { + self.storage_changes_root(parent_hash).ok().and_then(|h| h) } +} +/// Interface that provides trie related functionality. +#[runtime_interface] +pub trait Trie { /// A trie root formed from the iterated items. - fn blake2_256_trie_root(input: Vec<(Vec, Vec)>) -> H256 { + fn blake2_256_root(input: Vec<(Vec, Vec)>) -> H256 { Layout::::trie_root(input) } /// A trie root formed from the enumerated items. - fn blake2_256_ordered_trie_root(input: Vec>) -> H256 { + fn blake2_256_ordered_root(input: Vec>) -> H256 { Layout::::ordered_trie_root(input) } } @@ -779,6 +796,7 @@ pub type SubstrateHostFunctions = ( allocator::HostFunctions, logging::HostFunctions, sandbox::HostFunctions, + crate::trie::HostFunctions, ); #[cfg(test)] diff --git a/primitives/sr-primitives/src/traits.rs b/primitives/sr-primitives/src/traits.rs index 84ac039a1d945..7c6a88acc2368 100644 --- a/primitives/sr-primitives/src/traits.rs +++ b/primitives/sr-primitives/src/traits.rs @@ -384,12 +384,6 @@ pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + Parti /// The Patricia tree root of the given mapping. fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output; - - /// Acquire the global storage root. - fn storage_root() -> Self::Output; - - /// Acquire the global storage changes root. - fn storage_changes_root(parent_hash: Self::Output) -> Option; } /// Blake2-256 Hash implementation. @@ -405,19 +399,11 @@ impl Hash for BlakeTwo256 { } fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output { - runtime_io::storage::blake2_256_trie_root(input) + runtime_io::trie::blake2_256_root(input) } fn ordered_trie_root(input: Vec>) -> Self::Output { - runtime_io::storage::blake2_256_ordered_trie_root(input) - } - - fn storage_root() -> Self::Output { - runtime_io::storage::root().into() - } - - fn storage_changes_root(parent_hash: Self::Output) -> Option { - runtime_io::storage::changes_root(parent_hash.into()).map(Into::into) + runtime_io::trie::blake2_256_ordered_root(input) } } diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 5fbda1aa32f45..366634ae1a9d7 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -25,6 +25,7 @@ use trie::{ TrieMut, MemoryDB, child_trie_root, default_child_trie_root, TrieConfiguration, trie_types::{TrieDBMut, Layout}, }; +use codec::{Encode, Codec}; /// A state backend is used to read state data and can have changes committed /// to it. @@ -95,7 +96,7 @@ pub trait Backend: std::fmt::Debug { /// Calculate the child storage root, with given delta over what is already stored in /// the backend, and produce a "transaction" that can be used to commit. The second argument /// is true if child storage root equals default storage root. - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord; @@ -134,7 +135,7 @@ pub trait Backend: std::fmt::Debug { I1: IntoIterator, Option>)>, I2i: IntoIterator, Option>)>, I2: IntoIterator, I2i)>, - ::Out: Ord, + H::Out: Ord + Encode, { let mut txs: Self::Transaction = Default::default(); let mut child_roots: Vec<_> = Default::default(); @@ -146,7 +147,7 @@ pub trait Backend: std::fmt::Debug { if empty { child_roots.push((storage_key, None)); } else { - child_roots.push((storage_key, Some(child_root))); + child_roots.push((storage_key, Some(child_root.encode()))); } } let (root, parent_txs) = self.storage_root( @@ -190,7 +191,7 @@ impl<'a, T: Backend, H: Hasher> Backend for &'a T { (*self).storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord, @@ -287,7 +288,7 @@ impl PartialEq for InMemory { } } -impl InMemory { +impl InMemory where H::Out: Codec { /// Copy the state, with applied updates pub fn update(&self, changes: >::Transaction) -> Self { let mut inner: HashMap<_, _> = self.inner.clone(); @@ -362,7 +363,7 @@ impl InMemory { } } -impl Backend for InMemory { +impl Backend for InMemory where H::Out: Codec { type Error = Void; type Transaction = Vec<(Option>, Vec, Option>)>; type TrieBackendStorage = MemoryDB; @@ -418,7 +419,7 @@ impl Backend for InMemory { (root, full_transaction) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord diff --git a/primitives/state-machine/src/basic.rs b/primitives/state-machine/src/basic.rs index e758b3dd3b814..82a0c21f20969 100644 --- a/primitives/state-machine/src/basic.rs +++ b/primitives/state-machine/src/basic.rs @@ -26,9 +26,10 @@ use primitives::{ well_known_keys::is_child_storage_key, ChildStorageKey, StorageOverlay, ChildrenStorageOverlay }, - traits::Externalities, Blake2Hasher, hash::H256, + traits::Externalities, Blake2Hasher, }; use log::warn; +use codec::Encode; /// Simple HashMap-based Externalities impl. #[derive(Debug)] @@ -118,15 +119,15 @@ impl Externalities for BasicExternalities { self.top.get(key).cloned() } - fn storage_hash(&self, key: &[u8]) -> Option { - self.storage(key).map(|v| Blake2Hasher::hash(&v)) + fn storage_hash(&self, key: &[u8]) -> Option> { + self.storage(key).map(|v| Blake2Hasher::hash(&v).encode()) } fn original_storage(&self, key: &[u8]) -> Option> { self.storage(key) } - fn original_storage_hash(&self, key: &[u8]) -> Option { + fn original_storage_hash(&self, key: &[u8]) -> Option> { self.storage_hash(key) } @@ -134,11 +135,15 @@ impl Externalities for BasicExternalities { 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 { - self.child_storage(storage_key, key).map(|v| Blake2Hasher::hash(&v)) + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { + self.child_storage(storage_key, key).map(|v| Blake2Hasher::hash(&v).encode()) } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + key: &[u8], + ) -> Option> { self.child_storage_hash(storage_key, key) } @@ -196,7 +201,7 @@ impl Externalities for BasicExternalities { fn chain_id(&self) -> u64 { 42 } - fn storage_root(&mut self) -> H256 { + fn storage_root(&mut self) -> Vec { 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 @@ -215,7 +220,7 @@ impl Externalities for BasicExternalities { } } - Layout::::trie_root(self.top.clone()) + Layout::::trie_root(self.top.clone()).as_ref().into() } fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { @@ -225,10 +230,10 @@ impl Externalities for BasicExternalities { InMemory::::default().child_storage_root(storage_key.as_ref(), delta).0 } else { default_child_trie_root::>(storage_key.as_ref()) - } + }.encode() } - fn storage_changes_root(&mut self, _parent: H256) -> Result, ()> { + fn storage_changes_root(&mut self, _parent: &[u8]) -> Result>, ()> { Ok(None) } } @@ -243,7 +248,7 @@ impl externalities::ExtensionStore for BasicExternalities { #[cfg(test)] mod tests { use super::*; - use primitives::{H256, map}; + use primitives::map; use primitives::storage::well_known_keys::CODE; use hex_literal::hex; @@ -255,7 +260,7 @@ mod tests { ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa"); - assert_eq!(ext.storage_root(), H256::from(ROOT)); + assert_eq!(&ext.storage_root()[..], &ROOT); } #[test] diff --git a/primitives/state-machine/src/changes_trie/build.rs b/primitives/state-machine/src/changes_trie/build.rs index 10c38a41e2650..6c50c028ca66e 100644 --- a/primitives/state-machine/src/changes_trie/build.rs +++ b/primitives/state-machine/src/changes_trie/build.rs @@ -18,7 +18,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::collections::btree_map::Entry; -use codec::Decode; +use codec::{Decode, Encode}; use hash_db::Hasher; use num_traits::One; use crate::backend::Backend; @@ -47,6 +47,7 @@ pub(crate) fn prepare_input<'a, B, H, Number>( where B: Backend, H: Hasher + 'a, + H::Out: Encode, Number: BlockNumber, { let number = parent.number.clone() + One::one(); @@ -200,7 +201,7 @@ fn prepare_digest_input<'a, H, Number>( ), String> where H: Hasher, - H::Out: 'a, + H::Out: 'a + Encode, Number: BlockNumber, { let build_skewed_digest = config.end.as_ref() == Some(&block); diff --git a/primitives/state-machine/src/changes_trie/changes_iterator.rs b/primitives/state-machine/src/changes_trie/changes_iterator.rs index 2f61b87fe2199..017eb33d5270f 100644 --- a/primitives/state-machine/src/changes_trie/changes_iterator.rs +++ b/primitives/state-machine/src/changes_trie/changes_iterator.rs @@ -19,7 +19,7 @@ use std::cell::RefCell; use std::collections::VecDeque; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, Codec}; use hash_db::Hasher; use num_traits::Zero; use trie::Recorder; @@ -81,7 +81,7 @@ pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>( max: Number, storage_key: Option<&[u8]>, key: &[u8], -) -> Result>, String> { +) -> Result>, String> where H::Out: Codec { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); @@ -129,7 +129,7 @@ pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>( max: Number, storage_key: Option<&[u8]>, key: &[u8] -) -> Result, String> { +) -> Result, String> where H::Out: Encode { key_changes_proof_check_with_db( config, roots_storage, @@ -152,7 +152,7 @@ pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>( max: Number, storage_key: Option<&[u8]>, key: &[u8] -) -> Result, String> { +) -> Result, String> where H::Out: Encode { // we can't query any roots before root let max = ::std::cmp::min(max.clone(), end.number.clone()); @@ -316,8 +316,8 @@ pub struct DrilldownIterator<'a, H, Number> essence: DrilldownIteratorEssence<'a, H, Number>, } -impl<'a, H: Hasher, Number: BlockNumber> Iterator - for DrilldownIterator<'a, H, Number> +impl<'a, H: Hasher, Number: BlockNumber> Iterator for DrilldownIterator<'a, H, Number> + where H::Out: Encode { type Item = Result<(Number, u32), String>; @@ -358,7 +358,7 @@ impl<'a, H, Number> Iterator for ProvingDrilldownIterator<'a, H, Number> where Number: BlockNumber, H: Hasher, - H::Out: 'a, + H::Out: 'a + Codec, { type Item = Result<(Number, u32), String>; diff --git a/primitives/state-machine/src/changes_trie/mod.rs b/primitives/state-machine/src/changes_trie/mod.rs index f771fddf61964..0542ec6268156 100644 --- a/primitives/state-machine/src/changes_trie/mod.rs +++ b/primitives/state-machine/src/changes_trie/mod.rs @@ -181,7 +181,7 @@ pub fn build_changes_trie<'a, B: Backend, S: Storage, H: Hasher, N parent_hash: H::Out, ) -> Result, H::Out, CacheAction)>, ()> where - H::Out: Ord + 'static, + H::Out: Ord + 'static + Encode, { let (storage, config) = match (storage, changes.changes_trie_config.as_ref()) { (Some(storage), Some(config)) => (storage, config), diff --git a/primitives/state-machine/src/changes_trie/prune.rs b/primitives/state-machine/src/changes_trie/prune.rs index fccd177e60a2f..2f39f9162cc81 100644 --- a/primitives/state-machine/src/changes_trie/prune.rs +++ b/primitives/state-machine/src/changes_trie/prune.rs @@ -25,7 +25,7 @@ use crate::trie_backend_essence::TrieBackendEssence; use crate::changes_trie::{AnchorBlockId, Configuration, Storage, BlockNumber}; use crate::changes_trie::storage::TrieBackendAdapter; use crate::changes_trie::input::{ChildIndex, InputKey}; -use codec::Decode; +use codec::{Decode, Codec}; /// Get number of oldest block for which changes trie is not pruned /// given changes trie configuration, pruning parameter and number of @@ -55,7 +55,7 @@ pub fn prune, H: Hasher, Number: BlockNumber, F: FnMut(H:: min_blocks_to_keep: Number, current_block: &AnchorBlockId, mut remove_trie_node: F, -) { +) where H::Out: Codec { // select range for pruning let (first, last) = match pruning_range(config, min_blocks_to_keep, current_block.number.clone()) { @@ -116,7 +116,7 @@ fn prune_trie, H: Hasher, Number: BlockNumber, F: FnMut(H: storage: &S, root: H::Out, remove_trie_node: &mut F, -) { +) where H::Out: Codec { // enumerate all changes trie' keys, recording all nodes that have been 'touched' // (effectively - all changes trie nodes) @@ -221,13 +221,15 @@ mod tests { storage: &S, min_blocks_to_keep: u64, current_block: u64, - ) -> HashSet { + ) -> HashSet where H::Out: Codec { let mut pruned_trie_nodes = HashSet::new(); - prune(config, + prune( + config, storage, min_blocks_to_keep, &AnchorBlockId { hash: Default::default(), number: current_block }, - |node| { pruned_trie_nodes.insert(node); }); + |node| { pruned_trie_nodes.insert(node); }, + ); pruned_trie_nodes } diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 0e93302a95a54..57197a4ae3c45 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -30,6 +30,7 @@ use primitives::{ }; use trie::{trie_types::Layout, MemoryDB, default_child_trie_root}; use externalities::Extensions; +use codec::{Decode, Encode}; use std::{error, fmt, any::{Any, TypeId}}; use log::{warn, trace}; @@ -189,25 +190,25 @@ where result } - fn storage_hash(&self, key: &[u8]) -> Option { + fn storage_hash(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); let result = self.overlay .storage(key) .map(|x| x.map(|x| H::hash(x))) - .unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) - ); + .unwrap_or_else(|| self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)); + trace!(target: "state-trace", "{:04x}: Hash {}={:?}", self.id, HexDisplay::from(&key), result, ); - result + result.map(|r| r.encode()) } fn original_storage(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); let result = self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginal {}={:?}", self.id, HexDisplay::from(&key), @@ -216,15 +217,16 @@ where result } - fn original_storage_hash(&self, key: &[u8]) -> Option { + fn original_storage_hash(&self, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); let result = self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL); + trace!(target: "state-trace", "{:04x}: GetOriginalHash {}={:?}", self.id, HexDisplay::from(&key), result, ); - result + result.map(|r| r.encode()) } fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { @@ -246,7 +248,7 @@ where result } - fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); let result = self.overlay .child_storage(storage_key.as_ref(), key) @@ -262,7 +264,7 @@ where result, ); - result + result.map(|r| r.encode()) } fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option> { @@ -280,7 +282,11 @@ where result } - fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option { + fn original_child_storage_hash( + &self, + storage_key: ChildStorageKey, + key: &[u8], + ) -> Option> { let _guard = panic_handler::AbortGuard::force_abort(); let result = self.backend .child_storage_hash(storage_key.as_ref(), key) @@ -292,7 +298,7 @@ where HexDisplay::from(&key), result, ); - result + result.map(|r| r.encode()) } fn exists_storage(&self, key: &[u8]) -> bool { @@ -415,14 +421,14 @@ where 42 } - fn storage_root(&mut self) -> H256 { + fn storage_root(&mut self) -> Vec { let _guard = panic_handler::AbortGuard::force_abort(); if let Some((_, ref root)) = self.storage_transaction { trace!(target: "state-trace", "{:04x}: Root (cached) {}", self.id, HexDisplay::from(&root.as_ref()), ); - return root.clone(); + return root.encode(); } let child_storage_keys = @@ -447,7 +453,7 @@ where self.id, HexDisplay::from(&root.as_ref()), ); - root + root.encode() } fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec { @@ -455,6 +461,7 @@ where if self.storage_transaction.is_some() { let root = self .storage(storage_key.as_ref()) + .and_then(|k| Decode::decode(&mut &k[..]).ok()) .unwrap_or( default_child_trie_root::>(storage_key.as_ref()) ); @@ -463,7 +470,7 @@ where HexDisplay::from(&storage_key.as_ref()), HexDisplay::from(&root.as_ref()), ); - root + root.encode() } else { let storage_key = storage_key.as_ref(); @@ -481,7 +488,7 @@ where if is_empty { self.overlay.set_storage(storage_key.into(), None); } else { - self.overlay.set_storage(storage_key.into(), Some(root.clone())); + self.overlay.set_storage(storage_key.into(), Some(root.encode())); } trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}", @@ -489,20 +496,29 @@ where HexDisplay::from(&storage_key.as_ref()), HexDisplay::from(&root.as_ref()), ); - root - + root.encode() } } - fn storage_changes_root(&mut self, parent_hash: H256) -> Result, ()> { + fn storage_changes_root(&mut self, parent_hash: &[u8]) -> Result>, ()> { let _guard = panic_handler::AbortGuard::force_abort(); + self.changes_trie_transaction = build_changes_trie::<_, T, H, N>( self.backend, self.changes_trie_storage.clone(), self.overlay, - parent_hash, + H256::decode(&mut &parent_hash[..]).map_err(|e| + trace!( + target: "state-trace", + "Failed to decode changes root parent hash: {}", + e, + ) + )?, )?; - let result = Ok(self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.clone())); + let result = Ok( + self.changes_trie_transaction.as_ref().map(|(_, root, _)| root.encode()) + ); + trace!(target: "state-trace", "{:04x}: ChangesRoot({}) {:?}", self.id, HexDisplay::from(&parent_hash.as_ref()), @@ -566,7 +582,7 @@ mod tests { let mut overlay = prepare_overlay_with_changes(); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, None, None); - assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); + assert_eq!(ext.storage_changes_root(&H256::default().encode()).unwrap(), None); } #[test] @@ -576,7 +592,7 @@ mod tests { let storage = TestChangesTrieStorage::with_blocks(vec![(100, Default::default())]); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); - assert_eq!(ext.storage_changes_root(Default::default()).unwrap(), None); + assert_eq!(ext.storage_changes_root(&H256::default().encode()).unwrap(), None); } #[test] @@ -586,8 +602,8 @@ mod tests { let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( - ext.storage_changes_root(Default::default()).unwrap(), - Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").into()), + ext.storage_changes_root(&H256::default().encode()).unwrap(), + Some(hex!("bb0c2ef6e1d36d5490f9766cfcc7dfe2a6ca804504c3bb206053890d6dd02376").to_vec()), ); } @@ -599,8 +615,8 @@ mod tests { let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage), None); assert_eq!( - ext.storage_changes_root(Default::default()).unwrap(), - Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").into()), + ext.storage_changes_root(&H256::default().encode()).unwrap(), + Some(hex!("96f5aae4690e7302737b6f9b7f8567d5bbb9eac1c315f80101235a92d9ec27f4").to_vec()), ); } } diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index 151b1a776fd84..d4798ad4fb185 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -21,7 +21,7 @@ use std::{fmt, result, collections::HashMap, panic::UnwindSafe, marker::PhantomData}; use log::{warn, trace}; use hash_db::Hasher; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, Codec}; use primitives::{ storage::well_known_keys, NativeOrEncoded, NeverNativeValue, traits::CodeExecutor, hexdisplay::HexDisplay, hash::H256, @@ -567,7 +567,7 @@ pub fn prove_child_read( where B: Backend, H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -584,7 +584,7 @@ pub fn prove_read_on_trie_backend( where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -606,7 +606,7 @@ pub fn prove_child_read_on_trie_backend( where S: trie_backend_essence::TrieBackendStorage, H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -627,7 +627,7 @@ pub fn read_proof_check( ) -> Result, Option>>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -649,7 +649,7 @@ pub fn read_child_proof_check( ) -> Result, Option>>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, I: IntoIterator, I::Item: AsRef<[u8]>, { @@ -673,7 +673,7 @@ pub fn read_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, { proving_backend.storage(key).map_err(|e| Box::new(e) as Box) } @@ -686,7 +686,7 @@ pub fn read_child_proof_check_on_proving_backend( ) -> Result>, Box> where H: Hasher, - H::Out: Ord, + H::Out: Ord + Codec, { proving_backend.child_storage(storage_key, key).map_err(|e| Box::new(e) as Box) } diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index 73cb8b604a1c2..9bbfd68f67893 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -352,7 +352,7 @@ impl From>> for OverlayedValue { mod tests { use hex_literal::hex; use primitives::{ - Blake2Hasher, H256, traits::Externalities, storage::well_known_keys::EXTRINSIC_INDEX, + Blake2Hasher, traits::Externalities, storage::well_known_keys::EXTRINSIC_INDEX, }; use crate::backend::InMemory; use crate::changes_trie::InMemoryStorage as InMemoryChangesTrieStorage; @@ -426,7 +426,7 @@ mod tests { ); const ROOT: [u8; 32] = hex!("39245109cef3758c2eed2ccba8d9b370a917850af3824bc8348d505df2c298fa"); - assert_eq!(ext.storage_root(), H256::from(ROOT)); + assert_eq!(&ext.storage_root()[..], &ROOT); } #[test] diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 2ebd82f0c43c0..446dc635e1c6c 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -18,7 +18,7 @@ use std::sync::Arc; use parking_lot::RwLock; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, Codec}; use log::debug; use hash_db::{Hasher, HashDB, EMPTY_PREFIX, Prefix}; use trie::{ @@ -119,6 +119,7 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> where S: TrieBackendStorage, H: Hasher, + H::Out: Codec, { /// Produce proof for a key query. pub fn storage(&mut self, key: &[u8]) -> Result>, String> { @@ -145,6 +146,7 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> key: &[u8] ) -> Result>, String> { let root = self.storage(storage_key)? + .and_then(|r| Decode::decode(&mut &r[..]).ok()) .unwrap_or(default_child_trie_root::>(storage_key)); let mut read_overlay = S::Overlay::default(); @@ -158,7 +160,7 @@ impl<'a, S, H> ProvingBackendRecorder<'a, S, H> read_child_trie_value_with::, _, _>( storage_key, &eph, - &root, + &root.as_ref(), key, &mut *self.proof_recorder ).map_err(map_e) @@ -199,7 +201,9 @@ pub struct ProofRecorderBackend<'a, S: 'a + TrieBackendStorage, H: 'a + Hashe proof_recorder: ProofRecorder, } -impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> { +impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> + where H::Out: Codec +{ /// Create new proving backend. pub fn new(backend: &'a TrieBackend) -> Self { let proof_recorder = Default::default(); @@ -254,7 +258,7 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> where S: 'a + TrieBackendStorage, H: 'a + Hasher, - H::Out: Ord, + H::Out: Ord + Codec, { type Error = String; type Transaction = S::Overlay; @@ -302,7 +306,7 @@ impl<'a, S, H> Backend for ProvingBackend<'a, S, H> self.0.storage_root(delta) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, H::Out: Ord @@ -318,6 +322,7 @@ pub fn create_proof_check_backend( ) -> Result, H>, Box> where H: Hasher, + H::Out: Codec, { let db = create_proof_check_backend_storage(proof); diff --git a/primitives/state-machine/src/testing.rs b/primitives/state-machine/src/testing.rs index 61b338bc81acd..dd4f7c557e987 100644 --- a/primitives/state-machine/src/testing.rs +++ b/primitives/state-machine/src/testing.rs @@ -178,7 +178,7 @@ mod tests { ext.set_storage(b"dog".to_vec(), b"puppy".to_vec()); ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec()); const ROOT: [u8; 32] = hex!("2a340d3dfd52f5992c6b117e9e45f479e6da5afffafeb26ab619cf137a95aeb8"); - assert_eq!(ext.storage_root(), H256::from(ROOT)); + assert_eq!(&ext.storage_root()[..], &ROOT); } #[test] diff --git a/primitives/state-machine/src/trie_backend.rs b/primitives/state-machine/src/trie_backend.rs index 432ccf3e75f0e..a2ca5c5d4af93 100644 --- a/primitives/state-machine/src/trie_backend.rs +++ b/primitives/state-machine/src/trie_backend.rs @@ -22,13 +22,14 @@ use trie::{Trie, delta_trie_root, default_child_trie_root, child_delta_trie_root use trie::trie_types::{TrieDB, TrieError, Layout}; use crate::trie_backend_essence::{TrieBackendEssence, TrieBackendStorage, Ephemeral}; use crate::Backend; +use codec::{Codec, Decode}; /// Patricia trie-based backend. Transaction type is an overlay of changes to commit. pub struct TrieBackend, H: Hasher> { essence: TrieBackendEssence, } -impl, H: Hasher> TrieBackend { +impl, H: Hasher> TrieBackend where H::Out: Codec { /// Create new trie-based backend. pub fn new(storage: S, root: H::Out) -> Self { TrieBackend { @@ -64,7 +65,7 @@ impl, H: Hasher> std::fmt::Debug for TrieBackend } impl, H: Hasher> Backend for TrieBackend where - H::Out: Ord, + H::Out: Ord + Codec, { type Error = String; type Transaction = S::Overlay; @@ -159,16 +160,17 @@ impl, H: Hasher> Backend for TrieBackend where (root, write_overlay) } - fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (H::Out, bool, Self::Transaction) where I: IntoIterator, Option>)>, - H::Out: Ord + H::Out: Ord, { let default_root = default_child_trie_root::>(storage_key); let mut write_overlay = S::Overlay::default(); let mut root = match self.storage(storage_key) { - Ok(value) => value.unwrap_or(default_root.clone()), + Ok(value) => + value.and_then(|r| Decode::decode(&mut &r[..]).ok()).unwrap_or(default_root.clone()), Err(e) => { warn!(target: "trie", "Failed to read child storage root: {}", e); default_root.clone() @@ -181,10 +183,10 @@ impl, H: Hasher> Backend for TrieBackend where &mut write_overlay, ); - match child_delta_trie_root::, _, _, _, _>( + match child_delta_trie_root::, _, _, _, _, _>( storage_key, &mut eph, - root.clone(), + root, delta ) { Ok(ret) => root = ret, diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 5a5431963448c..a8572aff6019a 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -26,6 +26,7 @@ use trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue, for_keys_in_child_trie}; use trie::trie_types::{TrieDB, TrieError, Layout}; use crate::backend::Consolidate; +use codec::Encode; /// Patricia trie-based storage trait. pub trait Storage: Send + Sync { @@ -39,7 +40,7 @@ pub struct TrieBackendEssence, H: Hasher> { root: H::Out, } -impl, H: Hasher> TrieBackendEssence { +impl, H: Hasher> TrieBackendEssence where H::Out: Encode { /// Create new trie-based backend. pub fn new(storage: S, root: H::Out) -> Self { TrieBackendEssence { @@ -79,7 +80,7 @@ impl, H: Hasher> TrieBackendEssence { /// Get the value of child storage at given key. pub fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, String> { let root = self.storage(storage_key)? - .unwrap_or(default_child_trie_root::>(storage_key)); + .unwrap_or(default_child_trie_root::>(storage_key).encode()); let mut read_overlay = S::Overlay::default(); let eph = Ephemeral { @@ -95,7 +96,7 @@ impl, H: Hasher> TrieBackendEssence { /// Retrieve all entries keys of child storage and call `f` for each of those keys. pub fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { let root = match self.storage(storage_key) { - Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key)), + Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key).encode()), Err(e) => { debug!(target: "trie", "Error while iterating child storage: {}", e); return; @@ -119,9 +120,14 @@ impl, H: Hasher> TrieBackendEssence { } /// Execute given closure for all keys starting with prefix. - pub fn for_child_keys_with_prefix(&self, storage_key: &[u8], prefix: &[u8], mut f: F) { + pub fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + prefix: &[u8], + mut f: F, + ) { let root_vec = match self.storage(storage_key) { - Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key)), + Ok(v) => v.unwrap_or(default_child_trie_root::>(storage_key).encode()), Err(e) => { debug!(target: "trie", "Error while iterating child storage: {}", e); return; diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index de056cace1b7e..e1315f011f2a8 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -167,39 +167,45 @@ pub fn read_trie_value_with< } /// Determine the default child trie root. -pub fn default_child_trie_root(_storage_key: &[u8]) -> Vec { - L::trie_root::<_, Vec, Vec>(core::iter::empty()).as_ref().iter().cloned().collect() +pub fn default_child_trie_root( + _storage_key: &[u8], +) -> ::Out { + L::trie_root::<_, Vec, Vec>(core::iter::empty()) } /// Determine a child trie root given its ordered contents, closed form. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. -pub fn child_trie_root(_storage_key: &[u8], input: I) -> Vec +pub fn child_trie_root( + _storage_key: &[u8], + input: I, +) -> ::Out where I: IntoIterator, A: AsRef<[u8]> + Ord, B: AsRef<[u8]>, { - L::trie_root(input).as_ref().iter().cloned().collect() + L::trie_root(input) } /// Determine a child trie root given a hash DB and delta values. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. -pub fn child_delta_trie_root( +pub fn child_delta_trie_root( _storage_key: &[u8], db: &mut DB, - root_vec: Vec, - delta: I -) -> Result, Box>> + root_data: RD, + delta: I, +) -> Result<::Out, Box>> where I: IntoIterator)>, A: AsRef<[u8]> + Ord, B: AsRef<[u8]>, + RD: AsRef<[u8]>, DB: hash_db::HashDB + hash_db::PlainDB, trie_db::DBValue>, { let mut root = TrieHash::::default(); // root is fetched from DB, not writable by runtime, so it's always valid. - root.as_mut().copy_from_slice(&root_vec); + root.as_mut().copy_from_slice(root_data.as_ref()); { let mut trie = TrieDBMut::::from_existing(&mut *db, &mut root)?; @@ -212,7 +218,7 @@ pub fn child_delta_trie_root( } } - Ok(root.as_ref().to_vec()) + Ok(root) } /// Call `f` for all keys in a child trie. diff --git a/test/utils/runtime/src/system.rs b/test/utils/runtime/src/system.rs index 1ac318c417c27..1a04da1764323 100644 --- a/test/utils/runtime/src/system.rs +++ b/test/utils/runtime/src/system.rs @@ -30,7 +30,7 @@ use sr_primitives::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionValidityError, }, }; -use codec::{KeyedVec, Encode}; +use codec::{KeyedVec, Encode, Decode}; use frame_system::Trait; use crate::{ AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest, AuthorityId @@ -139,20 +139,26 @@ fn execute_block_with_state_root_handler( }); let o_new_authorities = ::take(); + let storage_root = Hash::decode(&mut &storage_root()[..]) + .expect("`storage_root` is a valid hash"); if let Mode::Overwrite = mode { - header.state_root = storage_root().into(); + header.state_root = storage_root; } else { // check storage root. - let storage_root = storage_root().into(); info_expect_equal_hash(&storage_root, &header.state_root); assert!(storage_root == header.state_root, "Storage root must match that calculated."); } // check digest let digest = &mut header.digest; - if let Some(storage_changes_root) = storage_changes_root(header.parent_hash.into()) { - digest.push(generic::DigestItem::ChangesTrieRoot(storage_changes_root.into())); + if let Some(storage_changes_root) = storage_changes_root(&header.parent_hash.encode()) { + digest.push( + generic::DigestItem::ChangesTrieRoot( + Hash::decode(&mut &storage_changes_root[..]) + .expect("`storage_changes_root` is a valid hash") + ) + ); } if let Some(new_authorities) = o_new_authorities { digest.push(generic::DigestItem::Consensus(*b"aura", new_authorities.encode())); @@ -226,8 +232,10 @@ pub fn finalize_block() -> Header { let o_new_authorities = ::take(); // This MUST come after all changes to storage are done. Otherwise we will fail the // “Storage root does not match that calculated” assertion. - let storage_root = BlakeTwo256::storage_root(); - let storage_changes_root = BlakeTwo256::storage_changes_root(parent_hash); + let storage_root = Hash::decode(&mut &storage_root()[..]) + .expect("`storage_root` is a valid hash"); + let storage_changes_root = storage_changes_root(&parent_hash.encode()) + .map(|r| Hash::decode(&mut &r[..]).expect("`storage_changes_root` is a valid hash")); if let Some(storage_changes_root) = storage_changes_root { digest.push(generic::DigestItem::ChangesTrieRoot(storage_changes_root));