diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index c139749441f71c513fbf46d95dc681bd443b9635..93f09afe025b81e9ef9932e1a17f142e179fa879 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -986,6 +986,7 @@ dependencies = [ "assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "native-runtime 0.1.0", "parity-wasm 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)", "polkadot-primitives 0.1.0", diff --git a/substrate/executor/Cargo.toml b/substrate/executor/Cargo.toml index 41fdef97057f6d957178e86cdf75d4643ef7ac0c..18e7aa61bc2eb05ddb7d4c8212a796cd2b406a18 100644 --- a/substrate/executor/Cargo.toml +++ b/substrate/executor/Cargo.toml @@ -16,6 +16,7 @@ rustc-hex = "1.0.0" native-runtime = { path = "../native-runtime", version = "0.1" } runtime-std = { path = "../native-runtime/std", version = "0.1" } triehash = "0.1.0" +hex-literal = "0.1.0" [dev-dependencies] assert_matches = "1.1" diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index e4ed7f95b0e8a4c5531da6e3f08f7f7bf26b89c9..f82518f03b38f5755397a1149d2736c4195e2e88 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -38,6 +38,10 @@ extern crate native_runtime; extern crate runtime_std; extern crate triehash; +#[cfg(test)] +#[macro_use] +extern crate hex_literal; + #[macro_use] extern crate error_chain; diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index 6cf7ac6c313c67fda75c5c6dd8c7819bcc4d2738..afa72e7aaaff0b991cc890f10a89dfe76be994c6 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -42,8 +42,9 @@ impl CodeExecutor for NativeExecutor { mod tests { use super::*; use runtime_std::TestExternalities; - use native_runtime::codec::KeyedVec; - use native_runtime::support::{one, two, StaticHexInto}; + use native_runtime::codec::{KeyedVec, Joiner, Slicable}; + use native_runtime::support::{one, two, StaticHexInto, Hashable}; + use native_runtime::primitives::*; use native_runtime::runtime::staking::balance; use primitives::twox_128; @@ -108,4 +109,96 @@ mod tests { assert_eq!(balance(&two), 69); }); } + + fn new_test_ext() -> TestExternalities { + let one = one(); + let two = two(); + let three = [3u8; 32]; + + TestExternalities { storage: map![ + twox_128(&0u64.to_keyed_vec(b"sys:old:")).to_vec() => [69u8; 32].to_vec(), + twox_128(b"gov:apr").to_vec() => vec![].join(&667u32), + twox_128(b"ses:len").to_vec() => vec![].join(&2u64), + twox_128(b"ses:val:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"ses:val:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"ses:val:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"ses:val:")).to_vec() => three.to_vec(), + twox_128(b"sta:wil:len").to_vec() => vec![].join(&3u32), + twox_128(&0u32.to_keyed_vec(b"sta:wil:")).to_vec() => one.to_vec(), + twox_128(&1u32.to_keyed_vec(b"sta:wil:")).to_vec() => two.to_vec(), + twox_128(&2u32.to_keyed_vec(b"sta:wil:")).to_vec() => three.to_vec(), + twox_128(b"sta:spe").to_vec() => vec![].join(&2u64), + twox_128(b"sta:vac").to_vec() => vec![].join(&3u64), + twox_128(b"sta:era").to_vec() => vec![].join(&0u64), + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] + ], } + } + + use primitives::ed25519::Pair; + fn secret_for(who: &AccountID) -> Option<Pair> { + match who { + x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), + x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), + _ => None, + } + } + + fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) { + use triehash::ordered_trie_root; + let one = one(); + let two = two(); + + let transactions = txs.into_iter().map(|transaction| { + let signature = secret_for(&transaction.signed).unwrap() + .sign(&transaction.to_vec()) + .inner(); + UncheckedTransaction { transaction, signature } + }).collect::<Vec<_>>(); + + let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0; + + let header = Header { + parent_hash, + number, + state_root, + transaction_root, + digest: Digest { logs: vec![], }, + }; + let hash = header.blake2_256(); + + (Block { header, transactions }.to_vec(), hash) + } + + fn block1() -> Vec<u8> { + construct_block(1, [69u8; 32], hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"), vec![Transaction { + signed: one(), + nonce: 0, + function: Function::StakingTransfer, + input_data: vec![].join(&two()).join(&69u64), + }]).0 + } + + #[test] + fn full_native_block_import_works() { + let mut t = new_test_ext(); + + NativeExecutor.call(&mut t, COMPACT_CODE, "execute_block", &CallData(block1())).unwrap(); + + runtime_std::with_externalities(&mut t, || { + assert_eq!(balance(&one()), 42); + assert_eq!(balance(&two()), 69); + }); + } + + #[test] + fn full_wasm_block_import_works() { + let mut t = new_test_ext(); + + WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &CallData(block1())).unwrap(); + + runtime_std::with_externalities(&mut t, || { + assert_eq!(balance(&one()), 42); + assert_eq!(balance(&two()), 69); + }); + } } diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index e1e4f0b6d9273c4b7df489a93c111d75a47b8f07..ff1b35250e20cab9500f50a0d54cec056c5aca8a 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -169,7 +169,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, let r = this.ext.storage_root(); this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; }, - ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8) => { + ext_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8) => { let values = (0..lens_len) .map(|i| this.memory.read_primitive(lens_data + i * 4)) .collect::<::std::result::Result<Vec<u32>, DummyUserError>>()? diff --git a/substrate/primitives/src/ed25519.rs b/substrate/primitives/src/ed25519.rs index b28e0bde6e2cc4131dabaea5933936133e403f54..b44d59c0b320624bd897e861b1ca343144935139 100644 --- a/substrate/primitives/src/ed25519.rs +++ b/substrate/primitives/src/ed25519.rs @@ -55,6 +55,11 @@ impl Signature { r.copy_from_slice(data); Signature(r) } + + /// Get the inner part. + pub fn inner(self) -> [u8; 64] { + self.0 + } } impl AsRef<[u8; 64]> for Signature { diff --git a/substrate/wasm-runtime/std/src/lib.rs b/substrate/wasm-runtime/std/src/lib.rs index 3feb8c5544644d57647715c01fa7446c317e8d55..7bf583af7d4ee95348b3c1fc4440065bdf7d6db6 100644 --- a/substrate/wasm-runtime/std/src/lib.rs +++ b/substrate/wasm-runtime/std/src/lib.rs @@ -43,7 +43,7 @@ extern "C" { fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; fn ext_storage_root(result: *mut u8); - fn ext_enumerated_trie_root(values_data: *const u8, values_len: u32, lens_data: *const u32, lens_len: u32, result: *mut u8); + fn ext_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); fn ext_chain_id() -> u64; fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); @@ -90,7 +90,7 @@ pub fn enumerated_trie_root(values: &[&[u8]]) -> [u8; 32] { let mut result: [u8; 32] = Default::default(); unsafe { ext_enumerated_trie_root( - values.as_ptr(), values.len() as u32, + values.as_ptr(), lens.as_ptr(), lens.len() as u32, result.as_mut_ptr() ); 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 36fe893442daba09d8a56b0e97829c475e9426de..112a5c0223c49219fec1b962d9a9aacbddd90d17 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm index bd48f63571704caab70c0474179775593a7a8e61..c0a1caa639953c6c95e73fc03694f5daea48e9a1 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 3905e9d9113959f2da7e70433a3943645341db65..fde5fdad98d95d6b27bd4f30dbaa0ab961481346 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm index 3a909f06b3487c624a82991ec51b467cfa9996f9..3011f185a3443eb2d284bc066905bc28c7b5e59d 100644 Binary files a/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.wasm differ