Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix runtime_test
  • Loading branch information
rphmeier authored and gavofyork committed Feb 9, 2018
commit 1fd8ad09bae9d9235f8e8661eb7fc352d57499bd
11 changes: 11 additions & 0 deletions substrate/executor/src/wasm_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
91 changes: 38 additions & 53 deletions substrate/executor/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).encode()
}

fn test_twox_256(input: &[u8]) -> Vec<u8> {
twox_256(&input).encode()
}

fn test_twox_128(input: &[u8]) -> Vec<u8> {
twox_128(&input).encode()
}

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].encode()
}

fn test_enumerated_trie_root(_input: &[u8]) -> Vec<u8> {
enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).encode()
}

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.encode()
}

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);
);
29 changes: 17 additions & 12 deletions substrate/runtime-io/with_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::encode(&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)]
Expand Down
89 changes: 58 additions & 31 deletions substrate/runtime-io/without_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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::encode(&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
}
}
}