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