diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 4f3bdfc57d502916d6b2c4bf1dfeac3f3fae2273..928c72939d1c2d74c34cb180a24421358565776a 100644 Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 735533a89742f7416fa67be5b74b862d3e84dfb7..03a42ab97111f3686ee79b74315049ab71cb17b1 100644 Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ diff --git a/substrate/substrate/executor/src/wasm_executor.rs b/substrate/substrate/executor/src/wasm_executor.rs index 60f437081a818574bacfe684e764169cdbf233b1..85c1e0e61bdb62e75fdbf1c5bd51cfb9bf256469 100644 --- a/substrate/substrate/executor/src/wasm_executor.rs +++ b/substrate/substrate/executor/src/wasm_executor.rs @@ -423,6 +423,17 @@ mod tests { let mut calldata = vec![]; calldata.extend_from_slice(key.public().as_ref()); calldata.extend_from_slice(sig.as_ref()); + + assert_eq!( + WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), + vec![1] + ); + + let other_sig = key.sign(b"all is not ok!"); + let mut calldata = vec![]; + calldata.extend_from_slice(key.public().as_ref()); + calldata.extend_from_slice(other_sig.as_ref()); + assert_eq!( WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &calldata).unwrap(), vec![0] diff --git a/substrate/substrate/executor/wasm/src/lib.rs b/substrate/substrate/executor/wasm/src/lib.rs index 2002d3cefc94dd1964c784e99b6f27582c7cd964..11401a39d7b45a6f35651d8fc50b2f20eb2fcb12 100644 --- a/substrate/substrate/executor/wasm/src/lib.rs +++ b/substrate/substrate/executor/wasm/src/lib.rs @@ -13,57 +13,42 @@ use runtime_io::{ twox_128, twox_256, ed25519_verify, enumerated_trie_root }; -fn test_blake2_256(input: &[u8]) -> Vec<u8> { - blake2_256(&input).to_vec() -} - -fn test_twox_256(input: &[u8]) -> Vec<u8> { - twox_256(&input).to_vec() -} - -fn test_twox_128(input: &[u8]) -> Vec<u8> { - twox_128(&input).to_vec() -} - -fn test_ed25519_verify(input: &[u8]) -> Vec<u8> { - let sig = &input[0..64]; - let pubkey = &input[64..96]; - let msg = b"all ok!"; - [ed25519_verify(sig, &msg[..], pubkey) as u8].to_vec() -} - -fn test_enumerated_trie_root(_input: &[u8]) -> Vec<u8> { - enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() -} - -fn test_data_in(input: &[u8]) -> Vec<u8> { - print("set_storage"); - set_storage(b"input", &input); - - print("storage"); - let foo = storage(b"foo"); - - print("set_storage"); - set_storage(b"baz", &foo); - - print("finished!"); - b"all ok!".to_vec() -} - -fn test_empty_return(_input: &[u8]) -> Vec<u8> { - Vec::new() -} - -fn test_panic(_input: &[u8]) -> Vec<u8> { - panic!("test panic"); -} - -fn test_conditional_panic(input: &[u8]) -> Vec<u8> { - if input.len() > 0 { - panic!("test panic"); +impl_stubs!( + test_data_in NO_DECODE => |input| { + print("set_storage"); + set_storage(b"input", input); + + print("storage"); + let foo = storage(b"foo"); + + print("set_storage"); + set_storage(b"baz", &foo); + + print("finished!"); + b"all ok!".to_vec() + }, + test_empty_return NO_DECODE => |_| Vec::new(), + test_panic NO_DECODE => |_| panic!("test panic"), + test_conditional_panic NO_DECODE => |input: &[u8]| { + if input.len() > 0 { + panic!("test panic") + } + input.to_vec() + }, + test_blake2_256 NO_DECODE => |input| blake2_256(input).to_vec(), + test_twox_256 NO_DECODE => |input| twox_256(input).to_vec(), + test_twox_128 NO_DECODE => |input| twox_128(input).to_vec(), + test_ed25519_verify NO_DECODE => |input: &[u8]| { + let mut pubkey = [0; 32]; + let mut sig = [0; 64]; + + pubkey.copy_from_slice(&input[0..32]); + sig.copy_from_slice(&input[32..96]); + + let msg = b"all ok!"; + [ed25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec() + }, + test_enumerated_trie_root NO_DECODE => |_| { + enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec() } - 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, test_enumerated_trie_root); +); diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 2b8e909b3e4b2e6608e409e5a5b1cf6d86e1fa33..6296f219c64cbef48b5a3a7428b3847c0eccfa23 100644 Binary files a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index b3e3b8389158fdd46669b05e916da8b65b536052..0f00a9675481128e88540e2386816fa406722f2b 100644 Binary files a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/substrate/runtime-io/with_std.rs b/substrate/substrate/runtime-io/with_std.rs index bcedb481162b573a5c8224e9be4b5dc960bd06a2..cb01133a6c112122dd69a14069bf4896ca2e6df9 100644 --- a/substrate/substrate/runtime-io/with_std.rs +++ b/substrate/substrate/runtime-io/with_std.rs @@ -126,25 +126,30 @@ pub fn print<T: Printable + Sized>(value: T) { #[macro_export] macro_rules! impl_stubs { - ( $( $name:ident => $invoke:expr ),* ) => { + ( $( $new_name:ident $($nodecode:ident)* => $invoke: expr ),*) => { /// Dispatch logic for the native runtime. - pub fn dispatch(method: &str, mut data: &[u8]) -> Option<Vec<u8>> { + pub fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> { match method { $( - stringify!($name) => { - let input = match $crate::codec::Slicable::decode(&mut data) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($name)), - }; - - let output = $invoke(input); - Some($crate::codec::Slicable::to_vec(&output)) - } + stringify!($new_name) => { impl_stubs!(@METHOD data $new_name $($nodecode)* => $invoke) } )* _ => None, } } - } + }; + (@METHOD $data: ident $new_name: ident NO_DECODE => $invoke:expr) => { + Some($invoke($data)) + }; + (@METHOD $data: ident $new_name: ident => $invoke:expr) => {{ + let mut data = $data; + let input = match $crate::codec::Slicable::decode(&mut data) { + Some(input) => input, + None => panic!("Bad input data provided to {}", stringify!($new_name)), + }; + + let output = $invoke(input); + Some($crate::codec::Slicable::to_vec(&output)) + }} } #[cfg(test)] diff --git a/substrate/substrate/runtime-io/without_std.rs b/substrate/substrate/runtime-io/without_std.rs index a4d8e4076d5ee6abdfbc35b04c9916ee4a183258..ecadddeeabdad22f9d75c86f38be26ac53cd855a 100644 --- a/substrate/substrate/runtime-io/without_std.rs +++ b/substrate/substrate/runtime-io/without_std.rs @@ -14,9 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see <http://www.gnu.org/licenses/>. -extern crate substrate_runtime_std as rstd; + extern crate substrate_primitives as primitives; +#[doc(hidden)] +pub extern crate substrate_runtime_std as rstd; + #[doc(hidden)] pub extern crate substrate_codec as codec; @@ -141,10 +144,10 @@ pub fn twox_128(data: &[u8]) -> [u8; 16] { } /// Verify a ed25519 signature. -pub fn ed25519_verify(sig: &[u8], msg: &[u8], pubkey: &[u8]) -> bool { - sig.len() == 64 && pubkey.len() == 32 && unsafe { - ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr()) - } == 0 +pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { + unsafe { + ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr()) == 0 + } } /// Trait for things which can be printed. @@ -181,33 +184,57 @@ pub fn print<T: Printable + Sized>(value: T) { #[macro_export] macro_rules! impl_stubs { - ( $( $new_name:ident => $invoke:expr ),* ) => { + ( $( $new_name:ident $($nodecode:ident)* => $invoke:expr ),* ) => { $( - #[no_mangle] - pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { - let mut input = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - $crate::slice::from_raw_parts(input_data, input_len) - } - }; - - let input = match $crate::codec::Slicable::decode(&mut input) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($name)), - }; - - let output = ($invoke)(input); - let output = $crate::codec::Slicable::to_vec(&output); - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - ::core::mem::forget(output); - res - } + impl_stubs!(@METHOD $new_name $($nodecode)* => $invoke); )* + }; + ( @METHOD $new_name:ident NO_DECODE => $invoke:expr ) => { + #[no_mangle] + pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { + let input: &[u8] = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::slice::from_raw_parts(input_data, input_len) + } + }; + + let output: $crate::rstd::vec::Vec<u8> = $invoke(input); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + ::core::mem::forget(output); + res + } + }; + ( @METHOD $new_name:ident => $invoke:expr ) => { + #[no_mangle] + pub fn $new_name(input_data: *mut u8, input_len: usize) -> u64 { + let mut input = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + $crate::slice::from_raw_parts(input_data, input_len) + } + }; + + let input = match $crate::codec::Slicable::decode(&mut input) { + Some(input) => input, + None => panic!("Bad input data provided to {}", stringify!($name)), + }; + + let output = ($invoke)(input); + let output = $crate::codec::Slicable::to_vec(&output); + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + ::core::mem::forget(output); + res + } } }