Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Prev Previous commit
Next Next commit
stubs which handle encoding and decoding themselves
  • Loading branch information
rphmeier committed Feb 8, 2018
commit 68c114a84108bc76a2467fa3c9af8a0f1afbdbb6
14 changes: 14 additions & 0 deletions codec/src/slicable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ impl<T: NonTrivialSlicable> Slicable for Vec<T> {
}
}

impl Slicable for () {
fn from_slice(_value: &mut &[u8]) -> Option<()> {
Some(())
}

fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(&[])
}

fn to_vec(&self) -> Vec<u8> {
Vec::new()
}
}

macro_rules! tuple_impl {
($one:ident,) => {
impl<$one: Slicable> Slicable for ($one,) {
Expand Down
8 changes: 4 additions & 4 deletions executor/src/native_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

use error::{Error, ErrorKind, Result};
use native_runtime as runtime;
use native_runtime::api;
use runtime_io;
use state_machine::{Externalities, CodeExecutor};
use wasm_executor::WasmExecutor;
Expand Down Expand Up @@ -43,9 +43,9 @@ impl CodeExecutor for NativeExecutor {
let native_equivalent = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm");
if code == &native_equivalent[..] {
runtime_io::with_externalities(ext, || match method {
"execute_block" => safe_call(|| runtime::execute_block(data)),
"execute_transaction" => safe_call(|| runtime::execute_transaction(data)),
"finalise_block" => safe_call(|| runtime::finalise_block(data)),
"execute_block" => safe_call(|| api::execute_encoded_block(data)),
"execute_transaction" => safe_call(|| api::execute_encoded_transaction(data)),
"finalise_block" => safe_call(|| api::finalise_encoded_block(data)),
_ => Err(ErrorKind::MethodNotFound(method.to_owned()).into()),
})
} else {
Expand Down
18 changes: 17 additions & 1 deletion runtime-io/with_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ extern crate substrate_primitives as primitives;
extern crate triehash;
extern crate ed25519;

#[doc(hidden)]
pub extern crate substrate_codec as codec;

pub use std::vec;
pub use std::rc;
pub use std::cell;
Expand Down Expand Up @@ -131,7 +134,20 @@ pub fn print<T: Printable + Sized>(value: T) {

#[macro_export]
macro_rules! impl_stubs {
($( $name:ident ),*) => {}
( $( $name:ident => $new_name:ident ),* ) => {
$(
/// Stub version of $name
pub fn $new_name(mut input: &[u8]) -> Vec<u8> {
let input = match $crate::codec::Slicable::from_slice(&mut input) {
Some(input) => input,
None => panic!("Bad input data provided to {}", stringify!($name)),
};

let output = $name(input);
$crate::codec::Slicable::to_vec(&output)
}
)*
}
}

#[cfg(test)]
Expand Down
22 changes: 18 additions & 4 deletions runtime-io/without_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ extern crate pwasm_libc;
#[cfg(feature = "nightly")]
extern crate pwasm_alloc;

#[doc(hidden)]
pub extern crate substrate_codec as codec;
extern crate substrate_primitives as primitives;

pub use alloc::vec;
Expand Down Expand Up @@ -186,21 +188,33 @@ pub fn print<T: Printable + Sized>(value: T) {

#[macro_export]
macro_rules! impl_stubs {
( $( $name:ident ),* ) => {
( $( $name:ident => $new_name:ident ),* ) => {
pub mod _internal {
$(
#[no_mangle]
pub fn $name(input_data: *mut u8, input_len: usize) -> u64 {
let input = if input_len == 0 {
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::from_slice(&mut input) {
Some(input) => input,
None => panic!("Bad input data provided to {}", stringify!($name)),
};

let output = super::$name(input);
output.as_ptr() as u64 + ((output.len() as u64) << 32)
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
}
)*
}
Expand Down
34 changes: 34 additions & 0 deletions wasm-runtime/polkadot/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,37 @@

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use rstd::prelude::*;
use codec::Slicable;
use polkadot_primitives::{Header, Block, UncheckedTransaction};

/// Execute a block.
pub fn execute_block(block: Block) {
::runtime::system::internal::execute_block(block);
}

/// Execute a transaction. Input data is the concatenation of a serialized header and
/// transaction. Returns the new header.
pub fn execute_transaction((header, utx): (Header, UncheckedTransaction)) -> Header {
::runtime::system::internal::execute_transaction(utx, header)
}

/// Finalize a block, given its header.
pub fn finalise_block(header: Header) -> Vec<u8> {
let header = ::runtime::system::internal::finalise_block(header);
header.to_vec()
}

/// Run whatever tests we have on a full block.
pub fn run_tests(block: Block) -> u32 {
let stxs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>();
stxs.len() as u32
}

impl_stubs!(
execute_block => execute_encoded_block,
execute_transaction => execute_encoded_transaction,
finalise_block => finalise_encoded_block,
run_tests => run_encoded_block_tests
);
41 changes: 0 additions & 41 deletions wasm-runtime/polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ pub mod support;
pub mod runtime;
pub mod api;

use rstd::prelude::*;
use codec::Slicable;
use polkadot_primitives::{Header, Block, UncheckedTransaction};

/// Type definitions and helpers for transactions.
pub mod transaction {
use rstd::ops;
Expand Down Expand Up @@ -81,40 +77,3 @@ pub mod transaction {
}
}
}

/// Execute a block, with `input` being the canonical serialisation of the block. Returns the
/// empty vector.
pub fn execute_block(mut input: &[u8]) -> Vec<u8> {
runtime::system::internal::execute_block(Block::from_slice(&mut input).unwrap());
Vec::new()
}

/// Execute a transaction. Input data is the concatenation of a serialized header and
/// transaction. Returns the new header.
pub fn execute_transaction(mut input: &[u8]) -> Vec<u8> {
let header = Header::from_slice(&mut input).unwrap();
let utx = UncheckedTransaction::from_slice(&mut input).unwrap();
let header = runtime::system::internal::execute_transaction(utx, header);
header.to_vec()
}

/// Finalize a block, given its header.
pub fn finalise_block(mut input: &[u8]) -> Vec<u8> {
let header = Header::from_slice(&mut input).unwrap();
let header = runtime::system::internal::finalise_block(header);
header.to_vec()
}

/// Run whatever tests we have on a full block.
pub fn run_tests(mut input: &[u8]) -> Vec<u8> {
use runtime_io::print;

print("run_tests...");
let block = Block::from_slice(&mut input).unwrap();
print("deserialised block.");
let stxs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>();
print("reserialised transactions.");
[stxs.len() as u8].to_vec()
}

impl_stubs!(execute_block, execute_transaction, finalise_block, run_tests);