From 0f2a8a70496f697b9de85e3fa650be97a239e251 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 18:29:26 +0100 Subject: [PATCH 01/12] Expose commit in externalities. Also refactor `TestExternalities` into a single place. --- executor/src/native_executor.rs | 3 +- executor/src/wasm_executor.rs | 4 +- native-runtime/std/src/lib.rs | 26 ++++-------- state_machine/src/ext.rs | 4 ++ state_machine/src/lib.rs | 25 ++++------- state_machine/src/testing.rs | 42 +++++++++++++++++++ .../polkadot/src/runtime/governance.rs | 4 +- wasm-runtime/polkadot/src/runtime/session.rs | 4 +- wasm-runtime/polkadot/src/runtime/staking.rs | 4 +- wasm-runtime/polkadot/src/runtime/system.rs | 4 +- .../polkadot/src/runtime/timestamp.rs | 3 +- wasm-runtime/polkadot/src/support/mod.rs | 2 +- wasm-runtime/polkadot/src/support/storage.rs | 5 +-- wasm-runtime/polkadot/src/support/testing.rs | 21 ---------- 14 files changed, 77 insertions(+), 74 deletions(-) create mode 100644 state_machine/src/testing.rs diff --git a/executor/src/native_executor.rs b/executor/src/native_executor.rs index b8c90f2d9a760..6cf7ac6c313c6 100644 --- a/executor/src/native_executor.rs +++ b/executor/src/native_executor.rs @@ -41,8 +41,9 @@ impl CodeExecutor for NativeExecutor { #[cfg(test)] mod tests { use super::*; + use runtime_std::TestExternalities; use native_runtime::codec::KeyedVec; - use native_runtime::support::{TestExternalities, one, two, StaticHexInto}; + use native_runtime::support::{one, two, StaticHexInto}; use native_runtime::runtime::staking::balance; use primitives::twox_128; diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 439defd449cd7..1039a206542ff 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -279,8 +279,8 @@ mod tests { use super::*; use rustc_hex::FromHex; use primitives::{blake2_256, twox_128}; - use runtime_std; - use native_runtime::support::{one, two, StaticHexInto, TestExternalities}; + use runtime_std::{self, TestExternalities}; + use native_runtime::support::{one, two, StaticHexInto}; use native_runtime::codec::KeyedVec; use native_runtime::runtime::staking::balance; diff --git a/native-runtime/std/src/lib.rs b/native-runtime/std/src/lib.rs index fb74093d186ba..24a66933755b7 100644 --- a/native-runtime/std/src/lib.rs +++ b/native-runtime/std/src/lib.rs @@ -39,7 +39,7 @@ pub mod prelude { pub use std::boxed::Box; } -pub use polkadot_state_machine::{Externalities, ExternalitiesError}; +pub use polkadot_state_machine::{Externalities, ExternalitiesError, TestExternalities}; use primitives::hexdisplay::HexDisplay; // TODO: use the real error, not NoError. @@ -92,6 +92,13 @@ pub fn chain_id() -> u64 { ).unwrap_or(0) } +/// "Commit" all existing operations and get the resultant storage root. +pub fn commit() -> [u8; 32] { + ext::with(|ext| + ext.commit() + ).unwrap_or([0u8; 32]) +} + /// Conduct a Keccak-256 hash of the given data. pub use primitives::{blake2_256, twox_128, twox_256}; @@ -140,23 +147,6 @@ macro_rules! impl_stubs { #[cfg(test)] mod tests { use super::*; - use std::collections::HashMap; - - #[derive(Debug, Default)] - struct TestExternalities { - storage: HashMap, Vec>, - } - impl Externalities for TestExternalities { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } - } macro_rules! map { ($( $name:expr => $value:expr ),*) => ( diff --git a/state_machine/src/ext.rs b/state_machine/src/ext.rs index 764c51de10df8..02901c48d596f 100644 --- a/state_machine/src/ext.rs +++ b/state_machine/src/ext.rs @@ -75,4 +75,8 @@ impl<'a, B: 'a> Externalities for Ext<'a, B> fn chain_id(&self) -> u64 { 42 } + + fn commit(&self) -> [u8; 32] { + unimplemented!(); + } } diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index cd7f9291bbbba..ce10400b1e93a 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -35,6 +35,9 @@ use primitives::contract::{CallData}; pub mod backend; mod ext; +mod testing; + +pub use testing::TestExternalities; /// Updates to be committed to the state. pub enum Update { @@ -141,6 +144,9 @@ pub trait Externalities { /// Get the identity of the chain. fn chain_id(&self) -> u64; + /// Get the trie root of the current storage map. + fn commit(&self) -> [u8; 32]; + /// Get the current set of authorities from storage. fn authorities(&self) -> Result, ExternalitiesError> { (0..self.storage(b"con:aut:len")?.into_iter() @@ -210,8 +216,7 @@ pub fn execute( #[cfg(test)] mod tests { - use std::collections::HashMap; - use super::{OverlayedChanges, Externalities, ExternalitiesError}; + use super::{OverlayedChanges, Externalities, TestExternalities}; #[test] fn overlayed_storage_works() { @@ -238,22 +243,6 @@ mod tests { assert!(overlayed.storage(&key).is_none()); } - #[derive(Debug, Default)] - struct TestExternalities { - storage: HashMap, Vec>, - } - impl Externalities for TestExternalities { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } - } - #[test] fn authorities_call_works() { let mut ext = TestExternalities::default(); diff --git a/state_machine/src/testing.rs b/state_machine/src/testing.rs new file mode 100644 index 0000000000000..248afa2025772 --- /dev/null +++ b/state_machine/src/testing.rs @@ -0,0 +1,42 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Test implementation for Externalities. + +use std::collections::HashMap; +use super::{Externalities, ExternalitiesError}; + +/// Simple HashMap based Externalities impl. +#[derive(Debug, Default)] +pub struct TestExternalities { + pub storage: HashMap, Vec>, +} + +impl Externalities for TestExternalities { + fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { + Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) + } + + fn set_storage(&mut self, key: Vec, value: Vec) { + self.storage.insert(key, value); + } + + fn chain_id(&self) -> u64 { 42 } + + fn commit(&self) -> [u8; 32] { + unimplemented!(); + } +} diff --git a/wasm-runtime/polkadot/src/runtime/governance.rs b/wasm-runtime/polkadot/src/runtime/governance.rs index 4f7f6d8688ee5..49605ce3eff6a 100644 --- a/wasm-runtime/polkadot/src/runtime/governance.rs +++ b/wasm-runtime/polkadot/src/runtime/governance.rs @@ -114,9 +114,9 @@ pub mod internal { #[cfg(test)] mod tests { use super::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, TestExternalities, with_env}; + use support::{one, two, with_env}; use primitives::{AccountID, InternalFunction}; use runtime::{staking, session}; diff --git a/wasm-runtime/polkadot/src/runtime/session.rs b/wasm-runtime/polkadot/src/runtime/session.rs index 0402816fdc7b1..6cda783beb608 100644 --- a/wasm-runtime/polkadot/src/runtime/session.rs +++ b/wasm-runtime/polkadot/src/runtime/session.rs @@ -132,9 +132,9 @@ mod tests { use super::public::*; use super::privileged::*; use super::internal::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, TestExternalities, with_env}; + use support::{one, two, with_env}; use primitives::AccountID; use runtime::{consensus, session}; diff --git a/wasm-runtime/polkadot/src/runtime/staking.rs b/wasm-runtime/polkadot/src/runtime/staking.rs index d9bb971647e51..df8d4d632fe5f 100644 --- a/wasm-runtime/polkadot/src/runtime/staking.rs +++ b/wasm-runtime/polkadot/src/runtime/staking.rs @@ -206,9 +206,9 @@ mod tests { use super::public::*; use super::privileged::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, TestExternalities, with_env}; + use support::{one, two, with_env}; use primitives::AccountID; use runtime::{staking, session}; diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index a6bf24718e031..2be96b19e358a 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -127,9 +127,9 @@ mod tests { use super::*; use super::internal::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{Joiner, KeyedVec, Slicable}; - use support::{StaticHexInto, TestExternalities, HexDisplay, one, two}; + use support::{StaticHexInto, HexDisplay, one, two}; use primitives::{UncheckedTransaction, Transaction, Function}; use runtime::staking; diff --git a/wasm-runtime/polkadot/src/runtime/timestamp.rs b/wasm-runtime/polkadot/src/runtime/timestamp.rs index f0a798d112419..abc3fab5b9ef7 100644 --- a/wasm-runtime/polkadot/src/runtime/timestamp.rs +++ b/wasm-runtime/polkadot/src/runtime/timestamp.rs @@ -42,10 +42,9 @@ mod tests { use super::*; use super::public::*; - use runtime_std::{with_externalities, twox_128}; + use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime::timestamp; use codec::{Joiner, KeyedVec}; - use support::TestExternalities; #[test] fn timestamp_works() { diff --git a/wasm-runtime/polkadot/src/support/mod.rs b/wasm-runtime/polkadot/src/support/mod.rs index 6bc60880a07b6..ce9961272f485 100644 --- a/wasm-runtime/polkadot/src/support/mod.rs +++ b/wasm-runtime/polkadot/src/support/mod.rs @@ -31,4 +31,4 @@ pub use self::hashable::Hashable; #[cfg(feature = "with-std")] pub use self::statichex::{StaticHexConversion, StaticHexInto}; #[cfg(feature = "with-std")] -pub use self::testing::{AsBytesRef, HexDisplay, TestExternalities, one, two}; +pub use self::testing::{AsBytesRef, HexDisplay, one, two}; diff --git a/wasm-runtime/polkadot/src/support/storage.rs b/wasm-runtime/polkadot/src/support/storage.rs index 3ff8b1c75d4c9..a0f2a93b495b6 100644 --- a/wasm-runtime/polkadot/src/support/storage.rs +++ b/wasm-runtime/polkadot/src/support/storage.rs @@ -146,9 +146,8 @@ pub trait StorageVec { mod tests { use super::*; use std::collections::HashMap; - use runtime_std::with_externalities; - use support::{TestExternalities, HexDisplay}; - use runtime_std::{storage, twox_128}; + use support::HexDisplay; + use runtime_std::{storage, twox_128, TestExternalities, with_externalities}; #[test] fn integers_can_be_stored() { diff --git a/wasm-runtime/polkadot/src/support/testing.rs b/wasm-runtime/polkadot/src/support/testing.rs index e0e1a336c8042..a2c8579c96282 100644 --- a/wasm-runtime/polkadot/src/support/testing.rs +++ b/wasm-runtime/polkadot/src/support/testing.rs @@ -16,30 +16,9 @@ //! Testing helpers. -use std::collections::HashMap; -use runtime_std::{Externalities, ExternalitiesError}; use primitives::AccountID; use super::statichex::StaticHexInto; -#[derive(Debug, Default)] -/// Simple externaties implementation. -pub struct TestExternalities { - /// The storage map. - pub storage: HashMap, Vec>, -} - -impl Externalities for TestExternalities { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) - } - - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); - } - - fn chain_id(&self) -> u64 { 42 } -} - #[macro_export] macro_rules! map { ($( $name:expr => $value:expr ),*) => ( From b30342c92a1bc71ca5d69615445239912984ab41 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 18:41:32 +0100 Subject: [PATCH 02/12] TestExternalities can commit. --- Cargo.lock | 35 ++++++++++++++++++ state_machine/Cargo.toml | 1 + state_machine/src/lib.rs | 2 + state_machine/src/testing.rs | 26 ++++++++++++- .../release/runtime_polkadot.compact.wasm | Bin 64085 -> 64314 bytes .../release/runtime_polkadot.wasm | Bin 64134 -> 64363 bytes 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c741c845a5848..d025b1556d34f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,6 +331,23 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hex-literal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal-impl" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "httparse" version = "1.2.3" @@ -794,6 +811,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", @@ -819,6 +837,19 @@ dependencies = [ "difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro-hack" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.3.15" @@ -1315,6 +1346,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90d069fe6beb9be359ef505650b3f73228c5591a3c4b1f32be2f4f44459ffa3a" "checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5" "checksum heapsize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54fab2624374e5137ae4df13bf32b0b269cb804df42d13a51221bbd431d1a237" +"checksum hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd546ef520ab3745f1aae5f2cdc6de9e6498e94d1ab138b9eb3ddfbf335847fb" +"checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" "checksum hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b45eac8b696d59491b079bd04fcb0f3488c0f6ed62dcb36bcfea8a543e9cdc3" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" @@ -1352,6 +1385,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995" "checksum pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94b6bbc8a323d89a019c4cdde21850522fb8405e97add70827177fc2f86c1495" +"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0" +"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" "checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" diff --git a/state_machine/Cargo.toml b/state_machine/Cargo.toml index 458bae8e1efe4..65c6feed54cd7 100644 --- a/state_machine/Cargo.toml +++ b/state_machine/Cargo.toml @@ -11,3 +11,4 @@ patricia-trie = "0.1.0" memorydb = "0.1.1" triehash = "0.1" byteorder = "1.1" +hex-literal = "0.1.0" diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index ce10400b1e93a..61b1fafd37f95 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -19,6 +19,8 @@ #![warn(missing_docs)] extern crate polkadot_primitives as primitives; +#[macro_use] +extern crate hex_literal; extern crate hashdb; extern crate memorydb; diff --git a/state_machine/src/testing.rs b/state_machine/src/testing.rs index 248afa2025772..74cfbb9dd5930 100644 --- a/state_machine/src/testing.rs +++ b/state_machine/src/testing.rs @@ -18,6 +18,7 @@ use std::collections::HashMap; use super::{Externalities, ExternalitiesError}; +use triehash::trie_root; /// Simple HashMap based Externalities impl. #[derive(Debug, Default)] @@ -25,6 +26,14 @@ pub struct TestExternalities { pub storage: HashMap, Vec>, } +impl TestExternalities { + fn new() -> Self { + TestExternalities { + storage: HashMap::new(), + } + } +} + impl Externalities for TestExternalities { fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { Ok(self.storage.get(&key.to_vec()).map_or(&[] as &[u8], Vec::as_slice)) @@ -37,6 +46,21 @@ impl Externalities for TestExternalities { fn chain_id(&self) -> u64 { 42 } fn commit(&self) -> [u8; 32] { - unimplemented!(); + trie_root(self.storage.clone()).0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn commit_should_work() { + let mut ext = TestExternalities::new(); + 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()); + const ROOT: [u8; 32] = hex!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"); + assert_eq!(ext.commit(), ROOT); } } diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index db7dab9917d324f143aea0837c0fdf2ee30504bc..0bd07dc534053aed194903000f119179e4b28a8c 100644 GIT binary patch delta 14956 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 CT9%vu delta 14648 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 DHXco| diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index a0dc5a2754ab33efa1b1deea73317bc369fdc975..1e4d2fb99ba3e5a29ef5e6a35c0dc8ad4d99950c 100644 GIT binary patch delta 15008 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 Ca-^aF delta 14681 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 From 15aad6fa6c1cb2ba3fe3e5f0b68257ccccaa42f5 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 19:21:54 +0100 Subject: [PATCH 03/12] Storage root for Ext. --- native-runtime/std/src/lib.rs | 4 ++-- state_machine/src/backend.rs | 7 +++++++ state_machine/src/ext.rs | 13 ++++++++++--- state_machine/src/lib.rs | 2 +- state_machine/src/testing.rs | 8 +++++--- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/native-runtime/std/src/lib.rs b/native-runtime/std/src/lib.rs index 24a66933755b7..be67b81babe42 100644 --- a/native-runtime/std/src/lib.rs +++ b/native-runtime/std/src/lib.rs @@ -93,9 +93,9 @@ pub fn chain_id() -> u64 { } /// "Commit" all existing operations and get the resultant storage root. -pub fn commit() -> [u8; 32] { +pub fn storage_root() -> [u8; 32] { ext::with(|ext| - ext.commit() + ext.storage_root() ).unwrap_or([0u8; 32]) } diff --git a/state_machine/src/backend.rs b/state_machine/src/backend.rs index ee6b0bbe8027b..9f07f2d98c316 100644 --- a/state_machine/src/backend.rs +++ b/state_machine/src/backend.rs @@ -40,6 +40,9 @@ pub trait Backend { /// Commit updates to the backend and get new state. fn commit(&mut self, changes: I) -> Committed where I: IntoIterator; + + /// Get all key/value pairs into a Vec. + fn pairs(&self) -> Vec<(&[u8], &[u8])>; } /// Error impossible. @@ -87,6 +90,10 @@ impl Backend for InMemory { storage_tree_root, } } + + fn pairs(&self) -> Vec<(&[u8], &[u8])> { + self.inner.storage.iter().map(|(k, v)| (&k[..], &v[..])).collect() + } } // TODO: DB-based backend diff --git a/state_machine/src/ext.rs b/state_machine/src/ext.rs index 02901c48d596f..1beca17fa6f81 100644 --- a/state_machine/src/ext.rs +++ b/state_machine/src/ext.rs @@ -17,7 +17,7 @@ //! Conrete externalities implementation. use std::{error, fmt}; - +use triehash::trie_root; use backend::Backend; use {Externalities, ExternalitiesError, OverlayedChanges}; @@ -76,7 +76,14 @@ impl<'a, B: 'a> Externalities for Ext<'a, B> 42 } - fn commit(&self) -> [u8; 32] { - unimplemented!(); + fn storage_root(&self) -> [u8; 32] { + let mut all_pairs = self.backend.pairs(); + all_pairs.extend( + self.overlay.committed.storage.iter() + .chain(self.overlay.prospective.storage.iter()) + .map(|(k, v)| (&k[..], &v[..])) + ); + + trie_root(all_pairs.into_iter().map(|(k, v)| (k.to_vec(), v.to_vec()))).0 } } diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index 61b1fafd37f95..e1e674a419719 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -147,7 +147,7 @@ pub trait Externalities { fn chain_id(&self) -> u64; /// Get the trie root of the current storage map. - fn commit(&self) -> [u8; 32]; + fn storage_root(&self) -> [u8; 32]; /// Get the current set of authorities from storage. fn authorities(&self) -> Result, ExternalitiesError> { diff --git a/state_machine/src/testing.rs b/state_machine/src/testing.rs index 74cfbb9dd5930..1c9c4dfcf8fa3 100644 --- a/state_machine/src/testing.rs +++ b/state_machine/src/testing.rs @@ -23,11 +23,13 @@ use triehash::trie_root; /// Simple HashMap based Externalities impl. #[derive(Debug, Default)] pub struct TestExternalities { + /// The storage. pub storage: HashMap, Vec>, } impl TestExternalities { - fn new() -> Self { + /// Create a new instance with empty storage. + pub fn new() -> Self { TestExternalities { storage: HashMap::new(), } @@ -45,7 +47,7 @@ impl Externalities for TestExternalities { fn chain_id(&self) -> u64 { 42 } - fn commit(&self) -> [u8; 32] { + fn storage_root(&self) -> [u8; 32] { trie_root(self.storage.clone()).0 } } @@ -61,6 +63,6 @@ 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!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"); - assert_eq!(ext.commit(), ROOT); + assert_eq!(ext.storage_root(), ROOT); } } From e42cc9215ca6ccfbdc1be8aa5bd31ffdc502c3ae Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 19:41:50 +0100 Subject: [PATCH 04/12] Test for overlaying and storage root calculation. --- state_machine/src/backend.rs | 12 ++++++++++++ state_machine/src/lib.rs | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/state_machine/src/backend.rs b/state_machine/src/backend.rs index 9f07f2d98c316..5362d03be126d 100644 --- a/state_machine/src/backend.rs +++ b/state_machine/src/backend.rs @@ -67,6 +67,18 @@ pub struct InMemory { inner: MemoryState, // keeps all the state in memory. } +#[cfg(test)] +impl InMemory { + /// Create a new instance from a given storage map. + pub fn from(storage: ::std::collections::HashMap, Vec>) -> Self { + InMemory { + inner: MemoryState { + storage + } + } + } +} + impl Backend for InMemory { type Error = Void; diff --git a/state_machine/src/lib.rs b/state_machine/src/lib.rs index e1e674a419719..11ea5adbb55e8 100644 --- a/state_machine/src/lib.rs +++ b/state_machine/src/lib.rs @@ -218,7 +218,9 @@ pub fn execute( #[cfg(test)] mod tests { - use super::{OverlayedChanges, Externalities, TestExternalities}; + use super::*; + use super::backend::InMemory; + use super::ext::Ext; #[test] fn overlayed_storage_works() { @@ -264,4 +266,34 @@ mod tests { ext.set_storage(b"con:aut:\x01\0\0\0".to_vec(), b"second".to_vec()); assert_eq!(ext.authorities(), Ok(vec![&b"first"[..], &b"second"[..]])); } + + macro_rules! map { + ($( $name:expr => $value:expr ),*) => ( + vec![ $( ( $name, $value ) ),* ].into_iter().collect() + ) + } + + #[test] + fn overlayed_storage_root_works() { + let mut backend = InMemory::from(map![ + b"doe".to_vec() => b"reindeer".to_vec(), + b"dog".to_vec() => b"puppyXXX".to_vec(), + b"dogglesworth".to_vec() => b"catXXX".to_vec() + ]); + let mut overlay = OverlayedChanges { + committed: MemoryState { storage: map![ + b"dog".to_vec() => b"puppy".to_vec(), + b"dogglesworth".to_vec() => b"catYYY".to_vec() + ], }, + prospective: MemoryState { storage: map![ + b"dogglesworth".to_vec() => b"cat".to_vec() + ], }, + }; + let ext = Ext { + backend: &mut backend, + overlay: &mut overlay, + }; + const ROOT: [u8; 32] = hex!("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3"); + assert_eq!(ext.storage_root(), ROOT); + } } From bd8349bd45be0949a10d6037a953c012b3ae9c78 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 20:09:06 +0100 Subject: [PATCH 05/12] Actually check state root. Also refactor wasm exports to be stricter on invalid mem references. --- executor/src/wasm_executor.rs | 136 ++++++++---------- wasm-runtime/polkadot/src/runtime/system.rs | 7 +- wasm-runtime/std/src/lib.rs | 13 +- .../release/runtime_polkadot.compact.wasm | Bin 64314 -> 64623 bytes .../release/runtime_polkadot.wasm | Bin 64363 -> 64672 bytes 5 files changed, 69 insertions(+), 87 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 1039a206542ff..a741a7b07badf 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -66,15 +66,15 @@ impl<'e, E: Externalities> FunctionExecutor<'e, E> { } trait WritePrimitive { - fn write_primitive(&self, offset: u32, t: T); + fn write_primitive(&self, offset: u32, t: T) -> ::std::result::Result<(), DummyUserError>; } impl WritePrimitive for MemoryInstance { - fn write_primitive(&self, offset: u32, t: u32) { + fn write_primitive(&self, offset: u32, t: u32) -> ::std::result::Result<(), DummyUserError> { use byteorder::{LittleEndian, ByteOrder}; let mut r = [0u8; 4]; LittleEndian::write_u32(&mut r, t); - let _ = self.set(offset, &r); + self.set(offset, &r).map_err(|_| DummyUserError) } } @@ -95,29 +95,29 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, println!("Runtime: {}", number); }, ext_memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 => { - if let (Ok(sl1), Ok(sl2)) - = (this.memory.get(s1, n as usize), this.memory.get(s2, n as usize)) { - match sl1.cmp(&sl2) { - Ordering::Greater => 1, - Ordering::Less => -1, - Ordering::Equal => 0, - } - } else { - return Err(DummyUserError.into()); + let sl1 = this.memory.get(s1, n as usize).map_err(|_| DummyUserError)?; + let sl2 = this.memory.get(s2, n as usize).map_err(|_| DummyUserError)?; + match sl1.cmp(&sl2) { + Ordering::Greater => 1, + Ordering::Less => -1, + Ordering::Equal => 0, } }, ext_memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { - let _ = this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize); + this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize) + .map_err(|_| DummyUserError)?; println!("memcpy {} from {}, {} bytes", dest, src, count); dest }, ext_memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { - let _ = this.memory.copy(src as usize, dest as usize, count as usize); + this.memory.copy(src as usize, dest as usize, count as usize) + .map_err(|_| DummyUserError)?; println!("memmove {} from {}, {} bytes", dest, src, count); dest }, ext_memset(dest: *mut u8, val: u32, count: usize) -> *mut u8 => { - let _ = this.memory.clear(dest as usize, val as u8, count as usize); + this.memory.clear(dest as usize, val as u8, count as usize) + .map_err(|_| DummyUserError)?; println!("memset {} with {}, {} bytes", dest, val, count); dest }, @@ -136,90 +136,66 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } }, ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { - let (offset, written) = if let Ok(key) = this.memory.get(key_data, key_len as usize) { - if let Ok(value) = this.ext.storage(&key) { - let offset = this.heap.allocate(value.len() as u32) as u32; - let _ = this.memory.set(offset, &value); - (offset, value.len() as u32) - } else { (0, 0) } - } else { (0, 0) }; - - this.memory.write_primitive(written_out, written); - offset as u32 + let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; + + let offset = this.heap.allocate(value.len() as u32) as u32; + this.memory.set(offset, &value).map_err(|_| DummyUserError)?; + + this.memory.write_primitive(written_out, value.len() as u32)?; + offset }, ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32 => { - if let Ok(key) = this.memory.get(key_data, key_len as usize) { - if let Ok(value) = this.ext.storage(&key) { - let value = &value[value_offset as usize..]; - let written = ::std::cmp::min(value_len as usize, value.len()); - let _ = this.memory.set(value_data, &value[..written]); - written as u32 - } else { 0 } - } else { 0 } + let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; + let value = &value[value_offset as usize..]; + let written = ::std::cmp::min(value_len as usize, value.len()); + this.memory.set(value_data, &value[..written]).map_err(|_| DummyUserError)?; + written as u32 + }, + ext_storage_root(result: *mut u8) => { + let r = this.ext.storage_root(); + this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; }, ext_chain_id() -> u64 => { this.ext.chain_id() }, ext_twox_128(data: *const u8, len: u32, out: *mut u8) => { - let maybe_value = if len == 0 { - Ok(vec![]) - } else { - this.memory.get(data, len as usize) - }; - let result = if let Ok(value) = maybe_value { - twox_128(&value) + let result = if len == 0 { + twox_128(&[0u8; 0]) } else { - [0; 16] + twox_128(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) }; - let _ = this.memory.set(out, &result); + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { - let maybe_value = if len == 0 { - Ok(vec![]) + let result = if len == 0 { + twox_256(&[0u8; 0]) } else { - this.memory.get(data, len as usize) + twox_256(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) }; - let result = if let Ok(value) = maybe_value { - twox_256(&value) - } else { - [0; 32] - }; - let _ = this.memory.set(out, &result); + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { - let maybe_value = if len == 0 { - Ok(vec![]) - } else { - this.memory.get(data, len as usize) - }; - let result = if let Ok(value) = maybe_value { - blake2_256(&value) + let result = if len == 0 { + blake2_256(&[0u8; 0]) } else { - [0; 32] + blake2_256(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) }; - let _ = this.memory.set(out, &result); + this.memory.set(out, &result).map_err(|_| DummyUserError)?; }, ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32 => { - (||{ - let mut sig = [0u8; 64]; - if let Err(_) = this.memory.get_into(sig_data, &mut sig[..]) { - return 2; - }; - let mut pubkey = [0u8; 32]; - if let Err(_) = this.memory.get_into(pubkey_data, &mut pubkey[..]) { - return 3; - }; - - if let Ok(msg) = this.memory.get(msg_data, msg_len as usize) { - if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { - 0 - } else { - 5 - } - } else { - 4 - } - })() + let mut sig = [0u8; 64]; + this.memory.get_into(sig_data, &mut sig[..]).map_err(|_| DummyUserError)?; + let mut pubkey = [0u8; 32]; + this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| DummyUserError)?; + let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| DummyUserError)?; + + if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { + 0 + } else { + 5 + } } => <'e, E: Externalities + 'e> ); diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 2be96b19e358a..8ca1704c20ac5 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -18,7 +18,7 @@ //! and depositing logs. use runtime_std::prelude::*; -use runtime_std::{mem, print}; +use runtime_std::{mem, print, storage_root}; use codec::KeyedVec; use support::{Hashable, storage, with_env}; use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder}; @@ -91,9 +91,8 @@ pub mod internal { // any final checks final_checks(&block); - // TODO: check storage root. - // this requires non-trivial changes to the externals API or compiling trie rooting into wasm - // so will wait until a little later. + // check storage root. + assert!(header.state_root == storage_root(), "Storage root must match that calculated."); } /// Execute a given transaction. diff --git a/wasm-runtime/std/src/lib.rs b/wasm-runtime/std/src/lib.rs index 9b7d385e694e6..13df07c49f6c5 100644 --- a/wasm-runtime/std/src/lib.rs +++ b/wasm-runtime/std/src/lib.rs @@ -42,6 +42,7 @@ extern "C" { fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; + fn ext_storage_root(result: *mut u8); fn ext_chain_id() -> u64; fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); @@ -72,6 +73,15 @@ pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> us } } +/// The current storage's root. +pub fn storage_root() -> [u8; 32] { + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_storage_root(result.as_mut_ptr()); + } + result +} + /// The current relay chain identifier. pub fn chain_id() -> u64 { unsafe { @@ -82,7 +92,6 @@ pub fn chain_id() -> u64 { /// Conduct a 256-bit Blake2 hash. pub fn blake2_256(data: &[u8]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); - // guaranteed to write into result. unsafe { ext_blake2_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } @@ -92,7 +101,6 @@ pub fn blake2_256(data: &[u8]) -> [u8; 32] { /// Conduct four XX hashes to give a 256-bit result. pub fn twox_256(data: &[u8]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); - // guaranteed to write into result. unsafe { ext_twox_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } @@ -102,7 +110,6 @@ pub fn twox_256(data: &[u8]) -> [u8; 32] { /// Conduct two XX hashes to give a 128-bit result. pub fn twox_128(data: &[u8]) -> [u8; 16] { let mut result: [u8; 16] = Default::default(); - // guaranteed to write into result. unsafe { ext_twox_128(data.as_ptr(), data.len() as u32, result.as_mut_ptr()); } diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index 0bd07dc534053aed194903000f119179e4b28a8c..efedffaadf90f38db73dd269166034bb41567390 100644 GIT binary patch delta 17591 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 delta 17315 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 ZnfOl}Yc@k{-lNTCWCP^ial_8G{{;|hxO@Nr diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index 1e4d2fb99ba3e5a29ef5e6a35c0dc8ad4d99950c..c4e00c3e3e2ca46605a6f4416500bc0c18f558de 100644 GIT binary patch delta 17541 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 Ih8<1+3$tsn?f?J) From 42db01fffecda6bceaa635d5c24b73fd5e54ca4f Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 20:52:59 +0100 Subject: [PATCH 06/12] test state root calculation. --- Cargo.lock | 1 + native-runtime/Cargo.toml | 1 + wasm-runtime/polkadot/src/lib.rs | 3 + wasm-runtime/polkadot/src/runtime/system.rs | 118 +++++++++++++++++++- 4 files changed, 117 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d025b1556d34f..7ae006d75ae3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,6 +570,7 @@ dependencies = [ name = "native-runtime" version = "0.1.0" dependencies = [ + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "runtime-std 0.1.0", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/native-runtime/Cargo.toml b/native-runtime/Cargo.toml index 25091c2cefb60..5ee1706e9cf08 100644 --- a/native-runtime/Cargo.toml +++ b/native-runtime/Cargo.toml @@ -11,3 +11,4 @@ without-std = [] [dependencies] runtime-std = { path = "./std", version = "0.1" } rustc-hex = "1.0" +hex-literal = "0.1.0" diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 1eeff3c64950e..6769ce9146220 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -25,6 +25,9 @@ extern crate runtime_std; #[cfg(feature = "with-std")] extern crate rustc_hex; +#[macro_use] +extern crate hex_literal; + pub mod codec; #[macro_use] pub mod support; diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 8ca1704c20ac5..dccf747929799 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -20,7 +20,7 @@ use runtime_std::prelude::*; use runtime_std::{mem, print, storage_root}; use codec::KeyedVec; -use support::{Hashable, storage, with_env}; +use support::{self, Hashable, storage, with_env}; use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder}; use runtime::{staking, session}; @@ -78,10 +78,6 @@ pub mod internal { // this requires non-trivial changes to the externals API or compiling trie rooting into wasm // so will wait until a little later. - // store the header hash in storage. - let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT); - storage::put(&header_hash_key, &header.blake2_256()); - // execute transactions block.transactions.iter().for_each(execute_transaction); @@ -91,8 +87,15 @@ pub mod internal { // any final checks final_checks(&block); + println!("SR: {}", super::support::HexDisplay::from(&storage_root())); + // check storage root. assert!(header.state_root == storage_root(), "Storage root must match that calculated."); + + // store the header hash in storage; we can't do it before otherwise there would be a + // cyclic dependency. + let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT); + storage::put(&header_hash_key, &header.blake2_256()); } /// Execute a given transaction. @@ -129,7 +132,7 @@ mod tests { use runtime_std::{with_externalities, twox_128, TestExternalities}; use codec::{Joiner, KeyedVec, Slicable}; use support::{StaticHexInto, HexDisplay, one, two}; - use primitives::{UncheckedTransaction, Transaction, Function}; + use primitives::{UncheckedTransaction, Transaction, Function, Header, Digest}; use runtime::staking; #[test] @@ -161,4 +164,107 @@ mod tests { assert_eq!(staking::balance(&two), 69); }); } + + fn new_test_ext() -> TestExternalities { + let one = one(); + let two = two(); + let three = [3u8; 32]; + + TestExternalities { storage: map![ + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), + twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), + twox_128(b"ses:len").to_vec() => vec![].join(&2u64), + twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), + twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), + twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), + twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], } + } + + #[test] + fn block_import_works() { + let one = one(); + let two = two(); + + let mut t = new_test_ext(); + + let tx = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two).join(&69u64), + }, + signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), + }; + // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 + // sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a + + let h = Header { + parent_hash: [69u8; 32], + number: 1, + state_root: hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"), + transaction_root: [0u8; 32], // Unchecked currently. + digest: Digest { logs: vec![], }, + }; + + let b = Block { + header: h, + transactions: vec![tx], + }; + + with_externalities(&mut t, || { + execute_block(b); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } + + #[test] + #[should_panic] + fn block_import_of_bad_state_root_fails() { + let one = one(); + let two = two(); + + let mut t = new_test_ext(); + + let tx = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two).join(&69u64), + }, + signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), + }; + // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 + // sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a + + let h = Header { + parent_hash: [69u8; 32], + number: 1, + state_root: [0u8; 32], + transaction_root: [0u8; 32], // Unchecked currently. + digest: Digest { logs: vec![], }, + }; + + let b = Block { + header: h, + transactions: vec![tx], + }; + + with_externalities(&mut t, || { + execute_block(b); + assert_eq!(staking::balance(&one), 42); + assert_eq!(staking::balance(&two), 69); + }); + } } From 7db71a43b678db647e164b8f8a51c9a7e3c57e24 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 20:56:57 +0100 Subject: [PATCH 07/12] Remove superfluous code. --- wasm-runtime/polkadot/src/runtime/system.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index dccf747929799..54936610e0ef0 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -20,7 +20,7 @@ use runtime_std::prelude::*; use runtime_std::{mem, print, storage_root}; use codec::KeyedVec; -use support::{self, Hashable, storage, with_env}; +use support::{Hashable, storage, with_env}; use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder}; use runtime::{staking, session}; @@ -87,7 +87,7 @@ pub mod internal { // any final checks final_checks(&block); - println!("SR: {}", super::support::HexDisplay::from(&storage_root())); +// println!("SR: {}", ::support::HexDisplay::from(&storage_root())); // check storage root. assert!(header.state_root == storage_root(), "Storage root must match that calculated."); @@ -205,8 +205,6 @@ mod tests { }, signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(), }; - // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 - // sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a let h = Header { parent_hash: [69u8; 32], From ab6c98be4e85721052ef10506327c0fb286ebeb8 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 30 Jan 2018 22:40:03 +0100 Subject: [PATCH 08/12] Implement enumerated trie root throughout. --- Cargo.lock | 3 +- executor/Cargo.toml | 2 +- executor/src/lib.rs | 2 +- executor/src/wasm_executor.rs | 36 ++++++++++++++++++ native-runtime/std/Cargo.toml | 1 + native-runtime/std/src/lib.rs | 8 ++++ wasm-runtime/polkadot/src/lib.rs | 1 + wasm-runtime/polkadot/src/runtime/system.rs | 15 ++++---- wasm-runtime/std/src/lib.rs | 16 ++++++++ .../release/runtime_polkadot.compact.wasm | Bin 64623 -> 67405 bytes .../release/runtime_polkadot.wasm | Bin 64672 -> 67454 bytes 11 files changed, 74 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b4783a191c9f0..c139749441f71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -986,7 +986,6 @@ dependencies = [ "assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "native-runtime 0.1.0", "parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", @@ -996,6 +995,7 @@ dependencies = [ "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1235,6 +1235,7 @@ dependencies = [ "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", "polkadot-state-machine 0.1.0", + "triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/executor/Cargo.toml b/executor/Cargo.toml index 5329eb7023098..41fdef97057f6 100644 --- a/executor/Cargo.toml +++ b/executor/Cargo.toml @@ -15,7 +15,7 @@ byteorder = "1.1" rustc-hex = "1.0.0" native-runtime = { path = "../native-runtime", version = "0.1" } runtime-std = { path = "../native-runtime/std", version = "0.1" } -libc = { version = "0.2.33" } +triehash = "0.1.0" [dev-dependencies] assert_matches = "1.1" diff --git a/executor/src/lib.rs b/executor/src/lib.rs index 9935f8aec81d2..e4ed7f95b0e8a 100644 --- a/executor/src/lib.rs +++ b/executor/src/lib.rs @@ -36,7 +36,7 @@ extern crate byteorder; extern crate rustc_hex; extern crate native_runtime; extern crate runtime_std; -extern crate libc; +extern crate triehash; #[macro_use] extern crate error_chain; diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index a741a7b07badf..5e18868238ea7 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -29,6 +29,7 @@ use wasm_utils::{MemoryInstance, UserDefinedElements, AddModuleWithoutFullDependentInstance}; use primitives::{ed25519, blake2_256, twox_128, twox_256}; use primitives::hexdisplay::HexDisplay; +use triehash::ordered_trie_root; struct Heap { end: u32, @@ -78,6 +79,17 @@ impl WritePrimitive for MemoryInstance { } } +trait ReadPrimitive { + fn read_primitive(&self, offset: u32) -> ::std::result::Result; +} + +impl ReadPrimitive for MemoryInstance { + fn read_primitive(&self, offset: u32) -> ::std::result::Result { + use byteorder::{LittleEndian, ByteOrder}; + Ok(LittleEndian::read_u32(&self.get(offset, 4).map_err(|_| DummyUserError)?)) + } +} + impl_function_executor!(this: FunctionExecutor<'e, E>, ext_print_utf8(utf8_data: *const u8, utf8_len: u32) => { if let Ok(utf8) = this.memory.get(utf8_data, utf8_len as usize) { @@ -157,6 +169,20 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, let r = this.ext.storage_root(); this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; }, + ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8) => { + let offsets = (0..lens_len) + .map(|i| this.memory.read_primitive(lens_data + i * 4)) + .collect::<::std::result::Result, DummyUserError>>()?; + let values = offsets.into_iter() + .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) + .map(|(offset, len)| + this.memory.get(values_data + offset, len as usize) + .map_err(|_| DummyUserError) + ) + .collect::<::std::result::Result, DummyUserError>>()?; + let r = ordered_trie_root(values.into_iter()); + this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; + }, ext_chain_id() -> u64 => { this.ext.chain_id() }, @@ -356,6 +382,16 @@ mod tests { ); } + #[test] + fn enumerated_trie_root_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_enumerated_trie_root", &CallData(vec![])).unwrap(), + vec![0] + ); + } + fn tx() -> Vec { "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000".convert() } #[test] diff --git a/native-runtime/std/Cargo.toml b/native-runtime/std/Cargo.toml index 0976e4b378fe8..a4f665bfcce28 100644 --- a/native-runtime/std/Cargo.toml +++ b/native-runtime/std/Cargo.toml @@ -12,3 +12,4 @@ parking_lot = "0.5" polkadot-state-machine = { path = "../../state_machine" , version = "0.1" } environmental = { path = "../../environmental", version = "0.1.0" } polkadot-primitives = { path = "../../primitives", version = "0.1.0" } +triehash = "0.1.0" diff --git a/native-runtime/std/src/lib.rs b/native-runtime/std/src/lib.rs index be67b81babe42..fba5462f7d920 100644 --- a/native-runtime/std/src/lib.rs +++ b/native-runtime/std/src/lib.rs @@ -20,6 +20,7 @@ extern crate environmental; extern crate polkadot_state_machine; extern crate polkadot_primitives as primitives; +extern crate triehash; use std::fmt; use primitives::ed25519; @@ -99,6 +100,13 @@ pub fn storage_root() -> [u8; 32] { ).unwrap_or([0u8; 32]) } +/// "Commit" all existing operations and get the resultant storage root. +pub fn enumerated_trie_root(serialised_values: &[&[u8]]) -> [u8; 32] { + ext::with(|ext| + triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0 + ).unwrap_or([0u8; 32]) +} + /// Conduct a Keccak-256 hash of the given data. pub use primitives::{blake2_256, twox_128, twox_256}; diff --git a/wasm-runtime/polkadot/src/lib.rs b/wasm-runtime/polkadot/src/lib.rs index 6769ce9146220..677272e93f472 100644 --- a/wasm-runtime/polkadot/src/lib.rs +++ b/wasm-runtime/polkadot/src/lib.rs @@ -25,6 +25,7 @@ extern crate runtime_std; #[cfg(feature = "with-std")] extern crate rustc_hex; +#[cfg(test)] #[macro_use] extern crate hex_literal; diff --git a/wasm-runtime/polkadot/src/runtime/system.rs b/wasm-runtime/polkadot/src/runtime/system.rs index 54936610e0ef0..8df20f138e7eb 100644 --- a/wasm-runtime/polkadot/src/runtime/system.rs +++ b/wasm-runtime/polkadot/src/runtime/system.rs @@ -18,8 +18,8 @@ //! and depositing logs. use runtime_std::prelude::*; -use runtime_std::{mem, print, storage_root}; -use codec::KeyedVec; +use runtime_std::{mem, print, storage_root, enumerated_trie_root}; +use codec::{KeyedVec, Slicable}; use support::{Hashable, storage, with_env}; use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder}; use runtime::{staking, session}; @@ -74,9 +74,11 @@ pub mod internal { "Parent hash should be valid." ); - // TODO: check transaction trie root represents the transactions. - // this requires non-trivial changes to the externals API or compiling trie rooting into wasm - // so will wait until a little later. + // check transaction trie root represents the transactions. + let txs = block.transactions.iter().map(Slicable::to_vec).collect::>(); + let txs_root = enumerated_trie_root(&txs.iter().map(Vec::as_slice).collect::>()); +// println!("TR: {}", ::support::HexDisplay::from(&txs_root)); + assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); // execute transactions block.transactions.iter().for_each(execute_transaction); @@ -87,7 +89,6 @@ pub mod internal { // any final checks final_checks(&block); -// println!("SR: {}", ::support::HexDisplay::from(&storage_root())); // check storage root. assert!(header.state_root == storage_root(), "Storage root must match that calculated."); @@ -210,7 +211,7 @@ mod tests { parent_hash: [69u8; 32], number: 1, state_root: hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"), - transaction_root: [0u8; 32], // Unchecked currently. + transaction_root: hex!("91fab88ad8c30a6d05ad8e0cf9ab139bf1b8cdddc69abd51cdfa6d2699038af1"), digest: Digest { logs: vec![], }, }; diff --git a/wasm-runtime/std/src/lib.rs b/wasm-runtime/std/src/lib.rs index 13df07c49f6c5..3feb8c5544644 100644 --- a/wasm-runtime/std/src/lib.rs +++ b/wasm-runtime/std/src/lib.rs @@ -43,6 +43,7 @@ extern "C" { fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; fn ext_storage_root(result: *mut u8); + fn ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8); fn ext_chain_id() -> u64; fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); @@ -82,6 +83,21 @@ pub fn storage_root() -> [u8; 32] { result } +/// A trie root calculated from enumerated values. +pub fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32] { + let lens = values.iter().map(|v| (v.len() as u32).to_le()).collect::>(); + let values = values.iter().fold(Vec::new(), |mut acc, sl| { acc.extend_from_slice(sl); acc }); + let mut result: [u8; 32] = Default::default(); + unsafe { + ext_enumerated_trie_root( + values.as_ptr(), values.len() as u32, + lens.as_ptr(), lens.len() as u32, + result.as_mut_ptr() + ); + } + result +} + /// The current relay chain identifier. pub fn chain_id() -> u64 { unsafe { diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index efedffaadf90f38db73dd269166034bb41567390..36fe893442daba09d8a56b0e97829c475e9426de 100644 GIT binary patch literal 67405 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 Date: Tue, 30 Jan 2018 22:45:20 +0100 Subject: [PATCH 09/12] Skip invalid test --- executor/src/wasm_executor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 5e18868238ea7..7518039df604a 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -382,7 +382,7 @@ mod tests { ); } - #[test] +/* #[test] fn enumerated_trie_root_should_work() { let mut ext = TestExternalities::default(); let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); @@ -391,7 +391,7 @@ mod tests { vec![0] ); } - +*/ fn tx() -> Vec { "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000".convert() } #[test] From 9cc7f67a6cec1c5d9f8fba6d2d04bda5ec57bc27 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 31 Jan 2018 06:52:40 +0100 Subject: [PATCH 10/12] Test enumerted trie root. --- executor/src/wasm_executor.rs | 6 +++--- .../release/runtime_test.compact.wasm | Bin 13189 -> 14114 bytes .../release/runtime_test.wasm | Bin 13314 -> 14239 bytes wasm-runtime/test/src/lib.rs | 9 +++++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index 7518039df604a..a64a4f91760b9 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -382,16 +382,16 @@ mod tests { ); } -/* #[test] + #[test] fn enumerated_trie_root_should_work() { let mut ext = TestExternalities::default(); let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_enumerated_trie_root", &CallData(vec![])).unwrap(), - vec![0] + ordered_trie_root(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]).0.to_vec() ); } -*/ + fn tx() -> Vec { "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000".convert() } #[test] diff --git a/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 63e7666aadfbfdef2c4286d3397788e339381d7b..3905e9d9113959f2da7e70433a3943645341db65 100644 GIT binary patch delta 3376 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 T>cCHS_I&1v*Fin=#D@PLVEVPx delta 2596 zcmZuzZD?E989wLSdvzrpeO%kJEX#I%WXrbv5&0vwaOpyF0ww8|G=VWP$X3@Maw5n2 zKvF)umRcKTl&u>MC*9U9V=DWdqSh&F41%_LBa~7M3#>mnFf2d%BR@pffj21ZxmW&3 z$1a@vocDP@&U@bXoGbk%|AVWX%$Ks15JF$@-R9l5$B$`mvB2%QDeg|+D$gw!(`lmL z{=)<{Za?|TN9nlI1KWpZSo#SzolLV0bjm@Z#0=E$Je;R^G)%pw_5 z=U8Mt5p<}9)%k1bsky0{6dCqAO!;R1mLrcmB~MPxlF_zi;H9aVnaOA8ZlsHur>TT_tw5I;0ox%Hr{!dnqswrc` zhTj=K1#F#l4KrITxo^?1dg6ZTWHl&2l&)A4xG?5ZRJq zKEQ4?#oWN|6-iU*Ixr(Fc$6JDzi=oPvZBmD2`T<>drdY|d1I2OXN zFcmJL3&S4gyR2YL7cPsbC%t3-U^K|B9#pa(MQ;+K?@~P)L+xUeOCh=Cm1EMt=BWh} zB28QnU815yJ|t4Zf?A9S9oHvD_w7Hj`KH4Tksiy-PQguAZ;RM$T<9~*9YZ4MO$_d~ zBV#zZ&*Rh*i*Z~(VVo8}+=v;VHJfHg^*^GA3KfYZUG=CWR$QHniFU>%w9-PKbfE>g z`~}4xz8@3zz4?0od+J+#-=n(P=^LPN_3OBxOm*~6?klNZec8YEKk5hZ30vKWpQb)_ zd|(>ts{?U(|75`SerMn^81LZFdR(vsv-;>g!Dd**$yYCzHwVA_1L8 zYH;UpuNs7efff+!AiamWIyqL5_YH1s!pP3=9)6DS`Gs;D2e<&!0E7w<24oY6Dm@kA zvB5W~l4GmtJI4mEeBnBZ^e!U79FaCm9ub(@JG}_}>Q3*PJaLd>9g7UYssU{NE)wE` ze3bIG$?qSm7guY^LAmEXTJyo-nwy@ZN|nmR!%EdWoG+}E(;|~wO5YMh);(%BInv+o zaJNX2Nu#-GCA?J6C#~k5()TluG=C! zIJbty&8z90D6M7|Gr22voGRyGktvD%^|Bp#A%8u$1j$*W&N)jaQFD0iIz=O-4s4#W zUC!O7>@wI7zLH#hK0eg(hL2kUtX<7Faoij?SydAg;Yc02i_i(^3P8KFI3+&y(nNf` z;p44h0a=u<9+UxTp-p~nS!T1~0@&v`-BIsOoImj?bPWUwfonNjtl{UOgX3uLG<{g+ z%>Z{DRJf|1n;c4R2e?&0RQm*O0{u?(M_>=)b{xeGsLjb}Xfw$DPNJxANz9j#V^uwv zyhJNo;i(j5wbrc{kAH*Giu&dB8Mf1|{xSV4)(CG^X0lX#(#azYU-QrjEcVqy*XVRE yOf_n^Q`Dol#QQcCU>kD#5Vdb!gx#pRFw)*p>EdnJtn-g*yf}Xo|7#X;`Th%0cp8ZS diff --git a/wasm-runtime/test/src/lib.rs b/wasm-runtime/test/src/lib.rs index c63ca73fca595..ae5a6c179cd40 100644 --- a/wasm-runtime/test/src/lib.rs +++ b/wasm-runtime/test/src/lib.rs @@ -8,7 +8,8 @@ use alloc::vec::Vec; #[macro_use] extern crate runtime_std; -use runtime_std::{set_storage, storage, print, blake2_256, twox_128, twox_256, ed25519_verify}; +use runtime_std::{set_storage, storage, print, blake2_256, twox_128, twox_256, ed25519_verify, + enumerated_trie_root}; fn test_blake2_256(input: &[u8]) -> Vec { blake2_256(&input).to_vec() @@ -29,6 +30,10 @@ fn test_ed25519_verify(input: &[u8]) -> Vec { [ed25519_verify(sig, &msg[..], pubkey) as u8].to_vec() } +fn test_enumerated_trie_root(_input: &[u8]) -> Vec { + enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() +} + fn test_data_in(input: &[u8]) -> Vec { print("set_storage"); set_storage(b"input", &input); @@ -59,4 +64,4 @@ fn test_conditional_panic(input: &[u8]) -> Vec { } impl_stubs!(test_data_in, test_empty_return, test_panic, test_conditional_panic, - test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify); + test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify, test_enumerated_trie_root); From e64b1e0cee52bf9a15d37ae67bcaf15d842ed1cb Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 31 Jan 2018 06:55:04 +0100 Subject: [PATCH 11/12] Minor cleanup --- executor/src/wasm_executor.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/executor/src/wasm_executor.rs b/executor/src/wasm_executor.rs index a64a4f91760b9..e1e4f0b6d9273 100644 --- a/executor/src/wasm_executor.rs +++ b/executor/src/wasm_executor.rs @@ -170,10 +170,10 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; }, ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8) => { - let offsets = (0..lens_len) + let values = (0..lens_len) .map(|i| this.memory.read_primitive(lens_data + i * 4)) - .collect::<::std::result::Result, DummyUserError>>()?; - let values = offsets.into_iter() + .collect::<::std::result::Result, DummyUserError>>()? + .into_iter() .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) .map(|(offset, len)| this.memory.get(values_data + offset, len as usize) From 063138c136306ada733626068f6cc3fbfe86df2e Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 31 Jan 2018 07:03:25 +0100 Subject: [PATCH 12/12] Strip unneeded logic. --- native-runtime/std/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/native-runtime/std/src/lib.rs b/native-runtime/std/src/lib.rs index fba5462f7d920..e24e9d7bb3a05 100644 --- a/native-runtime/std/src/lib.rs +++ b/native-runtime/std/src/lib.rs @@ -102,9 +102,7 @@ pub fn storage_root() -> [u8; 32] { /// "Commit" all existing operations and get the resultant storage root. pub fn enumerated_trie_root(serialised_values: &[&[u8]]) -> [u8; 32] { - ext::with(|ext| - triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0 - ).unwrap_or([0u8; 32]) + triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0 } /// Conduct a Keccak-256 hash of the given data.