From f05ae63afafcac987eb1742bcb4d0c787b67733d Mon Sep 17 00:00:00 2001
From: Arkadiy Paronyan <arkady.paronyan@gmail.com>
Date: Thu, 18 Jun 2020 09:36:52 +0200
Subject: [PATCH] Allow empty values in the storage (#6364)

* Allow empty values in the storage

* Bump trie-bench

* Bump trie-bench
---
 substrate/Cargo.lock                          | 12 +++----
 substrate/frame/executive/src/lib.rs          |  2 +-
 substrate/primitives/state-machine/Cargo.toml |  2 +-
 substrate/primitives/state-machine/src/lib.rs | 36 +++++++++++++++++++
 .../primitives/state-machine/src/testing.rs   |  6 ++--
 substrate/primitives/trie/Cargo.toml          |  6 ++--
 substrate/primitives/trie/src/lib.rs          |  1 +
 substrate/test-utils/runtime/Cargo.toml       |  4 +--
 8 files changed, 53 insertions(+), 16 deletions(-)

diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index aeacd6e3530..f67d22aa6eb 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -3057,9 +3057,9 @@ dependencies = [
 
 [[package]]
 name = "memory-db"
-version = "0.20.1"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be512cb2ccb4ecbdca937fdd4a62ea5f09f8e7195466a85e4632b3d5bcce82e6"
+checksum = "fb2999ff7a65d5a1d72172f6d51fa2ea03024b51aee709ba5ff81c3c629a2410"
 dependencies = [
  "ahash",
  "hash-db",
@@ -8935,9 +8935,9 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
 
 [[package]]
 name = "trie-bench"
-version = "0.21.1"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c48b309cdda1abbdada28424bdc46f8b85362b3e66d6786d91223e83874429c7"
+checksum = "ed8419971832eb3333dc26066e50943a20e0934efeb451b3df5ee94f7f7323ab"
 dependencies = [
  "criterion 0.2.11",
  "hash-db",
@@ -8951,9 +8951,9 @@ dependencies = [
 
 [[package]]
 name = "trie-db"
-version = "0.20.1"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcc309f34008563989045a4c4dbcc5770467f3a3785ee80a9b5cc0d83362475f"
+checksum = "cb230c24c741993b04cfccbabb45acff6f6480c5f00d3ed8794ea43db3a9d727"
 dependencies = [
  "hash-db",
  "hashbrown",
diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs
index c6371d914a3..9b0e4eab029 100644
--- a/substrate/frame/executive/src/lib.rs
+++ b/substrate/frame/executive/src/lib.rs
@@ -709,7 +709,7 @@ mod tests {
 				header: Header {
 					parent_hash: [69u8; 32].into(),
 					number: 1,
-					state_root: hex!("05a38fa4a48ca80ffa8482304be7749a484dc8c9c31462a570d0fbadde6a3633").into(),
+					state_root: hex!("e8ff7b3dd4375f6f3a76e24a1999e2a7be2d15b353e49ac94ace1eae3e80eb87").into(),
 					extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(),
 					digest: Digest { logs: vec![], },
 				},
diff --git a/substrate/primitives/state-machine/Cargo.toml b/substrate/primitives/state-machine/Cargo.toml
index 22dc73fc7e7..b94195db901 100644
--- a/substrate/primitives/state-machine/Cargo.toml
+++ b/substrate/primitives/state-machine/Cargo.toml
@@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 log = "0.4.8"
 parking_lot = "0.10.0"
 hash-db = "0.15.2"
-trie-db = "0.20.1"
+trie-db = "0.21.0"
 trie-root = "0.16.0"
 sp-trie = { version = "2.0.0-rc3", path = "../trie" }
 sp-core = { version = "2.0.0-rc3", path = "../core" }
diff --git a/substrate/primitives/state-machine/src/lib.rs b/substrate/primitives/state-machine/src/lib.rs
index 693a7bc12fa..b863d155e7d 100644
--- a/substrate/primitives/state-machine/src/lib.rs
+++ b/substrate/primitives/state-machine/src/lib.rs
@@ -1306,4 +1306,40 @@ mod tests {
 		}
 		assert!(!duplicate);
 	}
+
+	#[test]
+	fn set_storage_empty_allowed() {
+		let initial: BTreeMap<_, _> = map![
+			b"aaa".to_vec() => b"0".to_vec(),
+			b"bbb".to_vec() => b"".to_vec()
+		];
+		let mut state = InMemoryBackend::<BlakeTwo256>::from(initial);
+		let backend = state.as_trie_backend().unwrap();
+
+		let mut overlay = OverlayedChanges::default();
+		overlay.set_storage(b"ccc".to_vec(), Some(b"".to_vec()));
+		assert_eq!(overlay.storage(b"ccc"), Some(Some(&[][..])));
+		overlay.commit_prospective();
+		assert_eq!(overlay.storage(b"ccc"), Some(Some(&[][..])));
+		assert_eq!(overlay.storage(b"bbb"), None);
+
+		{
+			let mut offchain_overlay = Default::default();
+			let mut cache = StorageTransactionCache::default();
+			let mut ext = Ext::new(
+				&mut overlay,
+				&mut offchain_overlay,
+				&mut cache,
+				backend,
+				changes_trie::disabled_state::<_, u64>(),
+				None,
+			);
+			assert_eq!(ext.storage(b"bbb"), Some(vec![]));
+			assert_eq!(ext.storage(b"ccc"), Some(vec![]));
+			ext.clear_storage(b"ccc");
+			assert_eq!(ext.storage(b"ccc"), None);
+		}
+		overlay.commit_prospective();
+		assert_eq!(overlay.storage(b"ccc"), Some(None));
+	}
 }
diff --git a/substrate/primitives/state-machine/src/testing.rs b/substrate/primitives/state-machine/src/testing.rs
index 2ea2961830f..90da5479832 100644
--- a/substrate/primitives/state-machine/src/testing.rs
+++ b/substrate/primitives/state-machine/src/testing.rs
@@ -242,7 +242,7 @@ impl<H, N> sp_externalities::ExtensionStore for TestExternalities<H, N> where
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use sp_core::traits::Externalities;
+	use sp_core::{H256, traits::Externalities};
 	use sp_runtime::traits::BlakeTwo256;
 	use hex_literal::hex;
 
@@ -253,8 +253,8 @@ mod tests {
 		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());
-		const ROOT: [u8; 32] = hex!("555d4777b52e9196e3f6373c556cc661e79cd463f881ab9e921e70fc30144bf4");
-		assert_eq!(&ext.storage_root()[..], &ROOT);
+		let root = H256::from(hex!("2a340d3dfd52f5992c6b117e9e45f479e6da5afffafeb26ab619cf137a95aeb8"));
+		assert_eq!(H256::from_slice(ext.storage_root().as_slice()), root);
 	}
 
 	#[test]
diff --git a/substrate/primitives/trie/Cargo.toml b/substrate/primitives/trie/Cargo.toml
index c436092c099..823d5bc5dfc 100644
--- a/substrate/primitives/trie/Cargo.toml
+++ b/substrate/primitives/trie/Cargo.toml
@@ -20,13 +20,13 @@ harness = false
 codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false }
 sp-std = { version = "2.0.0-rc3", default-features = false, path = "../std" }
 hash-db = { version = "0.15.2", default-features = false }
-trie-db = { version = "0.20.1", default-features = false }
+trie-db = { version = "0.21.0", default-features = false }
 trie-root = { version = "0.16.0", default-features = false }
-memory-db = { version = "0.20.0", default-features = false }
+memory-db = { version = "0.21.0", default-features = false }
 sp-core = { version = "2.0.0-rc3", default-features = false, path = "../core" }
 
 [dev-dependencies]
-trie-bench = "0.21.0"
+trie-bench = "0.22.0"
 trie-standardmap = "0.15.2"
 criterion = "0.2.11"
 hex-literal = "0.2.1"
diff --git a/substrate/primitives/trie/src/lib.rs b/substrate/primitives/trie/src/lib.rs
index db471fd7137..7d1879a4f9f 100644
--- a/substrate/primitives/trie/src/lib.rs
+++ b/substrate/primitives/trie/src/lib.rs
@@ -51,6 +51,7 @@ pub struct Layout<H>(sp_std::marker::PhantomData<H>);
 
 impl<H: Hasher> TrieLayout for Layout<H> {
 	const USE_EXTENSION: bool = false;
+	const ALLOW_EMPTY: bool = true;
 	type Hash = H;
 	type Codec = NodeCodec<Self::Hash>;
 }
diff --git a/substrate/test-utils/runtime/Cargo.toml b/substrate/test-utils/runtime/Cargo.toml
index a4e4bd1f164..9016ddbff55 100644
--- a/substrate/test-utils/runtime/Cargo.toml
+++ b/substrate/test-utils/runtime/Cargo.toml
@@ -21,7 +21,7 @@ codec = { package = "parity-scale-codec", version = "1.3.0", default-features =
 frame-executive = { version = "2.0.0-rc3", default-features = false, path = "../../frame/executive" }
 sp-inherents = { version = "2.0.0-rc3", default-features = false, path = "../../primitives/inherents" }
 sp-keyring = { version = "2.0.0-rc3", optional = true, path = "../../primitives/keyring" }
-memory-db = { version = "0.20.0", default-features = false }
+memory-db = { version = "0.21.0", default-features = false }
 sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-rc3"}
 sp-core = { version = "2.0.0-rc3", default-features = false, path = "../../primitives/core" }
 sp-std = { version = "2.0.0-rc3", default-features = false, path = "../../primitives/std" }
@@ -39,7 +39,7 @@ pallet-timestamp = { version = "2.0.0-rc3", default-features = false, path = "..
 sp-finality-grandpa = { version = "2.0.0-rc3", default-features = false, path = "../../primitives/finality-grandpa" }
 sp-trie = { version = "2.0.0-rc3", default-features = false, path = "../../primitives/trie" }
 sp-transaction-pool = { version = "2.0.0-rc3", default-features = false, path = "../../primitives/transaction-pool" }
-trie-db = { version = "0.20.1", default-features = false }
+trie-db = { version = "0.21.0", default-features = false }
 parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] }
 sc-service = { version = "0.8.0-rc3", default-features = false, optional = true, features = ["test-helpers"], path = "../../client/service" }
 
-- 
GitLab