diff --git a/substrate/build.sh b/substrate/build.sh new file mode 100755 index 0000000000..40a1043226 --- /dev/null +++ b/substrate/build.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +cd wasm-runtime +./build.sh +cd .. + diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index 17b1ec9025..9bea6958de 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -34,7 +34,6 @@ extern crate serde; extern crate parity_wasm; extern crate byteorder; extern crate rustc_hex; -#[macro_use] extern crate native_runtime; extern crate runtime_support; extern crate memcmp; @@ -53,8 +52,6 @@ mod native_executor; pub mod error; /// Creates new RustExecutor for contracts. -pub fn executor() -> wasm_executor::WasmExecutor { - // TODO: check what the code to execute is and use NativeExecutor if the wasm is compiled with - // matches. - wasm_executor::WasmExecutor::default() +pub fn executor() -> native_executor::NativeExecutor { + native_executor::NativeExecutor } diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index 14e08f8e80..79e6af2ea9 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -6,7 +6,7 @@ use wasm_executor::WasmExecutor; use native_runtime as runtime; use runtime_support; -struct NativeExecutor; +pub struct NativeExecutor; impl CodeExecutor for NativeExecutor { type Error = Error; @@ -46,7 +46,31 @@ mod tests { fn tx() -> Vec { "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000".convert() } #[test] - fn execution_with_native_equivalent_code_runs_native_ok() { + fn panic_execution_with_foreign_code_gives_error() { + let one = one(); + let mut t = TestExternalities { storage: map![ + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); + let r = NativeExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); + assert!(r.is_err()); + } + + #[test] + fn panic_execution_with_native_equivalent_code_gives_error() { + let one = one(); + let mut t = TestExternalities { storage: map![ + twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] + ], }; + + let native_equivalent_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); + let r = NativeExecutor.call(&mut t, &native_equivalent_code[..], "execute_transaction", &CallData(tx())); + assert!(r.is_err()); + } + + #[test] + fn successful_execution_with_native_equivalent_code_gives_ok() { let one = one(); let two = two(); @@ -55,7 +79,8 @@ mod tests { ], }; let native_equivalent_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); - NativeExecutor.call(&mut t, &native_equivalent_code[..], "execute_transaction", &CallData(tx())); + let r = NativeExecutor.call(&mut t, &native_equivalent_code[..], "execute_transaction", &CallData(tx())); + assert!(r.is_ok()); runtime_support::with_externalities(&mut t, || { assert_eq!(balance(&one), 42); @@ -64,7 +89,7 @@ mod tests { } #[test] - fn execution_with_foreign_code_runs_wasm_ok() { + fn successful_execution_with_foreign_code_gives_ok() { let one = one(); let two = two(); @@ -72,14 +97,14 @@ mod tests { twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] ], }; - let mut foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); - NativeExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); + let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); + let r = NativeExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); + println!("{:?}", r); + assert!(r.is_ok()); runtime_support::with_externalities(&mut t, || { assert_eq!(balance(&one), 42); assert_eq!(balance(&two), 69); }); } - - // TODO: test panics. } diff --git a/substrate/executor/src/wasm_executor.rs b/substrate/executor/src/wasm_executor.rs index f7d922d6fb..05cb5580eb 100644 --- a/substrate/executor/src/wasm_executor.rs +++ b/substrate/executor/src/wasm_executor.rs @@ -234,7 +234,9 @@ impl CodeExecutor for WasmExecutor { .add_argument(I32(offset as i32)) .add_argument(I32(size as i32))) .and_then(|p| module.execute_export(method, p)) - .map_err(|_| -> Error { ErrorKind::Runtime.into() })?; + .map_err(|_| -> Error { + ErrorKind::Runtime.into() + })?; if let Some(I64(r)) = returned { memory.get(r as u32, (r >> 32) as u32 as usize) @@ -250,8 +252,28 @@ mod tests { use super::*; use rustc_hex::FromHex; - use state_machine::ExternalitiesError; - use native_runtime::testing::{TestExternalities, one, two}; + use native_runtime::testing::TestExternalities; + + #[test] + fn returning_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + + let output = WasmExecutor.call(&mut ext, &test_code[..], "test_empty_return", &CallData(vec![])).unwrap(); + assert_eq!(output, vec![0u8; 0]); + } + + #[test] + fn panicking_should_work() { + let mut ext = TestExternalities::default(); + let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); + + let output = WasmExecutor.call(&mut ext, &test_code[..], "test_panic", &CallData(vec![])); + assert!(output.is_err()); + + let output = WasmExecutor.call(&mut ext, &test_code[..], "test_conditional_panic", &CallData(vec![2])); + assert!(output.is_err()); + } #[test] fn storage_should_work() { diff --git a/substrate/wasm-runtime/polkadot/src/lib.rs b/substrate/wasm-runtime/polkadot/src/lib.rs index 1134d974a7..c03fcc83c5 100644 --- a/substrate/wasm-runtime/polkadot/src/lib.rs +++ b/substrate/wasm-runtime/polkadot/src/lib.rs @@ -38,12 +38,6 @@ use runtime_support::prelude::*; use slicable::Slicable; use primitives::{Block, UncheckedTransaction}; -/// A simple test. -pub fn simple_test(input: &[u8]) -> Vec { - println!("Executing block"); - Vec::new() -} - /// Execute a block, with `input` being the canonical serialisation of the block. Returns the /// empty vector. pub fn execute_block(input: &[u8]) -> Vec { @@ -53,11 +47,12 @@ pub fn execute_block(input: &[u8]) -> Vec { /// Execute a given, serialised, transaction. Returns the empty vector. pub fn execute_transaction(input: &[u8]) -> Vec { - println!("Deserialising... {:?}", input); + if input.len() == 0 { + panic!("no transaction data given!"); + } let utx = UncheckedTransaction::from_slice(input).unwrap(); - println!("Forwarding... {:?}", utx); runtime::system::execute_transaction(&utx); - Vec::new() + input.to_vec()//Vec::new() } impl_stubs!(execute_block, execute_transaction); diff --git a/substrate/wasm-runtime/polkadot/src/runtime/system.rs b/substrate/wasm-runtime/polkadot/src/runtime/system.rs index 70348574b1..042d1af2d7 100644 --- a/substrate/wasm-runtime/polkadot/src/runtime/system.rs +++ b/substrate/wasm-runtime/polkadot/src/runtime/system.rs @@ -84,7 +84,6 @@ pub fn execute_block(mut block: Block) { /// Execute a given transaction. pub fn execute_transaction(utx: &UncheckedTransaction) { - println!("Executing..."); // Verify the signature is good. assert!(utx.ed25519_verify(), "All transactions should be properly signed"); @@ -98,8 +97,6 @@ pub fn execute_transaction(utx: &UncheckedTransaction) { // increment nonce in storage (expected_nonce + 1).store(&nonce_key); - println!("Dispatching..."); - // decode parameters and dispatch tx.function.dispatch(&tx.signed, &tx.input_data); } diff --git a/substrate/wasm-runtime/support/src/lib.rs b/substrate/wasm-runtime/support/src/lib.rs index 0c13c17ff7..d0b4c8a799 100644 --- a/substrate/wasm-runtime/support/src/lib.rs +++ b/substrate/wasm-runtime/support/src/lib.rs @@ -144,7 +144,13 @@ macro_rules! impl_stubs { }; let output = super::$name(&input[..]); - &output[0] as *const u8 as u64 + ((output.len() as u64) << 32) + // things break if we try to take the address of an unallocated vec, so we + // shortcircuit the empty output case. + if output.len() > 0 { + &output[0] as *const u8 as u64 + ((output.len() as u64) << 32) + } else { + 0 + } } )* } 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 688c7bcdb8..dfff5d575e 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 861eb4c608..441bee2cd5 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 b2576fa074..3ae531562e 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 1b9dc8a1cd..ac94a72cde 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 diff --git a/substrate/wasm-runtime/test/src/lib.rs b/substrate/wasm-runtime/test/src/lib.rs index 6e257a091f..2b9a21c17f 100644 --- a/substrate/wasm-runtime/test/src/lib.rs +++ b/substrate/wasm-runtime/test/src/lib.rs @@ -43,4 +43,22 @@ fn test_data_in(input: &[u8]) -> Vec { b"all ok!".to_vec() } -impl_stubs!(test_data_in, test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify); +fn test_empty_return(_input: &[u8]) -> Vec { + Vec::new() +} + +fn test_panic(_input: &[u8]) -> Vec { + panic!("test panic"); +} + +fn test_conditional_panic(input: &[u8]) -> Vec { + if input.len() > 0 { + panic!("test panic"); + } else { + assert!(input.len() > 0); + } + input.to_vec() +} + +impl_stubs!(test_data_in, test_empty_return, test_panic, test_conditional_panic, + test_blake2_256, test_twox_256, test_twox_128, test_ed25519_verify);