Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new crate for wasm proof #4

Open
wants to merge 5 commits into
base: ibc-demo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
41 changes: 41 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ vergen = "3.0.4"

[workspace]
members = [
"core/wasm-proof",
"core/authority-discovery",
"core/application-crypto",
"core/chain-spec",
Expand Down
5 changes: 5 additions & 0 deletions core/executor/src/host_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ impl_wasm_host_interface! {
context.sandbox().memory_teardown(memory_idx)
}

ext_run_wasm() {
runtime_io::run_wasm();
Ok(())
}

ext_print_utf8(utf8_data: Pointer<u8>, utf8_len: WordSize) {
if let Ok(utf8) = context.read_memory(utf8_data, utf8_len) {
runtime_io::print_utf8(&utf8);
Expand Down
4 changes: 4 additions & 0 deletions core/rpc/api/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ pub trait StateApi<Hash> {
#[rpc(name = "state_getRuntimeVersion", alias("chain_getRuntimeVersion"))]
fn runtime_version(&self, hash: Option<Hash>) -> FutureResult<RuntimeVersion>;

/// Reads storage value at a given block + key, returning read proof.
#[rpc(name = "state_getReadProof")]
fn read_proof(&self, id: Option<Hash>, key: StorageKey) -> FutureResult<Vec<Vec<u8>>>;

/// Query historical storage entries (by key) starting from a block given as the second parameter.
///
/// NOTE This first returned result contains the initial state of storage for all keys.
Expand Down
7 changes: 7 additions & 0 deletions core/rpc/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ pub trait StateBackend<B, E, Block: BlockT, RA>: Send + Sync + 'static
/// Get the runtime version.
fn runtime_version(&self, block: Option<Block::Hash>) -> FutureResult<RuntimeVersion>;

/// Reads storage value at a given block + key, returning read proof.
fn read_proof(&self, block: Option<Block::Hash>, key: StorageKey) -> FutureResult<Vec<Vec<u8>>>;

/// Query historical storage entries (by key) starting from a block given as the second parameter.
///
/// NOTE This first returned result contains the initial state of storage for all keys.
Expand Down Expand Up @@ -323,6 +326,10 @@ impl<B, E, Block, RA> StateApi<Block::Hash> for State<B, E, Block, RA>
self.backend.runtime_version(at)
}

fn read_proof(&self, block: Option<Block::Hash>, key: StorageKey) -> FutureResult<Vec<Vec<u8>>> {
self.backend.read_proof(block, key)
}

fn subscribe_runtime_version(&self, meta: Self::Metadata, subscriber: Subscriber<RuntimeVersion>) {
self.backend.subscribe_runtime_version(meta, subscriber);
}
Expand Down
11 changes: 11 additions & 0 deletions core/rpc/src/state/state_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,17 @@ impl<B, E, Block, RA> StateBackend<B, E, Block, RA> for FullState<B, E, Block, R
.map_err(client_err)))
}

fn read_proof(
&self,
block: Option<Block::Hash>,
key: StorageKey,
) -> FutureResult<Vec<Vec<u8>>> {
Box::new(result(
self.block_or_best(block)
.and_then(|block| self.client.read_proof(&BlockId::Hash(block), &[key.0]))
.map_err(client_err)))
}

fn query_storage(
&self,
from: Block::Hash,
Expand Down
8 changes: 8 additions & 0 deletions core/rpc/src/state/state_light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,14 @@ impl<Block, F, B, E, RA> StateBackend<B, E, Block, RA> for LightState<Block, F,
).boxed().compat())
}

fn read_proof(
&self,
block: Option<Block::Hash>,
key: StorageKey,
) -> FutureResult<Vec<Vec<u8>>> {
Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient))))
}

fn query_storage(
&self,
_from: Block::Hash,
Expand Down
5 changes: 5 additions & 0 deletions core/sr-io/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ tiny-keccak = { version = "1.5.0", optional = true }
substrate-state-machine = { path = "../state-machine", optional = true }
trie = { package = "substrate-trie", path = "../trie", optional = true }
externalities = { package = "substrate-externalities", path = "../externalities", optional = true }
sandbox = { package = "sr-sandbox", path = "../sr-sandbox", default-features = false }

[dev-dependencies]
wabt = "~0.7.4"

[features]
default = ["std"]
std = [
"sandbox/std",
"primitives/std",
"codec/std",
"rstd/std",
Expand Down
1 change: 1 addition & 0 deletions core/sr-io/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export_api! {
pub(crate) trait OtherApi {
/// The current relay chain identifier.
fn chain_id() -> u64;
fn run_wasm();

/// Print a number.
fn print_num(val: u64);
Expand Down
78 changes: 78 additions & 0 deletions core/sr-io/with_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,74 @@ use trie::{TrieConfiguration, trie_types::Layout};
use std::{collections::HashMap, convert::TryFrom};

use externalities::{with_externalities, set_and_run_with_externalities, ExternalitiesExt};
use sandbox::{EnvironmentDefinitionBuilder, Error, HostError, Instance, ReturnValue, TypedValue};

// environmental!(ext: trait Externalities<Blake2Hasher>);

fn execute_wasm(code: &[u8], args: &[TypedValue]) -> Result<ReturnValue, HostError> {
struct State {
counter: u32,
}
fn check_read_proof(_e: &mut State, _args: &[TypedValue]) -> Result<ReturnValue, HostError> {
// TODO: Add true verification here
Ok(ReturnValue::Value(TypedValue::I32(1)))
}

let mut env_builder = EnvironmentDefinitionBuilder::new();

let mut state = State {counter: 0};

env_builder.add_host_func("env", "ext_check_read_proof", check_read_proof);

let memory = match sandbox::Memory::new(100, Some(100)) {
Ok(m) => m,
Err(_) => unreachable!("
Memory::new() can return Err only if parameters are borked; \
We passing params here explicitly and they're correct; \
Memory::new() can't return a Error qed"
),
};

env_builder.add_memory("env", "memory", memory);
let mut instance = Instance::new(code, &env_builder, &mut state)?;
let result = instance.invoke(b"check_read_proof", args, &mut state);

result.map_err(|err| {
HostError
})
}

#[test]
fn invoke_proof() {
let code = wabt::wat2wasm(r#"
(module
(type $t0 (func (result i32)))
(import "env" "memory" (memory $env.memory 17))
(import "env" "ext_check_read_proof" (func $ext_check_read_proof (type $t0)))
(func $check_read_proof (type $t0) (result i32)
(local $l0 i32)
call $ext_check_read_proof
set_local $l0
get_local $l0
return)
(table $__indirect_function_table 1 1 anyfunc)
(global $__data_end i32 (i32.const 1048610))
(global $__heap_base i32 (i32.const 1048610))
(global $__rustc_debug_gdb_scripts_section__ i32 (i32.const 1048576))
(export "__indirect_function_table" (table 0))
(export "__data_end" (global 0))
(export "__heap_base" (global 1))
(export "__rustc_debug_gdb_scripts_section__" (global 2))
(export "check_read_proof" (func $check_read_proof))
) "#).unwrap();

let result = execute_wasm(
&code,
&[],
);
assert_eq!(result.unwrap(), ReturnValue::Value(TypedValue::I32(1)));
}


/// Additional bounds for `Hasher` trait for with_std.
pub trait HasherBounds {}
Expand Down Expand Up @@ -179,6 +247,16 @@ impl OtherApi for () {
).unwrap_or(0)
}

fn run_wasm() {
use std::fs;

// TODO: Read wasm from chain
let code = fs::read("/tmp/proof.compact.wasm").expect("Wasm file not found");
let args = [];
let res = execute_wasm(&code, &args);
println!("result: {:?}", res);
}

fn print_num(val: u64) {
println!("{}", val);
}
Expand Down
7 changes: 7 additions & 0 deletions core/sr-io/without_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ pub mod ext {
/// (most importantly, storage) or perform heavy hash calculations.
/// See also "ext_" functions in sr-sandbox and sr-std
extern_functions! {
fn ext_run_wasm();
/// Host functions for printing, useful for debugging.
fn ext_print_utf8(utf8_data: *const u8, utf8_len: u32);
/// Print data as hex.
Expand Down Expand Up @@ -763,6 +764,12 @@ impl OtherApi for () {
}
}

fn run_wasm() {
unsafe {
ext_run_wasm.get()();
}
}

fn print_num(val: u64) {
unsafe {
ext_print_num.get()(val);
Expand Down
42 changes: 42 additions & 0 deletions core/wasm-proof/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[package]
name = "wasm-proof"
version = "2.0.0"
authors = ["Parity Technologies <[email protected]>"]
build = "build.rs"
edition = "2018"

[build-dependencies]
rustc_version = "0.2.3"

[dependencies]
rstd = { package = "sr-std", path = "../sr-std", default-features = false }
primitives = { package = "substrate-primitives", path = "../primitives", default-features = false }
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false }
hash-db = { version = "0.15.2", default-features = false }
substrate-state-machine = { path = "../state-machine", optional = true }
sandbox = { package = "sr-sandbox", path = "../sr-sandbox", default-features = false }
sr_primitives = { package = "sr-primitives", path = "../sr-primitives", default-features = false }
#wasm-interface = { package = "substrate-wasm-interface", path = "../wasm-interface"}

[dev-dependencies]
wabt = "~0.7.4"

[features]
default = ["std"]
std = [
"sandbox/std",
"primitives/std",
"codec/std",
"rstd/std",
"hash-db/std",
"substrate-state-machine",
]
nightly = []
strict = []

# These two features are used for `no_std` builds for the environments which already provides
# `#[panic_handler]` and `#[alloc_error_handler]`.
#
# For the regular wasm runtime builds those are not used.
no_panic_handler = []
no_oom = []
13 changes: 13 additions & 0 deletions core/wasm-proof/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! Set a nightly feature

use rustc_version::{version, version_meta, Channel};

fn main() {
// Assert we haven't traveled back in time
assert!(version().unwrap().major >= 1);

// Set cfg flags depending on release channel
if let Channel::Nightly = version_meta().unwrap().channel {
println!("cargo:rustc-cfg=feature=\"nightly\"");
}
}
Loading