From 4378ce7887b22db104f5b0127e984a434fb93f05 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Tue, 6 Feb 2018 16:35:19 +0100 Subject: [PATCH] fix tests and review grumbles --- substrate/Cargo.lock | 8 +- substrate/client/src/genesis.rs | 15 +- substrate/executor/src/native_executor.rs | 12 +- substrate/primitives/Cargo.toml | 4 +- substrate/primitives/src/lib.rs | 4 +- substrate/primitives/src/runtime_function.rs | 10 +- substrate/primitives/src/tests.rs | 233 ++++++++++++++++++ substrate/wasm-runtime/Cargo.lock | 8 +- .../polkadot/src/runtime/system.rs | 31 ++- .../release/runtime_polkadot.compact.wasm | Bin 66501 -> 67849 bytes .../release/runtime_polkadot.wasm | Bin 66580 -> 67928 bytes 11 files changed, 285 insertions(+), 40 deletions(-) create mode 100644 substrate/primitives/src/tests.rs diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 8d46cf6766..5261f91b80 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1077,7 +1077,7 @@ dependencies = [ "polkadot-runtime-codec 0.1.0", "polkadot-serializer 0.1.0", "pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1332,6 +1332,11 @@ name = "rustc-hex" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-hex" +version = "2.0.0" +source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7" + [[package]] name = "rustc-serialize" version = "0.3.24" @@ -1914,6 +1919,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" +"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" diff --git a/substrate/client/src/genesis.rs b/substrate/client/src/genesis.rs index 3a8a287e27..9a49df5e08 100644 --- a/substrate/client/src/genesis.rs +++ b/substrate/client/src/genesis.rs @@ -18,17 +18,16 @@ use std::collections::HashMap; use primitives::block::{Block, Header}; -use primitives::H256; use triehash::trie_root; /// Create a genesis block, given the initial storage. pub fn construct_genesis_block(storage: &HashMap, Vec>) -> Block { - let state_root = H256(trie_root(storage.clone().into_iter()).0); + let state_root = trie_root(storage.clone().into_iter()).0.into(); let header = Header { parent_hash: Default::default(), number: 0, state_root, - transaction_root: H256(trie_root(vec![].into_iter()).0), + transaction_root: trie_root(vec![].into_iter()).0.into(), digest: Default::default(), }; Block { @@ -47,7 +46,7 @@ mod tests { use state_machine::OverlayedChanges; use state_machine::backend::InMemory; use polkadot_executor::executor; - use primitives::{AccountId, Hash, H256}; + use primitives::{AccountId, Hash}; use primitives::block::{Number as BlockNumber, Header, Digest}; use primitives::runtime_function::Function; use primitives::transaction::{UncheckedTransaction, Transaction}; @@ -72,7 +71,7 @@ mod tests { UncheckedTransaction { transaction, signature } }).collect::>(); - let transaction_root = H256(ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0); + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into(); let mut header = Header { parent_hash, @@ -105,7 +104,7 @@ mod tests { ).unwrap(); header = Header::from_slice(&mut &ret_data[..]).unwrap(); - (vec![].join(&Block { header, transactions }), H256(hash)) + (vec![].join(&Block { header, transactions }), hash.into()) } fn block1(genesis_hash: Hash, backend: &InMemory) -> (Vec, Hash) { @@ -113,7 +112,7 @@ mod tests { backend, 1, genesis_hash, - H256(hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c")), + hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c").into(), vec![Transaction { signed: one(), nonce: 0, @@ -128,7 +127,7 @@ mod tests { vec![one(), two()], 1000 ).genesis_map(); let block = construct_genesis_block(&storage); - let genesis_hash = H256(block.header.blake2_256()); + let genesis_hash = block.header.blake2_256().into(); storage.extend(additional_storage_with_genesis(&block).into_iter()); let mut overlay = OverlayedChanges::default(); diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index df6e64908f..5e0bdaa7fb 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -46,7 +46,7 @@ mod tests { use native_runtime::support::{one, two, Hashable}; use native_runtime::runtime::staking::balance; use state_machine::TestExternalities; - use primitives::{twox_128, Hash, H256}; + use primitives::{twox_128, Hash}; use primitives::runtime_function::Function; use primitives::block::{Header, Number as BlockNumber, Block, Digest}; use primitives::transaction::{Transaction, UncheckedTransaction}; @@ -167,7 +167,7 @@ mod tests { UncheckedTransaction { transaction, signature } }).collect::>(); - let transaction_root = H256(ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0); + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into(); let header = Header { parent_hash, @@ -178,14 +178,14 @@ mod tests { }; let hash = header.blake2_256(); - (Block { header, transactions }.to_vec(), H256(hash)) + (Block { header, transactions }.to_vec(), hash.into()) } fn block1() -> (Vec, Hash) { construct_block( 1, - H256([69u8; 32]), - H256(hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db")), + [69u8; 32].into(), + hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db").into(), vec![Transaction { signed: one(), nonce: 0, @@ -198,7 +198,7 @@ mod tests { construct_block( 2, block1().1, - H256(hex!("2cdbbf9bd766c2286a5f4091c131fe161addd060ba6fc041b3419089f4601bda")), + hex!("e2ba57cfb94b870ea6670b012b49dc33cbb70e3aa8d36cf54dfa5e4e69cd0778").into(), vec![ Transaction { signed: two(), diff --git a/substrate/primitives/Cargo.toml b/substrate/primitives/Cargo.toml index 27c2e70f0e..6e5a4bd0c4 100644 --- a/substrate/primitives/Cargo.toml +++ b/substrate/primitives/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Parity Technologies "] [dependencies] crunchy = "0.1" fixed-hash = { git = "https://github.com/rphmeier/primitives.git", branch = "compile-for-wasm", default_features = false } -rustc-hex = { version = "1.0", optional = true } +rustc-hex = { git = "https://github.com/rphmeier/rustc-hex.git", version = "2.0", default_features = false } serde = { version = "1.0", default_features = false } serde_derive = { version = "1.0", optional = true } uint = { git = "https://github.com/rphmeier/primitives.git", branch = "compile-for-wasm" } @@ -26,7 +26,7 @@ std = [ "fixed-hash/std", "polkadot-runtime-codec/std", "serde/std", - "rustc-hex", + "rustc-hex/std", "twox-hash", "blake2-rfc", "serde_derive", diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs index 7b7da0c924..3ecc0a77c0 100644 --- a/substrate/primitives/src/lib.rs +++ b/substrate/primitives/src/lib.rs @@ -21,7 +21,6 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] -#[cfg(feature = "std")] extern crate rustc_hex; extern crate serde; @@ -77,6 +76,9 @@ pub mod transaction; pub mod uint; pub mod validator; +#[cfg(test)] +mod tests; + #[cfg(feature = "std")] pub mod hashing; diff --git a/substrate/primitives/src/runtime_function.rs b/substrate/primitives/src/runtime_function.rs index 9ec5da029c..48e5afdc61 100644 --- a/substrate/primitives/src/runtime_function.rs +++ b/substrate/primitives/src/runtime_function.rs @@ -82,10 +82,12 @@ impl Slicable for Function { Function::SessionSetKey(try_opt!(Slicable::from_slice(value))), FunctionId::StakingStake => Function::StakingStake, FunctionId::StakingUnstake => Function::StakingUnstake, - FunctionId::StakingTransfer => Function::StakingTransfer( - try_opt!(Slicable::from_slice(value)), - try_opt!(Slicable::from_slice(value)), - ), + FunctionId::StakingTransfer => { + let to = try_opt!(Slicable::from_slice(value)); + let amount = try_opt!(Slicable::from_slice(value)); + + Function::StakingTransfer(to, amount) + } FunctionId::GovernancePropose => Function::GovernancePropose(try_opt!(Slicable::from_slice(value))), FunctionId::GovernanceApprove => diff --git a/substrate/primitives/src/tests.rs b/substrate/primitives/src/tests.rs new file mode 100644 index 0000000000..311f596400 --- /dev/null +++ b/substrate/primitives/src/tests.rs @@ -0,0 +1,233 @@ +// 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 . + +//! Tests. + +use codec::Slicable; + +use ::AccountId; +use block::{Block, Header, Digest, Log}; +use runtime_function::Function; +use transaction::{UncheckedTransaction, Transaction}; + +#[test] +fn serialise_transaction_works() { + let one: AccountId = [1u8; 32]; + let two: AccountId = [2u8; 32]; + let tx = Transaction { + signed: one.clone(), + nonce: 69, + function: Function::StakingTransfer(two, 69), + }; + + let serialised = tx.to_vec(); + assert_eq!(serialised, vec![ + 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 69, 0, 0, 0, 0, 0, 0, 0, + 34, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0 + ]); +} + +#[test] +fn deserialise_transaction_works() { + let one: AccountId = [1u8; 32]; + let two: AccountId = [2u8; 32]; + let tx = Transaction { + signed: one.clone(), + nonce: 69, + function: Function::StakingTransfer(two, 69), + }; + + let data = [ + 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 69, 0, 0, 0, 0, 0, 0, 0, + 34, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0 + ]; + let deserialised = Transaction::from_slice(&mut &data[..]).unwrap(); + assert_eq!(deserialised, tx); +} + +#[test] +fn serialise_header_works() { + let h = Header { + parent_hash: [4u8; 32].into(), + number: 42, + state_root: [5u8; 32].into(), + transaction_root: [6u8; 32].into(), + digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], }, + }; + let serialised = h.to_vec(); + assert_eq!(serialised, vec![ + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 2, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 + ]); +} + +#[test] +fn deserialise_header_works() { + let h = Header { + parent_hash: [4u8; 32].into(), + number: 42, + state_root: [5u8; 32].into(), + transaction_root: [6u8; 32].into(), + digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], }, + }; + let data = [ + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 2, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 + ]; + let deserialised = Header::from_slice(&mut &data[..]).unwrap(); + assert_eq!(deserialised, h); +} + +#[test] +fn serialise_block_works() { + let one: AccountId = [1u8; 32]; + let two: AccountId = [2u8; 32]; + let tx1 = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 69, + function: Function::StakingTransfer(two, 69), + }, + signature: [1u8; 64].into(), + }; + let tx2 = UncheckedTransaction { + transaction: Transaction { + signed: two.clone(), + nonce: 42, + function: Function::StakingStake, + }, + signature: [2u8; 64].into(), + }; + let h = Header { + parent_hash: [4u8; 32].into(), + number: 42, + state_root: [5u8; 32].into(), + transaction_root: [6u8; 32].into(), + digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], }, + }; + let b = Block { + header: h, + transactions: vec![tx1, tx2], + }; + let serialised = b.to_vec(); + assert_eq!(serialised, vec![ + // header + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 2, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, + // transactions + 2, 0, 0, 0, + // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 69, 0, 0, 0, 0, 0, 0, 0, + 34, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 42, 0, 0, 0, 0, 0, 0, 0, + 32, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + ]); +} + +#[test] +fn deserialise_block_works() { + let one: AccountId = [1u8; 32]; + let two: AccountId = [2u8; 32]; + let tx1 = UncheckedTransaction { + transaction: Transaction { + signed: one.clone(), + nonce: 69, + function: Function::StakingTransfer(two, 69), + }, + signature: [1u8; 64].into(), + }; + let tx2 = UncheckedTransaction { + transaction: Transaction { + signed: two.clone(), + nonce: 42, + function: Function::StakingStake, + }, + signature: [2u8; 64].into(), + }; + let h = Header { + parent_hash: [4u8; 32].into(), + number: 42, + state_root: [5u8; 32].into(), + transaction_root: [6u8; 32].into(), + digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], }, + }; + let b = Block { + header: h, + transactions: vec![tx1, tx2], + }; + let data = [ + // header + 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 42, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 2, 0, 0, 0, + 7, 0, 0, 0, + 111, 110, 101, 32, 108, 111, 103, + 11, 0, 0, 0, + 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, + // transactions + 2, 0, 0, 0, + // tx1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 69, 0, 0, 0, 0, 0, 0, 0, + 34, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 69, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // tx2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 42, 0, 0, 0, 0, 0, 0, 0, + 32, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + ]; + let deserialised = Block::from_slice(&mut &data[..]).unwrap(); + assert_eq!(deserialised, b); +} diff --git a/substrate/wasm-runtime/Cargo.lock b/substrate/wasm-runtime/Cargo.lock index 71665b12ce..287249192e 100644 --- a/substrate/wasm-runtime/Cargo.lock +++ b/substrate/wasm-runtime/Cargo.lock @@ -384,7 +384,7 @@ dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)", "polkadot-runtime-codec 0.1.0", - "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -568,6 +568,11 @@ name = "rustc-hex" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-hex" +version = "2.0.0" +source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7" + [[package]] name = "rustc_version" version = "0.2.1" @@ -825,6 +830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" "checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" +"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" diff --git a/substrate/wasm-runtime/polkadot/src/runtime/system.rs b/substrate/wasm-runtime/polkadot/src/runtime/system.rs index 6a56698923..22f72fff79 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/system.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/system.rs @@ -21,7 +21,7 @@ use runtime_std::prelude::*; use runtime_std::{mem, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; use support::{Hashable, storage, with_env}; -use primitives::{AccountId, Hash, H256, TxOrder}; +use primitives::{AccountId, Hash, TxOrder}; use primitives::block::{Block, Header, Number as BlockNumber}; use primitives::transaction::UncheckedTransaction; use primitives::runtime_function::Function; @@ -78,7 +78,7 @@ pub mod internal { // check transaction trie root represents the transactions. let txs = block.transactions.iter().map(Slicable::to_vec).collect::>(); let txs = txs.iter().map(Vec::as_slice).collect::>(); - let txs_root = H256(enumerated_trie_root(&txs)); + let txs_root = enumerated_trie_root(&txs).into(); debug_assert_hash(&header.transaction_root, &txs_root); assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); @@ -94,7 +94,7 @@ pub mod internal { final_checks(&block); // check storage root. - let storage_root = H256(storage_root()); + let storage_root = storage_root().into(); debug_assert_hash(&header.state_root, &storage_root); assert!(header.state_root == storage_root, "Storage root must match that calculated."); @@ -125,7 +125,7 @@ pub mod internal { staking::internal::check_new_era(); session::internal::check_rotate_session(); - header.state_root = H256(storage_root()); + header.state_root = storage_root().into(); with_env(|e| { mem::swap(&mut header.digest, &mut e.digest); }); @@ -218,7 +218,6 @@ mod tests { use primitives::transaction::{UncheckedTransaction, Transaction}; use primitives::runtime_function::Function; use primitives::block::{Header, Digest}; - use primitives::hash::{H256, H512}; use runtime::staking; #[test] @@ -236,10 +235,8 @@ mod tests { nonce: 0, function: Function::StakingTransfer(two, 69), }, - signature: "b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".parse().unwrap(), + signature: "5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05".parse().unwrap(), }; - // tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000 - // sig: b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00 with_externalities(&mut t, || { internal::execute_transaction(tx, Header::from_block_number(1)); @@ -280,10 +277,10 @@ mod tests { let mut t = new_test_ext(); let h = Header { - parent_hash: H256([69u8; 32]), + parent_hash: [69u8; 32].into(), number: 1, - state_root: H256(hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0")), - transaction_root: H256(hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")), + state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0").into(), + transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; @@ -306,10 +303,10 @@ mod tests { let mut t = new_test_ext(); let h = Header { - parent_hash: H256([69u8; 32]), + parent_hash: [69u8; 32].into(), number: 1, - state_root: H256([0u8; 32]), - transaction_root: H256(hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")), + state_root: [0u8; 32].into(), + transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), digest: Digest { logs: vec![], }, }; @@ -332,10 +329,10 @@ mod tests { let mut t = new_test_ext(); let h = Header { - parent_hash: H256([69u8; 32]), + parent_hash: [69u8; 32].into(), number: 1, - state_root: H256(hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0")), - transaction_root: H256([0u8; 32]), + state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0").into(), + transaction_root: [0u8; 32].into(), digest: Digest { logs: vec![], }, }; diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm index d29436d0d42ab6c117ab733811222fb5594d658d..669fb901a1e40b239ce3879e9156336e82058abc 100644 GIT binary patch delta 18019 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 delta 16966 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 HlTH19zuj)_ delta 16740 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