This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Prerequisites for validate_block in Cumulus
#1926
Merged
Merged
Changes from 25 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
ded8fdb
Adds benchmark for direct/indirect wasm function calls
bkchr a8052d1
Store the benchmark function pointer in a `Cell`
bkchr 456ddac
Add some documentation
bkchr c9a5b11
Make function implementations exchangeable
bkchr 0638c55
Add parachain stub
bkchr 7bb9d20
Add macro for registering the `validate_block` function
bkchr 3d650b9
Make all functions replace-able by unimplemented
bkchr b41e6d0
Some more refactoring
bkchr b1c99b8
Adds tests for executing empty parachain block
bkchr 2524f95
Work on a new test with empty witness data
bkchr 4e6e32d
Don't exchange `ext_print_*` stuff
bkchr 603897b
Some cleanup and one more function for `validate_block`
bkchr c1630ea
More tests and more functions
bkchr e4962c9
Merge branch 'master' into bkchr-validate_block
bkchr ab63852
Fixes after merging master
bkchr eeab2ce
Use `parity-codec` `derive` feature
bkchr 481749d
CHange implementation of `wasm-nice-panic-message`
bkchr 73f282f
Move `parachain` stuff to cumulus
bkchr 8090c35
devops-parity updated wasm runtime blobs 98cfecb1 and merged in maste…
devops-parity e1124fb
Merge remote-tracking branch 'origin/master' into bkchr-validate_block
bkchr dd09ee6
Updated wasm files
bkchr d0b1f5a
Merge branch 'master' into bkchr-validate_block
bkchr 9e20490
Integrate feedback
bkchr ea99855
Switch to `ExchangeableFunction` struct
bkchr 682eafa
More fixes
bkchr c0131c2
Merge remote-tracking branch 'origin/master' into bkchr-validate_block
bkchr f958f0f
Switch to Cell and panic on multiple replaces
bkchr 99823e8
Increase `impl_version`
bkchr b382c7f
Fix shifting
bkchr 7f390ce
Make the API more verbose of `ExchangeableFunction`
bkchr a8e8b0b
devops-parity updated wasm runtime blobs 99191521 and merged in maste…
devops-parity 3800235
Increase `impl_version`
bkchr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,7 @@ use secp256k1; | |
| use wasmi::{ | ||
| Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, | ||
| }; | ||
| use wasmi::RuntimeValue::{I32, I64}; | ||
| use wasmi::RuntimeValue::{I32, I64, self}; | ||
| use wasmi::memory_units::{Pages}; | ||
| use state_machine::Externalities; | ||
| use crate::error::{Error, ErrorKind, Result}; | ||
|
|
@@ -393,10 +393,12 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, | |
| .map_err(|_| UserError("Invalid attempt to get parent_hash in ext_storage_changes_root"))?; | ||
| parent_hash.as_mut().copy_from_slice(&raw_parent_hash[..]); | ||
| let r = this.ext.storage_changes_root(parent_hash, parent_number); | ||
| if let Some(ref r) = r { | ||
| if let Some(r) = r { | ||
| this.memory.set(result, &r[..]).map_err(|_| UserError("Invalid attempt to set memory in ext_storage_changes_root"))?; | ||
| Ok(1) | ||
| } else { | ||
| Ok(0) | ||
| } | ||
| Ok(if r.is_some() { 1u32 } else { 0u32 }) | ||
| }, | ||
| ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8) => { | ||
| let values = (0..lens_len) | ||
|
|
@@ -637,17 +639,19 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, | |
| /// | ||
| /// Executes the provided code in a sandboxed wasm runtime. | ||
| #[derive(Debug, Clone)] | ||
| pub struct WasmExecutor { | ||
| } | ||
| pub struct WasmExecutor; | ||
|
|
||
| impl WasmExecutor { | ||
|
|
||
| /// Create a new instance. | ||
| pub fn new() -> Self { | ||
| WasmExecutor{} | ||
| WasmExecutor | ||
| } | ||
|
|
||
| /// Call a given method in the given code. | ||
| /// | ||
| /// Signature of this method needs to be `(I32, I32) -> I64`. | ||
| /// | ||
| /// This should be used for tests only. | ||
| pub fn call<E: Externalities<Blake2Hasher>>( | ||
| &self, | ||
|
|
@@ -656,12 +660,34 @@ impl WasmExecutor { | |
| code: &[u8], | ||
| method: &str, | ||
| data: &[u8], | ||
| ) -> Result<Vec<u8>> { | ||
| ) -> Result<Vec<u8>> { | ||
| let module = ::wasmi::Module::from_buffer(code)?; | ||
| let module = self.prepare_module(ext, heap_pages, &module)?; | ||
| self.call_in_wasm_module(ext, &module, method, data) | ||
| } | ||
|
|
||
| /// Call a given method with a custom signature in the given code. | ||
| /// | ||
| /// This should be used for tests only. | ||
| pub fn call_with_custom_signature< | ||
| E: Externalities<Blake2Hasher>, | ||
| F: FnOnce(&mut FnMut(&[u8]) -> Result<u32>) -> Result<Vec<RuntimeValue>>, | ||
| FR: FnOnce(Option<RuntimeValue>, &MemoryRef) -> Result<Option<R>>, | ||
| R, | ||
| >( | ||
| &self, | ||
| ext: &mut E, | ||
| heap_pages: usize, | ||
| code: &[u8], | ||
| method: &str, | ||
| create_parameters: F, | ||
| filter_result: FR, | ||
| ) -> Result<R> { | ||
| let module = wasmi::Module::from_buffer(code)?; | ||
| let module = self.prepare_module(ext, heap_pages, &module)?; | ||
| self.call_in_wasm_module_with_custom_signature(ext, &module, method, create_parameters, filter_result) | ||
| } | ||
|
|
||
| fn get_mem_instance(module: &ModuleRef) -> Result<MemoryRef> { | ||
| Ok(module | ||
| .export_by_name("memory") | ||
|
|
@@ -679,6 +705,40 @@ impl WasmExecutor { | |
| method: &str, | ||
| data: &[u8], | ||
| ) -> Result<Vec<u8>> { | ||
| self.call_in_wasm_module_with_custom_signature( | ||
| ext, | ||
| module_instance, | ||
| method, | ||
| |alloc| { | ||
| let offset = alloc(data)?; | ||
| Ok(vec![I32(offset as i32), I32(data.len() as i32)]) | ||
| }, | ||
| |res, memory| { | ||
| if let Some(I64(r)) = res { | ||
| let offset = r as u32; | ||
| let length = (r >> 32) as usize; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, I wonder if this is correct. Can you check my logic?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tomusdrw FYI. We both need to go back and learn shifting :D |
||
| memory.get(offset, length).map_err(|_| ErrorKind::Runtime.into()).map(Some) | ||
| } else { | ||
| Ok(None) | ||
| } | ||
| } | ||
| ) | ||
| } | ||
|
|
||
| /// Call a given method in the given wasm-module runtime. | ||
| fn call_in_wasm_module_with_custom_signature< | ||
| E: Externalities<Blake2Hasher>, | ||
| F: FnOnce(&mut FnMut(&[u8]) -> Result<u32>) -> Result<Vec<RuntimeValue>>, | ||
| FR: FnOnce(Option<RuntimeValue>, &MemoryRef) -> Result<Option<R>>, | ||
| R, | ||
| >( | ||
| &self, | ||
| ext: &mut E, | ||
| module_instance: &ModuleRef, | ||
| method: &str, | ||
| create_parameters: F, | ||
| filter_result: FR, | ||
| ) -> Result<R> { | ||
| // extract a reference to a linear memory, optional reference to a table | ||
| // and then initialize FunctionExecutor. | ||
| let memory = Self::get_mem_instance(module_instance)?; | ||
|
|
@@ -689,26 +749,22 @@ impl WasmExecutor { | |
| let low = memory.lowest_used(); | ||
| let used_mem = memory.used_size(); | ||
| let mut fec = FunctionExecutor::new(memory.clone(), table, ext)?; | ||
| let size = data.len() as u32; | ||
| let offset = fec.heap.allocate(size).map_err(|_| ErrorKind::Runtime)?; | ||
| memory.set(offset, &data)?; | ||
| let parameters = create_parameters(&mut |data: &[u8]| { | ||
| let offset = fec.heap.allocate(data.len() as u32).map_err(|_| ErrorKind::Runtime)?; | ||
| memory.set(offset, &data)?; | ||
| Ok(offset) | ||
| })?; | ||
|
|
||
| let result = module_instance.invoke_export( | ||
| method, | ||
| &[ | ||
| I32(offset as i32), | ||
| I32(size as i32) | ||
| ], | ||
| ¶meters, | ||
| &mut fec | ||
| ); | ||
| let result = match result { | ||
| Ok(Some(I64(r))) => { | ||
| let offset = r as u32; | ||
| let length = (r >> 32) as u32 as usize; | ||
| memory.get(offset, length) | ||
| .map_err(|_| ErrorKind::Runtime.into()) | ||
| Ok(val) => match filter_result(val, &memory)? { | ||
| Some(val) => Ok(val), | ||
| None => Err(ErrorKind::InvalidReturn.into()), | ||
| }, | ||
| Ok(_) => Err(ErrorKind::InvalidReturn.into()), | ||
| Err(e) => { | ||
| trace!(target: "wasm-executor", "Failed to execute code with {} pages", memory.current_size().0); | ||
| Err(e.into()) | ||
|
|
@@ -738,7 +794,7 @@ impl WasmExecutor { | |
| module, | ||
| &ImportsBuilder::new() | ||
| .with_resolver("env", FunctionExecutor::<E>::resolver()) | ||
| )?; | ||
| )?; | ||
|
|
||
| // extract a reference to a linear memory, optional reference to a table | ||
| // and then initialize FunctionExecutor. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,3 +35,4 @@ std = [ | |
| ] | ||
| nightly = [] | ||
| strict = [] | ||
| wasm-nice-panic-message = [] | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.