diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 0ab058e8ed7328f8a792920912ee0a3b10ce9091..aacb4cc50f56fc14676eade39ead8a9dee8a63d4 100644 Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index 8887b0a3ab25d7ddd57c78886df6eae9433526b9..c673dc860153374be0d7aa4b64f69d3a85f6fa51 100755 Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index b81c6f912785f20f22b001556592c5c9a3fa65ec..ec1f5320ed508e31cf12d348402156a016e906d7 100644 Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 4430bf8545f650ea9ea4f02c94f95e6814af6054..dfc9b4c24e5a75524d6ed770ba418e0cf2d8202b 100755 Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ diff --git a/substrate/substrate/executor/src/sandbox.rs b/substrate/substrate/executor/src/sandbox.rs index 51cbb85fb5a0325eb79cd19131b1c9cd081cb037..fd061bbe245b6825e85c82bc7e172fb3b30df903 100644 --- a/substrate/substrate/executor/src/sandbox.rs +++ b/substrate/substrate/executor/src/sandbox.rs @@ -22,7 +22,7 @@ use std::collections::HashMap; use std::rc::Rc; use codec::Slicable; use primitives::sandbox as sandbox_primitives; -use wasm_utils::DummyUserError; +use wasm_utils::UserError; use wasmi; use wasmi::memory_units::Pages; use wasmi::{ @@ -161,14 +161,14 @@ pub trait SandboxCapabilities { /// # Errors /// /// Returns `Err` if `ptr + data.len()` is out of bounds. - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<(), DummyUserError>; + fn write_memory(&mut self, ptr: u32, data: &[u8]) -> Result<(), UserError>; /// Read `len` bytes from the supervisor memory. /// /// # Errors /// /// Returns `Err` if `ptr + len` is out of bounds. - fn read_memory(&self, ptr: u32, len: u32) -> Result<Vec<u8>, DummyUserError>; + fn read_memory(&self, ptr: u32, len: u32) -> Result<Vec<u8>, UserError>; } /// Implementation of [`Externals`] that allows execution of guest module with @@ -182,7 +182,7 @@ pub struct GuestExternals<'a, FE: SandboxCapabilities + Externals + 'a> { } fn trap() -> Trap { - TrapKind::Host(Box::new(DummyUserError)).into() + TrapKind::Host(Box::new(UserError("Sandbox error"))).into() } fn deserialize_result(serialized_result: &[u8]) -> Result<Option<RuntimeValue>, Trap> { @@ -338,8 +338,8 @@ impl SandboxInstance { fn decode_environment_definition( raw_env_def: &[u8], memories: &[Option<MemoryRef>], -) -> Result<(Imports, GuestToSupervisorFunctionMapping), DummyUserError> { - let env_def = sandbox_primitives::EnvironmentDefinition::decode(&mut &raw_env_def[..]).ok_or_else(|| DummyUserError)?; +) -> Result<(Imports, GuestToSupervisorFunctionMapping), UserError> { + let env_def = sandbox_primitives::EnvironmentDefinition::decode(&mut &raw_env_def[..]).ok_or_else(|| UserError("Sandbox error"))?; let mut func_map = HashMap::new(); let mut memories_map = HashMap::new(); @@ -359,8 +359,8 @@ fn decode_environment_definition( let memory_ref = memories .get(memory_idx as usize) .cloned() - .ok_or_else(|| DummyUserError)? - .ok_or_else(|| DummyUserError)?; + .ok_or_else(|| UserError("Sandbox error"))? + .ok_or_else(|| UserError("Sandbox error"))?; memories_map.insert((module, field), memory_ref); } } @@ -395,12 +395,12 @@ pub fn instantiate<FE: SandboxCapabilities + Externals>( wasm: &[u8], raw_env_def: &[u8], state: u32, -) -> Result<u32, DummyUserError> { +) -> Result<u32, UserError> { let (imports, guest_to_supervisor_mapping) = decode_environment_definition(raw_env_def, &supervisor_externals.store().memories)?; - let module = Module::from_buffer(wasm).map_err(|_| DummyUserError)?; - let instance = ModuleInstance::new(&module, &imports).map_err(|_| DummyUserError)?; + let module = Module::from_buffer(wasm).map_err(|_| UserError("Sandbox error"))?; + let instance = ModuleInstance::new(&module, &imports).map_err(|_| UserError("Sandbox error"))?; let sandbox_instance = Rc::new(SandboxInstance { // In general, it's not a very good idea to use `.not_started_instance()` for anything @@ -418,7 +418,7 @@ pub fn instantiate<FE: SandboxCapabilities + Externals>( |guest_externals| { instance .run_start(guest_externals) - .map_err(|_| DummyUserError) + .map_err(|_| UserError("Sandbox error")) }, )?; @@ -451,14 +451,14 @@ impl Store { /// /// Returns `Err` if the memory couldn't be created. /// Typically happens if `initial` is more than `maximum`. - pub fn new_memory(&mut self, initial: u32, maximum: u32) -> Result<u32, DummyUserError> { + pub fn new_memory(&mut self, initial: u32, maximum: u32) -> Result<u32, UserError> { let maximum = match maximum { sandbox_primitives::MEM_UNLIMITED => None, specified_limit => Some(Pages(specified_limit as usize)), }; let mem = - MemoryInstance::alloc(Pages(initial as usize), maximum).map_err(|_| DummyUserError)?; + MemoryInstance::alloc(Pages(initial as usize), maximum).map_err(|_| UserError("Sandbox error"))?; let mem_idx = self.memories.len(); self.memories.push(Some(mem)); Ok(mem_idx as u32) @@ -470,12 +470,12 @@ impl Store { /// /// Returns `Err` If `instance_idx` isn't a valid index of an instance or /// instance is already torndown. - pub fn instance(&self, instance_idx: u32) -> Result<Rc<SandboxInstance>, DummyUserError> { + pub fn instance(&self, instance_idx: u32) -> Result<Rc<SandboxInstance>, UserError> { self.instances .get(instance_idx as usize) .cloned() - .ok_or_else(|| DummyUserError)? - .ok_or_else(|| DummyUserError) + .ok_or_else(|| UserError("Sandbox error"))? + .ok_or_else(|| UserError("Sandbox error")) } /// Returns reference to a memory instance by `memory_idx`. @@ -484,12 +484,12 @@ impl Store { /// /// Returns `Err` If `memory_idx` isn't a valid index of an memory or /// memory is already torndown. - pub fn memory(&self, memory_idx: u32) -> Result<MemoryRef, DummyUserError> { + pub fn memory(&self, memory_idx: u32) -> Result<MemoryRef, UserError> { self.memories .get(memory_idx as usize) .cloned() - .ok_or_else(|| DummyUserError)? - .ok_or_else(|| DummyUserError) + .ok_or_else(|| UserError("Sandbox error"))? + .ok_or_else(|| UserError("Sandbox error")) } /// Teardown the memory at the specified index. @@ -497,18 +497,18 @@ impl Store { /// # Errors /// /// Returns `Err` if `memory_idx` isn't a valid index of an memory. - pub fn memory_teardown(&mut self, memory_idx: u32) -> Result<(), DummyUserError> { + pub fn memory_teardown(&mut self, memory_idx: u32) -> Result<(), UserError> { if memory_idx as usize >= self.memories.len() { - return Err(DummyUserError); + return Err(UserError("Sandbox error")); } self.memories[memory_idx as usize] = None; Ok(()) } /// Teardown the instance at the specified index. - pub fn instance_teardown(&mut self, instance_idx: u32) -> Result<(), DummyUserError> { + pub fn instance_teardown(&mut self, instance_idx: u32) -> Result<(), UserError> { if instance_idx as usize >= self.instances.len() { - return Err(DummyUserError); + return Err(UserError("Sandbox error")); } self.instances[instance_idx as usize] = None; Ok(()) diff --git a/substrate/substrate/executor/src/wasm_executor.rs b/substrate/substrate/executor/src/wasm_executor.rs index f48a3a93bc042f5c5370f7ba98ad8d98dea7f5d8..891f6724566fdf6c17345e784ee84d05209bee07 100644 --- a/substrate/substrate/executor/src/wasm_executor.rs +++ b/substrate/substrate/executor/src/wasm_executor.rs @@ -25,7 +25,7 @@ use wasmi::RuntimeValue::{I32, I64}; use wasmi::memory_units::{Pages, Bytes}; use state_machine::{Externalities, CodeExecutor}; use error::{Error, ErrorKind, Result}; -use wasm_utils::{DummyUserError}; +use wasm_utils::UserError; use primitives::{blake2_256, twox_128, twox_256}; use primitives::hexdisplay::HexDisplay; use primitives::sandbox as sandbox_primitives; @@ -45,7 +45,7 @@ impl Heap { /// This could mean that wasm binary specifies memory /// limit and we are trying to allocate beyond that limit. fn new(memory: &MemoryRef) -> Result<Self> { - const HEAP_SIZE_IN_PAGES: usize = 8; + const HEAP_SIZE_IN_PAGES: usize = 1024; let prev_page_count = memory .grow(Pages(HEAP_SIZE_IN_PAGES)) @@ -98,35 +98,35 @@ impl<'e, E: Externalities> sandbox::SandboxCapabilities for FunctionExecutor<'e, fn deallocate(&mut self, ptr: u32) { self.heap.deallocate(ptr) } - fn write_memory(&mut self, ptr: u32, data: &[u8]) -> ::std::result::Result<(), DummyUserError> { - self.memory.set(ptr, data).map_err(|_| DummyUserError) + fn write_memory(&mut self, ptr: u32, data: &[u8]) -> ::std::result::Result<(), UserError> { + self.memory.set(ptr, data).map_err(|_| UserError("Invalid attempt to write_memory")) } - fn read_memory(&self, ptr: u32, len: u32) -> ::std::result::Result<Vec<u8>, DummyUserError> { - self.memory.get(ptr, len as usize).map_err(|_| DummyUserError) + fn read_memory(&self, ptr: u32, len: u32) -> ::std::result::Result<Vec<u8>, UserError> { + self.memory.get(ptr, len as usize).map_err(|_| UserError("Invalid attempt to write_memory")) } } trait WritePrimitive<T: Sized> { - fn write_primitive(&self, offset: u32, t: T) -> ::std::result::Result<(), DummyUserError>; + fn write_primitive(&self, offset: u32, t: T) -> ::std::result::Result<(), UserError>; } impl WritePrimitive<u32> for MemoryInstance { - fn write_primitive(&self, offset: u32, t: u32) -> ::std::result::Result<(), DummyUserError> { + fn write_primitive(&self, offset: u32, t: u32) -> ::std::result::Result<(), UserError> { use byteorder::{LittleEndian, ByteOrder}; let mut r = [0u8; 4]; LittleEndian::write_u32(&mut r, t); - self.set(offset, &r).map_err(|_| DummyUserError) + self.set(offset, &r).map_err(|_| UserError("Invalid attempt to write_primitive")) } } trait ReadPrimitive<T: Sized> { - fn read_primitive(&self, offset: u32) -> ::std::result::Result<T, DummyUserError>; + fn read_primitive(&self, offset: u32) -> ::std::result::Result<T, UserError>; } impl ReadPrimitive<u32> for MemoryInstance { - fn read_primitive(&self, offset: u32) -> ::std::result::Result<u32, DummyUserError> { + fn read_primitive(&self, offset: u32) -> ::std::result::Result<u32, UserError> { use byteorder::{LittleEndian, ByteOrder}; - Ok(LittleEndian::read_u32(&self.get(offset, 4).map_err(|_| DummyUserError)?)) + Ok(LittleEndian::read_u32(&self.get(offset, 4).map_err(|_| UserError("Invalid attempt to read_primitive"))?)) } } @@ -168,8 +168,8 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, Ok(()) }, ext_memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 => { - let sl1 = this.memory.get(s1, n as usize).map_err(|_| DummyUserError)?; - let sl2 = this.memory.get(s2, n as usize).map_err(|_| DummyUserError)?; + let sl1 = this.memory.get(s1, n as usize).map_err(|_| UserError("Invalid attempt to read from memory in first arg of ext_memcmp"))?; + let sl2 = this.memory.get(s2, n as usize).map_err(|_| UserError("Invalid attempt to read from memory in second arg of ext_memcmp"))?; Ok(match sl1.cmp(&sl2) { Ordering::Greater => 1, Ordering::Less => -1, @@ -178,20 +178,20 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, }, ext_memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { this.memory.copy_nonoverlapping(src as usize, dest as usize, count as usize) - .map_err(|_| DummyUserError)?; + .map_err(|_| UserError("Invalid attempt to copy_nonoverlapping in ext_memcpy"))?; trace!(target: "runtime-io", "memcpy {} from {}, {} bytes", dest, src, count); Ok(dest) }, ext_memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 => { this.memory.copy(src as usize, dest as usize, count as usize) - .map_err(|_| DummyUserError)?; + .map_err(|_| UserError("Invalid attempt to copy in ext_memmove"))?; trace!(target: "runtime-io", "memmove {} from {}, {} bytes", dest, src, count); Ok(dest) }, ext_memset(dest: *mut u8, val: u32, count: usize) -> *mut u8 => { - this.memory.clear(dest as usize, val as u8, count as usize) - .map_err(|_| DummyUserError)?; trace!(target: "runtime-io", "memset {} with {}, {} bytes", dest, val, count); + this.memory.clear(dest as usize, val as u8, count as usize) + .map_err(|_| UserError("Invalid attempt to clear in ext_memset"))?; Ok(dest) }, ext_malloc(size: usize) -> *mut u8 => { @@ -205,8 +205,8 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, Ok(()) }, ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32) => { - let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; - let value = this.memory.get(value_data, value_len as usize).map_err(|_| DummyUserError)?; + let key = this.memory.get(key_data, key_len as usize).map_err(|_| UserError("Invalid attempt to determine key in ext_set_storage"))?; + let value = this.memory.get(value_data, value_len as usize).map_err(|_| UserError("Invalid attempt to determine value in ext_set_storage"))?; if let Some(preimage) = this.hash_lookup.get(&key) { trace!(target: "wasm-trace", "*** Setting storage: %{} -> {} [k={}]", ascii_format(&preimage), HexDisplay::from(&value), HexDisplay::from(&key)); } else { @@ -216,7 +216,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, Ok(()) }, ext_clear_storage(key_data: *const u8, key_len: u32) => { - let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let key = this.memory.get(key_data, key_len as usize).map_err(|_| UserError("Invalid attempt to determine key in ext_clear_storage"))?; if let Some(preimage) = this.hash_lookup.get(&key) { trace!(target: "wasm-trace", "*** Clearing storage: %{} [k={}]", ascii_format(&preimage), HexDisplay::from(&key)); } else { @@ -226,13 +226,13 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, Ok(()) }, ext_clear_prefix(prefix_data: *const u8, prefix_len: u32) => { - let prefix = this.memory.get(prefix_data, prefix_len as usize).map_err(|_| DummyUserError)?; + let prefix = this.memory.get(prefix_data, prefix_len as usize).map_err(|_| UserError("Invalid attempt to determine prefix in ext_clear_prefix"))?; this.ext.clear_prefix(&prefix); Ok(()) }, // return 0 and place u32::max_value() into written_out if no value exists for the key. ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8 => { - let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let key = this.memory.get(key_data, key_len as usize).map_err(|_| UserError("Invalid attempt to determine key in ext_get_allocated_storage"))?; let maybe_value = this.ext.storage(&key); if let Some(preimage) = this.hash_lookup.get(&key) { @@ -243,17 +243,19 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, if let Some(value) = maybe_value { let offset = this.heap.allocate(value.len() as u32) as u32; - this.memory.set(offset, &value).map_err(|_| DummyUserError)?; - this.memory.write_primitive(written_out, value.len() as u32)?; + this.memory.set(offset, &value).map_err(|_| UserError("Invalid attempt to set memory in ext_get_allocated_storage"))?; + this.memory.write_primitive(written_out, value.len() as u32) + .map_err(|_| UserError("Invalid attempt to write written_out in ext_get_allocated_storage"))?; Ok(offset) } else { - this.memory.write_primitive(written_out, u32::max_value())?; + this.memory.write_primitive(written_out, u32::max_value()) + .map_err(|_| UserError("Invalid attempt to write failed written_out in ext_get_allocated_storage"))?; Ok(0) } }, // return u32::max_value() if no value exists for the key. ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32 => { - let key = this.memory.get(key_data, key_len as usize).map_err(|_| DummyUserError)?; + let key = this.memory.get(key_data, key_len as usize).map_err(|_| UserError("Invalid attempt to get key in ext_get_storage_into"))?; let maybe_value = this.ext.storage(&key); if let Some(preimage) = this.hash_lookup.get(&key) { trace!(target: "wasm-trace", " Getting storage: %{} == {} [k={}]", ascii_format(&preimage), if let Some(ref b) = maybe_value { format!("{}", HexDisplay::from(b)) } else { "<empty>".to_owned() }, HexDisplay::from(&key)); @@ -263,7 +265,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, if let Some(value) = maybe_value { let value = &value[value_offset as usize..]; let written = ::std::cmp::min(value_len as usize, value.len()); - this.memory.set(value_data, &value[..written]).map_err(|_| DummyUserError)?; + this.memory.set(value_data, &value[..written]).map_err(|_| UserError("Invalid attempt to set value in ext_get_storage_into"))?; Ok(written as u32) } else { Ok(u32::max_value()) @@ -271,22 +273,22 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, }, ext_storage_root(result: *mut u8) => { let r = this.ext.storage_root(); - this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; + this.memory.set(result, &r[..]).map_err(|_| UserError("Invalid attempt to set memory in ext_storage_root"))?; Ok(()) }, ext_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8) => { let values = (0..lens_len) .map(|i| this.memory.read_primitive(lens_data + i * 4)) - .collect::<::std::result::Result<Vec<u32>, DummyUserError>>()? + .collect::<::std::result::Result<Vec<u32>, UserError>>()? .into_iter() .scan(0u32, |acc, v| { let o = *acc; *acc += v; Some((o, v)) }) .map(|(offset, len)| this.memory.get(values_data + offset, len as usize) - .map_err(|_| DummyUserError) + .map_err(|_| UserError("Invalid attempt to get memory in ext_enumerated_trie_root")) ) - .collect::<::std::result::Result<Vec<_>, DummyUserError>>()?; + .collect::<::std::result::Result<Vec<_>, UserError>>()?; let r = ordered_trie_root(values.into_iter()); - this.memory.set(result, &r[..]).map_err(|_| DummyUserError)?; + this.memory.set(result, &r[..]).map_err(|_| UserError("Invalid attempt to set memory in ext_enumerated_trie_root"))?; Ok(()) }, ext_chain_id() -> u64 => { @@ -299,7 +301,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, this.hash_lookup.insert(hashed.to_vec(), vec![]); hashed } else { - let key = this.memory.get(data, len as usize).map_err(|_| DummyUserError)?; + let key = this.memory.get(data, len as usize).map_err(|_| UserError("Invalid attempt to get key in ext_twox_128"))?; let hashed_key = twox_128(&key); if let Ok(skey) = ::std::str::from_utf8(&key) { trace!(target: "xxhash", "XXhash: {} -> {}", skey, HexDisplay::from(&hashed_key)); @@ -310,33 +312,33 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, hashed_key }; - this.memory.set(out, &result).map_err(|_| DummyUserError)?; + this.memory.set(out, &result).map_err(|_| UserError("Invalid attempt to set result in ext_twox_128"))?; Ok(()) }, ext_twox_256(data: *const u8, len: u32, out: *mut u8) => { let result = if len == 0 { twox_256(&[0u8; 0]) } else { - twox_256(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) + twox_256(&this.memory.get(data, len as usize).map_err(|_| UserError("Invalid attempt to get data in ext_twox_256"))?) }; - this.memory.set(out, &result).map_err(|_| DummyUserError)?; + this.memory.set(out, &result).map_err(|_| UserError("Invalid attempt to set result in ext_twox_256"))?; Ok(()) }, ext_blake2_256(data: *const u8, len: u32, out: *mut u8) => { let result = if len == 0 { blake2_256(&[0u8; 0]) } else { - blake2_256(&this.memory.get(data, len as usize).map_err(|_| DummyUserError)?) + blake2_256(&this.memory.get(data, len as usize).map_err(|_| UserError("Invalid attempt to get data in ext_blake2_256"))?) }; - this.memory.set(out, &result).map_err(|_| DummyUserError)?; + this.memory.set(out, &result).map_err(|_| UserError("Invalid attempt to set result in ext_blake2_256"))?; Ok(()) }, ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32 => { let mut sig = [0u8; 64]; - this.memory.get_into(sig_data, &mut sig[..]).map_err(|_| DummyUserError)?; + this.memory.get_into(sig_data, &mut sig[..]).map_err(|_| UserError("Invalid attempt to get signature in ext_ed25519_verify"))?; let mut pubkey = [0u8; 32]; - this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| DummyUserError)?; - let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| DummyUserError)?; + this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| UserError("Invalid attempt to get pubkey in ext_ed25519_verify"))?; + let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| UserError("Invalid attempt to get message in ext_ed25519_verify"))?; Ok(if ::ed25519::verify(&sig, &msg, &pubkey) { 0 @@ -345,15 +347,15 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, }) }, ext_sandbox_instantiate(dispatch_thunk_idx: usize, wasm_ptr: *const u8, wasm_len: usize, imports_ptr: *const u8, imports_len: usize, state: usize) -> u32 => { - let wasm = this.memory.get(wasm_ptr, wasm_len as usize).map_err(|_| DummyUserError)?; - let raw_env_def = this.memory.get(imports_ptr, imports_len as usize).map_err(|_| DummyUserError)?; + let wasm = this.memory.get(wasm_ptr, wasm_len as usize).map_err(|_| UserError("Sandbox error"))?; + let raw_env_def = this.memory.get(imports_ptr, imports_len as usize).map_err(|_| UserError("Sandbox error"))?; // Extract a dispatch thunk from instance's table by the specified index. let dispatch_thunk = { - let table = this.table.as_ref().ok_or_else(|| DummyUserError)?; + let table = this.table.as_ref().ok_or_else(|| UserError("Sandbox error"))?; table.get(dispatch_thunk_idx) - .map_err(|_| DummyUserError)? - .ok_or_else(|| DummyUserError)? + .map_err(|_| UserError("Sandbox error"))? + .ok_or_else(|| UserError("Sandbox error"))? .clone() }; @@ -368,10 +370,10 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, ext_sandbox_invoke(instance_idx: u32, export_ptr: *const u8, export_len: usize, state: usize) -> u32 => { trace!(target: "runtime-sandbox", "invoke, instance_idx={}", instance_idx); let export = this.memory.get(export_ptr, export_len as usize) - .map_err(|_| DummyUserError) + .map_err(|_| UserError("Sandbox error")) .and_then(|b| String::from_utf8(b) - .map_err(|_| DummyUserError) + .map_err(|_| UserError("Sandbox error")) )?; let instance = this.sandbox_store.instance(instance_idx)?; @@ -388,17 +390,17 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, trace!(target: "runtime-sandbox", "invoke, instance_idx={}", instance_idx); let export = this.memory.get(export_ptr, export_len as usize) - .map_err(|_| DummyUserError) + .map_err(|_| UserError("Sandbox error")) .and_then(|b| String::from_utf8(b) - .map_err(|_| DummyUserError) + .map_err(|_| UserError("Sandbox error")) )?; // Deserialize arguments and convert them into wasmi types. let serialized_args = this.memory.get(args_ptr, args_len as usize) - .map_err(|_| DummyUserError)?; + .map_err(|_| UserError("Sandbox error"))?; let args = Vec::<sandbox_primitives::TypedValue>::decode(&mut &serialized_args[..]) - .ok_or_else(|| DummyUserError)? + .ok_or_else(|| UserError("Sandbox error"))? .into_iter() .map(Into::into) .collect::<Vec<_>>(); @@ -412,11 +414,11 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, // Serialize return value and write it back into the memory. sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { if val.len() > return_val_len as usize { - Err(DummyUserError)?; + Err(UserError("Sandbox error"))?; } this.memory .set(return_val_ptr, val) - .map_err(|_| DummyUserError)?; + .map_err(|_| UserError("Sandbox error"))?; Ok(sandbox_primitives::ERR_OK) }) } diff --git a/substrate/substrate/executor/src/wasm_utils.rs b/substrate/substrate/executor/src/wasm_utils.rs index 8bd9f98feb375c0587b350225a337747fc3f9ccb..5459266ba46c09bc35bb3898d2b712bef517e407 100644 --- a/substrate/substrate/executor/src/wasm_utils.rs +++ b/substrate/substrate/executor/src/wasm_utils.rs @@ -21,13 +21,13 @@ use wasmi::nan_preserving_float::{F32, F64}; use std::fmt; #[derive(Debug)] -pub struct DummyUserError; -impl fmt::Display for DummyUserError { +pub struct UserError(pub &'static str); +impl fmt::Display for UserError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "DummyUserError") + write!(f, "UserError: {}", self.0) } } -impl HostError for DummyUserError { +impl HostError for UserError { } pub trait ConvertibleToWasm { const VALUE_TYPE: ValueType; type NativeType; fn to_runtime_value(self) -> RuntimeValue; } diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index c098995d4274051069fb9fbd616145487726a897..3c6b428a74641d1c7b940a014560fef91c12554b 100644 Binary files a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index 11fb0a7073966435624510e56bd740552c5393f9..eea9464baa730120954b01638214360ca57f83e7 100755 Binary files a/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index cc2e8a03c3265cdf173f1a756fea9030e6032ea3..fe3124878830afe197a4894ba430d0b163713e1f 100644 Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index dc9dffdade8135ede20c1573be02836e60b564e5..d2fee52bcda7533157d17e756ab7cab131bca477 100755 Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ