From ec9060460ca80f4d859cd496fab7980f404d7711 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 19 Feb 2018 20:05:30 +0100 Subject: [PATCH] Optional storage entries (#75) * Block builder (substrate) * Fix wasm build * Bulid on any block * Test for block builder. * Block import tests for client. * Tidy ups * Repotted client * Avoid pointless work * All backend stuff now manages optional storage. Also simplified a lot of the backend. * Native runtime-io now supports empty storage items. * Finish up the API transition. * Build fix. * Fix tests. * Remerge in changes to client. * Final fixes. * Unrevert typos * Remove accidentally committed change * Bring back zero copy * Fix merge. --- substrate/polkadot/executor/src/lib.rs | 28 +- .../runtime/src/runtime/governance.rs | 4 +- .../runtime/src/runtime/parachains.rs | 4 +- .../polkadot/runtime/src/runtime/session.rs | 4 +- .../polkadot/runtime/src/runtime/staking.rs | 20 +- .../polkadot/runtime/src/runtime/system.rs | 8 +- .../polkadot/runtime/src/runtime/timestamp.rs | 4 +- substrate/polkadot/runtime/wasm/genesis.wasm | Bin 70449 -> 76656 bytes .../release/polkadot_runtime.compact.wasm | Bin 75751 -> 76656 bytes .../release/polkadot_runtime.wasm | Bin 75800 -> 76705 bytes substrate/substrate/client/src/backend.rs | 2 +- substrate/substrate/client/src/client.rs | 504 ++++++++++++++++++ substrate/substrate/client/src/error.rs | 31 +- substrate/substrate/client/src/genesis.rs | 15 +- substrate/substrate/client/src/in_mem.rs | 2 +- substrate/substrate/client/src/lib.rs | 484 +---------------- .../substrate/executor/src/wasm_executor.rs | 51 +- substrate/substrate/executor/wasm/src/lib.rs | 2 +- .../release/runtime_test.compact.wasm | Bin 13451 -> 14298 bytes .../release/runtime_test.wasm | Bin 13576 -> 14394 bytes substrate/substrate/rpc/src/state/tests.rs | 2 +- substrate/substrate/runtime-io/with_std.rs | 64 +-- substrate/substrate/runtime-io/without_std.rs | 27 +- .../substrate/runtime-support/src/storage.rs | 83 ++- .../substrate/state-machine/src/backend.rs | 48 +- substrate/substrate/state-machine/src/ext.rs | 42 +- substrate/substrate/state-machine/src/lib.rs | 130 ++--- .../substrate/state-machine/src/testing.rs | 30 +- .../substrate/test-runtime/src/system.rs | 4 +- .../substrate/test-runtime/wasm/genesis.wasm | Bin 31744 -> 32296 bytes .../substrate_test_runtime.compact.wasm | Bin 31904 -> 32296 bytes .../release/substrate_test_runtime.wasm | Bin 31984 -> 32376 bytes 32 files changed, 856 insertions(+), 737 deletions(-) create mode 100644 substrate/substrate/client/src/client.rs diff --git a/substrate/polkadot/executor/src/lib.rs b/substrate/polkadot/executor/src/lib.rs index a7cef0c3cb..f7ded05025 100644 --- a/substrate/polkadot/executor/src/lib.rs +++ b/substrate/polkadot/executor/src/lib.rs @@ -73,9 +73,9 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { let one = Keyring::One.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); @@ -84,9 +84,9 @@ mod tests { #[test] fn panic_execution_with_native_equivalent_code_gives_error() { let one = Keyring::One.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); @@ -97,9 +97,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); @@ -115,9 +115,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); @@ -133,7 +133,7 @@ mod tests { let two = Keyring::Two.to_raw_public(); let three = [3u8; 32]; - TestExternalities { storage: map![ + map![ twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].encode(), twox_128(b"gov:apr").to_vec() => vec![].and(&667u32), twox_128(b"ses:len").to_vec() => vec![].and(&2u64), @@ -149,7 +149,7 @@ mod tests { twox_128(b"sta:vac").to_vec() => vec![].and(&3u64), twox_128(b"sta:era").to_vec() => vec![].and(&0u64), twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], } + ] } fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec) -> (Vec, Hash) { @@ -250,9 +250,9 @@ mod tests { #[test] fn panic_execution_gives_error() { let one = Keyring::One.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm"); let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); @@ -264,9 +264,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm"); let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); diff --git a/substrate/polkadot/runtime/src/runtime/governance.rs b/substrate/polkadot/runtime/src/runtime/governance.rs index b8733b9776..9138a3eddf 100644 --- a/substrate/polkadot/runtime/src/runtime/governance.rs +++ b/substrate/polkadot/runtime/src/runtime/governance.rs @@ -157,7 +157,7 @@ mod tests { let two = Keyring::Two.to_raw_public(); let three = [3u8; 32]; - TestExternalities { storage: map![ + map![ twox_128(APPROVALS_REQUIRED).to_vec() => vec![].and(&667u32), twox_128(b"ses:len").to_vec() => vec![].and(&1u64), twox_128(b"ses:val:len").to_vec() => vec![].and(&3u32), @@ -171,7 +171,7 @@ mod tests { twox_128(b"sta:spe").to_vec() => vec![].and(&1u64), twox_128(b"sta:vac").to_vec() => vec![].and(&3u64), twox_128(b"sta:era").to_vec() => vec![].and(&1u64) - ], } + ] } #[test] diff --git a/substrate/polkadot/runtime/src/runtime/parachains.rs b/substrate/polkadot/runtime/src/runtime/parachains.rs index dd7485ddc8..1cd4151cf9 100644 --- a/substrate/polkadot/runtime/src/runtime/parachains.rs +++ b/substrate/polkadot/runtime/src/runtime/parachains.rs @@ -83,10 +83,10 @@ mod tests { use runtime::{consensus, session}; fn simple_setup() -> TestExternalities { - TestExternalities { storage: map![ + map![ twox_128(b"ses:val:len").to_vec() => vec![].and(&8u32), twox_128(b"par:cou").to_vec() => vec![].and(&2u32) - ], } + ] } #[test] diff --git a/substrate/polkadot/runtime/src/runtime/session.rs b/substrate/polkadot/runtime/src/runtime/session.rs index a3a43d88cc..e9bf5f3765 100644 --- a/substrate/polkadot/runtime/src/runtime/session.rs +++ b/substrate/polkadot/runtime/src/runtime/session.rs @@ -145,7 +145,7 @@ mod tests { use runtime::{consensus, session}; fn simple_setup() -> TestExternalities { - TestExternalities { storage: map![ + map![ twox_128(SESSION_LENGTH).to_vec() => vec![].and(&2u64), // the validators (10, 20, ...) twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32), @@ -155,7 +155,7 @@ mod tests { b":auth:len".to_vec() => vec![].and(&2u32), 0u32.to_keyed_vec(b":auth:") => vec![11; 32], 1u32.to_keyed_vec(b":auth:") => vec![21; 32] - ], } + ] } #[test] diff --git a/substrate/polkadot/runtime/src/runtime/staking.rs b/substrate/polkadot/runtime/src/runtime/staking.rs index a66d43eeb9..0bb4372c6d 100644 --- a/substrate/polkadot/runtime/src/runtime/staking.rs +++ b/substrate/polkadot/runtime/src/runtime/staking.rs @@ -227,7 +227,7 @@ mod tests { let three = [3u8; 32]; let four = [4u8; 32]; - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(b"ses:len").to_vec() => vec![].and(&1u64), twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![10; 32], @@ -239,7 +239,7 @@ mod tests { twox_128(&two.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64), twox_128(&three.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64), twox_128(&four.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&40u64) - ], }; + ]; with_externalities(&mut t, || { assert_eq!(era_length(), 2u64); @@ -296,10 +296,10 @@ mod tests { #[test] fn staking_eras_work() { - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(b"ses:len").to_vec() => vec![].and(&1u64), twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64) - ], }; + ]; with_externalities(&mut t, || { assert_eq!(era_length(), 2u64); assert_eq!(sessions_per_era(), 2u64); @@ -363,9 +363,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64) - ], }; + ]; with_externalities(&mut t, || { assert_eq!(balance(&one), 42); @@ -378,9 +378,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64) - ], }; + ]; with_externalities(&mut t, || { transfer(&one, &two, 69); @@ -395,9 +395,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64) - ], }; + ]; with_externalities(&mut t, || { stake(&one); diff --git a/substrate/polkadot/runtime/src/runtime/system.rs b/substrate/polkadot/runtime/src/runtime/system.rs index 2f8f5c25c7..7d5e8835ed 100644 --- a/substrate/polkadot/runtime/src/runtime/system.rs +++ b/substrate/polkadot/runtime/src/runtime/system.rs @@ -247,9 +247,9 @@ mod tests { let one = Keyring::One.to_raw_public(); let two = Keyring::Two.to_raw_public(); - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], }; + ]; let tx = UncheckedTransaction { transaction: Transaction { @@ -272,7 +272,7 @@ mod tests { let two = Keyring::Two.to_raw_public(); let three = [3u8; 32]; - TestExternalities { storage: map![ + map![ twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].encode(), twox_128(b"gov:apr").to_vec() => vec![].and(&667u32), twox_128(b"ses:len").to_vec() => vec![].and(&2u64), @@ -288,7 +288,7 @@ mod tests { twox_128(b"sta:vac").to_vec() => vec![].and(&3u64), twox_128(b"sta:era").to_vec() => vec![].and(&0u64), twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], } + ] } #[test] diff --git a/substrate/polkadot/runtime/src/runtime/timestamp.rs b/substrate/polkadot/runtime/src/runtime/timestamp.rs index c64a511ad0..0b96f39bd4 100644 --- a/substrate/polkadot/runtime/src/runtime/timestamp.rs +++ b/substrate/polkadot/runtime/src/runtime/timestamp.rs @@ -47,9 +47,9 @@ mod tests { #[test] fn timestamp_works() { - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].and(&42u64) - ], }; + ]; with_externalities(&mut t, || { assert_eq!(get(), 42); diff --git a/substrate/polkadot/runtime/wasm/genesis.wasm b/substrate/polkadot/runtime/wasm/genesis.wasm index 91c7b475743cb7b9cbb48c6dcc162501fe9e43c0..bc0cb89235c570beee9e2749b796933e05e9f774 100644 GIT binary patch literal 76656 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 literal 70449 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 diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index a92614dcc2d6fc281b868d3754d5c972ece62333..160550b5c786ffa6addf6c2a3ec6210a8605e9dd 100644 GIT binary patch delta 29773 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 Mnp-`44)-DcAD;FDR17zYg5|F7!q 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, justification: Option, is_new_best: bool) -> error::Result<()>; /// Inject storage data into the database. - fn set_storage, Vec)>>(&mut self, iter: I) -> error::Result<()>; + fn set_storage, Option>)>>(&mut self, changes: I) -> error::Result<()>; /// Inject storage data into the database. fn reset_storage, Vec)>>(&mut self, iter: I) -> error::Result<()>; } diff --git a/substrate/substrate/client/src/client.rs b/substrate/substrate/client/src/client.rs new file mode 100644 index 0000000000..3ccc9debff --- /dev/null +++ b/substrate/substrate/client/src/client.rs @@ -0,0 +1,504 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Substrate Client + +use primitives::{self, block, AuthorityId}; +use primitives::block::Id as BlockId; +use primitives::storage::{StorageKey, StorageData}; +use runtime_support::Hashable; +use codec::{KeyedVec, Slicable}; +use state_machine::{self, Ext, OverlayedChanges, Backend as StateBackend, CodeExecutor}; + +use backend::{self, BlockImportOperation}; +use blockchain::{self, Info as ChainInfo, Backend as ChainBackend}; +use {error, in_mem, block_builder, runtime_io, bft}; + +/// Polkadot Client +#[derive(Debug)] +pub struct Client where B: backend::Backend { + backend: B, + executor: E, +} + +/// Client info +// TODO: split queue info from chain info and amalgamate into single struct. +#[derive(Debug)] +pub struct ClientInfo { + /// Best block hash. + pub chain: ChainInfo, + /// Best block number in the queue. + pub best_queued_number: Option, + /// Best queued block hash. + pub best_queued_hash: Option, +} + +/// Information regarding the result of a call. +pub struct CallResult { + /// The data that was returned from the call. + pub return_data: Vec, + /// The changes made to the state by the call. + pub changes: OverlayedChanges, +} + +/// Block import result. +#[derive(Debug)] +pub enum ImportResult { + /// Added to the import queue. + Queued, + /// Already in the import queue. + AlreadyQueued, + /// Already in the blockchain. + AlreadyInChain, + /// Block or parent is known to be bad. + KnownBad, + /// Block parent is not in the chain. + UnknownParent, +} + +/// Block status. +#[derive(Debug, PartialEq, Eq)] +pub enum BlockStatus { + /// Added to the import queue. + Queued, + /// Already in the blockchain. + InChain, + /// Block or parent is known to be bad. + KnownBad, + /// Not in the queue or the blockchain. + Unknown, +} + +/// A header paired with a justification which has already been checked. +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct JustifiedHeader { + header: block::Header, + justification: bft::Justification, +} + +impl JustifiedHeader { + /// Deconstruct the justified header into parts. + pub fn into_inner(self) -> (block::Header, bft::Justification) { + (self.header, self.justification) + } +} + +/// Create an instance of in-memory client. +pub fn new_in_mem( + executor: E, + build_genesis: F +) -> error::Result> + where + E: CodeExecutor, + F: FnOnce() -> (block::Header, Vec<(Vec, Vec)>) +{ + Client::new(in_mem::Backend::new(), executor, build_genesis) +} + +impl Client where + B: backend::Backend, + E: CodeExecutor, + error::Error: From<<::State as StateBackend>::Error>, +{ + /// Creates new Polkadot Client with given blockchain and code executor. + pub fn new( + backend: B, + executor: E, + build_genesis: F + ) -> error::Result + where + F: FnOnce() -> (block::Header, Vec<(Vec, Vec)>) + { + if backend.blockchain().header(BlockId::Number(0))?.is_none() { + trace!("Empty database, writing genesis block"); + let (genesis_header, genesis_store) = build_genesis(); + let mut op = backend.begin_operation(BlockId::Hash(block::HeaderHash::default()))?; + op.reset_storage(genesis_store.into_iter())?; + op.set_block_data(genesis_header, Some(vec![]), None, true)?; + backend.commit_operation(op)?; + } + Ok(Client { + backend, + executor, + }) + } + + /// Get a reference to the state at a given block. + pub fn state_at(&self, block: &BlockId) -> error::Result { + self.backend.state_at(*block) + } + + /// Expose backend reference. To be used in tests only + pub fn backend(&self) -> &B { + &self.backend + } + + /// Return single storage entry of contract under given address in state in a block of given hash. + pub fn storage(&self, id: &BlockId, key: &StorageKey) -> error::Result { + Ok(StorageData(self.state_at(id)? + .storage(&key.0)? + .ok_or_else(|| error::ErrorKind::NoValueForKey(key.0.clone()))? + .to_vec())) + } + + /// Get the code at a given block. + pub fn code_at(&self, id: &BlockId) -> error::Result> { + self.storage(id, &StorageKey(b":code".to_vec())).map(|data| data.0) + } + + /// Clone a new instance of Executor. + pub fn clone_executor(&self) -> E where E: Clone { + self.executor.clone() + } + + /// Get the current set of authorities from storage. + pub fn authorities_at(&self, id: &BlockId) -> error::Result> { + let state = self.state_at(id)?; + (0..u32::decode(&mut state.storage(b":auth:len")?.ok_or(error::ErrorKind::AuthLenEmpty)?).ok_or(error::ErrorKind::AuthLenInvalid)?) + .map(|i| state.storage(&i.to_keyed_vec(b":auth:")) + .map_err(|_| error::ErrorKind::Backend) + .and_then(|v| v.ok_or(error::ErrorKind::AuthEmpty(i))) + .and_then(|mut s| AuthorityId::decode(&mut s).ok_or(error::ErrorKind::AuthInvalid(i))) + .map_err(Into::into) + ).collect() + } + + /// Execute a call to a contract on top of state in a block of given hash. + /// + /// No changes are made. + pub fn call(&self, id: &BlockId, method: &str, call_data: &[u8]) -> error::Result { + let mut changes = OverlayedChanges::default(); + let return_data = state_machine::execute( + &self.state_at(id)?, + &mut changes, + &self.executor, + method, + call_data, + )?; + Ok(CallResult { return_data, changes }) + } + + /// Set up the native execution environment to call into a native runtime code. + pub fn using_environment T, T>( + &self, f: F + ) -> error::Result { + self.using_environment_at(&BlockId::Number(self.info()?.chain.best_number), &mut Default::default(), f) + } + + /// Set up the native execution environment to call into a native runtime code. + pub fn using_environment_at T, T>( + &self, + id: &BlockId, + overlay: &mut OverlayedChanges, + f: F + ) -> error::Result { + Ok(runtime_io::with_externalities(&mut Ext { backend: &self.state_at(id)?, overlay }, f)) + } + + /// Create a new block, built on the head of the chain. + pub fn new_block(&self) -> error::Result> where E: Clone { + block_builder::BlockBuilder::new(self) + } + + /// Create a new block, built on top of `parent`. + pub fn new_block_at(&self, parent: &BlockId) -> error::Result> where E: Clone { + block_builder::BlockBuilder::at_block(parent, &self) + } + + /// Check a header's justification. + pub fn check_justification( + &self, + header: block::Header, + justification: bft::UncheckedJustification, + ) -> error::Result { + let authorities = self.authorities_at(&BlockId::Hash(header.parent_hash))?; + let just = bft::check_justification(&authorities[..], header.parent_hash, justification) + .map_err(|_| error::ErrorKind::BadJustification(BlockId::Hash(header.hash())))?; + Ok(JustifiedHeader { + header, + justification: just, + }) + } + + /// Queue a block for import. + pub fn import_block( + &self, + header: JustifiedHeader, + body: Option, + ) -> error::Result { + // TODO: import lock + // TODO: validate block + // TODO: import justification. + let (header, justification) = header.into_inner(); + match self.backend.blockchain().status(BlockId::Hash(header.parent_hash))? { + blockchain::BlockStatus::InChain => (), + blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent), + } + + let mut transaction = self.backend.begin_operation(BlockId::Hash(header.parent_hash))?; + let mut overlay = OverlayedChanges::default(); + + state_machine::execute( + transaction.state()?, + &mut overlay, + &self.executor, + "execute_block", + &block::Block { header: header.clone(), transactions: body.clone().unwrap_or_default().clone() }.encode() + )?; + + let is_new_best = header.number == self.backend.blockchain().info()?.best_number + 1; + trace!("Imported {}, (#{}), best={}", block::HeaderHash::from(header.blake2_256()), header.number, is_new_best); + transaction.set_block_data(header, body, Some(justification.uncheck().into()), is_new_best)?; + transaction.set_storage(overlay.drain())?; + self.backend.commit_operation(transaction)?; + Ok(ImportResult::Queued) + } + + /// Get blockchain info. + pub fn info(&self) -> error::Result { + let info = self.backend.blockchain().info().map_err(|e| error::Error::from_blockchain(Box::new(e)))?; + Ok(ClientInfo { + chain: info, + best_queued_hash: None, + best_queued_number: None, + }) + } + + /// Get block status. + pub fn block_status(&self, id: &BlockId) -> error::Result { + // TODO: more efficient implementation + match self.backend.blockchain().header(*id).map_err(|e| error::Error::from_blockchain(Box::new(e)))?.is_some() { + true => Ok(BlockStatus::InChain), + false => Ok(BlockStatus::Unknown), + } + } + + /// Get block hash by number. + pub fn block_hash(&self, block_number: block::Number) -> error::Result> { + self.backend.blockchain().hash(block_number) + } + + /// Convert an arbitrary block ID into a block hash. + pub fn block_hash_from_id(&self, id: &BlockId) -> error::Result> { + match *id { + BlockId::Hash(h) => Ok(Some(h)), + BlockId::Number(n) => self.block_hash(n), + } + } + + /// Convert an arbitrary block ID into a block hash. + pub fn block_number_from_id(&self, id: &BlockId) -> error::Result> { + match *id { + BlockId::Hash(_) => Ok(self.header(id)?.map(|h| h.number)), + BlockId::Number(n) => Ok(Some(n)), + } + } + + /// Get block header by id. + pub fn header(&self, id: &BlockId) -> error::Result> { + self.backend.blockchain().header(*id) + } + + /// Get block body by id. + pub fn body(&self, id: &BlockId) -> error::Result> { + self.backend.blockchain().body(*id) + } + + /// Get block justification set by id. + pub fn justification(&self, id: &BlockId) -> error::Result> { + self.backend.blockchain().justification(*id) + } +} + +impl bft::BlockImport for Client + where + B: backend::Backend, + E: state_machine::CodeExecutor, + error::Error: From<::Error> +{ + fn import_block(&self, block: block::Block, justification: bft::Justification) { + let justified_header = JustifiedHeader { + header: block.header, + justification, + }; + + let _ = self.import_block(justified_header, Some(block.transactions)); + } +} + +impl bft::Authorities for Client + where + B: backend::Backend, + E: state_machine::CodeExecutor, + error::Error: From<::Error> +{ + fn authorities(&self, at: &BlockId) -> Result, bft::Error> { + self.authorities_at(at).map_err(|_| bft::ErrorKind::StateUnavailable(*at).into()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use codec::Slicable; + use keyring::Keyring; + use {primitives, genesis}; + use primitives::block::Transaction as PrimitiveTransaction; + use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; + use test_runtime::{UncheckedTransaction, Transaction}; + use test_runtime; + + native_executor_instance!(Executor, test_runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); + + fn genesis_config() -> GenesisConfig { + GenesisConfig::new_simple(vec![ + Keyring::Alice.to_raw_public(), + Keyring::Bob.to_raw_public(), + Keyring::Charlie.to_raw_public() + ], 1000) + } + + fn prepare_genesis() -> (primitives::block::Header, Vec<(Vec, Vec)>) { + let mut storage = genesis_config().genesis_map(); + let block = genesis::construct_genesis_block(&storage); + storage.extend(additional_storage_with_genesis(&block)); + (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + } + + // since we are in the client module we can create falsely justified + // headers. + // TODO: remove this in favor of custom verification pipelines for the + // client + fn justify(header: &block::Header) -> bft::UncheckedJustification { + let hash = header.hash(); + let authorities = vec![ + Keyring::Alice.into(), + Keyring::Bob.into(), + Keyring::Charlie.into(), + ]; + + bft::UncheckedJustification { + digest: hash, + signatures: authorities.iter().map(|key| { + bft::sign_message( + bft::generic::Message::Commit(1, hash), + key, + header.parent_hash + ).signature + }).collect(), + round_number: 1, + } + } + + #[test] + fn client_initialises_from_genesis_ok() { + let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); + let genesis_hash = client.block_hash(0).unwrap().unwrap(); + + assert_eq!(client.using_environment(|| test_runtime::system::latest_block_hash()).unwrap(), genesis_hash); + assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Alice.to_raw_public())).unwrap(), 1000); + assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Ferdie.to_raw_public())).unwrap(), 0); + } + + #[test] + fn authorities_call_works() { + let genesis_config = genesis_config(); + + let prepare_genesis = || { + let mut storage = genesis_config.genesis_map(); + let block = genesis::construct_genesis_block(&storage); + storage.extend(additional_storage_with_genesis(&block)); + (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + }; + let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); + + assert_eq!(client.info().unwrap().chain.best_number, 0); + assert_eq!(client.authorities_at(&BlockId::Number(0)).unwrap(), vec![ + Keyring::Alice.to_raw_public(), + Keyring::Bob.to_raw_public(), + Keyring::Charlie.to_raw_public() + ]); + } + + #[test] + fn block_builder_works_with_no_transactions() { + let genesis_config = genesis_config(); + + let prepare_genesis = || { + let mut storage = genesis_config.genesis_map(); + let block = genesis::construct_genesis_block(&storage); + storage.extend(additional_storage_with_genesis(&block)); + (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + }; + let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); + + let builder = client.new_block().unwrap(); + let block = builder.bake().unwrap(); + + let justification = justify(&block.header); + let justified = client.check_justification(block.header, justification).unwrap(); + client.import_block(justified, Some(block.transactions)).unwrap(); + + assert_eq!(client.info().unwrap().chain.best_number, 1); + assert_eq!(client.using_environment(|| test_runtime::system::latest_block_hash()).unwrap(), client.block_hash(1).unwrap().unwrap()); + } + + trait Signable { + fn signed(self) -> PrimitiveTransaction; + } + impl Signable for Transaction { + fn signed(self) -> PrimitiveTransaction { + let signature = Keyring::from_raw_public(self.from.clone()).unwrap().sign(&self.encode()); + PrimitiveTransaction::decode(&mut UncheckedTransaction { signature, tx: self }.encode().as_ref()).unwrap() + } + } + + #[test] + fn block_builder_works_with_transactions() { + let genesis_config = GenesisConfig::new_simple(vec![ + Keyring::Alice.to_raw_public(), + Keyring::Bob.to_raw_public(), + Keyring::Charlie.to_raw_public() + ], 1000); + + let prepare_genesis = || { + let mut storage = genesis_config.genesis_map(); + let block = genesis::construct_genesis_block(&storage); + storage.extend(additional_storage_with_genesis(&block)); + (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + }; + let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); + + let mut builder = client.new_block().unwrap(); + + builder.push(Transaction { + from: Keyring::Alice.to_raw_public(), + to: Keyring::Ferdie.to_raw_public(), + amount: 42, + nonce: 0 + }.signed()).unwrap(); + let block = builder.bake().unwrap(); + + let justification = justify(&block.header); + let justified = client.check_justification(block.header, justification).unwrap(); + client.import_block(justified, Some(block.transactions)).unwrap(); + + assert_eq!(client.info().unwrap().chain.best_number, 1); + assert!(client.state_at(&BlockId::Number(1)).unwrap() != client.state_at(&BlockId::Number(0)).unwrap()); + assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Alice.to_raw_public())).unwrap(), 958); + assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Ferdie.to_raw_public())).unwrap(), 42); + } +} diff --git a/substrate/substrate/client/src/error.rs b/substrate/substrate/client/src/error.rs index 2ae07c870c..179fa7d910 100644 --- a/substrate/substrate/client/src/error.rs +++ b/substrate/substrate/client/src/error.rs @@ -18,6 +18,7 @@ use std; use state_machine; +use primitives::hexdisplay::HexDisplay; error_chain! { errors { @@ -45,23 +46,41 @@ error_chain! { display("Blockchain: {}", e), } - /// Bad justification for header. - BadJustification(h: ::primitives::block::Id) { - description("bad justification for header"), - display("bad justification for header: {}", h), + /// Attempt to read storage yet nothing set for that key. + NoValueForKey(key: Vec) { + description("storage doesn't contain key"), + display("Storage does not contain the key entry: {}", HexDisplay::from(key)), } /// Invalid state data. - AuthLen { + AuthLenEmpty { + description("authority count state error"), + display("Current state of blockchain has no authority count value"), + } + + /// Invalid state data. + AuthEmpty(i: u32) { + description("authority value state error"), + display("Current state of blockchain has no authority value for index {}", i), + } + + /// Invalid state data. + AuthLenInvalid { description("authority count state error"), display("Current state of blockchain has invalid authority count value"), } /// Invalid state data. - Auth(i: u32) { + AuthInvalid(i: u32) { description("authority value state error"), display("Current state of blockchain has invalid authority value for index {}", i), } + + /// Bad justification for header. + BadJustification(h: ::primitives::block::Id) { + description("bad justification for header"), + display("bad justification for header: {}", h), + } } } diff --git a/substrate/substrate/client/src/genesis.rs b/substrate/substrate/client/src/genesis.rs index fb3e228d03..5008609777 100644 --- a/substrate/substrate/client/src/genesis.rs +++ b/substrate/substrate/client/src/genesis.rs @@ -114,7 +114,7 @@ mod tests { } #[test] - fn construct_genesis_should_work() { + fn construct_genesis_should_work_with_native() { let mut storage = GenesisConfig::new_simple( vec![Keyring::One.to_raw_public(), Keyring::Two.to_raw_public()], 1000 ).genesis_map(); @@ -133,6 +133,19 @@ mod tests { "execute_block", &b1data ).unwrap(); + } + + #[test] + fn construct_genesis_should_work_with_wasm() { + let mut storage = GenesisConfig::new_simple( + vec![Keyring::One.to_raw_public(), Keyring::Two.to_raw_public()], 1000 + ).genesis_map(); + let block = construct_genesis_block(&storage); + let genesis_hash = block.header.blake2_256().into(); + storage.extend(additional_storage_with_genesis(&block).into_iter()); + + let backend = InMemory::from(storage); + let (b1data, _b1hash) = block1(genesis_hash, &backend); let mut overlay = OverlayedChanges::default(); let _ = execute( diff --git a/substrate/substrate/client/src/in_mem.rs b/substrate/substrate/client/src/in_mem.rs index 62ef3b9715..b6a0341169 100644 --- a/substrate/substrate/client/src/in_mem.rs +++ b/substrate/substrate/client/src/in_mem.rs @@ -180,7 +180,7 @@ impl backend::BlockImportOperation for BlockImportOperation { Ok(()) } - fn set_storage, Vec)>>(&mut self, changes: I) -> error::Result<()> { + fn set_storage, Option>)>>(&mut self, changes: I) -> error::Result<()> { self.pending_state.commit(changes); Ok(()) } diff --git a/substrate/substrate/client/src/lib.rs b/substrate/substrate/client/src/lib.rs index c86c06afef..6054808f9b 100644 --- a/substrate/substrate/client/src/lib.rs +++ b/substrate/substrate/client/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate Client +//! Substrate Client and associated logic. #![warn(missing_docs)] @@ -41,485 +41,7 @@ pub mod backend; pub mod in_mem; pub mod genesis; pub mod block_builder; +mod client; +pub use client::{Client, ClientInfo, CallResult, ImportResult, BlockStatus, new_in_mem}; pub use blockchain::Info as ChainInfo; - -use primitives::{block, AuthorityId}; -use primitives::block::Id as BlockId; -use primitives::storage::{StorageKey, StorageData}; -use codec::{KeyedVec, Slicable}; - -use blockchain::Backend as BlockchainBackend; -use backend::BlockImportOperation; -use state_machine::backend::Backend as StateBackend; -use state_machine::{Ext, OverlayedChanges}; -use runtime_support::Hashable; - -/// Polkadot Client -#[derive(Debug)] -pub struct Client where B: backend::Backend { - backend: B, - executor: E, -} - -/// Client info -// TODO: split queue info from chain info and amalgamate into single struct. -#[derive(Debug)] -pub struct ClientInfo { - /// Best block hash. - pub chain: ChainInfo, - /// Best block number in the queue. - pub best_queued_number: Option, - /// Best queued block hash. - pub best_queued_hash: Option, -} - -/// Information regarding the result of a call. -pub struct CallResult { - /// The data that was returned from the call. - pub return_data: Vec, - /// The changes made to the state by the call. - pub changes: state_machine::OverlayedChanges, -} - -/// Block import result. -#[derive(Debug)] -pub enum ImportResult { - /// Added to the import queue. - Queued, - /// Already in the import queue. - AlreadyQueued, - /// Already in the blockchain. - AlreadyInChain, - /// Block or parent is known to be bad. - KnownBad, - /// Block parent is not in the chain. - UnknownParent, -} - -/// Block status. -#[derive(Debug, PartialEq, Eq)] -pub enum BlockStatus { - /// Added to the import queue. - Queued, - /// Already in the blockchain. - InChain, - /// Block or parent is known to be bad. - KnownBad, - /// Not in the queue or the blockchain. - Unknown, -} - -/// A header paired with a justification which has already been checked. -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct JustifiedHeader { - header: block::Header, - justification: bft::Justification, -} - -impl JustifiedHeader { - /// Deconstruct the justified header into parts. - pub fn into_inner(self) -> (block::Header, bft::Justification) { - (self.header, self.justification) - } -} - -/// Create an instance of in-memory client. -pub fn new_in_mem( - executor: E, - build_genesis: F -) -> error::Result> - where - E: state_machine::CodeExecutor, - F: FnOnce() -> (block::Header, Vec<(Vec, Vec)>) -{ - Client::new(in_mem::Backend::new(), executor, build_genesis) -} - -impl Client where - B: backend::Backend, - E: state_machine::CodeExecutor, - error::Error: From<<::State as state_machine::backend::Backend>::Error>, -{ - /// Creates new Polkadot Client with given blockchain and code executor. - pub fn new( - backend: B, - executor: E, - build_genesis: F - ) -> error::Result - where - F: FnOnce() -> (block::Header, Vec<(Vec, Vec)>) - { - if backend.blockchain().header(BlockId::Number(0))?.is_none() { - trace!("Empty database, writing genesis block"); - let (genesis_header, genesis_store) = build_genesis(); - let mut op = backend.begin_operation(BlockId::Hash(block::HeaderHash::default()))?; - op.reset_storage(genesis_store.into_iter())?; - op.set_block_data(genesis_header, Some(vec![]), None, true)?; - backend.commit_operation(op)?; - } - Ok(Client { - backend, - executor, - }) - } - - /// Get a reference to the state at a given block. - pub fn state_at(&self, block: &BlockId) -> error::Result { - self.backend.state_at(*block) - } - - /// Expose backend reference. To be used in tests only - pub fn backend(&self) -> &B { - &self.backend - } - - /// Return single storage entry of contract under given address in state in a block of given hash. - pub fn storage(&self, id: &BlockId, key: &StorageKey) -> error::Result { - Ok(self.state_at(id)? - .storage(&key.0) - .map(|x| StorageData(x.to_vec()))?) - } - - /// Get the code at a given block. - pub fn code_at(&self, id: &BlockId) -> error::Result> { - self.storage(id, &StorageKey(b":code".to_vec())).map(|data| data.0) - } - - /// Clone a new instance of Executor. - pub fn clone_executor(&self) -> E where E: Clone { - self.executor.clone() - } - - /// Get the current set of authorities from storage. - pub fn authorities_at(&self, id: &BlockId) -> error::Result> { - let state = self.state_at(id)?; - (0..u32::decode(&mut state.storage(b":auth:len")?).ok_or(error::ErrorKind::AuthLen)?) - .map(|i| state.storage(&i.to_keyed_vec(b":auth:")) - .map_err(|_| error::ErrorKind::Backend) - .and_then(|mut s| AuthorityId::decode(&mut s).ok_or(error::ErrorKind::Auth(i))) - .map_err(Into::into) - ).collect() - } - - /// Execute a call to a contract on top of state in a block of given hash. - /// - /// No changes are made. - pub fn call(&self, id: &BlockId, method: &str, call_data: &[u8]) -> error::Result { - let mut changes = state_machine::OverlayedChanges::default(); - let return_data = state_machine::execute( - &self.state_at(id)?, - &mut changes, - &self.executor, - method, - call_data, - )?; - Ok(CallResult { return_data, changes }) - } - - /// Set up the native execution environment to call into a native runtime code. - pub fn using_environment T, T>( - &self, f: F - ) -> error::Result { - self.using_environment_at(&BlockId::Number(self.info()?.chain.best_number), &mut Default::default(), f) - } - - /// Set up the native execution environment to call into a native runtime code. - pub fn using_environment_at T, T>( - &self, - id: &BlockId, - overlay: &mut OverlayedChanges, - f: F - ) -> error::Result { - Ok(runtime_io::with_externalities(&mut Ext { backend: &self.state_at(id)?, overlay }, f)) - } - - /// Create a new block, built on the head of the chain. - pub fn new_block(&self) -> error::Result> where E: Clone { - block_builder::BlockBuilder::new(self) - } - - /// Create a new block, built on top of `parent`. - pub fn new_block_at(&self, parent: &BlockId) -> error::Result> where E: Clone { - block_builder::BlockBuilder::at_block(parent, &self) - } - - /// Check a header's justification. - pub fn check_justification( - &self, - header: block::Header, - justification: bft::UncheckedJustification, - ) -> error::Result { - let authorities = self.authorities_at(&BlockId::Hash(header.parent_hash))?; - let just = bft::check_justification(&authorities[..], header.parent_hash, justification) - .map_err(|_| error::ErrorKind::BadJustification(BlockId::Hash(header.hash())))?; - Ok(JustifiedHeader { - header, - justification: just, - }) - } - - /// Queue a block for import. - pub fn import_block( - &self, - header: JustifiedHeader, - body: Option, - ) -> error::Result { - // TODO: import lock - // TODO: validate block - // TODO: import justification. - let (header, justification) = header.into_inner(); - match self.backend.blockchain().status(BlockId::Hash(header.parent_hash))? { - blockchain::BlockStatus::InChain => (), - blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent), - } - - let mut transaction = self.backend.begin_operation(BlockId::Hash(header.parent_hash))?; - let mut overlay = OverlayedChanges::default(); - - state_machine::execute( - transaction.state()?, - &mut overlay, - &self.executor, - "execute_block", - &block::Block { header: header.clone(), transactions: body.clone().unwrap_or_default().clone() }.encode() - )?; - - let is_new_best = header.number == self.backend.blockchain().info()?.best_number + 1; - trace!("Imported {}, (#{}), best={}", block::HeaderHash::from(header.blake2_256()), header.number, is_new_best); - transaction.set_block_data(header, body, Some(justification.uncheck().into()), is_new_best)?; - transaction.set_storage(overlay.drain())?; - self.backend.commit_operation(transaction)?; - Ok(ImportResult::Queued) - } - - /// Get blockchain info. - pub fn info(&self) -> error::Result { - let info = self.backend.blockchain().info().map_err(|e| error::Error::from_blockchain(Box::new(e)))?; - Ok(ClientInfo { - chain: info, - best_queued_hash: None, - best_queued_number: None, - }) - } - - /// Get block status. - pub fn block_status(&self, id: &BlockId) -> error::Result { - // TODO: more efficient implementation - match self.backend.blockchain().header(*id).map_err(|e| error::Error::from_blockchain(Box::new(e)))?.is_some() { - true => Ok(BlockStatus::InChain), - false => Ok(BlockStatus::Unknown), - } - } - - /// Get block hash by number. - pub fn block_hash(&self, block_number: block::Number) -> error::Result> { - self.backend.blockchain().hash(block_number) - } - - /// Convert an arbitrary block ID into a block hash. - pub fn block_hash_from_id(&self, id: &BlockId) -> error::Result> { - match *id { - BlockId::Hash(h) => Ok(Some(h)), - BlockId::Number(n) => self.block_hash(n), - } - } - - /// Convert an arbitrary block ID into a block hash. - pub fn block_number_from_id(&self, id: &BlockId) -> error::Result> { - match *id { - BlockId::Hash(_) => Ok(self.header(id)?.map(|h| h.number)), - BlockId::Number(n) => Ok(Some(n)), - } - } - - /// Get block header by id. - pub fn header(&self, id: &BlockId) -> error::Result> { - self.backend.blockchain().header(*id) - } - - /// Get block body by id. - pub fn body(&self, id: &BlockId) -> error::Result> { - self.backend.blockchain().body(*id) - } - - /// Get block justification set by id. - pub fn justification(&self, id: &BlockId) -> error::Result> { - self.backend.blockchain().justification(*id) - } -} - -impl bft::BlockImport for Client - where - B: backend::Backend, - E: state_machine::CodeExecutor, - error::Error: From<::Error> -{ - fn import_block(&self, block: block::Block, justification: bft::Justification) { - let justified_header = JustifiedHeader { - header: block.header, - justification, - }; - - let _ = self.import_block(justified_header, Some(block.transactions)); - } -} - -impl bft::Authorities for Client - where - B: backend::Backend, - E: state_machine::CodeExecutor, - error::Error: From<::Error> -{ - fn authorities(&self, at: &BlockId) -> Result, bft::Error> { - self.authorities_at(at).map_err(|_| bft::ErrorKind::StateUnavailable(*at).into()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use codec::Slicable; - use keyring::Keyring; - use primitives::block::Transaction as PrimitiveTransaction; - use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; - use test_runtime::{UncheckedTransaction, Transaction}; - use test_runtime; - - native_executor_instance!(Executor, test_runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); - - fn genesis_config() -> GenesisConfig { - GenesisConfig::new_simple(vec![ - Keyring::Alice.to_raw_public(), - Keyring::Bob.to_raw_public(), - Keyring::Charlie.to_raw_public() - ], 1000) - } - - fn prepare_genesis() -> (primitives::block::Header, Vec<(Vec, Vec)>) { - let mut storage = genesis_config().genesis_map(); - let block = genesis::construct_genesis_block(&storage); - storage.extend(additional_storage_with_genesis(&block)); - (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) - } - - // since we are in the client module we can create falsely justified - // headers. - // TODO: remove this in favor of custom verification pipelines for the - // client - fn justify(header: &block::Header) -> bft::UncheckedJustification { - let hash = header.hash(); - let authorities = vec![ - Keyring::Alice.into(), - Keyring::Bob.into(), - Keyring::Charlie.into(), - ]; - - bft::UncheckedJustification { - digest: hash, - signatures: authorities.iter().map(|key| { - bft::sign_message( - bft::generic::Message::Commit(1, hash), - key, - header.parent_hash - ).signature - }).collect(), - round_number: 1, - } - } - - #[test] - fn client_initialises_from_genesis_ok() { - let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); - let genesis_hash = client.block_hash(0).unwrap().unwrap(); - - assert_eq!(client.using_environment(|| test_runtime::system::latest_block_hash()).unwrap(), genesis_hash); - assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Alice.to_raw_public())).unwrap(), 1000); - assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Ferdie.to_raw_public())).unwrap(), 0); - } - - #[test] - fn authorities_call_works() { - let genesis_config = genesis_config(); - - let prepare_genesis = || { - let mut storage = genesis_config.genesis_map(); - let block = genesis::construct_genesis_block(&storage); - storage.extend(additional_storage_with_genesis(&block)); - (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) - }; - let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); - - assert_eq!(client.info().unwrap().chain.best_number, 0); - assert_eq!(client.authorities_at(&BlockId::Number(0)).unwrap(), vec![ - Keyring::Alice.to_raw_public(), - Keyring::Bob.to_raw_public(), - Keyring::Charlie.to_raw_public() - ]); - } - - #[test] - fn block_builder_works_with_no_transactions() { - let genesis_config = genesis_config(); - - let prepare_genesis = || { - let mut storage = genesis_config.genesis_map(); - let block = genesis::construct_genesis_block(&storage); - storage.extend(additional_storage_with_genesis(&block)); - (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) - }; - let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); - - let builder = client.new_block().unwrap(); - let block = builder.bake().unwrap(); - - let justification = justify(&block.header); - let justified = client.check_justification(block.header, justification).unwrap(); - client.import_block(justified, Some(block.transactions)).unwrap(); - - assert_eq!(client.info().unwrap().chain.best_number, 1); - assert_eq!(client.using_environment(|| test_runtime::system::latest_block_hash()).unwrap(), client.block_hash(1).unwrap().unwrap()); - } - - trait Signable { - fn signed(self) -> PrimitiveTransaction; - } - impl Signable for Transaction { - fn signed(self) -> PrimitiveTransaction { - let signature = Keyring::from_raw_public(self.from.clone()).unwrap().sign(&self.encode()); - PrimitiveTransaction::decode(&mut UncheckedTransaction { signature, tx: self }.encode().as_ref()).unwrap() - } - } - - #[test] - fn block_builder_works_with_transactions() { - let genesis_config = genesis_config(); - - let prepare_genesis = || { - let mut storage = genesis_config.genesis_map(); - let block = genesis::construct_genesis_block(&storage); - storage.extend(additional_storage_with_genesis(&block)); - (primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) - }; - let client = new_in_mem(Executor::new(), prepare_genesis).unwrap(); - - let mut builder = client.new_block().unwrap(); - - builder.push(Transaction { - from: Keyring::Alice.to_raw_public(), - to: Keyring::Ferdie.to_raw_public(), - amount: 42, - nonce: 0 - }.signed()).unwrap(); - let block = builder.bake().unwrap(); - - let justification = justify(&block.header); - let justified = client.check_justification(block.header, justification).unwrap(); - client.import_block(justified, Some(block.transactions)).unwrap(); - - assert_eq!(client.info().unwrap().chain.best_number, 1); - assert!(client.state_at(&BlockId::Number(1)).unwrap() != client.state_at(&BlockId::Number(0)).unwrap()); - assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Alice.to_raw_public())).unwrap(), 958); - assert_eq!(client.using_environment(|| test_runtime::system::balance_of(Keyring::Ferdie.to_raw_public())).unwrap(), 42); - } -} diff --git a/substrate/substrate/executor/src/wasm_executor.rs b/substrate/substrate/executor/src/wasm_executor.rs index 00bdb55865..4d525a5975 100644 --- a/substrate/substrate/executor/src/wasm_executor.rs +++ b/substrate/substrate/executor/src/wasm_executor.rs @@ -171,34 +171,53 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, } this.ext.set_storage(key, value); }, + ext_clear_storage(key_data: *const u8, key_len: u32) => { + let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + if let Some(preimage) = this.hash_lookup.get(&key) { + info!(target: "wasm-trace", "*** Clearing storage: %{} [k={}]", ascii_format(&preimage), HexDisplay::from(&key)); + } else { + info!(target: "wasm-trace", "*** Clearing storage: {} [k={}]", ascii_format(&key), HexDisplay::from(&key)); + } + this.ext.clear_storage(&key); + }, + // return 0 and place u32::max_value() into written_out if no value exists for the key. ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; - let value = this.ext.storage(&key).map_err(|_| DummyUserError)?; + let maybe_value = this.ext.storage(&key); if let Some(preimage) = this.hash_lookup.get(&key) { - info!(target: "wasm-trace", " Getting storage: %{} == {} [k={}]", ascii_format(&preimage), HexDisplay::from(&value), HexDisplay::from(&key)); + info!(target: "wasm-trace", " Getting storage: %{} == {} [k={}]", ascii_format(&preimage), if let Some(ref b) = maybe_value { format!("{}", HexDisplay::from(b)) } else { "".to_owned() }, HexDisplay::from(&key)); } else { - info!(target: "wasm-trace", " Getting storage: {} == {} [k={}]", ascii_format(&key), HexDisplay::from(&value), HexDisplay::from(&key)); + info!(target: "wasm-trace", " Getting storage: {} == {} [k={}]", ascii_format(&key), if let Some(ref b) = maybe_value { format!("{}", HexDisplay::from(b)) } else { "".to_owned() }, HexDisplay::from(&key)); } - 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 + if let Some(value) = maybe_value { + 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 + } else { + this.memory.write_primitive(written_out, u32::max_value())?; + 0 + } }, + // return u32::max_value() if no value exists for the key. ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> 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 maybe_value = this.ext.storage(&key); if let Some(preimage) = this.hash_lookup.get(&key) { - info!(target: "wasm-trace", " Getting storage: %{} == {} [k={}]", ascii_format(&preimage), HexDisplay::from(&value), HexDisplay::from(&key)); + info!(target: "wasm-trace", " Getting storage: %{} == {} [k={}]", ascii_format(&preimage), if let Some(ref b) = maybe_value { format!("{}", HexDisplay::from(b)) } else { "".to_owned() }, HexDisplay::from(&key)); } else { - info!(target: "wasm-trace", " Getting storage: {} == {} [k={}]", ascii_format(&key), HexDisplay::from(&value), HexDisplay::from(&key)); + info!(target: "wasm-trace", " Getting storage: {} == {} [k={}]", ascii_format(&key), if let Some(ref b) = maybe_value { format!("{}", HexDisplay::from(b)) } else { "".to_owned() }, HexDisplay::from(&key)); + } + if let Some(value) = maybe_value { + 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 + } else { + u32::max_value() } - 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(); @@ -369,7 +388,7 @@ mod tests { b"foo".to_vec() => b"bar".to_vec(), b"baz".to_vec() => b"bar".to_vec() ]; - assert_eq!(expected, ext.storage); + assert_eq!(expected, ext); } #[test] diff --git a/substrate/substrate/executor/wasm/src/lib.rs b/substrate/substrate/executor/wasm/src/lib.rs index 11401a39d7..013ecca1ed 100644 --- a/substrate/substrate/executor/wasm/src/lib.rs +++ b/substrate/substrate/executor/wasm/src/lib.rs @@ -19,7 +19,7 @@ impl_stubs!( set_storage(b"input", input); print("storage"); - let foo = storage(b"foo"); + let foo = storage(b"foo").unwrap(); print("set_storage"); set_storage(b"baz", &foo); diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index d5fd4dfb021bc0d9dc3253288694113321c46df3..cbc81694c0999d1af58aaad064d227df8200e417 100644 GIT binary patch literal 14298 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 C);o&; literal 13451 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 diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index 2623dc31b8a59c862375e4abce3c9f6bf086602b..ab23e9b4f7a2a110b637faa5c07e1bf18823a350 100644 GIT binary patch literal 14394 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 literal 13576 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 diff --git a/substrate/substrate/rpc/src/state/tests.rs b/substrate/substrate/rpc/src/state/tests.rs index 469b794b05..9bae8b1cd5 100644 --- a/substrate/substrate/rpc/src/state/tests.rs +++ b/substrate/substrate/rpc/src/state/tests.rs @@ -35,7 +35,7 @@ fn should_return_storage() { assert_matches!( StateApi::storage(&client, StorageKey(vec![10]), genesis_hash), - Ok(ref x) if x.0.is_empty() + Err(Error(ErrorKind::Client(client::error::ErrorKind::NoValueForKey(ref k)), _)) if *k == vec![10] ) } diff --git a/substrate/substrate/runtime-io/with_std.rs b/substrate/substrate/runtime-io/with_std.rs index 98864baa63..5d785119c5 100644 --- a/substrate/substrate/runtime-io/with_std.rs +++ b/substrate/substrate/runtime-io/with_std.rs @@ -27,45 +27,45 @@ pub extern crate substrate_codec as codec; // re-export hashing functions. pub use primitives::{blake2_256, twox_128, twox_256}; -pub use substrate_state_machine::{Externalities, ExternalitiesError, TestExternalities}; +pub use substrate_state_machine::{Externalities, TestExternalities}; use primitives::hexdisplay::HexDisplay; // TODO: use the real error, not NoError. -environmental!(ext : trait Externalities); +environmental!(ext: trait Externalities); /// Get `key` from storage and return a `Vec`, empty if there's a problem. -pub fn storage(key: &[u8]) -> Vec { - ext::with(|ext| ext.storage(key).ok().map(|s| s.to_vec())) +pub fn storage(key: &[u8]) -> Option> { + ext::with(|ext| ext.storage(key).map(|s| s.to_vec())) .expect("read_storage cannot be called outside of an Externalities-provided environment.") - .unwrap_or_else(Vec::new) } /// Get `key` from storage, placing the value into `value_out` (as much as possible) and return -/// the number of bytes that the key in storage was beyond the offset. -pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> usize { - ext::with(|ext| { - if let Ok(value) = ext.storage(key) { - let value = &value[value_offset..]; - let written = ::std::cmp::min(value.len(), value_out.len()); - value_out[0..written].copy_from_slice(&value[0..written]); - value.len() - } else { - // no-entry is treated as an empty vector of bytes. - // TODO: consider allowing empty-vector to exist separately to no-entry (i.e. return - // Option) - 0 - } - }).expect("read_storage cannot be called outside of an Externalities-provided environment.") +/// the number of bytes that the key in storage was beyond the offset or None if the storage entry +/// doesn't exist at all. +pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { + ext::with(|ext| ext.storage(key).map(|value| { + let value = &value[value_offset..]; + let written = ::std::cmp::min(value.len(), value_out.len()); + value_out[0..written].copy_from_slice(&value[0..written]); + value.len() + })).expect("read_storage cannot be called outside of an Externalities-provided environment.") } -/// Set the storage to some particular key. +/// Set the storage of some particular key to Some value. pub fn set_storage(key: &[u8], value: &[u8]) { ext::with(|ext| ext.set_storage(key.to_vec(), value.to_vec()) ); } +/// Clear the storage of some particular key. +pub fn clear_storage(key: &[u8]) { + ext::with(|ext| + ext.clear_storage(key) + ); +} + /// The current relay chain identifier. pub fn chain_id() -> u64 { ext::with(|ext| @@ -164,37 +164,37 @@ mod std_tests { #[test] fn storage_works() { - let mut t = TestExternalities { storage: map![], }; + let mut t = TestExternalities::new(); assert!(with_externalities(&mut t, || { - assert_eq!(storage(b"hello"), b"".to_vec()); + assert_eq!(storage(b"hello"), None); set_storage(b"hello", b"world"); - assert_eq!(storage(b"hello"), b"world".to_vec()); - assert_eq!(storage(b"foo"), b"".to_vec()); + assert_eq!(storage(b"hello"), Some(b"world".to_vec())); + assert_eq!(storage(b"foo"), None); set_storage(b"foo", &[1, 2, 3][..]); true })); - t.storage = map![b"foo".to_vec() => b"bar".to_vec()]; + t = map![b"foo".to_vec() => b"bar".to_vec()]; assert!(!with_externalities(&mut t, || { - assert_eq!(storage(b"hello"), b"".to_vec()); - assert_eq!(storage(b"foo"), b"bar".to_vec()); + assert_eq!(storage(b"hello"), None); + assert_eq!(storage(b"foo"), Some(b"bar".to_vec())); false })); } #[test] fn read_storage_works() { - let mut t = TestExternalities { storage: map![ + let mut t: TestExternalities = map![ b":test".to_vec() => b"\x0b\0\0\0Hello world".to_vec() - ], }; + ]; with_externalities(&mut t, || { let mut v = [0u8; 4]; - assert!(read_storage(b":test", &mut v[..], 0) >= 4); + assert!(read_storage(b":test", &mut v[..], 0).unwrap() >= 4); assert_eq!(v, [11u8, 0, 0, 0]); let mut w = [0u8; 11]; - assert!(read_storage(b":test", &mut w[..], 4) >= 11); + assert!(read_storage(b":test", &mut w[..], 4).unwrap() >= 11); assert_eq!(&w, b"Hello world"); }); } diff --git a/substrate/substrate/runtime-io/without_std.rs b/substrate/substrate/runtime-io/without_std.rs index cac6b6dff2..ad31020cc4 100644 --- a/substrate/substrate/runtime-io/without_std.rs +++ b/substrate/substrate/runtime-io/without_std.rs @@ -43,6 +43,7 @@ extern "C" { fn ext_print_hex(data: *const u8, len: u32); fn ext_print_num(value: u64); fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); + fn ext_clear_storage(key_data: *const u8, key_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); @@ -55,11 +56,15 @@ extern "C" { } /// Get `key` from storage and return a `Vec`, empty if there's a problem. -pub fn storage(key: &[u8]) -> Vec { +pub fn storage(key: &[u8]) -> Option> { let mut length: u32 = 0; unsafe { let ptr = ext_get_allocated_storage(key.as_ptr(), key.len() as u32, &mut length); - Vec::from_raw_parts(ptr, length as usize, length as usize) + if length == u32::max_value() { + None + } else { + Some(Vec::from_raw_parts(ptr, length as usize, length as usize)) + } } } @@ -73,15 +78,27 @@ pub fn set_storage(key: &[u8], value: &[u8]) { } } +/// Set the storage to some particular key. +pub fn clear_storage(key: &[u8]) { + unsafe { + ext_clear_storage( + key.as_ptr(), key.len() as u32 + ); + } +} + /// Get `key` from storage, placing the value into `value_out` (as much as possible) and return /// the number of bytes that the key in storage was beyond the offset. -pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> usize { +pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> Option { unsafe { - ext_get_storage_into( + match ext_get_storage_into( key.as_ptr(), key.len() as u32, value_out.as_mut_ptr(), value_out.len() as u32, value_offset as u32 - ) as usize + ) { + none if none == u32::max_value() => None, + length => Some(length as usize), + } } } diff --git a/substrate/substrate/runtime-support/src/storage.rs b/substrate/substrate/runtime-support/src/storage.rs index 9896cb07c6..7dbfd8013b 100644 --- a/substrate/substrate/runtime-support/src/storage.rs +++ b/substrate/substrate/runtime-support/src/storage.rs @@ -18,14 +18,34 @@ use rstd::prelude::*; use runtime_io::{self, twox_128}; -use codec::{Slicable, KeyedVec}; +use codec::{Slicable, KeyedVec, Input}; // TODO: consider using blake256 to avoid possible preimage attack. -/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. +struct IncrementalInput<'a> { + key: &'a [u8], + pos: usize, +} + +impl<'a> Input for IncrementalInput<'a> { + fn read(&mut self, into: &mut [u8]) -> usize { + let len = runtime_io::read_storage(self.key, into, self.pos).unwrap_or(0); + let read = ::rstd::cmp::min(len, into.len()); + self.pos += read; + read + } +} + + /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { - let raw = runtime_io::storage(&twox_128(key)[..]); - Slicable::decode(&mut &raw[..]) + let key = twox_128(key); + runtime_io::read_storage(&key[..], &mut [0; 0][..], 0).map(|_| { + let mut input = IncrementalInput { + key: &key[..], + pos: 0, + }; + Slicable::decode(&mut input).expect("stroage is not null, therefore must be a valid type") + }) } /// Return the value of the item in storage under `key`, or the type's default if there is no @@ -85,17 +105,17 @@ pub fn take_or_else T>(key: &[u8], default_v /// Check to see if `key` has an explicit entry in storage. pub fn exists(key: &[u8]) -> bool { - let mut x = [0u8; 1]; - runtime_io::read_storage(&twox_128(key)[..], &mut x[..], 0) >= 1 + let mut x = [0u8; 0]; + runtime_io::read_storage(&twox_128(key)[..], &mut x[..], 0).is_some() } /// Ensure `key` has no explicit entry in storage. pub fn kill(key: &[u8]) { - runtime_io::set_storage(&twox_128(key)[..], b""); + runtime_io::clear_storage(&twox_128(key)[..]); } /// Get a Vec of bytes from storage. -pub fn get_raw(key: &[u8]) -> Vec { +pub fn get_raw(key: &[u8]) -> Option> { runtime_io::storage(&twox_128(key)[..]) } @@ -127,12 +147,18 @@ pub trait StorageVec { } } + fn clear_item(index: u32) { + if index < Self::count() { + kill(&index.to_keyed_vec(Self::PREFIX)); + } + } + fn item(index: u32) -> Self::Item { get_or_default(&index.to_keyed_vec(Self::PREFIX)) } fn set_count(count: u32) { - (count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default())); + (count..Self::count()).for_each(Self::clear_item); put(&b"len".to_keyed_vec(Self::PREFIX), &count); } @@ -142,12 +168,17 @@ pub trait StorageVec { } pub mod unhashed { - use super::{runtime_io, Slicable, KeyedVec, Vec}; + use super::{runtime_io, Slicable, KeyedVec, Vec, IncrementalInput}; /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. pub fn get(key: &[u8]) -> Option { - let raw = runtime_io::storage(key); - T::decode(&mut &raw[..]) + runtime_io::read_storage(key, &mut [0; 0][..], 0).map(|_| { + let mut input = IncrementalInput { + key, + pos: 0, + }; + Slicable::decode(&mut input).expect("stroage is not null, therefore must be a valid type") + }) } /// Return the value of the item in storage under `key`, or the type's default if there is no @@ -207,17 +238,16 @@ pub mod unhashed { /// Check to see if `key` has an explicit entry in storage. pub fn exists(key: &[u8]) -> bool { - let mut x = [0u8; 1]; - runtime_io::read_storage(key, &mut x[..], 0) >= 1 + runtime_io::read_storage(key, &mut [0;0][..], 0).is_some() } /// Ensure `key` has no explicit entry in storage. pub fn kill(key: &[u8]) { - runtime_io::set_storage(key, b""); + runtime_io::clear_storage(key); } /// Get a Vec of bytes from storage. - pub fn get_raw(key: &[u8]) -> Vec { + pub fn get_raw(key: &[u8]) -> Option> { runtime_io::storage(key) } @@ -249,12 +279,18 @@ pub mod unhashed { } } + fn clear_item(index: u32) { + if index < Self::count() { + kill(&index.to_keyed_vec(Self::PREFIX)); + } + } + fn item(index: u32) -> Self::Item { get_or_default(&index.to_keyed_vec(Self::PREFIX)) } fn set_count(count: u32) { - (count..Self::count()).for_each(|i| Self::set_item(i, &Self::Item::default())); + (count..Self::count()).for_each(Self::clear_item); put(&b"len".to_keyed_vec(Self::PREFIX), &count); } @@ -267,13 +303,12 @@ pub mod unhashed { #[cfg(test)] mod tests { use super::*; - use std::collections::HashMap; use primitives::hexdisplay::HexDisplay; use runtime_io::{storage, twox_128, TestExternalities, with_externalities}; #[test] fn integers_can_be_stored() { - let mut t = TestExternalities { storage: HashMap::new(), }; + let mut t = TestExternalities::new(); with_externalities(&mut t, || { let x = 69u32; put(b":test", &x); @@ -290,7 +325,7 @@ mod tests { #[test] fn bools_can_be_stored() { - let mut t = TestExternalities { storage: HashMap::new(), }; + let mut t = TestExternalities::new(); with_externalities(&mut t, || { let x = true; put(b":test", &x); @@ -308,11 +343,11 @@ mod tests { #[test] fn vecs_can_be_retrieved() { - let mut t = TestExternalities { storage: HashMap::new(), }; + let mut t = TestExternalities::new(); with_externalities(&mut t, || { runtime_io::set_storage(&twox_128(b":test"), b"\x0b\0\0\0Hello world"); let x = b"Hello world".to_vec(); - println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")))); + println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")).unwrap())); let y = get::>(b":test").unwrap(); assert_eq!(x, y); @@ -321,7 +356,7 @@ mod tests { #[test] fn vecs_can_be_stored() { - let mut t = TestExternalities { storage: HashMap::new(), }; + let mut t = TestExternalities::new(); let x = b"Hello world".to_vec(); with_externalities(&mut t, || { @@ -330,7 +365,7 @@ mod tests { println!("Ext is {:?}", t); with_externalities(&mut t, || { - println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")))); + println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")).unwrap())); let y: Vec = get(b":test").unwrap(); assert_eq!(x, y); }); diff --git a/substrate/substrate/state-machine/src/backend.rs b/substrate/substrate/state-machine/src/backend.rs index f77e9a59d8..2c019510ff 100644 --- a/substrate/substrate/state-machine/src/backend.rs +++ b/substrate/substrate/state-machine/src/backend.rs @@ -17,11 +17,7 @@ //! State machine backends. These manage the code and storage of contracts. use std::{error, fmt}; - -use super::{Update, MemoryState}; - -/// Output of a commit. -pub struct Committed {} +use std::collections::HashMap; /// A state backend is used to read state data and can have changes committed /// to it. @@ -29,12 +25,12 @@ pub trait Backend { /// An error type when fetching data is not possible. type Error: super::Error; - /// Get keyed storage associated with specific address. - fn storage(&self, key: &[u8]) -> Result<&[u8], Self::Error>; + /// Get keyed storage associated with specific address, or None if there is nothing associated. + fn storage(&self, key: &[u8]) -> Result, Self::Error>; /// Commit updates to the backend and get new state. - fn commit(&mut self, changes: I) -> Committed - where I: IntoIterator; + fn commit(&mut self, changes: I) + where I: IntoIterator, Option>)>; /// Get all key/value pairs into a Vec. fn pairs(&self) -> Vec<(&[u8], &[u8])>; @@ -57,38 +53,28 @@ impl error::Error for Void { /// In-memory backend. Fully recomputes tries on each commit but useful for /// tests. -#[derive(Debug, PartialEq, Default, Clone)] -pub struct InMemory { - inner: MemoryState, // keeps all the state in memory. -} - -impl InMemory { - /// Create a new instance from a given storage map. - pub fn from(storage: ::std::collections::HashMap, Vec>) -> Self { - InMemory { - inner: MemoryState { - storage - } - } - } -} +pub type InMemory = HashMap, Vec>; impl Backend for InMemory { type Error = Void; - fn storage(&self, key: &[u8]) -> Result<&[u8], Self::Error> { - Ok(self.inner.storage(key).unwrap_or(&[])) + fn storage(&self, key: &[u8]) -> Result, Self::Error> { + Ok(self.get(key).map(AsRef::as_ref)) } - fn commit(&mut self, changes: I) -> Committed - where I: IntoIterator + fn commit(&mut self, changes: I) + where I: IntoIterator, Option>)> { - self.inner.update(changes); - Committed {} + for (key, val) in changes { + match val { + Some(v) => { self.insert(key, v); }, + None => { self.remove(&key); }, + } + } } fn pairs(&self) -> Vec<(&[u8], &[u8])> { - self.inner.storage.iter().map(|(k, v)| (&k[..], &v[..])).collect() + self.iter().map(|(k, v)| (&k[..], &v[..])).collect() } } diff --git a/substrate/substrate/state-machine/src/ext.rs b/substrate/substrate/state-machine/src/ext.rs index e0176ad41c..ac047a31c3 100644 --- a/substrate/substrate/state-machine/src/ext.rs +++ b/substrate/substrate/state-machine/src/ext.rs @@ -17,9 +17,10 @@ //! Conrete externalities implementation. use std::{error, fmt}; +use std::collections::HashMap; use triehash::trie_root; use backend::Backend; -use {Externalities, ExternalitiesError, OverlayedChanges}; +use {Externalities, OverlayedChanges}; /// Errors that can occur when interacting with the externalities. #[derive(Debug, Copy, Clone)] @@ -58,17 +59,29 @@ pub struct Ext<'a, B: 'a> { pub backend: &'a B, } +#[cfg(test)] +impl<'a, B: 'a + Backend> Ext<'a, B> { + pub fn storage_pairs(&self) -> Vec<(Vec, Vec)> { + self.backend.pairs().iter() + .map(|&(ref k, ref v)| (k.to_vec(), Some(v.to_vec()))) + .chain(self.overlay.committed.clone().into_iter()) + .chain(self.overlay.prospective.clone().into_iter()) + .collect::>() + .into_iter() + .filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val))) + .collect() + } +} + impl<'a, B: 'a> Externalities for Ext<'a, B> where B: Backend { - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError> { - match self.overlay.storage(key) { - Some(x) => Ok(x), - None => self.backend.storage(key).map_err(|_| ExternalitiesError), - } + fn storage(&self, key: &[u8]) -> Option<&[u8]> { + self.overlay.storage(key).unwrap_or_else(|| + self.backend.storage(key).expect("Externalities not allowed to fail within runtime")) } - fn set_storage(&mut self, key: Vec, value: Vec) { + fn place_storage(&mut self, key: Vec, value: Option>) { self.overlay.set_storage(key, value); } @@ -77,13 +90,12 @@ impl<'a, B: 'a> Externalities for Ext<'a, B> } 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 + trie_root(self.backend.pairs().iter() + .map(|&(ref k, ref v)| (k.to_vec(), Some(v.to_vec()))) + .chain(self.overlay.committed.clone().into_iter()) + .chain(self.overlay.prospective.clone().into_iter()) + .collect::>() + .into_iter() + .filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val)))).0 } } diff --git a/substrate/substrate/state-machine/src/lib.rs b/substrate/substrate/state-machine/src/lib.rs index a3f2e3dc4b..363f293830 100644 --- a/substrate/substrate/state-machine/src/lib.rs +++ b/substrate/substrate/state-machine/src/lib.rs @@ -32,6 +32,7 @@ extern crate triehash; extern crate byteorder; use std::collections::HashMap; +use std::collections::hash_map::Drain; use std::fmt; pub mod backend; @@ -40,35 +41,7 @@ mod testing; pub use testing::TestExternalities; pub use ext::Ext; - -/// Updates to be committed to the state. -pub type Update = (Vec, Vec); - -// in-memory section of the state. -#[derive(Debug, PartialEq, Default, Clone)] -struct MemoryState { - storage: HashMap, Vec>, -} - -impl MemoryState { - fn storage(&self, key: &[u8]) -> Option<&[u8]> { - self.storage.get(key).map(|v| &v[..]) - } - - fn set_storage(&mut self, key: Vec, val: Vec) { - self.storage.insert(key, val); - } - - fn update(&mut self, changes: I) where I: IntoIterator { - for (key, val) in changes { - if val.is_empty() { - self.storage.remove(&key); - } else { - self.storage.insert(key, val); - } - } - } -} +pub use backend::Backend; /// The overlayed changes to state to be queried on top of the backend. /// @@ -76,34 +49,41 @@ impl MemoryState { /// that can be cleared. #[derive(Default)] pub struct OverlayedChanges { - prospective: MemoryState, - committed: MemoryState, + prospective: HashMap, Option>>, + committed: HashMap, Option>>, } impl OverlayedChanges { - fn storage(&self, key: &[u8]) -> Option<&[u8]> { - self.prospective.storage(key) - .or_else(|| self.committed.storage(key)) - .and_then(|v| if v.is_empty() { None } else { Some(v) }) + /// Returns a double-Option: None if the key is unknown (i.e. and the query should be refered + /// to the backend); Some(None) if the key has been deleted. Some(Some(...)) for a key whose + /// value has been set. + pub fn storage(&self, key: &[u8]) -> Option> { + self.prospective.get(key) + .or_else(|| self.committed.get(key)) + .map(|x| x.as_ref().map(AsRef::as_ref)) } - fn set_storage(&mut self, key: Vec, val: Vec) { - self.prospective.set_storage(key, val); + fn set_storage(&mut self, key: Vec, val: Option>) { + self.prospective.insert(key, val); } /// Discard prospective changes to state. pub fn discard_prospective(&mut self) { - self.prospective.storage.clear(); + self.prospective.clear(); } /// Commit prospective changes to state. pub fn commit_prospective(&mut self) { - self.committed.update(self.prospective.storage.drain()); + if self.committed.is_empty() { + ::std::mem::swap(&mut self.prospective, &mut self.committed); + } else { + self.committed.extend(self.prospective.drain()); + } } /// Drain prospective changes to an iterator. - pub fn drain(&mut self) -> ::std::collections::hash_map::Drain, std::vec::Vec> { - self.committed.storage.drain() + pub fn drain(&mut self) -> Drain, Option>> { + self.committed.drain() } } @@ -119,19 +99,32 @@ impl Error for E where E: 'static + fmt::Debug + fmt::Display + Send {} /// would not be executed unless externalities were available. This is included for completeness, /// and as a transition away from the pre-existing framework. #[derive(Debug, Eq, PartialEq)] -pub struct ExternalitiesError; +pub enum ExecutionError { + /// The entry `:code` doesn't exist in storage so there's no way we can execute anything. + CodeEntryDoesNotExist +} -impl fmt::Display for ExternalitiesError { +impl fmt::Display for ExecutionError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") } } /// Externalities: pinned to specific active address. pub trait Externalities { /// Read storage of current contract being called. - fn storage(&self, key: &[u8]) -> Result<&[u8], ExternalitiesError>; + fn storage(&self, key: &[u8]) -> Option<&[u8]>; - /// Set storage of current contract being called (effective immediately). - fn set_storage(&mut self, key: Vec, value: Vec); + /// Set storage entry `key` of current contract being called (effective immediately). + fn set_storage(&mut self, key: Vec, value: Vec) { + self.place_storage(key, Some(value)); + } + + /// Clear a storage entry (`key`) of current contract being called (effective immediately). + fn clear_storage(&mut self, key: &[u8]) { + self.place_storage(key.to_vec(), None); + } + + /// Set or clear a storage entry (`key`) of current contract being called (effective immediately). + fn place_storage(&mut self, key: Vec, value: Option>); /// Get the identity of the chain. fn chain_id(&self) -> u64; @@ -167,7 +160,8 @@ pub fn execute( exec: &Exec, method: &str, call_data: &[u8], -) -> Result, Box> { +) -> Result, Box> +{ let result = { let mut externalities = ext::Ext { @@ -175,7 +169,9 @@ pub fn execute( overlay: &mut *overlay }; // make a copy. - let code = externalities.storage(b":code").unwrap_or(&[]).to_vec(); + let code = externalities.storage(b":code") + .ok_or(Box::new(ExecutionError::CodeEntryDoesNotExist) as Box)? + .to_vec(); exec.call( &mut externalities, @@ -211,21 +207,24 @@ mod tests { assert!(overlayed.storage(&key).is_none()); - overlayed.set_storage(key.clone(), vec![1, 2, 3]); - assert_eq!(overlayed.storage(&key).unwrap(), &[1, 2, 3]); + overlayed.set_storage(key.clone(), Some(vec![1, 2, 3])); + assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..])); overlayed.commit_prospective(); - assert_eq!(overlayed.storage(&key).unwrap(), &[1, 2, 3]); + assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..])); - overlayed.set_storage(key.clone(), vec![]); - assert!(overlayed.storage(&key).is_none()); + overlayed.set_storage(key.clone(), Some(vec![])); + assert_eq!(overlayed.storage(&key).unwrap(), Some(&[][..])); + + overlayed.set_storage(key.clone(), None); + assert!(overlayed.storage(&key).unwrap().is_none()); overlayed.discard_prospective(); - assert_eq!(overlayed.storage(&key).unwrap(), &[1, 2, 3]); + assert_eq!(overlayed.storage(&key).unwrap(), Some(&[1, 2, 3][..])); - overlayed.set_storage(key.clone(), vec![]); + overlayed.set_storage(key.clone(), None); overlayed.commit_prospective(); - assert!(overlayed.storage(&key).is_none()); + assert!(overlayed.storage(&key).unwrap().is_none()); } macro_rules! map { @@ -239,16 +238,19 @@ mod tests { 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() + b"dogglesworth".to_vec() => b"catXXX".to_vec(), + b"doug".to_vec() => b"notadog".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() - ], }, + committed: map![ + b"dog".to_vec() => Some(b"puppy".to_vec()), + b"dogglesworth".to_vec() => Some(b"catYYY".to_vec()), + b"doug".to_vec() => Some(vec![]) + ], + prospective: map![ + b"dogglesworth".to_vec() => Some(b"cat".to_vec()), + b"doug".to_vec() => None + ], }; let ext = Ext { backend: &mut backend, diff --git a/substrate/substrate/state-machine/src/testing.rs b/substrate/substrate/state-machine/src/testing.rs index a85e1d3f4a..6d991a9aca 100644 --- a/substrate/substrate/state-machine/src/testing.rs +++ b/substrate/substrate/state-machine/src/testing.rs @@ -17,38 +17,28 @@ //! Test implementation for Externalities. use std::collections::HashMap; -use super::{Externalities, ExternalitiesError}; +use super::Externalities; use triehash::trie_root; /// Simple HashMap based Externalities impl. -#[derive(Debug, Default)] -pub struct TestExternalities { - /// The storage. - pub storage: HashMap, Vec>, -} - -impl TestExternalities { - /// Create a new instance with empty storage. - pub fn new() -> Self { - TestExternalities { - storage: HashMap::new(), - } - } -} +pub type TestExternalities = 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 storage(&self, key: &[u8]) -> Option<&[u8]> { + self.get(key).map(AsRef::as_ref) } - fn set_storage(&mut self, key: Vec, value: Vec) { - self.storage.insert(key, value); + fn place_storage(&mut self, key: Vec, maybe_value: Option>) { + match maybe_value { + Some(value) => { self.insert(key, value); } + None => { self.remove(&key); } + } } fn chain_id(&self) -> u64 { 42 } fn storage_root(&self) -> [u8; 32] { - trie_root(self.storage.clone()).0 + trie_root(self.clone()).0 } } diff --git a/substrate/substrate/test-runtime/src/system.rs b/substrate/substrate/test-runtime/src/system.rs index 4c98e16003..a6de75760a 100644 --- a/substrate/substrate/test-runtime/src/system.rs +++ b/substrate/substrate/test-runtime/src/system.rs @@ -136,14 +136,14 @@ mod tests { use ::{Header, Digest, Transaction, UncheckedTransaction}; fn new_test_ext() -> TestExternalities { - TestExternalities { storage: map![ + map![ twox_128(b"latest").to_vec() => vec![69u8; 32], twox_128(b":auth:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b":auth:")).to_vec() => Keyring::Alice.to_raw_public().to_vec(), twox_128(&1u32.to_keyed_vec(b":auth:")).to_vec() => Keyring::Bob.to_raw_public().to_vec(), twox_128(&2u32.to_keyed_vec(b":auth:")).to_vec() => Keyring::Charlie.to_raw_public().to_vec(), twox_128(&Keyring::Alice.to_raw_public().to_keyed_vec(b"balance:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] - ], } + ] } fn construct_signed_tx(tx: Transaction) -> UncheckedTransaction { diff --git a/substrate/substrate/test-runtime/wasm/genesis.wasm b/substrate/substrate/test-runtime/wasm/genesis.wasm index 3eca5047352e7efbcf6808672b0454858e410327..7daba8a15c5866dd375c889a8eeb5f9cec8e7dbe 100644 GIT binary patch literal 32296 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 delta 1596 zcmaJ>U1%It6u#%q?9OZ^voo74=4WGjW?Eu4Ki&K_o4?xJty|HwC@Mv$7-HCBrXh(Y zLLZ`=C+S0x!Yvd;H24yIXiXd+T1p`gzWCZ_g`j;9EVM#F#fqLgyR)_k?y~3J`<>tK z+`H$CN3it=?CgLA3B#g~kw|cP3rUD)2)({%q%SmI|6yDmdO*29?+x|@?%yN6&{e%Jjo z$*-TeNAk0tMUtuf9Q4V>{0)+RZ$I>fFZEu6@QvB8oa#g1P~{&8N&Cr%+d+h@7Bm zq-A63C{#WST-~EkJsdq&VxES)#EP0yV}Kw`%EW{*n{%_Bd`5lgXue=mlDvkVUII^R z1`Ao)CJC-)2~vr{K(W$G47Cz_C1+h7;2A|*KJ1%>f-LmU%8mYMFv6Std4OK|)4=O6 z7)~GQ05Ig4!bnE~Tf|*0z*fbl1)VXzuVMCO+mxRdPPX}gEs9q*(u%F5YJhLbKMO_f zG5PFZN0nG8PqAOqQ5n%$E&ItDt~f^Y4$k_HB8X1ePLa+GM0?;fbo0C(g%CIJoq9al zrXE*O?hI-%LZ$KjYO=^pGJn9LST?d)9YGX9N2d+}W@4rCHH&ZEQ+_gp)ux8Q9yN*#n$UUzqTm*qF{FZT z5w*P}HLkgiIv7XE{OhbN_o61G8{CZsje7M)nSja1lW!WTJ8q*X zsYWj}1bK0|%Qi5+nM#-iYp}h#s^ysWNyQr8m#P>$Gek;*dvAfczie8qLMI`q?L>lzE-xg za&F>%Fy#*uZD?LA@eloM2`_HjcEglHk!h-IJ2E@@T9#g#fWWiRwm~q@5#SkeWAe>5 zx=Bo{-)Z{ac+^sAu|qZdI+<-Y%C>1?+H>fw$;^~b^hT$)Nq#?d#Uw+E&!8Dzn9c!} za^+YLSDw2B6#7wl7oZScfBw1_T4(QBFckiN?l(QHF=ko6 Qc=Ob3OTQfcy>!?82fd*jGynhq diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index 3329885da9a60eb0dbabb75aadba95405ccefe2a..a57d2f1fd4eadc2f17d3e74e3fccab8997e96901 100644 GIT binary patch delta 1882 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 SS-*Jm)N4z>5I*w4q5BVG!yEhn