diff --git a/substrate/core/client/src/call_executor.rs b/substrate/core/client/src/call_executor.rs
index 9e544604149ba9fb74693c57026976a0966e8764..13ff478f3becb1ef271596256eb6659e1e47e1fd 100644
--- a/substrate/core/client/src/call_executor.rs
+++ b/substrate/core/client/src/call_executor.rs
@@ -169,15 +169,14 @@ where
 	) -> error::Result<Vec<u8>> {
 		let mut changes = OverlayedChanges::default();
 		let state = self.backend.state_at(*id)?;
-		let return_data = state_machine::execute_using_consensus_failure_handler::<
-			_, _, _, _, _, NeverNativeValue, fn() -> _
-		>(
+		let return_data = state_machine::new(
 			&state,
 			self.backend.changes_trie_storage(),
 			&mut changes,
 			&self.executor,
 			method,
 			call_data,
+		).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
 			strategy.get_manager(),
 			false,
 			None,
@@ -209,15 +208,14 @@ where
 		let state = self.backend.state_at(*at)?;
 		if method != "Core_initialise_block" && initialised_block.map(|id| id != *at).unwrap_or(true) {
 			let header = prepare_environment_block()?;
-			state_machine::execute_using_consensus_failure_handler::<
-				_, _, _, _, _, R, fn() -> _,
-			>(
+			state_machine::new(
 				&state,
 				self.backend.changes_trie_storage(),
 				changes,
 				&self.executor,
 				"Core_initialise_block",
 				&header.encode(),
+			).execute_using_consensus_failure_handler::<_, R, fn() -> _>(
 				execution_manager.clone(),
 				false,
 				None,
@@ -225,13 +223,14 @@ where
 			*initialised_block = Some(*at);
 		}
 
-		let result = state_machine::execute_using_consensus_failure_handler(
+		let result = state_machine::new(
 			&state,
 			self.backend.changes_trie_storage(),
 			changes,
 			&self.executor,
 			method,
 			call_data,
+		).execute_using_consensus_failure_handler(
 			execution_manager,
 			false,
 			native_call,
@@ -270,13 +269,14 @@ where
 		manager: ExecutionManager<F>,
 		native_call: Option<NC>,
 	) -> error::Result<(NativeOrEncoded<R>, S::Transaction, Option<MemoryDB<Blake2Hasher>>)> {
-		state_machine::execute_using_consensus_failure_handler(
+		state_machine::new(
 			state,
 			self.backend.changes_trie_storage(),
 			changes,
 			&self.executor,
 			method,
 			call_data,
+		).execute_using_consensus_failure_handler(
 			manager,
 			true,
 			native_call,
diff --git a/substrate/core/client/src/genesis.rs b/substrate/core/client/src/genesis.rs
index 2dc8df08aa91d74e55af528c951b8f4da7c21178..a048433d39b561a1e535b6067ee9e3a043a83b46 100644
--- a/substrate/core/client/src/genesis.rs
+++ b/substrate/core/client/src/genesis.rs
@@ -43,7 +43,7 @@ mod tests {
 	use parity_codec::{Encode, Decode, Joiner};
 	use keyring::Keyring;
 	use executor::{NativeExecutionDispatch, native_executor_instance};
-	use state_machine::{execute, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage};
+	use state_machine::{self, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage};
 	use state_machine::backend::InMemory;
 	use test_client::runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
 	use test_client::runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest, Extrinsic};
@@ -86,35 +86,38 @@ mod tests {
 		let hash = header.hash();
 		let mut overlay = OverlayedChanges::default();
 
-		execute(
+		state_machine::new(
 			backend,
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut overlay,
 			&executor(),
 			"Core_initialise_block",
 			&header.encode(),
+		).execute(
 			ExecutionStrategy::NativeElseWasm,
 		).unwrap();
 
 		for tx in transactions.iter() {
-			execute(
+			state_machine::new(
 				backend,
 				Some(&InMemoryChangesTrieStorage::new()),
 				&mut overlay,
 				&executor(),
 				"BlockBuilder_apply_extrinsic",
 				&tx.encode(),
+			).execute(
 				ExecutionStrategy::NativeElseWasm,
 			).unwrap();
 		}
 
-		let (ret_data, _, _) = execute(
+		let (ret_data, _, _) = state_machine::new(
 			backend,
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut overlay,
 			&executor(),
 			"BlockBuilder_finalise_block",
 			&[],
+		).execute(
 			ExecutionStrategy::NativeElseWasm,
 		).unwrap();
 		header = Header::decode(&mut &ret_data[..]).unwrap();
@@ -152,13 +155,14 @@ mod tests {
 		let (b1data, _b1hash) = block1(genesis_hash, &backend);
 
 		let mut overlay = OverlayedChanges::default();
-		let _ = execute(
+		let _ = state_machine::new(
 			&backend,
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut overlay,
 			&executor(),
 			"Core_execute_block",
 			&b1data,
+		).execute(
 			ExecutionStrategy::NativeElseWasm,
 		).unwrap();
 	}
@@ -177,13 +181,14 @@ mod tests {
 		let (b1data, _b1hash) = block1(genesis_hash, &backend);
 
 		let mut overlay = OverlayedChanges::default();
-		let _ = execute(
+		let _ = state_machine::new(
 			&backend,
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut overlay,
 			&executor(),
 			"Core_execute_block",
 			&b1data,
+		).execute(
 			ExecutionStrategy::AlwaysWasm,
 		).unwrap();
 	}
@@ -203,13 +208,14 @@ mod tests {
 		let (b1data, _b1hash) = block1(genesis_hash, &backend);
 
 		let mut overlay = OverlayedChanges::default();
-		let _ = execute(
+		let _ = state_machine::new(
 			&backend,
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut overlay,
 			&Executor::new(None),
 			"Core_execute_block",
 			&b1data,
+		).execute(
 			ExecutionStrategy::NativeElseWasm,
 		).unwrap();
 	}
diff --git a/substrate/core/state-machine/src/lib.rs b/substrate/core/state-machine/src/lib.rs
index 4e3535cfb040e7df509635e541c23a351906f640..3b9e482e8211f0c697fd64e73f2622ae57f0b66f 100644
--- a/substrate/core/state-machine/src/lib.rs
+++ b/substrate/core/state-machine/src/lib.rs
@@ -18,7 +18,7 @@
 
 #![warn(missing_docs)]
 
-use std::{fmt, panic::UnwindSafe, result};
+use std::{fmt, panic::UnwindSafe, result, marker::PhantomData};
 use log::warn;
 use hash_db::Hasher;
 use heapsize::HeapSizeOf;
@@ -81,6 +81,8 @@ impl fmt::Display for ExecutionError {
 	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Externalities Error") }
 }
 
+type CallResult<R, E> = Result<NativeOrEncoded<R>, E>;
+
 /// Externalities: pinned to specific active address.
 pub trait Externalities<H: Hasher> {
 	/// Read runtime storage.
@@ -167,7 +169,7 @@ pub trait CodeExecutor<H: Hasher>: Sized + Send + Sync {
 		data: &[u8],
 		use_native: bool,
 		native_call: Option<NC>,
-	) -> (Result<NativeOrEncoded<R>, Self::Error>, bool);
+	) -> (CallResult<R, Self::Error>, bool);
 }
 
 /// Strategy for executing a call into the runtime.
@@ -183,6 +185,11 @@ pub enum ExecutionStrategy {
 	NativeElseWasm,
 }
 
+type DefaultHandler<R, E> = fn(
+	CallResult<R, E>,
+	CallResult<R, E>,
+) -> CallResult<R, E>;
+
 /// Like `ExecutionStrategy` only it also stores a handler in case of consensus failure.
 #[derive(Clone)]
 pub enum ExecutionManager<F> {
@@ -209,12 +216,7 @@ impl<'a, F> From<&'a ExecutionManager<F>> for ExecutionStrategy {
 
 impl ExecutionStrategy {
 	/// Gets the corresponding manager for the execution strategy.
-	pub fn get_manager<E: std::fmt::Debug, R: Decode + Encode>(self) -> 
-		ExecutionManager<fn(
-			Result<NativeOrEncoded<R>, E>,
-			Result<NativeOrEncoded<R>, E>
-		) -> Result<NativeOrEncoded<R>, E>> 
-		{
+	pub fn get_manager<E: std::fmt::Debug, R: Decode + Encode>(self) -> ExecutionManager<DefaultHandler<R, E>> {
 		match self {
 			ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm,
 			ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible,
@@ -231,278 +233,229 @@ impl ExecutionStrategy {
 	}
 }
 
+
 /// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type.
-pub fn native_when_possible<E, R: Decode>() ->
-	ExecutionManager<
-		fn(
-			Result<NativeOrEncoded<R>, E>,
-			Result<NativeOrEncoded<R>, E>
-		) -> Result<NativeOrEncoded<R>, E>
-	>
-{
-	ExecutionManager::NativeWhenPossible
+pub fn native_when_possible<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
+	 ExecutionManager::NativeWhenPossible
 }
 
 /// Evaluate to ExecutionManager::NativeElseWasm, without having to figure out the type.
-pub fn native_else_wasm<E, R: Decode>() ->
-	ExecutionManager<
-		fn(
-			Result<NativeOrEncoded<R>, E>,
-			Result<NativeOrEncoded<R>, E>
-		) -> Result<NativeOrEncoded<R>, E>
-	>
-{
+pub fn native_else_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
 	ExecutionManager::NativeElseWasm
 }
 
 /// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type.
-pub fn always_wasm<E, R: Decode>() ->
-	ExecutionManager<
-		fn(
-			Result<NativeOrEncoded<R>, E>,
-			Result<NativeOrEncoded<R>, E>
-		) -> Result<NativeOrEncoded<R>, E>
-	>
-{
+pub fn always_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
 	ExecutionManager::AlwaysWasm
 }
 
-/// Execute a call using the given state backend, overlayed changes, and call executor.
-/// Produces a state-backend-specific "transaction" which can be used to apply the changes
-/// to the backing store, such as the disk.
-///
-/// On an error, no prospective changes are written to the overlay.
-///
-/// Note: changes to code will be in place if this call is made again. For running partial
-/// blocks (e.g. a transaction at a time), ensure a different method is used.
-pub fn execute<H, B, T, Exec>(
-	backend: &B,
-	changes_trie_storage: Option<&T>,
-	overlay: &mut OverlayedChanges,
-	exec: &Exec,
-	method: &str,
-	call_data: &[u8],
-	strategy: ExecutionStrategy,
-) -> Result<(Vec<u8>, B::Transaction, Option<MemoryDB<H>>), Box<Error>>
-where
-	H: Hasher,
-	Exec: CodeExecutor<H>,
-	B: Backend<H>,
-	T: ChangesTrieStorage<H>,
-	H::Out: Ord + HeapSizeOf,
-{
-	// We are not giving a native call and thus we are sure that the result can never be a native
-	// value.
-	execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> _>(
+/// Creates new substrate state machine.
+pub fn new<'a, H, B, T, Exec>(
+	backend: &'a B,
+	changes_trie_storage: Option<&'a T>,
+	overlay: &'a mut OverlayedChanges,
+	exec: &'a Exec,
+	method: &'a str,
+	call_data: &'a [u8],
+) -> StateMachine<'a, H, B, T, Exec> {
+	StateMachine {
 		backend,
 		changes_trie_storage,
 		overlay,
 		exec,
 		method,
 		call_data,
-		strategy.get_manager(),
-		true,
-		None,
-	)
-	.map(|(result, storage_tx, changes_tx)| (
-		result.into_encoded(),
-		storage_tx.expect("storage_tx is always computed when compute_tx is true; qed"),
-		changes_tx,
-	))
+		_hasher: PhantomData,
+	}
 }
 
-
-fn execute_aux<H, B, T, Exec, R: Decode + Encode + PartialEq, 
-	NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe>(
-	overlay: &mut OverlayedChanges,
-	backend: &B,
-	changes_trie_storage: Option<&T>,
-	exec: &Exec,
-	method: &str,
-	call_data: &[u8],
-	compute_tx: bool,
-	use_native: bool,
-	native_call: Option<NC>,
-) -> (Result<NativeOrEncoded<R>, Exec::Error>, bool, Option<B::Transaction>, Option<MemoryDB<H>>)
-where
-	H: Hasher,
-	Exec: CodeExecutor<H>,
-	B: Backend<H>,
-	T: ChangesTrieStorage<H>,
-	H::Out: Ord + HeapSizeOf
-{
-	let mut externalities = ext::Ext::new(overlay, backend, changes_trie_storage);
-	let (result, was_native) = exec.call(
-		&mut externalities,
-		method,
-		call_data,
-		use_native,
-		native_call,
-	);
-	let (storage_delta, changes_delta) = if compute_tx {
-		let (storage_delta, changes_delta) = externalities.transaction();
-		(Some(storage_delta), changes_delta)
-	} else {
-		(None, None)
-	};
-	(result, was_native, storage_delta, changes_delta)
+/// The substrate state machine.
+pub struct StateMachine<'a, H, B, T, Exec> {
+	backend: &'a B,
+	changes_trie_storage: Option<&'a T>,
+	overlay: &'a mut OverlayedChanges,
+	exec: &'a Exec,
+	method: &'a str,
+	call_data: &'a [u8],
+	_hasher: PhantomData<H>,
 }
 
-fn execute_call_with_both_strategy<H, B, T, Exec,  Handler, R: Decode + Encode + PartialEq,
-	NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe>(
-	overlay: &mut OverlayedChanges,
-	backend: &B,
-	changes_trie_storage: Option<&T>,
-	exec: &Exec,
-	method: &str,
-	call_data: &[u8],
-	compute_tx: bool,
-	mut native_call: Option<NC>,
-	orig_prospective: OverlayedChangeSet,
-	on_consensus_failure: Handler,
-) -> (Result<NativeOrEncoded<R>, Exec::Error>, Option<B::Transaction>, Option<MemoryDB<H>>)
-where
+impl<'a, H, B, T, Exec> StateMachine<'a, H, B, T, Exec> where
 	H: Hasher,
 	Exec: CodeExecutor<H>,
 	B: Backend<H>,
 	T: ChangesTrieStorage<H>,
 	H::Out: Ord + HeapSizeOf,
-	Handler: FnOnce(
-		Result<NativeOrEncoded<R>, Exec::Error>,
-		Result<NativeOrEncoded<R>, Exec::Error>
-	) -> Result<NativeOrEncoded<R>, Exec::Error>
 {
-	let (result, was_native, storage_delta, changes_delta) = execute_aux(overlay, backend, changes_trie_storage, 
-		exec, method, call_data, compute_tx, true, native_call.take());
+	/// Execute a call using the given state backend, overlayed changes, and call executor.
+	/// Produces a state-backend-specific "transaction" which can be used to apply the changes
+	/// to the backing store, such as the disk.
+	///
+	/// On an error, no prospective changes are written to the overlay.
+	///
+	/// Note: changes to code will be in place if this call is made again. For running partial
+	/// blocks (e.g. a transaction at a time), ensure a different method is used.
+	pub fn execute(
+		&mut self,
+		strategy: ExecutionStrategy,
+	) -> Result<(Vec<u8>, B::Transaction, Option<MemoryDB<H>>), Box<Error>> {
+		// We are not giving a native call and thus we are sure that the result can never be a native
+		// value.
+		self.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
+			strategy.get_manager(),
+			true,
+			None,
+		)
+		.map(|(result, storage_tx, changes_tx)| (
+			result.into_encoded(),
+			storage_tx.expect("storage_tx is always computed when compute_tx is true; qed"),
+			changes_tx,
+		))
+	}
 
-	if was_native {
-		overlay.prospective = orig_prospective.clone();
-		let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = execute_aux(overlay, backend, changes_trie_storage, 
-			exec, method, call_data, compute_tx, false, native_call);	
+	fn execute_aux<R, NC>(
+		&mut self,
+		compute_tx: bool,
+		use_native: bool,
+		native_call: Option<NC>,
+	) -> (CallResult<R, Exec::Error>, bool, Option<B::Transaction>, Option<MemoryDB<H>>) where
+		R: Decode + Encode + PartialEq,
+		NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe,
+	{
+		let mut externalities = ext::Ext::new(self.overlay, self.backend, self.changes_trie_storage);
+		let (result, was_native) = self.exec.call(
+			&mut externalities,
+			self.method,
+			self.call_data,
+			use_native,
+			native_call,
+		);
+		let (storage_delta, changes_delta) = if compute_tx {
+			let (storage_delta, changes_delta) = externalities.transaction();
+			(Some(storage_delta), changes_delta)
+		} else {
+			(None, None)
+		};
+		(result, was_native, storage_delta, changes_delta)
+	}
 
-		if (result.is_ok() && wasm_result.is_ok()
-			&& result.as_ref().ok() == wasm_result.as_ref().ok())
-			|| result.is_err() && wasm_result.is_err() {
-			(result, storage_delta, changes_delta)
+	fn execute_call_with_both_strategy<Handler, R, NC>(
+		&mut self,
+		compute_tx: bool,
+		mut native_call: Option<NC>,
+		orig_prospective: OverlayedChangeSet,
+		on_consensus_failure: Handler,
+	) -> (CallResult<R, Exec::Error>, Option<B::Transaction>, Option<MemoryDB<H>>) where
+		R: Decode + Encode + PartialEq,
+		NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe,
+		Handler: FnOnce(
+			CallResult<R, Exec::Error>,
+			CallResult<R, Exec::Error>
+		) -> CallResult<R, Exec::Error>
+	{
+		let (result, was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call.take());
+
+		if was_native {
+			self.overlay.prospective = orig_prospective.clone();
+			let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux(compute_tx, false, native_call);
+
+			if (result.is_ok() && wasm_result.is_ok()
+				&& result.as_ref().ok() == wasm_result.as_ref().ok())
+				|| result.is_err() && wasm_result.is_err() {
+				(result, storage_delta, changes_delta)
+			} else {
+				(on_consensus_failure(wasm_result, result), wasm_storage_delta, wasm_changes_delta)
+			}
 		} else {
-			(on_consensus_failure(wasm_result, result), wasm_storage_delta, wasm_changes_delta)
+			(result, storage_delta, changes_delta)
 		}
-	} else {
-		(result, storage_delta, changes_delta)
 	}
-}
 
-fn execute_call_with_native_else_wasm_strategy<H, B, T, Exec, R: Decode + Encode + PartialEq,
-	NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe>(
-	overlay: &mut OverlayedChanges,
-	backend: &B,
-	changes_trie_storage: Option<&T>,
-	exec: &Exec,
-	method: &str,
-	call_data: &[u8],
-	compute_tx: bool,
-	mut native_call: Option<NC>,
-	orig_prospective: OverlayedChangeSet,
-) -> (Result<NativeOrEncoded<R>, Exec::Error>, Option<B::Transaction>, Option<MemoryDB<H>>)
-where
-	H: Hasher,
-	Exec: CodeExecutor<H>,
-	B: Backend<H>,
-	T: ChangesTrieStorage<H>,
-	H::Out: Ord + HeapSizeOf,
-{
-	let (result, was_native, storage_delta, changes_delta) = execute_aux(overlay, backend, changes_trie_storage, 
-		exec, method, call_data, compute_tx, true, native_call.take());
-
-	if !was_native || result.is_ok() {
-		(result, storage_delta, changes_delta)
-	} else {
-		overlay.prospective = orig_prospective.clone();
-		let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = execute_aux(overlay, backend,
-			changes_trie_storage, exec, method, call_data, compute_tx, false, native_call);
-		(wasm_result, wasm_storage_delta, wasm_changes_delta)
+	fn execute_call_with_native_else_wasm_strategy<R, NC>(
+		&mut self,
+		compute_tx: bool,
+		mut native_call: Option<NC>,
+		orig_prospective: OverlayedChangeSet,
+	) -> (CallResult<R, Exec::Error>, Option<B::Transaction>, Option<MemoryDB<H>>) where
+		R: Decode + Encode + PartialEq,
+		NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe,
+	{
+		let (result, was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call.take());
+
+		if !was_native || result.is_ok() {
+			(result, storage_delta, changes_delta)
+		} else {
+			self.overlay.prospective = orig_prospective.clone();
+			let (wasm_result, _, wasm_storage_delta, wasm_changes_delta) = self.execute_aux(compute_tx, false, native_call);
+			(wasm_result, wasm_storage_delta, wasm_changes_delta)
+		}
 	}
-}
 
-/// Execute a call using the given state backend, overlayed changes, and call executor.
-/// Produces a state-backend-specific "transaction" which can be used to apply the changes
-/// to the backing store, such as the disk.
-///
-/// On an error, no prospective changes are written to the overlay.
-///
-/// Note: changes to code will be in place if this call is made again. For running partial
-/// blocks (e.g. a transaction at a time), ensure a different method is used.
-pub fn execute_using_consensus_failure_handler<
-	H, B, T, Exec, Handler, R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe
->(
-	backend: &B,
-	changes_trie_storage: Option<&T>,
-	overlay: &mut OverlayedChanges,
-	exec: &Exec,
-	method: &str,
-	call_data: &[u8],
-	manager: ExecutionManager<Handler>,
-	compute_tx: bool,
-	mut native_call: Option<NC>,
-) -> Result<(NativeOrEncoded<R>, Option<B::Transaction>, Option<MemoryDB<H>>), Box<Error>>
-where
-	H: Hasher,
-	Exec: CodeExecutor<H>,
-	B: Backend<H>,
-	T: ChangesTrieStorage<H>,
-	H::Out: Ord + HeapSizeOf,
-	Handler: FnOnce(
-		Result<NativeOrEncoded<R>, Exec::Error>,
-		Result<NativeOrEncoded<R>, Exec::Error>
-	) -> Result<NativeOrEncoded<R>, Exec::Error>
-{
-	// read changes trie configuration. The reason why we're doing it here instead of the
-	// `OverlayedChanges` constructor is that we need proofs for this read as a part of
-	// proof-of-execution on light clients. And the proof is recorded by the backend which
-	// is created after OverlayedChanges
-
-	let init_overlay = |overlay: &mut OverlayedChanges, final_check: bool| {
-		let changes_trie_config = try_read_overlay_value(
-			overlay,
-			backend,
-			well_known_keys::CHANGES_TRIE_CONFIG
-		)?;
-		set_changes_trie_config(overlay, changes_trie_config, final_check)
-	};
-	init_overlay(overlay, false)?;
-
-	let result = {
-		let orig_prospective = overlay.prospective.clone();
-		
-		let (result, storage_delta, changes_delta) = match manager {
-			ExecutionManager::Both(on_consensus_failure) => {
-				execute_call_with_both_strategy(overlay, backend, changes_trie_storage, 
-					exec, method, call_data, compute_tx, native_call.take(),
-					orig_prospective, on_consensus_failure)
-			},
-			ExecutionManager::NativeElseWasm => {
-				execute_call_with_native_else_wasm_strategy(overlay, backend, changes_trie_storage, 
-					exec, method, call_data, compute_tx, native_call.take(), orig_prospective)
-			},
-			ExecutionManager::AlwaysWasm => {
-				let (result, _, storage_delta, changes_delta) = execute_aux(overlay, backend, changes_trie_storage, 
-					exec, method, call_data, compute_tx, false, native_call);
-				(result, storage_delta, changes_delta)
-			},
-			ExecutionManager::NativeWhenPossible => {
-				let (result, _was_native, storage_delta, changes_delta) = execute_aux(overlay, backend, changes_trie_storage, 
-					exec, method, call_data, compute_tx, true, native_call);
-				(result, storage_delta, changes_delta)
-			},
+	/// Execute a call using the given state backend, overlayed changes, and call executor.
+	/// Produces a state-backend-specific "transaction" which can be used to apply the changes
+	/// to the backing store, such as the disk.
+	///
+	/// On an error, no prospective changes are written to the overlay.
+	///
+	/// Note: changes to code will be in place if this call is made again. For running partial
+	/// blocks (e.g. a transaction at a time), ensure a different method is used.
+	pub fn execute_using_consensus_failure_handler<Handler, R, NC>(
+		&mut self,
+		manager: ExecutionManager<Handler>,
+		compute_tx: bool,
+		mut native_call: Option<NC>,
+	) -> Result<(NativeOrEncoded<R>, Option<B::Transaction>, Option<MemoryDB<H>>), Box<Error>> where
+		R: Decode + Encode + PartialEq,
+		NC: FnOnce() -> result::Result<R, &'static str> + UnwindSafe,
+		Handler: FnOnce(
+			CallResult<R, Exec::Error>,
+			CallResult<R, Exec::Error>
+		) -> CallResult<R, Exec::Error>
+	{
+		// read changes trie configuration. The reason why we're doing it here instead of the
+		// `OverlayedChanges` constructor is that we need proofs for this read as a part of
+		// proof-of-execution on light clients. And the proof is recorded by the backend which
+		// is created after OverlayedChanges
+
+		let backend = self.backend.clone();
+		let init_overlay = |overlay: &mut OverlayedChanges, final_check: bool| {
+			let changes_trie_config = try_read_overlay_value(
+				overlay,
+				backend,
+				well_known_keys::CHANGES_TRIE_CONFIG
+			)?;
+			set_changes_trie_config(overlay, changes_trie_config, final_check)
 		};
-		result.map(move |out| (out, storage_delta, changes_delta))
-	};
+		init_overlay(self.overlay, false)?;
 
-	if result.is_ok() {
-		init_overlay(overlay, true)?;
-	}
+		let result = {
+			let orig_prospective = self.overlay.prospective.clone();
+
+			let (result, storage_delta, changes_delta) = match manager {
+				ExecutionManager::Both(on_consensus_failure) => {
+					self.execute_call_with_both_strategy(compute_tx, native_call.take(), orig_prospective, on_consensus_failure)
+				},
+				ExecutionManager::NativeElseWasm => {
+					self.execute_call_with_native_else_wasm_strategy(compute_tx, native_call.take(), orig_prospective)
+				},
+				ExecutionManager::AlwaysWasm => {
+					let (result, _, storage_delta, changes_delta) = self.execute_aux(compute_tx, false, native_call);
+					(result, storage_delta, changes_delta)
+				},
+				ExecutionManager::NativeWhenPossible => {
+					let (result, _was_native, storage_delta, changes_delta) = self.execute_aux(compute_tx, true, native_call);
+					(result, storage_delta, changes_delta)
+				},
+			};
+			result.map(move |out| (out, storage_delta, changes_delta))
+		};
 
-	result.map_err(|e| Box::new(e) as _)
+		if result.is_ok() {
+			init_overlay(self.overlay, true)?;
+		}
+
+		result.map_err(|e| Box::new(e) as _)
+	}
 }
 
 /// Prove execution using the given state backend, overlayed changes, and call executor.
@@ -547,15 +500,16 @@ where
 	H::Out: Ord + HeapSizeOf,
 {
 	let proving_backend = proving_backend::ProvingBackend::new(trie_backend);
-	let (result, _, _) = execute_using_consensus_failure_handler::
-		<H, _, changes_trie::InMemoryStorage<H>, _, _, NeverNativeValue, fn() -> _>
-	(
-		&proving_backend,
-		None,
+	let mut sm = StateMachine {
+		backend: &proving_backend,
+		changes_trie_storage: None as Option<&changes_trie::InMemoryStorage<H>>,
 		overlay,
 		exec,
 		method,
 		call_data,
+		_hasher: PhantomData,
+	};
+	let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
 		native_else_wasm(),
 		false,
 		None,
@@ -595,15 +549,16 @@ where
 	Exec: CodeExecutor<H>,
 	H::Out: Ord + HeapSizeOf,
 {
-	execute_using_consensus_failure_handler::
-		<H, _, changes_trie::InMemoryStorage<H>, _, _, NeverNativeValue, fn() -> _>
-	(
-		trie_backend,
-		None,
+	let mut sm = StateMachine {
+		backend: trie_backend,
+		changes_trie_storage: None as Option<&changes_trie::InMemoryStorage<H>>,
 		overlay,
 		exec,
 		method,
 		call_data,
+		_hasher: PhantomData,
+	};
+	sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
 		native_else_wasm(),
 		false,
 		None,
@@ -733,7 +688,7 @@ mod tests {
 			_data: &[u8],
 			use_native: bool,
 			_native_call: Option<NC>,
-		) -> (Result<NativeOrEncoded<R>, Self::Error>, bool) {
+		) -> (CallResult<R, Self::Error>, bool) {
 			if self.change_changes_trie_config {
 				ext.place_storage(
 					well_known_keys::CHANGES_TRIE_CONFIG.to_vec(),
@@ -770,7 +725,7 @@ mod tests {
 
 	#[test]
 	fn execute_works() {
-		assert_eq!(execute(
+		assert_eq!(new(
 			&trie_backend::tests::test_trie(),
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut Default::default(),
@@ -782,6 +737,7 @@ mod tests {
 			},
 			"test",
 			&[],
+		).execute(
 			ExecutionStrategy::NativeWhenPossible
 		).unwrap().0, vec![66]);
 	}
@@ -789,7 +745,7 @@ mod tests {
 
 	#[test]
 	fn execute_works_with_native_else_wasm() {
-		assert_eq!(execute(
+		assert_eq!(new(
 			&trie_backend::tests::test_trie(),
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut Default::default(),
@@ -801,6 +757,7 @@ mod tests {
 			},
 			"test",
 			&[],
+		).execute(
 			ExecutionStrategy::NativeElseWasm
 		).unwrap().0, vec![66]);
 	}
@@ -808,7 +765,7 @@ mod tests {
 	#[test]
 	fn dual_execution_strategy_detects_consensus_failure() {
 		let mut consensus_failed = false;
-		assert!(execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> _>(
+		assert!(new(
 			&trie_backend::tests::test_trie(),
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut Default::default(),
@@ -820,6 +777,7 @@ mod tests {
 			},
 			"test",
 			&[],
+		).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
 			ExecutionManager::Both(|we, _ne| {
 				consensus_failed = true;
 				println!("HELLO!");
@@ -926,7 +884,7 @@ mod tests {
 
 	#[test]
 	fn cannot_change_changes_trie_config() {
-		assert!(execute(
+		assert!(new(
 			&trie_backend::tests::test_trie(),
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut Default::default(),
@@ -938,13 +896,14 @@ mod tests {
 			},
 			"test",
 			&[],
+		).execute(
 			ExecutionStrategy::NativeWhenPossible
 		).is_err());
 	}
 
 	#[test]
 	fn cannot_change_changes_trie_config_with_native_else_wasm() {
-		assert!(execute(
+		assert!(new(
 			&trie_backend::tests::test_trie(),
 			Some(&InMemoryChangesTrieStorage::new()),
 			&mut Default::default(),
@@ -956,6 +915,7 @@ mod tests {
 			},
 			"test",
 			&[],
+		).execute(
 			ExecutionStrategy::NativeElseWasm
 		).is_err());
 	}