fix runtime_test

This commit is contained in:
Robert Habermeier
2018-02-08 22:36:24 +01:00
parent 6c7e286967
commit 4ca99758df
8 changed files with 119 additions and 91 deletions
@@ -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]
+33 -48
View File
@@ -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()
}
impl_stubs!(
test_data_in NO_DECODE => |input| {
print("set_storage");
set_storage(b"input", input);
fn test_twox_256(input: &[u8]) -> Vec<u8> {
twox_256(&input).to_vec()
}
print("storage");
let foo = storage(b"foo");
fn test_twox_128(input: &[u8]) -> Vec<u8> {
twox_128(&input).to_vec()
}
print("set_storage");
set_storage(b"baz", &foo);
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()
}
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];
fn test_enumerated_trie_root(_input: &[u8]) -> Vec<u8> {
enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec()
}
pubkey.copy_from_slice(&input[0..32]);
sig.copy_from_slice(&input[32..96]);
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");
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);
);
+17 -12
View File
@@ -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)]
+58 -31
View File
@@ -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
}
}
}