diff --git a/polkadot/cli/src/genesis.rs b/polkadot/cli/src/genesis.rs deleted file mode 100644 index 5e82d9a507..0000000000 --- a/polkadot/cli/src/genesis.rs +++ /dev/null @@ -1,142 +0,0 @@ -// 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 . - -//! Tool for creating the genesis block. - -use std::collections::HashMap; -use polkadot_primitives::{Block, Header}; -use triehash::trie_root; - -/// Create a genesis block, given the initial storage. -pub fn construct_genesis_block(storage: &HashMap, Vec>) -> Block { - let state_root = trie_root(storage.clone().into_iter()).0.into(); - let header = Header { - parent_hash: Default::default(), - number: 0, - state_root, - transaction_root: trie_root(vec![].into_iter()).0.into(), - digest: Default::default(), - }; - Block { - header, - transactions: vec![], - } -} - -#[cfg(test)] -mod tests { - use super::*; - use codec::{Slicable, Joiner}; - use polkadot_runtime::support::{one, two, Hashable}; - use polkadot_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; - use state_machine::execute; - use state_machine::OverlayedChanges; - use state_machine::backend::InMemory; - use polkadot_executor::executor; - use polkadot_primitives::{AccountId, Hash, BlockNumber, Header, Digest, UncheckedTransaction, - Transaction, Function}; - use ed25519::Pair; - - fn secret_for(who: &AccountId) -> Option { - match who { - x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), - x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), - _ => None, - } - } - - fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec) -> (Vec, Hash) { - use triehash::ordered_trie_root; - - let transactions = txs.into_iter().map(|transaction| { - let signature = secret_for(&transaction.signed).unwrap() - .sign(&transaction.to_vec()); - - UncheckedTransaction { transaction, signature } - }).collect::>(); - - let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into(); - - let mut header = Header { - parent_hash, - number, - state_root, - transaction_root, - digest: Digest { logs: vec![], }, - }; - let hash = header.blake2_256(); - - let mut overlay = OverlayedChanges::default(); - - for tx in transactions.iter() { - let ret_data = execute( - backend, - &mut overlay, - &executor(), - "execute_transaction", - &vec![].join(&header).join(tx) - ).unwrap(); - header = Header::decode(&mut &ret_data[..]).unwrap(); - } - - let ret_data = execute( - backend, - &mut overlay, - &executor(), - "finalise_block", - &vec![].join(&header) - ).unwrap(); - header = Header::decode(&mut &ret_data[..]).unwrap(); - - (vec![].join(&Block { header, transactions }), hash.into()) - } - - fn block1(genesis_hash: Hash, backend: &InMemory) -> (Vec, Hash) { - construct_block( - backend, - 1, - genesis_hash, - hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c").into(), - vec![Transaction { - signed: one(), - nonce: 0, - function: Function::StakingTransfer(two(), 69), - }] - ) - } - - #[test] - fn construct_genesis_should_work() { - let mut storage = GenesisConfig::new_simple( - vec![one(), two()], 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 mut overlay = OverlayedChanges::default(); - let backend = InMemory::from(storage); - let (b1data, _b1hash) = block1(genesis_hash, &backend); - - let _ = execute( - &backend, - &mut overlay, - &executor(), - "execute_block", - &b1data - ).unwrap(); - } -} diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs index ac452bfef3..59e6ef270e 100644 --- a/polkadot/cli/src/lib.rs +++ b/polkadot/cli/src/lib.rs @@ -39,11 +39,11 @@ extern crate error_chain; #[macro_use] extern crate log; -mod genesis; pub mod error; use codec::Slicable; use polkadot_runtime::genesismap::{additional_storage_with_genesis, GenesisConfig}; +use client::genesis; /// Parse command line arguments and start the node. /// @@ -83,7 +83,7 @@ pub fn run(args: I) -> error::Result<()> where 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.to_vec().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect()) + (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 = client::new_in_mem(executor, prepare_genesis)?; diff --git a/polkadot/executor/Cargo.toml b/polkadot/executor/Cargo.toml index 2c268ad51d..60cd4ee20d 100644 --- a/polkadot/executor/Cargo.toml +++ b/polkadot/executor/Cargo.toml @@ -10,6 +10,7 @@ triehash = { version = "0.1" } ed25519 = { path = "../../substrate/ed25519" } substrate-codec = { path = "../../substrate/codec" } substrate-runtime-io = { path = "../../substrate/runtime-io" } +substrate-runtime-support = { path = "../../substrate/runtime-support" } substrate-state-machine = { path = "../../substrate/state-machine" } substrate-executor = { path = "../../substrate/executor" } substrate-primitives = { path = "../../substrate/primitives" } diff --git a/polkadot/executor/src/lib.rs b/polkadot/executor/src/lib.rs index f4d5af026f..7db96440a4 100644 --- a/polkadot/executor/src/lib.rs +++ b/polkadot/executor/src/lib.rs @@ -26,9 +26,9 @@ extern crate substrate_primitives as primitives; extern crate polkadot_primitives as polkadot_primitives; extern crate ed25519; extern crate triehash; -#[cfg(test)] -#[macro_use] -extern crate hex_literal; + +#[cfg(test)] extern crate substrate_runtime_support as runtime_support; +#[cfg(test)] #[macro_use] extern crate hex_literal; use polkadot_runtime as runtime; use substrate_executor::error::{Error, ErrorKind}; @@ -62,7 +62,7 @@ mod tests { use super::*; use substrate_executor::WasmExecutor; use codec::{KeyedVec, Slicable, Joiner}; - use polkadot_runtime::support::{one, two, Hashable}; + use runtime_support::{one, two, Hashable}; use polkadot_runtime::runtime::staking::balance; use state_machine::{CodeExecutor, TestExternalities}; use primitives::twox_128; @@ -87,7 +87,7 @@ mod tests { function: Function::StakingTransfer(two(), 69), }; let signature = secret_for(&transaction.signed).unwrap() - .sign(&transaction.to_vec()); + .sign(&transaction.encode()); UncheckedTransaction { transaction, signature } } @@ -99,7 +99,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); } @@ -110,7 +110,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); } @@ -123,7 +123,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -141,7 +141,7 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -156,20 +156,20 @@ mod tests { let three = [3u8; 32]; TestExternalities { storage: map![ - twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), - twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), - twox_128(b"ses:len").to_vec() => vec![].join(&2u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&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), + twox_128(b"ses:val:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), - twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(b"sta:wil:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), - twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), - twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), - twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(b"sta:spe").to_vec() => vec![].and(&2u64), + 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] ], } } @@ -187,12 +187,12 @@ mod tests { let transactions = txs.into_iter().map(|transaction| { let signature = secret_for(&transaction.signed).unwrap() - .sign(&transaction.to_vec()); + .sign(&transaction.encode()); UncheckedTransaction { transaction, signature } }).collect::>(); - let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into(); + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::encode)).0.into(); let header = Header { parent_hash, @@ -203,7 +203,7 @@ mod tests { }; let hash = header.blake2_256(); - (Block { header, transactions }.to_vec(), hash.into()) + (Block { header, transactions }.encode(), hash.into()) } fn block1() -> (Vec, Hash) { @@ -285,7 +285,7 @@ mod tests { ], }; 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![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_err()); } @@ -299,7 +299,7 @@ mod tests { ], }; 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![].join(&Header::from_block_number(1u64)).join(&tx())); + let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx())); assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { diff --git a/polkadot/primitives/src/block.rs b/polkadot/primitives/src/block.rs index 4894113517..d71fa82e1c 100644 --- a/polkadot/primitives/src/block.rs +++ b/polkadot/primitives/src/block.rs @@ -42,8 +42,8 @@ impl Slicable for Log { Vec::::decode(input).map(Log) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } @@ -62,8 +62,8 @@ impl Slicable for Digest { Vec::::decode(input).map(|logs| Digest { logs }) } - fn as_slice_then R>(&self, f: F) -> R { - self.logs.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.logs.using_encoded(f) } } @@ -86,18 +86,14 @@ impl Slicable for Block { Some(Block { header, transactions }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - v.extend(self.header.to_vec()); - v.extend(self.transactions.to_vec()); + v.extend(self.header.encode()); + v.extend(self.transactions.encode()); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } /// A relay chain block header. @@ -144,21 +140,17 @@ impl Slicable for Header { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - self.parent_hash.as_slice_then(|s| v.extend(s)); - self.number.as_slice_then(|s| v.extend(s)); - self.state_root.as_slice_then(|s| v.extend(s)); - self.transaction_root.as_slice_then(|s| v.extend(s)); - self.digest.as_slice_then(|s| v.extend(s)); + self.parent_hash.using_encoded(|s| v.extend(s)); + self.number.using_encoded(|s| v.extend(s)); + self.state_root.using_encoded(|s| v.extend(s)); + self.transaction_root.using_encoded(|s| v.extend(s)); + self.digest.using_encoded(|s| v.extend(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } #[cfg(test)] @@ -189,7 +181,7 @@ mod tests { } }"#); - let v = header.to_vec(); + let v = header.encode(); assert_eq!(Header::decode(&mut &v[..]).unwrap(), header); } } diff --git a/polkadot/primitives/src/parachain.rs b/polkadot/primitives/src/parachain.rs index 6535e0f0e0..0f4c4adefc 100644 --- a/polkadot/primitives/src/parachain.rs +++ b/polkadot/primitives/src/parachain.rs @@ -40,8 +40,8 @@ impl Slicable for Id { u32::decode(input).map(Id) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } @@ -66,21 +66,21 @@ impl Slicable for Chain { } } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); match *self { - Chain::Relay => { 0u8.as_slice_then(|s| v.extend(s)); } + Chain::Relay => { 0u8.using_encoded(|s| v.extend(s)); } Chain::Parachain(id) => { - 1u8.as_slice_then(|s| v.extend(s)); - id.as_slice_then(|s| v.extend(s)); + 1u8.using_encoded(|s| v.extend(s)); + id.using_encoded(|s| v.extend(s)); } } v } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec().as_slice()) + fn using_encoded R>(&self, f: F) -> R { + f(&self.encode().as_slice()) } } @@ -105,17 +105,17 @@ impl Slicable for DutyRoster { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - v.extend(self.validator_duty.to_vec()); - v.extend(self.guarantor_duty.to_vec()); + v.extend(self.validator_duty.encode()); + v.extend(self.guarantor_duty.encode()); v } - fn as_slice_then R>(&self, f: F) -> R { - f(&self.to_vec().as_slice()) + fn using_encoded R>(&self, f: F) -> R { + f(&self.encode().as_slice()) } } @@ -204,8 +204,8 @@ impl Slicable for Activity { Vec::::decode(input).map(Activity) } - fn as_slice_then R>(&self, f: F) -> R { - self.0.as_slice_then(f) + fn using_encoded R>(&self, f: F) -> R { + self.0.using_encoded(f) } } diff --git a/polkadot/primitives/src/transaction.rs b/polkadot/primitives/src/transaction.rs index 0a68256f74..24a3ae4ee3 100644 --- a/polkadot/primitives/src/transaction.rs +++ b/polkadot/primitives/src/transaction.rs @@ -113,47 +113,43 @@ impl Slicable for Proposal { Some(function) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); match *self { Proposal::SystemSetCode(ref data) => { - (InternalFunctionId::SystemSetCode as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::SystemSetCode as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::SessionSetLength(ref data) => { - (InternalFunctionId::SessionSetLength as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::SessionSetLength as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::SessionForceNewSession => { - (InternalFunctionId::SessionForceNewSession as u8).as_slice_then(|s| v.extend(s)); + (InternalFunctionId::SessionForceNewSession as u8).using_encoded(|s| v.extend(s)); } Proposal::StakingSetSessionsPerEra(ref data) => { - (InternalFunctionId::StakingSetSessionsPerEra as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingSetSessionsPerEra as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::StakingSetBondingDuration(ref data) => { - (InternalFunctionId::StakingSetBondingDuration as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingSetBondingDuration as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::StakingSetValidatorCount(ref data) => { - (InternalFunctionId::StakingSetValidatorCount as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingSetValidatorCount as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Proposal::StakingForceNewEra => { - (InternalFunctionId::StakingForceNewEra as u8).as_slice_then(|s| v.extend(s)); + (InternalFunctionId::StakingForceNewEra as u8).using_encoded(|s| v.extend(s)); } Proposal::GovernanceSetApprovalPpmRequired(ref data) => { - (InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } } v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } @@ -232,43 +228,43 @@ impl Slicable for Function { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); match *self { Function::TimestampSet(ref data) => { - (FunctionId::TimestampSet as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::TimestampSet as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Function::SessionSetKey(ref data) => { - (FunctionId::SessionSetKey as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::SessionSetKey as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Function::StakingStake => { - (FunctionId::StakingStake as u8).as_slice_then(|s| v.extend(s)); + (FunctionId::StakingStake as u8).using_encoded(|s| v.extend(s)); } Function::StakingUnstake => { - (FunctionId::StakingUnstake as u8).as_slice_then(|s| v.extend(s)); + (FunctionId::StakingUnstake as u8).using_encoded(|s| v.extend(s)); } Function::StakingTransfer(ref to, ref amount) => { - (FunctionId::StakingTransfer as u8).as_slice_then(|s| v.extend(s)); - to.as_slice_then(|s| v.extend(s)); - amount.as_slice_then(|s| v.extend(s)); + (FunctionId::StakingTransfer as u8).using_encoded(|s| v.extend(s)); + to.using_encoded(|s| v.extend(s)); + amount.using_encoded(|s| v.extend(s)); } Function::GovernancePropose(ref data) => { - (FunctionId::GovernancePropose as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::GovernancePropose as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } Function::GovernanceApprove(ref data) => { - (FunctionId::GovernanceApprove as u8).as_slice_then(|s| v.extend(s)); - data.as_slice_then(|s| v.extend(s)); + (FunctionId::GovernanceApprove as u8).using_encoded(|s| v.extend(s)); + data.using_encoded(|s| v.extend(s)); } } v } - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) + fn using_encoded R>(&self, f: F) -> R { + f(self.encode().as_slice()) } } @@ -293,19 +289,15 @@ impl Slicable for Transaction { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); - self.signed.as_slice_then(|s| v.extend(s)); - self.nonce.as_slice_then(|s| v.extend(s)); - self.function.as_slice_then(|s| v.extend(s)); + self.signed.using_encoded(|s| v.extend(s)); + self.nonce.using_encoded(|s| v.extend(s)); + self.function.using_encoded(|s| v.extend(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } impl ::codec::NonTrivialSlicable for Transaction {} @@ -334,27 +326,23 @@ impl Slicable for UncheckedTransaction { }) } - fn to_vec(&self) -> Vec { + fn encode(&self) -> Vec { let mut v = Vec::new(); // need to prefix with the total length as u32 to ensure it's binary comptible with // Vec. we'll make room for it here, then overwrite once we know the length. v.extend(&[0u8; 4]); - self.transaction.signed.as_slice_then(|s| v.extend(s)); - self.transaction.nonce.as_slice_then(|s| v.extend(s)); - self.transaction.function.as_slice_then(|s| v.extend(s)); - self.signature.as_slice_then(|s| v.extend(s)); + self.transaction.signed.using_encoded(|s| v.extend(s)); + self.transaction.nonce.using_encoded(|s| v.extend(s)); + self.transaction.function.using_encoded(|s| v.extend(s)); + self.signature.using_encoded(|s| v.extend(s)); let length = (v.len() - 4) as u32; - length.as_slice_then(|s| v[0..4].copy_from_slice(s)); + length.using_encoded(|s| v[0..4].copy_from_slice(s)); v } - - fn as_slice_then R>(&self, f: F) -> R { - f(self.to_vec().as_slice()) - } } impl ::codec::NonTrivialSlicable for UncheckedTransaction {} @@ -396,7 +384,7 @@ mod tests { // df0f0200 // 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - let v = Slicable::to_vec(&tx); + let v = Slicable::encode(&tx); println!("{}", HexDisplay::from(&v)); assert_eq!(UncheckedTransaction::decode(&mut &v[..]).unwrap(), tx); } diff --git a/polkadot/runtime/Cargo.toml b/polkadot/runtime/Cargo.toml index d3b3cfb34f..c8decd0462 100644 --- a/polkadot/runtime/Cargo.toml +++ b/polkadot/runtime/Cargo.toml @@ -10,6 +10,7 @@ log = { version = "0.3", optional = true } substrate-codec = { path = "../../substrate/codec" } substrate-runtime-std = { path = "../../substrate/runtime-std" } substrate-runtime-io = { path = "../../substrate/runtime-io" } +substrate-runtime-support = { path = "../../substrate/runtime-support" } substrate-primitives = { path = "../../substrate/primitives" } polkadot-primitives = { path = "../primitives" } @@ -19,6 +20,7 @@ std = [ "substrate-codec/std", "substrate-runtime-std/std", "substrate-runtime-io/std", + "substrate-runtime-support/std", "substrate-primitives/std", "polkadot-primitives/std", "log" diff --git a/polkadot/runtime/src/support/environment.rs b/polkadot/runtime/src/environment.rs similarity index 100% rename from polkadot/runtime/src/support/environment.rs rename to polkadot/runtime/src/environment.rs diff --git a/polkadot/runtime/src/genesismap.rs b/polkadot/runtime/src/genesismap.rs index 7cb0aba5b6..4100f411b0 100644 --- a/polkadot/runtime/src/genesismap.rs +++ b/polkadot/runtime/src/genesismap.rs @@ -17,11 +17,12 @@ //! Tool for creating the genesis block. use codec::{KeyedVec, Joiner}; -use polkadot_primitives::{BlockNumber, Block, AccountId}; use std::collections::HashMap; use runtime_io::twox_128; +use runtime_support::Hashable; +use primitives::Block; +use polkadot_primitives::{BlockNumber, AccountId}; use runtime::staking::Balance; -use support::Hashable; /// Configuration of a general Polkadot genesis block. pub struct GenesisConfig { @@ -52,32 +53,32 @@ impl GenesisConfig { pub fn genesis_map(&self) -> HashMap, Vec> { let wasm_runtime = include_bytes!("../wasm/genesis.wasm").to_vec(); vec![ - (&b"gov:apr"[..], vec![].join(&self.approval_ratio)), - (&b"ses:len"[..], vec![].join(&self.session_length)), - (&b"ses:val:len"[..], vec![].join(&(self.validators.len() as u32))), - (&b"sta:wil:len"[..], vec![].join(&0u32)), - (&b"sta:spe"[..], vec![].join(&self.sessions_per_era)), - (&b"sta:vac"[..], vec![].join(&(self.validators.len() as u32))), - (&b"sta:era"[..], vec![].join(&0u64)), + (&b"gov:apr"[..], vec![].and(&self.approval_ratio)), + (&b"ses:len"[..], vec![].and(&self.session_length)), + (&b"ses:val:len"[..], vec![].and(&(self.validators.len() as u32))), + (&b"sta:wil:len"[..], vec![].and(&0u32)), + (&b"sta:spe"[..], vec![].and(&self.sessions_per_era)), + (&b"sta:vac"[..], vec![].and(&(self.validators.len() as u32))), + (&b"sta:era"[..], vec![].and(&0u64)), ].into_iter() .map(|(k, v)| (k.into(), v)) .chain(self.validators.iter() .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(b"ses:val:"), vec![].join(account))) + .map(|(i, account)| ((i as u32).to_keyed_vec(b"ses:val:"), vec![].and(account))) ).chain(self.authorities.iter() .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].join(account))) + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].and(account))) ).chain(self.balances.iter() - .map(|&(account, balance)| (account.to_keyed_vec(b"sta:bal:"), vec![].join(&balance))) + .map(|&(account, balance)| (account.to_keyed_vec(b"sta:bal:"), vec![].and(&balance))) ) .map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec())) .chain(vec![ (b":code"[..].into(), wasm_runtime), - (b":auth:len"[..].into(), vec![].join(&(self.authorities.len() as u32))), + (b":auth:len"[..].into(), vec![].and(&(self.authorities.len() as u32))), ].into_iter()) .chain(self.authorities.iter() .enumerate() - .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].join(account))) + .map(|(i, account)| ((i as u32).to_keyed_vec(b":auth:"), vec![].and(account))) ) .collect() } @@ -86,6 +87,6 @@ impl GenesisConfig { pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap, Vec> { use codec::Slicable; map![ - twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => genesis_block.header.blake2_256().to_vec() + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => genesis_block.header.blake2_256().encode() ] } diff --git a/polkadot/runtime/src/lib.rs b/polkadot/runtime/src/lib.rs index 10d37aacae..6eb3a259fe 100644 --- a/polkadot/runtime/src/lib.rs +++ b/polkadot/runtime/src/lib.rs @@ -19,28 +19,22 @@ #![cfg_attr(not(feature = "std"), no_std)] extern crate substrate_runtime_std as rstd; +#[macro_use] extern crate substrate_runtime_io as runtime_io; +extern crate substrate_runtime_support as runtime_support; -#[macro_use] -extern crate substrate_runtime_io as runtime_io; - -#[cfg(feature = "std")] -extern crate rustc_hex; +#[cfg(feature = "std")] extern crate rustc_hex; extern crate substrate_codec as codec; -extern crate substrate_primitives; +#[cfg(feature = "std")] #[macro_use] extern crate substrate_primitives as primitives; extern crate polkadot_primitives; -#[cfg(test)] -#[macro_use] -extern crate hex_literal; +#[cfg(test)] #[macro_use] extern crate hex_literal; -#[macro_use] -pub mod support; +pub mod environment; pub mod runtime; pub mod api; -#[cfg(feature = "std")] -pub mod genesismap; +#[cfg(feature = "std")] pub mod genesismap; /// Type definitions and helpers for transactions. pub mod transaction { @@ -72,7 +66,7 @@ pub mod transaction { /// /// On failure, return the transaction back. pub fn check(tx: UncheckedTransaction) -> Result { - let msg = ::codec::Slicable::to_vec(&tx.transaction); + let msg = ::codec::Slicable::encode(&tx.transaction); if ::runtime_io::ed25519_verify(&tx.signature.0, &msg, &tx.transaction.signed) { Ok(CheckedTransaction(tx)) } else { diff --git a/polkadot/runtime/src/runtime/consensus.rs b/polkadot/runtime/src/runtime/consensus.rs index bbc62eeba0..7d50f6abd4 100644 --- a/polkadot/runtime/src/runtime/consensus.rs +++ b/polkadot/runtime/src/runtime/consensus.rs @@ -17,7 +17,7 @@ //! Conensus module for runtime; manages the authority set ready for the native code. use rstd::prelude::*; -use support::storage::unhashed::StorageVec; +use runtime_support::storage::unhashed::StorageVec; use polkadot_primitives::SessionKey; struct AuthorityStorageVec {} diff --git a/polkadot/runtime/src/runtime/governance.rs b/polkadot/runtime/src/runtime/governance.rs index a7d2baf677..4ac1e17a33 100644 --- a/polkadot/runtime/src/runtime/governance.rs +++ b/polkadot/runtime/src/runtime/governance.rs @@ -27,7 +27,7 @@ use rstd::prelude::*; use codec::KeyedVec; -use support::storage; +use runtime_support::storage; use polkadot_primitives::{Proposal, AccountId, Hash, BlockNumber}; use runtime::{staking, system, session}; @@ -147,7 +147,8 @@ mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; + use environment::with_env; use polkadot_primitives::{AccountId, Proposal}; use runtime::{staking, session}; @@ -157,19 +158,19 @@ mod tests { let three = [3u8; 32]; TestExternalities { storage: map![ - twox_128(APPROVALS_REQUIRED).to_vec() => vec![].join(&667u32), - twox_128(b"ses:len").to_vec() => vec![].join(&1u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + 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), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), - twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(b"sta:wil:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), - twox_128(b"sta:spe").to_vec() => vec![].join(&1u64), - twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), - twox_128(b"sta:era").to_vec() => vec![].join(&1u64) + 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) ], } } diff --git a/polkadot/runtime/src/runtime/parachains.rs b/polkadot/runtime/src/runtime/parachains.rs index c039892c03..56559ee356 100644 --- a/polkadot/runtime/src/runtime/parachains.rs +++ b/polkadot/runtime/src/runtime/parachains.rs @@ -18,8 +18,9 @@ use rstd::prelude::*; use codec::{Slicable, Joiner}; +use runtime_support::{Hashable, storage}; +use environment::with_env; use runtime::session; -use support::{Hashable, with_env, storage}; use polkadot_primitives::parachain::{Id, Chain, DutyRoster}; const PARACHAIN_COUNT: &[u8] = b"par:cou"; @@ -43,7 +44,7 @@ pub fn calculate_duty_roster() -> DutyRoster { let mut roles_gua = roles_val.clone(); let h = with_env(|e| e.parent_hash.clone()); - let mut seed = Vec::::new().join(&h).join(b"validator_role_pairs").blake2_256(); + let mut seed = Vec::::new().and(&h).and(b"validator_role_pairs").blake2_256(); // shuffle for i in 0..(validator_count - 1) { @@ -78,13 +79,13 @@ mod tests { use super::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; use runtime::{consensus, session}; fn simple_setup() -> TestExternalities { TestExternalities { storage: map![ - twox_128(b"ses:val:len").to_vec() => vec![].join(&8u32), - twox_128(b"par:cou").to_vec() => vec![].join(&2u32) + twox_128(b"ses:val:len").to_vec() => vec![].and(&8u32), + twox_128(b"par:cou").to_vec() => vec![].and(&2u32) ], } } diff --git a/polkadot/runtime/src/runtime/session.rs b/polkadot/runtime/src/runtime/session.rs index 56a12f05c0..9252e9774d 100644 --- a/polkadot/runtime/src/runtime/session.rs +++ b/polkadot/runtime/src/runtime/session.rs @@ -19,7 +19,7 @@ use rstd::prelude::*; use codec::KeyedVec; -use support::{storage, StorageVec}; +use runtime_support::{storage, StorageVec}; use polkadot_primitives::{AccountId, SessionKey, BlockNumber}; use runtime::{system, staking, consensus}; @@ -139,19 +139,20 @@ mod tests { use super::internal::*; use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; + use environment::with_env; use polkadot_primitives::AccountId; use runtime::{consensus, session}; fn simple_setup() -> TestExternalities { TestExternalities { storage: map![ - twox_128(SESSION_LENGTH).to_vec() => vec![].join(&2u64), + twox_128(SESSION_LENGTH).to_vec() => vec![].and(&2u64), // the validators (10, 20, ...) - twox_128(b"ses:val:len").to_vec() => vec![].join(&2u32), + twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32), twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32], twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32], // initial session keys (11, 21, ...) - b":auth:len".to_vec() => vec![].join(&2u32), + 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] ], } diff --git a/polkadot/runtime/src/runtime/staking.rs b/polkadot/runtime/src/runtime/staking.rs index 210c518146..b281bc5cd5 100644 --- a/polkadot/runtime/src/runtime/staking.rs +++ b/polkadot/runtime/src/runtime/staking.rs @@ -20,7 +20,7 @@ use rstd::prelude::*; use rstd::cell::RefCell; use runtime_io::print; use codec::KeyedVec; -use support::{storage, StorageVec}; +use runtime_support::{storage, StorageVec}; use polkadot_primitives::{BlockNumber, AccountId}; use runtime::{system, session, governance}; @@ -215,7 +215,8 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{KeyedVec, Joiner}; - use support::{one, two, with_env}; + use runtime_support::{one, two}; + use environment::with_env; use polkadot_primitives::AccountId; use runtime::{staking, session}; @@ -227,17 +228,17 @@ mod tests { let four = [4u8; 32]; let mut t = TestExternalities { storage: map![ - twox_128(b"ses:len").to_vec() => vec![].join(&1u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&2u32), + 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], twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => vec![20; 32], - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].join(&2u64), - twox_128(VALIDATOR_COUNT).to_vec() => vec![].join(&2u32), - twox_128(BONDING_DURATION).to_vec() => vec![].join(&3u64), - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&10u64), - twox_128(&two.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&20u64), - twox_128(&three.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&30u64), - twox_128(&four.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&40u64) + twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64), + twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&2u32), + twox_128(BONDING_DURATION).to_vec() => vec![].and(&3u64), + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64), + 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, || { @@ -296,8 +297,8 @@ mod tests { #[test] fn staking_eras_work() { let mut t = TestExternalities { storage: map![ - twox_128(b"ses:len").to_vec() => vec![].join(&1u64), - twox_128(SESSIONS_PER_ERA).to_vec() => vec![].join(&2u64) + 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); @@ -363,7 +364,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&42u64) + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64) ], }; with_externalities(&mut t, || { @@ -378,7 +379,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&111u64) + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64) ], }; with_externalities(&mut t, || { @@ -395,7 +396,7 @@ mod tests { let two = two(); let mut t = TestExternalities { storage: map![ - twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].join(&111u64) + twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64) ], }; with_externalities(&mut t, || { diff --git a/polkadot/runtime/src/runtime/system.rs b/polkadot/runtime/src/runtime/system.rs index a82d911ea9..2a8519a683 100644 --- a/polkadot/runtime/src/runtime/system.rs +++ b/polkadot/runtime/src/runtime/system.rs @@ -21,7 +21,8 @@ use rstd::prelude::*; use rstd::mem; use runtime_io::{print, storage_root, enumerated_trie_root}; use codec::{KeyedVec, Slicable}; -use support::{Hashable, storage, with_env}; +use runtime_support::{Hashable, storage}; +use environment::with_env; use polkadot_primitives::{AccountId, Hash, TxOrder, BlockNumber, Block, Header, UncheckedTransaction, Function, Log}; use runtime::{staking, session}; @@ -184,7 +185,7 @@ fn initial_checks(block: &Block) { ); // check transaction trie root represents the transactions. - let txs = block.transactions.iter().map(Slicable::to_vec).collect::>(); + let txs = block.transactions.iter().map(Slicable::encode).collect::>(); let txs = txs.iter().map(Vec::as_slice).collect::>(); let txs_root = enumerated_trie_root(&txs).into(); info_expect_equal_hash(&header.transaction_root, &txs_root); @@ -213,7 +214,7 @@ fn post_finalise(header: &Header) { #[cfg(feature = "std")] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { - use support::HexDisplay; + use primitives::hexdisplay::HexDisplay; if given != expected { println!("Hash: given={}, expected={}", HexDisplay::from(&given.0), HexDisplay::from(&expected.0)); } @@ -235,7 +236,9 @@ mod tests { use runtime_io::{with_externalities, twox_128, TestExternalities}; use codec::{Joiner, KeyedVec, Slicable}; - use support::{StaticHexInto, HexDisplay, one, two}; + use runtime_support::{one, two}; + use environment::with_env; + use primitives::hexdisplay::HexDisplay; use polkadot_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function}; use runtime::staking; @@ -254,7 +257,7 @@ mod tests { nonce: 0, function: Function::StakingTransfer(two, 69), }, - signature: "5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05".parse().unwrap(), + signature: hex!("5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05").into(), }; with_externalities(&mut t, || { @@ -270,20 +273,20 @@ mod tests { let three = [3u8; 32]; TestExternalities { storage: map![ - twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), - twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), - twox_128(b"ses:len").to_vec() => vec![].join(&2u64), - twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&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), + twox_128(b"ses:val:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), - twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(b"sta:wil:len").to_vec() => vec![].and(&3u32), twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), - twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), - twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), - twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(b"sta:spe").to_vec() => vec![].and(&2u64), + 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] ], } } diff --git a/polkadot/runtime/src/runtime/timestamp.rs b/polkadot/runtime/src/runtime/timestamp.rs index 45ebdcbe70..c64a511ad0 100644 --- a/polkadot/runtime/src/runtime/timestamp.rs +++ b/polkadot/runtime/src/runtime/timestamp.rs @@ -16,7 +16,7 @@ //! Timestamp manager: just handles the current timestamp. -use support::storage; +use runtime_support::storage; pub type Timestamp = u64; @@ -48,7 +48,7 @@ mod tests { #[test] fn timestamp_works() { let mut t = TestExternalities { storage: map![ - twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].join(&42u64) + twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].and(&42u64) ], }; with_externalities(&mut t, || { diff --git a/polkadot/runtime/src/support/hashable.rs b/polkadot/runtime/src/support/hashable.rs deleted file mode 100644 index b6ad775396..0000000000 --- a/polkadot/runtime/src/support/hashable.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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 . - -//! Hashable trait. - -use codec::Slicable; -use runtime_io::{blake2_256, twox_128, twox_256}; - -pub trait Hashable: Sized { - fn blake2_256(&self) -> [u8; 32]; - fn twox_128(&self) -> [u8; 16]; - fn twox_256(&self) -> [u8; 32]; -} - -impl Hashable for T { - fn blake2_256(&self) -> [u8; 32] { - blake2_256(&self.to_vec()) - } - fn twox_128(&self) -> [u8; 16] { - twox_128(&self.to_vec()) - } - fn twox_256(&self) -> [u8; 32] { - twox_256(&self.to_vec()) - } -} diff --git a/polkadot/runtime/src/support/mod.rs b/polkadot/runtime/src/support/mod.rs deleted file mode 100644 index 652fb82aa6..0000000000 --- a/polkadot/runtime/src/support/mod.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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 . - -//! Support code for the runtime. - -mod environment; -pub mod storage; -mod hashable; -#[cfg(feature = "std")] -mod statichex; -#[macro_use] -#[cfg(feature = "std")] -mod testing; - -pub use self::environment::with_env; -pub use self::storage::StorageVec; -pub use self::hashable::Hashable; - -#[cfg(feature = "std")] -pub use self::statichex::{StaticHexConversion, StaticHexInto}; - -#[cfg(feature = "std")] -pub use self::testing::{AsBytesRef, HexDisplay, one, two}; diff --git a/polkadot/runtime/src/support/statichex.rs b/polkadot/runtime/src/support/statichex.rs deleted file mode 100644 index b750a8ca10..0000000000 --- a/polkadot/runtime/src/support/statichex.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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 . - -//! Interpret a static string of hex as a desired type. - -use rustc_hex::FromHex; - -/// Trait to allow conversion from a static hex string to an instance. -pub trait StaticHexConversion: Sized { - /// Convert the static str into Self. Use just like `From::from`. - fn from_static_hex(hex: &'static str) -> Self; -} - -macro_rules! impl_sizes { - ( $( $t:expr ),* ) => { $( - impl StaticHexConversion for [u8; $t] { - fn from_static_hex(hex: &'static str) -> Self { - let mut r = [0u8; $t]; - r.copy_from_slice(&FromHex::from_hex(hex).unwrap()); - r - } - } - )* } -} - -impl StaticHexConversion for Vec { - fn from_static_hex(hex: &'static str) -> Self { - FromHex::from_hex(hex).unwrap() - } -} - -impl_sizes!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 451, 42, 43, 44, 45, 46, 47, 48, - 56, 64, 80, 96, 112, 128); - -/// Trait to allow converting from itself (only implemented for a static str) into some useful -/// type (which must implement `StaticHexConversion`). -pub trait StaticHexInto { - /// Convert self (i.e. a static str) into the appropriate type. Use just like `Into::into`. - fn convert(self) -> T; -} - -impl StaticHexInto for &'static str { - fn convert(self) -> T { - T::from_static_hex(self) - } -} diff --git a/polkadot/runtime/src/support/storage.rs b/polkadot/runtime/src/support/storage.rs deleted file mode 100644 index 8306906914..0000000000 --- a/polkadot/runtime/src/support/storage.rs +++ /dev/null @@ -1,373 +0,0 @@ -// 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 . - -//! Stuff to do with the runtime's storage. - -use rstd::prelude::*; -use runtime_io::{self, twox_128}; -use codec::{Input, Slicable, KeyedVec}; - -// TODO: consider using blake256 to avoid possible preimage attack. - -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); - 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 key = twox_128(key); - let mut input = IncrementalInput { - key: &key[..], - pos: 0, - }; - - Slicable::decode(&mut input) -} - -/// Return the value of the item in storage under `key`, or the type's default if there is no -/// explicit entry. -pub fn get_or_default(key: &[u8]) -> T { - get(key).unwrap_or_else(Default::default) -} - -/// Return the value of the item in storage under `key`, or `default_value` if there is no -/// explicit entry. -pub fn get_or(key: &[u8], default_value: T) -> T { - get(key).unwrap_or(default_value) -} - -/// Return the value of the item in storage under `key`, or `default_value()` if there is no -/// explicit entry. -pub fn get_or_else T>(key: &[u8], default_value: F) -> T { - get(key).unwrap_or_else(default_value) -} - -/// Please `value` in storage under `key`. -pub fn put(key: &[u8], value: &T) { - value.as_slice_then(|slice| runtime_io::set_storage(&twox_128(key)[..], slice)); -} - -/// Please `value` in storage under `key`. -pub fn place(key: &[u8], value: T) { - value.as_slice_then(|slice| runtime_io::set_storage(&twox_128(key)[..], slice)); -} - -/// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. -pub fn take(key: &[u8]) -> Option { - let r = get(key); - if r.is_some() { - kill(key); - } - r -} - -/// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, -/// the default for its type. -pub fn take_or_default(key: &[u8]) -> T { - take(key).unwrap_or_else(Default::default) -} - -/// Return the value of the item in storage under `key`, or `default_value` if there is no -/// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or(key: &[u8], default_value: T) -> T { - take(key).unwrap_or(default_value) -} - -/// Return the value of the item in storage under `key`, or `default_value()` if there is no -/// explicit entry. Ensure there is no explicit entry on return. -pub fn take_or_else T>(key: &[u8], default_value: F) -> T { - take(key).unwrap_or_else(default_value) -} - -/// 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 -} - -/// Ensure `key` has no explicit entry in storage. -pub fn kill(key: &[u8]) { - runtime_io::set_storage(&twox_128(key)[..], b""); -} - -/// Get a Vec of bytes from storage. -pub fn get_raw(key: &[u8]) -> Vec { - runtime_io::storage(&twox_128(key)[..]) -} - -/// Put a raw byte slice into storage. -pub fn put_raw(key: &[u8], value: &[u8]) { - runtime_io::set_storage(&twox_128(key)[..], value) -} - -/// A trait to conveniently store a vector of storable data. -// TODO: add iterator support -pub trait StorageVec { - type Item: Default + Sized + Slicable; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: &[Self::Item]) { - Self::set_count(items.len() as u32); - items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i)); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&index.to_keyed_vec(Self::PREFIX), item); - } - } - - 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())); - put(&b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) - } -} - -pub mod unhashed { - 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 mut input = IncrementalInput { - key, - pos: 0, - }; - - T::decode(&mut input) - } - - /// Return the value of the item in storage under `key`, or the type's default if there is no - /// explicit entry. - pub fn get_or_default(key: &[u8]) -> T { - get(key).unwrap_or_else(Default::default) - } - - /// Return the value of the item in storage under `key`, or `default_value` if there is no - /// explicit entry. - pub fn get_or(key: &[u8], default_value: T) -> T { - get(key).unwrap_or(default_value) - } - - /// Return the value of the item in storage under `key`, or `default_value()` if there is no - /// explicit entry. - pub fn get_or_else T>(key: &[u8], default_value: F) -> T { - get(key).unwrap_or_else(default_value) - } - - /// Please `value` in storage under `key`. - pub fn put(key: &[u8], value: &T) { - value.as_slice_then(|slice| runtime_io::set_storage(key, slice)); - } - - /// Please `value` in storage under `key`. - pub fn place(key: &[u8], value: T) { - value.as_slice_then(|slice| runtime_io::set_storage(key, slice)); - } - - /// Remove `key` from storage, returning its value if it had an explicit entry or `None` otherwise. - pub fn take(key: &[u8]) -> Option { - let r = get(key); - if r.is_some() { - kill(key); - } - r - } - - /// Remove `key` from storage, returning its value, or, if there was no explicit entry in storage, - /// the default for its type. - pub fn take_or_default(key: &[u8]) -> T { - take(key).unwrap_or_else(Default::default) - } - - /// Return the value of the item in storage under `key`, or `default_value` if there is no - /// explicit entry. Ensure there is no explicit entry on return. - pub fn take_or(key: &[u8], default_value: T) -> T { - take(key).unwrap_or(default_value) - } - - /// Return the value of the item in storage under `key`, or `default_value()` if there is no - /// explicit entry. Ensure there is no explicit entry on return. - pub fn take_or_else T>(key: &[u8], default_value: F) -> T { - take(key).unwrap_or_else(default_value) - } - - /// 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 - } - - /// Ensure `key` has no explicit entry in storage. - pub fn kill(key: &[u8]) { - runtime_io::set_storage(key, b""); - } - - /// Get a Vec of bytes from storage. - pub fn get_raw(key: &[u8]) -> Vec { - runtime_io::storage(key) - } - - /// Put a raw byte slice into storage. - pub fn put_raw(key: &[u8], value: &[u8]) { - runtime_io::set_storage(key, value) - } - - /// A trait to conveniently store a vector of storable data. - // TODO: add iterator support - pub trait StorageVec { - type Item: Default + Sized + Slicable; - const PREFIX: &'static [u8]; - - /// Get the current set of items. - fn items() -> Vec { - (0..Self::count()).into_iter().map(Self::item).collect() - } - - /// Set the current set of items. - fn set_items(items: &[Self::Item]) { - Self::set_count(items.len() as u32); - items.iter().enumerate().for_each(|(v, ref i)| Self::set_item(v as u32, i)); - } - - fn set_item(index: u32, item: &Self::Item) { - if index < Self::count() { - put(&index.to_keyed_vec(Self::PREFIX), item); - } - } - - 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())); - put(&b"len".to_keyed_vec(Self::PREFIX), &count); - } - - fn count() -> u32 { - get_or_default(&b"len".to_keyed_vec(Self::PREFIX)) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::collections::HashMap; - use support::HexDisplay; - use runtime_io::{storage, twox_128, TestExternalities, with_externalities}; - - #[test] - fn integers_can_be_stored() { - let mut t = TestExternalities { storage: HashMap::new(), }; - with_externalities(&mut t, || { - let x = 69u32; - put(b":test", &x); - let y: u32 = get(b":test").unwrap(); - assert_eq!(x, y); - }); - with_externalities(&mut t, || { - let x = 69426942i64; - put(b":test", &x); - let y: i64 = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn bools_can_be_stored() { - let mut t = TestExternalities { storage: HashMap::new(), }; - with_externalities(&mut t, || { - let x = true; - put(b":test", &x); - let y: bool = get(b":test").unwrap(); - assert_eq!(x, y); - }); - - with_externalities(&mut t, || { - let x = false; - put(b":test", &x); - let y: bool = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn vecs_can_be_retrieved() { - let mut t = TestExternalities { storage: HashMap::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")))); - let y = get::>(b":test").unwrap(); - assert_eq!(x, y); - - }); - } - - #[test] - fn vecs_can_be_stored() { - let mut t = TestExternalities { storage: HashMap::new(), }; - let x = b"Hello world".to_vec(); - - with_externalities(&mut t, || { - put(b":test", &x); - }); - - println!("Ext is {:?}", t); - with_externalities(&mut t, || { - println!("Hex: {}", HexDisplay::from(&storage(&twox_128(b":test")))); - let y: Vec = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } - - #[test] - fn proposals_can_be_stored() { - use polkadot_primitives::Proposal; - let mut t = TestExternalities { storage: HashMap::new(), }; - with_externalities(&mut t, || { - let x = Proposal::StakingSetSessionsPerEra(25519); - put(b":test", &x); - let y: Proposal = get(b":test").unwrap(); - assert_eq!(x, y); - }); - } -} diff --git a/polkadot/runtime/src/support/testing.rs b/polkadot/runtime/src/support/testing.rs deleted file mode 100644 index a230ded26f..0000000000 --- a/polkadot/runtime/src/support/testing.rs +++ /dev/null @@ -1,83 +0,0 @@ -// 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 . - -//! Testing helpers. - -use polkadot_primitives::AccountId; -use super::statichex::StaticHexInto; - -#[macro_export] -macro_rules! map { - ($( $name:expr => $value:expr ),*) => ( - vec![ $( ( $name, $value ) ),* ].into_iter().collect() - ) -} - -/// One account (to which we know the secret key). -pub fn one() -> AccountId { - "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() -} -/// Another account (secret key known). -pub fn two() -> AccountId { - "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() -} - -/// Hex display, this time for no_std. See main codebase for documentation. -pub struct HexDisplay<'a>(&'a [u8]); - -impl<'a> HexDisplay<'a> { - /// See main codebase for documentation. - pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } -} - -impl<'a> ::std::fmt::Display for HexDisplay<'a> { - fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for byte in self.0 { - try!( fmtr.write_fmt(format_args!("{:02x}", byte))); - } - Ok(()) - } -} - -/// See main codebase for documentation. -pub trait AsBytesRef { - /// See main codebase for documentation. - fn as_bytes_ref(&self) -> &[u8]; -} - -impl AsBytesRef for [u8] { - fn as_bytes_ref(&self) -> &[u8] { &self } -} - -impl<'a> AsBytesRef for &'a[u8] { - fn as_bytes_ref(&self) -> &[u8] { self } -} - -impl AsBytesRef for Vec { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } -} - -macro_rules! impl_non_endians { - ( $( $t:ty ),* ) => { $( - impl AsBytesRef for $t { - fn as_bytes_ref(&self) -> &[u8] { &self[..] } - } - )* } -} - -impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8], - [u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40], - [u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); diff --git a/polkadot/runtime/wasm/Cargo.lock b/polkadot/runtime/wasm/Cargo.lock index 506b138461..1ed330a400 100644 --- a/polkadot/runtime/wasm/Cargo.lock +++ b/polkadot/runtime/wasm/Cargo.lock @@ -395,6 +395,7 @@ dependencies = [ "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", ] [[package]] @@ -638,6 +639,19 @@ dependencies = [ "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "substrate-runtime-support" +version = "0.1.0" +dependencies = [ + "environmental 0.1.0", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-primitives 0.1.0", + "substrate-runtime-io 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-state-machine 0.1.0", +] + [[package]] name = "substrate-state-machine" version = "0.1.0" diff --git a/polkadot/runtime/wasm/Cargo.toml b/polkadot/runtime/wasm/Cargo.toml index 10bfbc330f..2452ce9bd2 100644 --- a/polkadot/runtime/wasm/Cargo.toml +++ b/polkadot/runtime/wasm/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["cdylib"] substrate-codec = { path = "../../../substrate/codec", default-features = false } substrate-runtime-std = { path = "../../../substrate/runtime-std", default-features = false } substrate-runtime-io = { path = "../../../substrate/runtime-io", default-features = false } +substrate-runtime-support = { path = "../../../substrate/runtime-support", default-features = false } substrate-primitives = { path = "../../../substrate/primitives", default-features = false } polkadot-primitives = { path = "../../primitives", default-features = false } @@ -19,8 +20,9 @@ std = [ "substrate-codec/std", "substrate-runtime-io/std", "substrate-runtime-std/std", + "substrate-runtime-support/std", "substrate-primitives/std", - "polkadot-primitives/std" + "polkadot-primitives/std", ] [profile.release] diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 5418e0432c..e56ad51f9a 100644 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 98dabfb1bb..6341c45abc 100644 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ