From d9cffa0bb57f86fbd6b6748bd78402254a2de441 Mon Sep 17 00:00:00 2001
From: cheme <emericchevalier.pro@gmail.com>
Date: Fri, 18 Oct 2019 09:52:25 +0200
Subject: [PATCH] Code redundancy between ext implementation and testing.
 (#3830)

* fix child_storage_hash

* extract common implementation for ext and testing

* cleaning impl.

* replace ExtBasisMut by actual Ext

* remove extbasis.

* Update tests to use Ext from test externalities.

* use Ext constructor for getting ext from TestExternalities.

* Add missing extensions from ext.

* fix wasmi test

* Fix merge error.
---
 substrate/core/executor/src/lib.rs            |   1 +
 substrate/core/executor/src/sandbox.rs        |  10 +
 .../core/executor/src/wasmi_execution.rs      |  70 ++++---
 substrate/core/state-machine/src/ext.rs       |  28 +--
 substrate/core/state-machine/src/testing.rs   | 176 ++----------------
 .../core/state-machine/src/trie_backend.rs    |   2 +-
 substrate/core/test-runtime/src/system.rs     |   6 +-
 substrate/node/executor/src/lib.rs            |  89 +++++----
 8 files changed, 151 insertions(+), 231 deletions(-)

diff --git a/substrate/core/executor/src/lib.rs b/substrate/core/executor/src/lib.rs
index 582ebbca349..ac98388cd7b 100644
--- a/substrate/core/executor/src/lib.rs
+++ b/substrate/core/executor/src/lib.rs
@@ -98,6 +98,7 @@ mod tests {
 	#[test]
 	fn call_in_interpreted_wasm_works() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let res = call_in_wasm(
 			"test_empty_return",
 			&[],
diff --git a/substrate/core/executor/src/sandbox.rs b/substrate/core/executor/src/sandbox.rs
index c4122274a9d..e1e9e0db952 100644
--- a/substrate/core/executor/src/sandbox.rs
+++ b/substrate/core/executor/src/sandbox.rs
@@ -610,6 +610,7 @@ mod tests {
 	#[test]
 	fn sandbox_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -642,6 +643,7 @@ mod tests {
 	#[test]
 	fn sandbox_trap() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -663,6 +665,7 @@ mod tests {
 	#[test]
 	fn sandbox_should_trap_when_heap_exhausted() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -691,6 +694,7 @@ mod tests {
 	#[test]
 	fn start_called() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -729,6 +733,7 @@ mod tests {
 	#[test]
 	fn invoke_args() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -763,6 +768,7 @@ mod tests {
 	#[test]
 	fn return_val() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -785,6 +791,7 @@ mod tests {
 	#[test]
 	fn unlinkable_module() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -805,6 +812,7 @@ mod tests {
 	#[test]
 	fn corrupted_module() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		// Corrupted wasm file
@@ -819,6 +827,7 @@ mod tests {
 	#[test]
 	fn start_fn_ok() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
@@ -842,6 +851,7 @@ mod tests {
 	#[test]
 	fn start_fn_traps() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let code = wabt::wat2wasm(r#"
diff --git a/substrate/core/executor/src/wasmi_execution.rs b/substrate/core/executor/src/wasmi_execution.rs
index ba7738a9937..2b832b49064 100644
--- a/substrate/core/executor/src/wasmi_execution.rs
+++ b/substrate/core/executor/src/wasmi_execution.rs
@@ -681,6 +681,7 @@ mod tests {
 	#[test]
 	fn returning_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let output = call(&mut ext, 8, &test_code[..], "test_empty_return", &[]).unwrap();
@@ -690,6 +691,7 @@ mod tests {
 	#[test]
 	fn panicking_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 
 		let output = call(&mut ext, 8, &test_code[..], "test_panic", &[]);
@@ -705,18 +707,22 @@ mod tests {
 	#[test]
 	fn storage_should_work() {
 		let mut ext = TestExternalities::default();
-		ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
-		let test_code = WASM_BINARY;
 
-		let output = call(
-			&mut ext,
-			8,
-			&test_code[..],
-			"test_data_in",
-			&b"Hello world".to_vec().encode(),
-		).unwrap();
+		{
+			let mut ext = ext.ext();
+			ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
+			let test_code = WASM_BINARY;
+
+			let output = call(
+				&mut ext,
+				8,
+				&test_code[..],
+				"test_data_in",
+				&b"Hello world".to_vec().encode(),
+			).unwrap();
 
-		assert_eq!(output, b"all ok!".to_vec().encode());
+			assert_eq!(output, b"all ok!".to_vec().encode());
+		}
 
 		let expected = TestExternalities::new((map![
 			b"input".to_vec() => b"Hello world".to_vec(),
@@ -729,23 +735,26 @@ mod tests {
 	#[test]
 	fn clear_prefix_should_work() {
 		let mut ext = TestExternalities::default();
-		ext.set_storage(b"aaa".to_vec(), b"1".to_vec());
-		ext.set_storage(b"aab".to_vec(), b"2".to_vec());
-		ext.set_storage(b"aba".to_vec(), b"3".to_vec());
-		ext.set_storage(b"abb".to_vec(), b"4".to_vec());
-		ext.set_storage(b"bbb".to_vec(), b"5".to_vec());
-		let test_code = WASM_BINARY;
-
-		// This will clear all entries which prefix is "ab".
-		let output = call(
-			&mut ext,
-			8,
-			&test_code[..],
-			"test_clear_prefix",
-			&b"ab".to_vec().encode(),
-		).unwrap();
+		{
+			let mut ext = ext.ext();
+			ext.set_storage(b"aaa".to_vec(), b"1".to_vec());
+			ext.set_storage(b"aab".to_vec(), b"2".to_vec());
+			ext.set_storage(b"aba".to_vec(), b"3".to_vec());
+			ext.set_storage(b"abb".to_vec(), b"4".to_vec());
+			ext.set_storage(b"bbb".to_vec(), b"5".to_vec());
+			let test_code = WASM_BINARY;
+
+			// This will clear all entries which prefix is "ab".
+			let output = call(
+				&mut ext,
+				8,
+				&test_code[..],
+				"test_clear_prefix",
+				&b"ab".to_vec().encode(),
+			).unwrap();
 
-		assert_eq!(output, b"all ok!".to_vec().encode());
+			assert_eq!(output, b"all ok!".to_vec().encode());
+		}
 
 		let expected = TestExternalities::new((map![
 			b"aaa".to_vec() => b"1".to_vec(),
@@ -758,6 +767,7 @@ mod tests {
 	#[test]
 	fn blake2_256_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 		assert_eq!(
 			call(&mut ext, 8, &test_code[..], "test_blake2_256", &[0]).unwrap(),
@@ -778,6 +788,7 @@ mod tests {
 	#[test]
 	fn blake2_128_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 		assert_eq!(
 			call(&mut ext, 8, &test_code[..], "test_blake2_128", &[0]).unwrap(),
@@ -798,6 +809,7 @@ mod tests {
 	#[test]
 	fn twox_256_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 		assert_eq!(
 			call(&mut ext, 8, &test_code[..], "test_twox_256", &[0]).unwrap(),
@@ -822,6 +834,7 @@ mod tests {
 	#[test]
 	fn twox_128_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 		assert_eq!(
 			call(&mut ext, 8, &test_code[..], "test_twox_128", &[0]).unwrap(),
@@ -842,6 +855,7 @@ mod tests {
 	#[test]
 	fn ed25519_verify_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 		let key = ed25519::Pair::from_seed(&blake2_256(b"test"));
 		let sig = key.sign(b"all ok!");
@@ -868,6 +882,7 @@ mod tests {
 	#[test]
 	fn sr25519_verify_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let test_code = WASM_BINARY;
 		let key = sr25519::Pair::from_seed(&blake2_256(b"test"));
 		let sig = key.sign(b"all ok!");
@@ -894,6 +909,7 @@ mod tests {
 	#[test]
 	fn ordered_trie_root_should_work() {
 		let mut ext = TestExternalities::default();
+		let mut ext = ext.ext();
 		let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()];
 		let test_code = WASM_BINARY;
 		assert_eq!(
@@ -910,6 +926,7 @@ mod tests {
 		let (offchain, state) = testing::TestOffchainExt::new();
 		ext.register_extension(OffchainExt::new(offchain));
 		let test_code = WASM_BINARY;
+		let mut ext = ext.ext();
 		assert_eq!(
 			call(&mut ext, 8, &test_code[..], "test_offchain_local_storage", &[0]).unwrap(),
 			true.encode(),
@@ -937,6 +954,7 @@ mod tests {
 		);
 
 		let test_code = WASM_BINARY;
+		let mut ext = ext.ext();
 		assert_eq!(
 			call(&mut ext, 8, &test_code[..], "test_offchain_http", &[0]).unwrap(),
 			true.encode(),
diff --git a/substrate/core/state-machine/src/ext.rs b/substrate/core/state-machine/src/ext.rs
index 3433aee92cf..0e93302a95a 100644
--- a/substrate/core/state-machine/src/ext.rs
+++ b/substrate/core/state-machine/src/ext.rs
@@ -32,7 +32,6 @@ use trie::{trie_types::Layout, MemoryDB, default_child_trie_root};
 use externalities::Extensions;
 
 use std::{error, fmt, any::{Any, TypeId}};
-
 use log::{warn, trace};
 
 const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime";
@@ -99,6 +98,7 @@ where
 	T: 'a + ChangesTrieStorage<H, N>,
 	N: crate::changes_trie::BlockNumber,
 {
+
 	/// Create a new `Ext` from overlayed changes and read-only backend
 	pub fn new(
 		overlay: &'a mut OverlayedChanges,
@@ -467,16 +467,22 @@ where
 		} else {
 			let storage_key = storage_key.as_ref();
 
-			let delta = self.overlay.committed.children.get(storage_key)
-				.into_iter()
-				.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))
-				.chain(self.overlay.prospective.children.get(storage_key)
-						.into_iter()
-						.flat_map(|map| map.clone().into_iter().map(|(k, v)| (k.clone(), v.value.clone()))));
-
-			let root = self.backend.child_storage_root(storage_key, delta).0;
-
-			self.overlay.set_storage(storage_key.to_vec(), Some(root.to_vec()));
+			let (root, is_empty, _) = {
+				let delta = self.overlay.committed.children.get(storage_key)
+					.into_iter()
+					.flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))
+					.chain(self.overlay.prospective.children.get(storage_key)
+							.into_iter()
+							.flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))));
+
+				self.backend.child_storage_root(storage_key, delta)
+			};
+
+			if is_empty {
+				self.overlay.set_storage(storage_key.into(), None);
+			} else {
+				self.overlay.set_storage(storage_key.into(), Some(root.clone()));
+			}
 
 			trace!(target: "state-trace", "{:04x}: ChildRoot({}) {}",
 				self.id,
diff --git a/substrate/core/state-machine/src/testing.rs b/substrate/core/state-machine/src/testing.rs
index ca89921ff05..16ff62020b5 100644
--- a/substrate/core/state-machine/src/testing.rs
+++ b/substrate/core/state-machine/src/testing.rs
@@ -21,22 +21,20 @@ use hash_db::Hasher;
 use crate::{
 	backend::{InMemory, Backend}, OverlayedChanges,
 	changes_trie::{
-		build_changes_trie, InMemoryStorage as ChangesTrieInMemoryStorage,
+		InMemoryStorage as ChangesTrieInMemoryStorage,
 		BlockNumber as ChangesTrieBlockNumber,
 	},
+	ext::Ext,
 };
 use primitives::{
 	storage::{
-		ChildStorageKey,
 		well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES, is_child_storage_key}
 	},
-	traits::Externalities, hash::H256, Blake2Hasher,
+	hash::H256, Blake2Hasher,
 };
 use codec::Encode;
 use externalities::{Extensions, Extension};
 
-const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime";
-
 type StorageTuple = (HashMap<Vec<u8>, Vec<u8>>, HashMap<Vec<u8>, HashMap<Vec<u8>, Vec<u8>>>);
 
 /// Simple HashMap-based Externalities impl.
@@ -48,6 +46,17 @@ pub struct TestExternalities<H: Hasher<Out=H256>=Blake2Hasher, N: ChangesTrieBlo
 }
 
 impl<H: Hasher<Out=H256>, N: ChangesTrieBlockNumber> TestExternalities<H, N> {
+
+	/// Get externalities implementation.
+	pub fn ext(&mut self) -> Ext<H, N, InMemory<H>, ChangesTrieInMemoryStorage<H, N>> {
+		Ext::new(
+			&mut self.overlay,
+			&self.backend,
+			Some(&self.changes_trie_storage),
+			Some(&mut self.extensions),
+		)
+	}
+
 	/// Create a new instance of `TestExternalities` with storage.
 	pub fn new(storage: StorageTuple) -> Self {
 		Self::new_with_code(&[], storage)
@@ -118,7 +127,8 @@ impl<H: Hasher<Out=H256>, N: ChangesTrieBlockNumber> TestExternalities<H, N> {
 	///
 	/// Returns the result of the given closure.
 	pub fn execute_with<R>(&mut self, execute: impl FnOnce() -> R) -> R {
-		externalities::set_and_run_with_externalities(self, execute)
+		let mut ext = self.ext();
+		externalities::set_and_run_with_externalities(&mut ext, execute)
 	}
 }
 
@@ -146,156 +156,6 @@ impl<H: Hasher<Out=H256>, N: ChangesTrieBlockNumber> From<StorageTuple> for Test
 	}
 }
 
-impl<H, N> Externalities for TestExternalities<H, N> where
-	H: Hasher<Out=H256>,
-	N: ChangesTrieBlockNumber,
-{
-	fn storage(&self, key: &[u8]) -> Option<Vec<u8>> {
-		self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(||
-			self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL))
-	}
-
-	fn storage_hash(&self, key: &[u8]) -> Option<H256> {
-		self.storage(key).map(|v| H::hash(&v))
-	}
-
-	fn original_storage(&self, key: &[u8]) -> Option<Vec<u8>> {
-		self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)
-	}
-
-	fn original_storage_hash(&self, key: &[u8]) -> Option<H256> {
-		self.storage_hash(key)
-	}
-
-	fn child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
-		self.overlay
-			.child_storage(storage_key.as_ref(), key)
-			.map(|x| x.map(|x| x.to_vec()))
-			.unwrap_or_else(|| self.backend
-				.child_storage(storage_key.as_ref(), key)
-				.expect(EXT_NOT_ALLOWED_TO_FAIL)
-			)
-	}
-
-	fn child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<H256> {
-		self.child_storage(storage_key, key).map(|v| H::hash(&v))
-	}
-
-	fn original_child_storage(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<Vec<u8>> {
-		self.backend
-			.child_storage(storage_key.as_ref(), key)
-			.map(|x| x.map(|x| x.to_vec()))
-			.expect(EXT_NOT_ALLOWED_TO_FAIL)
-	}
-
-	fn original_child_storage_hash(&self, storage_key: ChildStorageKey, key: &[u8]) -> Option<H256> {
-		self.child_storage_hash(storage_key, key)
-	}
-
-	fn place_storage(&mut self, key: Vec<u8>, maybe_value: Option<Vec<u8>>) {
-		if is_child_storage_key(&key) {
-			panic!("Refuse to directly set child storage key");
-		}
-
-		self.overlay.set_storage(key, maybe_value);
-	}
-
-	fn place_child_storage(
-		&mut self,
-		storage_key: ChildStorageKey,
-		key: Vec<u8>,
-		value: Option<Vec<u8>>,
-	) {
-		self.overlay.set_child_storage(storage_key.into_owned(), key, value);
-	}
-
-	fn kill_child_storage(&mut self, storage_key: ChildStorageKey) {
-		let backend = &self.backend;
-		let overlay = &mut self.overlay;
-
-		overlay.clear_child_storage(storage_key.as_ref());
-		backend.for_keys_in_child_storage(storage_key.as_ref(), |key| {
-			overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None);
-		});
-	}
-
-	fn clear_prefix(&mut self, prefix: &[u8]) {
-		if is_child_storage_key(prefix) {
-			panic!("Refuse to directly clear prefix that is part of child storage key");
-		}
-
-		self.overlay.clear_prefix(prefix);
-
-		let backend = &self.backend;
-		let overlay = &mut self.overlay;
-		backend.for_keys_with_prefix(prefix, |key| {
-			overlay.set_storage(key.to_vec(), None);
-		});
-	}
-
-	fn clear_child_prefix(&mut self, storage_key: ChildStorageKey, prefix: &[u8]) {
-		self.overlay.clear_child_prefix(storage_key.as_ref(), prefix);
-
-		let backend = &self.backend;
-		let overlay = &mut self.overlay;
-		backend.for_child_keys_with_prefix(storage_key.as_ref(), prefix, |key| {
-			overlay.set_child_storage(storage_key.as_ref().to_vec(), key.to_vec(), None);
-		});
-	}
-
-	fn chain_id(&self) -> u64 { 42 }
-
-	fn storage_root(&mut self) -> H256 {
-		let child_storage_keys =
-			self.overlay.prospective.children.keys()
-				.chain(self.overlay.committed.children.keys());
-
-		let child_delta_iter = child_storage_keys.map(|storage_key|
-			(storage_key.clone(), self.overlay.committed.children.get(storage_key)
-				.into_iter()
-				.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone())))
-				.chain(self.overlay.prospective.children.get(storage_key)
-					.into_iter()
-					.flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.value.clone()))))));
-
-
-		// compute and memoize
-		let delta = self.overlay.committed.top.iter().map(|(k, v)| (k.clone(), v.value.clone()))
-			.chain(self.overlay.prospective.top.iter().map(|(k, v)| (k.clone(), v.value.clone())));
-		self.backend.full_storage_root(delta, child_delta_iter).0
-	}
-
-	fn child_storage_root(&mut self, storage_key: ChildStorageKey) -> Vec<u8> {
-		let storage_key = storage_key.as_ref();
-
-		let (root, is_empty, _) = {
-			let delta = self.overlay.committed.children.get(storage_key)
-				.into_iter()
-				.flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value)))
-				.chain(self.overlay.prospective.children.get(storage_key)
-						.into_iter()
-						.flat_map(|map| map.clone().into_iter().map(|(k, v)| (k, v.value))));
-
-			self.backend.child_storage_root(storage_key, delta)
-		};
-		if is_empty {
-			self.overlay.set_storage(storage_key.into(), None);
-		} else {
-			self.overlay.set_storage(storage_key.into(), Some(root.clone()));
-		}
-		root
-	}
-
-	fn storage_changes_root(&mut self, parent: H256) -> Result<Option<H256>, ()> {
-		Ok(build_changes_trie::<_, _, H, N>(
-			&self.backend,
-			Some(&self.changes_trie_storage),
-			&self.overlay,
-			parent,
-		)?.map(|(_, root, _)| root))
-	}
-}
-
 impl<H, N> externalities::ExtensionStore for TestExternalities<H, N> where
 	H: Hasher<Out=H256>,
 	N: ChangesTrieBlockNumber,
@@ -308,12 +168,13 @@ impl<H, N> externalities::ExtensionStore for TestExternalities<H, N> where
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use primitives::{Blake2Hasher, H256};
+	use primitives::traits::Externalities;
 	use hex_literal::hex;
 
 	#[test]
 	fn commit_should_work() {
 		let mut ext = TestExternalities::<Blake2Hasher, u64>::default();
+		let mut ext = ext.ext();
 		ext.set_storage(b"doe".to_vec(), b"reindeer".to_vec());
 		ext.set_storage(b"dog".to_vec(), b"puppy".to_vec());
 		ext.set_storage(b"dogglesworth".to_vec(), b"cat".to_vec());
@@ -324,6 +185,7 @@ mod tests {
 	#[test]
 	fn set_and_retrieve_code() {
 		let mut ext = TestExternalities::<Blake2Hasher, u64>::default();
+		let mut ext = ext.ext();
 
 		let code = vec![1, 2, 3];
 		ext.set_storage(CODE.to_vec(), code.clone());
diff --git a/substrate/core/state-machine/src/trie_backend.rs b/substrate/core/state-machine/src/trie_backend.rs
index ce5773c0b79..432ccf3e75f 100644
--- a/substrate/core/state-machine/src/trie_backend.rs
+++ b/substrate/core/state-machine/src/trie_backend.rs
@@ -168,7 +168,7 @@ impl<S: TrieBackendStorage<H>, H: Hasher> Backend<H> for TrieBackend<S, H> where
 
 		let mut write_overlay = S::Overlay::default();
 		let mut root = match self.storage(storage_key) {
-			Ok(value) => value.unwrap_or(default_child_trie_root::<Layout<H>>(storage_key)),
+			Ok(value) => value.unwrap_or(default_root.clone()),
 			Err(e) => {
 				warn!(target: "trie", "Failed to read child storage root: {}", e);
 				default_root.clone()
diff --git a/substrate/core/test-runtime/src/system.rs b/substrate/core/test-runtime/src/system.rs
index d06bef5923d..fc4de0ce4b9 100644
--- a/substrate/core/test-runtime/src/system.rs
+++ b/substrate/core/test-runtime/src/system.rs
@@ -376,8 +376,9 @@ mod tests {
 	#[test]
 	fn block_import_works_wasm() {
 		block_import_works(|b, ext| {
+			let mut ext = ext.ext();
 			executor().call::<_, NeverNativeValue, fn() -> _>(
-				ext,
+				&mut ext,
 				"Core_execute_block",
 				&b.encode(),
 				false,
@@ -468,8 +469,9 @@ mod tests {
 	#[test]
 	fn block_import_with_transaction_works_wasm() {
 		block_import_with_transaction_works(|b, ext| {
+			let mut ext = ext.ext();
 			executor().call::<_, NeverNativeValue, fn() -> _>(
-				ext,
+				&mut ext,
 				"Core_execute_block",
 				&b.encode(),
 				false,
diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs
index 3558987716b..3c97b3cd11c 100644
--- a/substrate/node/executor/src/lib.rs
+++ b/substrate/node/executor/src/lib.rs
@@ -34,6 +34,7 @@ native_executor_instance!(
 
 #[cfg(test)]
 mod tests {
+	use substrate_executor::error::Result;
 	use super::Executor;
 	use {balances, contracts, indices, system, timestamp};
 	use codec::{Encode, Decode, Joiner};
@@ -122,6 +123,26 @@ mod tests {
 		ext.place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(heap_pages.encode()));
 	}
 
+	fn executor_call<
+		R:Decode + Encode + PartialEq,
+		NC: FnOnce() -> std::result::Result<R, String> + std::panic::UnwindSafe
+	>(
+		t: &mut TestExternalities<Blake2Hasher>,
+		method: &str,
+		data: &[u8],
+		use_native: bool,
+		native_call: Option<NC>,
+	) -> (Result<NativeOrEncoded<R>>, bool) {
+		let mut t = t.ext();
+		executor().call::<_, R, NC>(
+			&mut t,
+			method,
+			data,
+			use_native,
+			native_call,
+		)
+	}
+
 	#[test]
 	fn panic_execution_with_foreign_code_gives_error() {
 		let mut t = TestExternalities::<Blake2Hasher>::new_with_code(BLOATY_CODE, (map![
@@ -139,7 +160,7 @@ mod tests {
 			}
 		], map![]));
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -147,7 +168,7 @@ mod tests {
 			None,
 		).0;
 		assert!(r.is_ok());
-		let v = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let v = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt()),
@@ -175,7 +196,7 @@ mod tests {
 			}
 		], map![]));
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -183,7 +204,7 @@ mod tests {
 			None,
 		).0;
 		assert!(r.is_ok());
-		let v = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let v = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt()),
@@ -207,7 +228,7 @@ mod tests {
 			<system::BlockHash<Runtime>>::hashed_key_for(0) => vec![0u8; 32]
 		], map![]));
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -218,7 +239,7 @@ mod tests {
 
 		let fm = t.execute_with(TransactionPayment::next_fee_multiplier);
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt()),
@@ -246,7 +267,7 @@ mod tests {
 			<system::BlockHash<Runtime>>::hashed_key_for(0) => vec![0u8; 32]
 		], map![]));
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -257,7 +278,7 @@ mod tests {
 
 		let fm = t.execute_with(TransactionPayment::next_fee_multiplier);
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt()),
@@ -307,7 +328,7 @@ mod tests {
 		};
 
 		// execute the block to get the real header.
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			env,
 			"Core_initialize_block",
 			&header.encode(),
@@ -316,7 +337,7 @@ mod tests {
 		).0.unwrap();
 
 		for i in extrinsics.iter() {
-			executor().call::<_, NeverNativeValue, fn() -> _>(
+			executor_call::<NeverNativeValue, fn() -> _>(
 				env,
 				"BlockBuilder_apply_extrinsic",
 				&i.encode(),
@@ -325,7 +346,7 @@ mod tests {
 			).0.unwrap();
 		}
 
-		let header = match executor().call::<_, NeverNativeValue, fn() -> _>(
+		let header = match executor_call::<NeverNativeValue, fn() -> _>(
 			env,
 			"BlockBuilder_finalize_block",
 			&[0u8;0],
@@ -432,7 +453,7 @@ mod tests {
 		let mut alice_last_known_balance: Balance = Default::default();
 		let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier);
 
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block1.0,
@@ -471,7 +492,7 @@ mod tests {
 
 		fm = t.execute_with(TransactionPayment::next_fee_multiplier);
 
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block2.0,
@@ -544,7 +565,7 @@ mod tests {
 		let mut alice_last_known_balance: Balance = Default::default();
 		let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier);
 
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block1.0,
@@ -560,7 +581,7 @@ mod tests {
 
 		fm = t.execute_with(TransactionPayment::next_fee_multiplier);
 
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block2.0,
@@ -720,7 +741,7 @@ mod tests {
 
 		let mut t = new_test_ext(COMPACT_CODE, false);
 
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&b.0,
@@ -744,9 +765,9 @@ mod tests {
 	fn wasm_big_block_import_fails() {
 		let mut t = new_test_ext(COMPACT_CODE, false);
 
-		set_heap_pages(&mut t, 4);
+		set_heap_pages(&mut t.ext(), 4);
 
-		let result = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let result = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block_with_size(42, 0, 120_000).0,
@@ -760,7 +781,7 @@ mod tests {
 	fn native_big_block_import_succeeds() {
 		let mut t = new_test_ext(COMPACT_CODE, false);
 
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block_with_size(42, 0, 120_000).0,
@@ -774,7 +795,7 @@ mod tests {
 		let mut t = new_test_ext(COMPACT_CODE, false);
 
 		assert!(
-			executor().call::<_, NeverNativeValue, fn() -> _>(
+			executor_call::<NeverNativeValue, fn() -> _>(
 				&mut t,
 				"Core_execute_block",
 				&block_with_size(42, 0, 120_000).0,
@@ -797,7 +818,7 @@ mod tests {
 			<system::BlockHash<Runtime>>::hashed_key_for(0) => vec![0u8; 32]
 		], map![]));
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -805,7 +826,7 @@ mod tests {
 			None,
 		).0;
 		assert!(r.is_ok());
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt()),
@@ -829,7 +850,7 @@ mod tests {
 			<system::BlockHash<Runtime>>::hashed_key_for(0) => vec![0u8; 32]
 		], map![]));
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -838,7 +859,7 @@ mod tests {
 		).0;
 		assert!(r.is_ok());
 		let fm = t.execute_with(TransactionPayment::next_fee_multiplier);
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt()),
@@ -863,7 +884,7 @@ mod tests {
 		let block = Block::decode(&mut &block_data[..]).unwrap();
 
 		let mut t = new_test_ext(COMPACT_CODE, true);
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block.encode(),
@@ -871,7 +892,7 @@ mod tests {
 			None,
 		).0.unwrap();
 
-		assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some());
+		assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some());
 	}
 
 	#[test]
@@ -879,7 +900,7 @@ mod tests {
 		let block1 = changes_trie_block();
 
 		let mut t = new_test_ext(COMPACT_CODE, true);
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block1.0,
@@ -887,7 +908,7 @@ mod tests {
 			None,
 		).0.unwrap();
 
-		assert!(t.storage_changes_root(GENESIS_HASH.into()).unwrap().is_some());
+		assert!(t.ext().storage_changes_root(GENESIS_HASH.into()).unwrap().is_some());
 	}
 
 	#[test]
@@ -953,7 +974,7 @@ mod tests {
 		println!("++ Block 1 size: {} / Block 2 size {}", block1.0.encode().len(), block2.0.encode().len());
 
 		// execute a big block.
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block1.0,
@@ -970,7 +991,7 @@ mod tests {
 		});
 
 		// execute a big block.
-		executor().call::<_, NeverNativeValue, fn() -> _>(
+		executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_execute_block",
 			&block2.0,
@@ -1015,7 +1036,7 @@ mod tests {
 			function: Call::Balances(default_transfer_call()),
 		});
 
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"Core_initialize_block",
 			&vec![].and(&from_block_number(1u32)),
@@ -1024,7 +1045,7 @@ mod tests {
 		).0;
 
 		assert!(r.is_ok());
-		let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+		let r = executor_call::<NeverNativeValue, fn() -> _>(
 			&mut t,
 			"BlockBuilder_apply_extrinsic",
 			&vec![].and(&xt.clone()),
@@ -1109,7 +1130,7 @@ mod tests {
 				len / 1024 / 1024,
 			);
 
-			let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+			let r = executor_call::<NeverNativeValue, fn() -> _>(
 				&mut t,
 				"Core_execute_block",
 				&block.0,
@@ -1173,7 +1194,7 @@ mod tests {
 				len / 1024 / 1024,
 			);
 
-			let r = executor().call::<_, NeverNativeValue, fn() -> _>(
+			let r = executor_call::<NeverNativeValue, fn() -> _>(
 				&mut t,
 				"Core_execute_block",
 				&block.0,
-- 
GitLab