Fix everything.

This commit is contained in:
Gav
2018-01-27 13:32:30 +01:00
parent a9c864e098
commit ace1387076
10 changed files with 154 additions and 55 deletions
@@ -99,7 +99,6 @@ mod tests {
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, || {
+83 -25
View File
@@ -27,6 +27,7 @@ use error::{Error, ErrorKind, Result};
use wasm_utils::{MemoryInstance, UserDefinedElements,
AddModuleWithoutFullDependentInstance};
use primitives::{ed25519, blake2_256, twox_128, twox_256};
use primitives::hexdisplay::HexDisplay;
struct Heap {
end: u32,
@@ -151,47 +152,63 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
this.ext.chain_id()
},
ext_twox_128(data: *const u8, len: u32, out: *mut u8) => {
let result =
if let Ok(value) = this.memory.get(data, len as usize) {
twox_128(&value)
} else {
[0; 16]
};
let maybe_value = if len == 0 {
Ok(vec![])
} else {
this.memory.get(data, len as usize)
};
let result = if let Ok(value) = maybe_value {
twox_128(&value)
} else {
[0; 16]
};
let _ = this.memory.set(out, &result);
},
ext_twox_256(data: *const u8, len: u32, out: *mut u8) => {
let result =
if let Ok(value) = this.memory.get(data, len as usize) {
twox_256(&value)
} else {
[0; 32]
};
let maybe_value = if len == 0 {
Ok(vec![])
} else {
this.memory.get(data, len as usize)
};
let result = if let Ok(value) = maybe_value {
twox_256(&value)
} else {
[0; 32]
};
let _ = this.memory.set(out, &result);
},
ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => {
let result =
if let Ok(value) = this.memory.get(data, len as usize) {
blake2_256(&value)
} else {
[0; 32]
};
let maybe_value = if len == 0 {
Ok(vec![])
} else {
this.memory.get(data, len as usize)
};
let result = if let Ok(value) = maybe_value {
blake2_256(&value)
} else {
[0; 32]
};
let _ = this.memory.set(out, &result);
},
ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32 => {
(||{
let mut sig = [0u8; 64];
if let Err(_) = this.memory.get_into(sig_data, &mut sig[..]) {
return 0;
return 2;
};
let mut pubkey = [0u8; 32];
if let Err(_) = this.memory.get_into(pubkey_data, &mut pubkey[..]) {
return 0;
return 3;
};
if let Ok(msg) = this.memory.get(msg_data, msg_len as usize) {
if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { 1 } else { 0 }
if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) {
0
} else {
5
}
} else {
0
4
}
})()
}
@@ -253,6 +270,7 @@ mod tests {
use super::*;
use rustc_hex::FromHex;
use native_runtime::testing::TestExternalities;
use primitives::hashing::blake2_256;
#[test]
fn returning_should_work() {
@@ -299,11 +317,11 @@ mod tests {
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &CallData(b"".to_vec())).unwrap(),
FromHex::from_hex("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8").unwrap()
blake2_256(&b""[..]).to_vec()
);
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_blake2_256", &CallData(b"Hello world!".to_vec())).unwrap(),
FromHex::from_hex("3fbc092db9350757e2ab4f7ee9792bfcd2f5220ada5a4bc684487f60c6034369").unwrap()
blake2_256(&b"Hello world!"[..]).to_vec()
);
}
@@ -346,7 +364,47 @@ mod tests {
calldata.extend_from_slice(sig.as_ref());
assert_eq!(
WasmExecutor.call(&mut ext, &test_code[..], "test_ed25519_verify", &CallData(calldata)).unwrap(),
vec![1]
vec![0]
);
}
use primitives::twox_128;
use native_runtime::testing::{one, two};
use native_runtime::statichex::StaticHexInto;
use native_runtime::keyedvec::KeyedVec;
use native_runtime::runtime::staking::balance;
use runtime_support;
fn tx() -> Vec<u8> { "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000".convert() }
#[test]
fn panic_execution_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 = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx()));
assert!(r.is_err());
}
#[test]
fn successful_execution_gives_ok() {
let one = one();
let two = two();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
], };
let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm");
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx()));
assert!(r.is_ok());
runtime_support::with_externalities(&mut t, || {
assert_eq!(balance(&one), 42);
assert_eq!(balance(&two), 69);
});
}
}
@@ -105,6 +105,28 @@ pub fn with_externalities<R, F: FnOnce() -> R>(ext: &mut Externalities, f: F) ->
ext::using(ext, f)
}
pub trait Printable {
fn print(self);
}
impl<'a> Printable for &'a [u8] {
fn print(self) {
if let Ok(s) = ::std::str::from_utf8(self) {
println!("Runtime: {}", s);
}
}
}
impl Printable for u64 {
fn print(self) {
println!("Runtime: {}", self);
}
}
pub fn print<T: Printable + Sized>(value: T) {
value.print();
}
#[macro_export]
macro_rules! impl_stubs {
($( $name:ident ),*) => {}
+1 -4
View File
@@ -47,12 +47,9 @@ pub fn execute_block(input: &[u8]) -> Vec<u8> {
/// Execute a given, serialised, transaction. Returns the empty vector.
pub fn execute_transaction(input: &[u8]) -> Vec<u8> {
if input.len() == 0 {
panic!("no transaction data given!");
}
let utx = UncheckedTransaction::from_slice(input).unwrap();
runtime::system::execute_transaction(&utx);
input.to_vec()//Vec::new()
Vec::new()
}
impl_stubs!(execute_block, execute_transaction);
@@ -20,6 +20,7 @@
use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder, Hashable};
use runtime_support::mem;
use runtime_support::prelude::*;
use runtime_support::print;
use storable::Storable;
use keyedvec::KeyedVec;
use environment::with_env;
@@ -84,6 +85,7 @@ pub fn execute_block(mut block: Block) {
/// Execute a given transaction.
pub fn execute_transaction(utx: &UncheckedTransaction) {
print(&b"HERE"[..]);
// Verify the signature is good.
assert!(utx.ed25519_verify(), "All transactions should be properly signed");
+46 -25
View File
@@ -1,9 +1,9 @@
#![no_std]
#![feature(lang_items)]
#![feature(core_intrinsics)]
#![feature(alloc)]
#![cfg_attr(feature = "strict", deny(warnings))]
#![feature(alloc)]
extern crate alloc;
pub use alloc::vec;
@@ -26,8 +26,13 @@ extern crate pwasm_alloc;
#[lang = "panic_fmt"]
#[no_mangle]
pub fn panic_fmt() -> ! {
loop {}
pub extern fn panic_fmt(_fmt: ::core::fmt::Arguments, _file: &'static str, _line: u32, _col: u32) {
unsafe {
ext_print(_file.as_ptr() as *const u8, _file.len() as u32);
ext_print_num(_line as u64);
ext_print_num(_col as u64);
::core::intrinsics::abort()
}
}
extern "C" {
@@ -46,7 +51,7 @@ extern "C" {
pub fn storage(key: &[u8]) -> Vec<u8> {
let mut length: u32 = 0;
unsafe {
let ptr = ext_get_allocated_storage(&key[0], key.len() as u32, &mut length);
let ptr = ext_get_allocated_storage(key.as_ptr(), key.len() as u32, &mut length);
Vec::from_raw_parts(ptr, length as usize, length as usize)
}
}
@@ -54,15 +59,15 @@ pub fn storage(key: &[u8]) -> Vec<u8> {
pub fn set_storage(key: &[u8], value: &[u8]) {
unsafe {
ext_set_storage(
&key[0] as *const u8, key.len() as u32,
&value[0] as *const u8, value.len() as u32
key.as_ptr(), key.len() as u32,
value.as_ptr(), value.len() as u32
);
}
}
pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> usize {
unsafe {
ext_get_storage_into(&key[0], key.len() as u32, &mut value_out[0], value_out.len() as u32, value_offset as u32) as usize
ext_get_storage_into(key.as_ptr(), key.len() as u32, value_out.as_mut_ptr(), value_out.len() as u32, value_offset as u32) as usize
}
}
@@ -72,41 +77,61 @@ pub fn chain_id() -> u64 {
ext_chain_id()
}
}
/*
trait AsPtr {
fn ptr(self) -> *const u8;
}
impl<'a> AsPtr for &'a[u8] {
fn ptr(self) -> *const u8 {
if self.len() > 0 { &self[0] } else { 0 as *const u8 }
}
}
trait AsPtrMut {
fn ptr(self) -> *mut u8;
}
impl<'a> AsPtrMut for &'a mut [u8] {
fn ptr(self) -> *mut u8 {
if self.len() > 0 { &mut self[0] } else { 0 as *mut u8 }
}
}
*/
/// Conduct a 256-bit Blake2 hash.
pub fn blake2_256(data: &[u8]) -> [u8; 32] {
let mut result: [u8; 32] = Default::default();
// guaranteed to write into result.
unsafe {
let mut result: [u8; 32] = Default::default();
// guaranteed to write into result.
ext_blake2_256(&data[0], data.len() as u32, &mut result[0]);
result
ext_blake2_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr());
}
result
}
/// Conduct four XX hashes to give a 256-bit result.
pub fn twox_256(data: &[u8]) -> [u8; 32] {
let mut result: [u8; 32] = Default::default();
// guaranteed to write into result.
unsafe {
let mut result: [u8; 32] = Default::default();
// guaranteed to write into result.
ext_twox_256(&data[0], data.len() as u32, &mut result[0]);
result
ext_twox_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr());
}
result
}
/// Conduct two XX hashes to give a 256-bit result.
pub fn twox_128(data: &[u8]) -> [u8; 16] {
let mut result: [u8; 16] = Default::default();
// guaranteed to write into result.
unsafe {
let mut result: [u8; 16] = Default::default();
// guaranteed to write into result.
ext_twox_128(&data[0], data.len() as u32, &mut result[0]);
result
ext_twox_128(data.as_ptr(), data.len() as u32, result.as_mut_ptr());
}
result
}
/// 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[0], msg.len() as u32, &sig[0], &pubkey[0])
ext_ed25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ptr())
} == 0
}
@@ -150,11 +175,7 @@ macro_rules! impl_stubs {
let output = super::$name(&input[..]);
// 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
}
output.as_ptr() as u64 + ((output.len() as u64) << 32)
}
)*
}