diff --git a/substrate/substrate/state-db/src/lib.rs b/substrate/substrate/state-db/src/lib.rs
index f3bcc645bf631eb7b890c52c4c16d557274150c0..8bdc5372afc34cf3ab2478bef46b346be5fb2f11 100644
--- a/substrate/substrate/state-db/src/lib.rs
+++ b/substrate/substrate/state-db/src/lib.rs
@@ -194,6 +194,8 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
 	}
 
 	pub fn finalize_block(&mut self, hash: &BlockHash) -> CommitSet<Key> {
+		// clear the temporary overlay from the previous finalization.
+		self.unfinalized.clear_overlay();
 		let mut commit = match self.mode {
 			PruningMode::ArchiveAll => {
 				CommitSet::default()
diff --git a/substrate/substrate/state-db/src/unfinalized.rs b/substrate/substrate/state-db/src/unfinalized.rs
index a6c5ceeb03a50dca7c4304e38f765e1dd4d32593..df3b98c8ca7dc728b4d5812b7c9994ca5697fe35 100644
--- a/substrate/substrate/state-db/src/unfinalized.rs
+++ b/substrate/substrate/state-db/src/unfinalized.rs
@@ -16,6 +16,9 @@
 
 //! Finalization window.
 //! Maintains trees of block overlays and allows discarding trees/roots
+//! The overlays are added in `insert` and removed in `finalize`.
+//! Last finalized overlay is kept in memory until next call to `finalize` or
+//! `clear_overlay`
 
 use std::collections::{HashMap, VecDeque};
 use super::{Error, DBValue, ChangeSet, CommitSet, MetaDb, Hash, to_meta_key};
@@ -29,6 +32,7 @@ pub struct UnfinalizedOverlay<BlockHash: Hash, Key: Hash> {
 	last_finalized: Option<(BlockHash, u64)>,
 	levels: VecDeque<Vec<BlockOverlay<BlockHash, Key>>>,
 	parents: HashMap<BlockHash, BlockHash>,
+	last_finalized_overlay: HashMap<Key, DBValue>,
 }
 
 struct JournalRecord<BlockHash: Hash, Key: Hash> {
@@ -121,6 +125,7 @@ impl<BlockHash: Hash, Key: Hash> UnfinalizedOverlay<BlockHash, Key> {
 			last_finalized: last_finalized,
 			levels,
 			parents,
+			last_finalized_overlay: Default::default(),
 		})
 	}
 
@@ -199,6 +204,11 @@ impl<BlockHash: Hash, Key: Hash> UnfinalizedOverlay<BlockHash, Key> {
 		self.last_finalized.as_ref().map(|&(_, n)| n + 1).unwrap_or(0)
 	}
 
+	/// This may be called when the last finalization commit was applied to the database.
+	pub fn clear_overlay(&mut self) {
+		self.last_finalized_overlay.clear();
+	}
+
 	/// Select a top-level root and finalized it. Discards all sibling subtrees and the root.
 	/// Returns a set of changes that need to be added to the DB.
 	pub fn finalize(&mut self, hash: &BlockHash) -> CommitSet<Key> {
@@ -212,8 +222,9 @@ impl<BlockHash: Hash, Key: Hash> UnfinalizedOverlay<BlockHash, Key> {
 		for (i, overlay) in level.into_iter().enumerate() {
 			self.parents.remove(&overlay.hash);
 			if i == index {
+				self.last_finalized_overlay = overlay.values;
 				// that's the one we need to finalize
-				commit.data.inserted = overlay.values.into_iter().collect();
+				commit.data.inserted = self.last_finalized_overlay.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
 				commit.data.deleted = overlay.deleted;
 			} else {
 				// TODO: borrow checker won't allow us to split out mutable refernces
@@ -236,6 +247,9 @@ impl<BlockHash: Hash, Key: Hash> UnfinalizedOverlay<BlockHash, Key> {
 
 	/// Get a value from the node overlay. This searches in every existing changeset.
 	pub fn get(&self, key: &Key) -> Option<DBValue> {
+		if let Some(value) = self.last_finalized_overlay.get(&key) {
+			return Some(value.clone());
+		}
 		for level in self.levels.iter() {
 			for overlay in level.iter() {
 				if let Some(value) = overlay.values.get(&key) {
@@ -374,9 +388,12 @@ mod tests {
 		db.commit(&overlay.finalize(&h1));
 		assert_eq!(overlay.levels.len(), 1);
 		assert_eq!(overlay.parents.len(), 1);
+		assert!(contains(&overlay, 5));
+		overlay.clear_overlay();
 		assert!(!contains(&overlay, 5));
 		assert!(contains(&overlay, 7));
 		db.commit(&overlay.finalize(&h2));
+		overlay.clear_overlay();
 		assert_eq!(overlay.levels.len(), 0);
 		assert_eq!(overlay.parents.len(), 0);
 		assert!(db.data_eq(&make_db(&[1, 4, 6, 7, 8])));
@@ -446,6 +463,7 @@ mod tests {
 
 		// finalize 1. 2 and all its children should be discarded
 		db.commit(&overlay.finalize(&h_1));
+		overlay.clear_overlay();
 		assert_eq!(overlay.levels.len(), 2);
 		assert_eq!(overlay.parents.len(), 6);
 		assert!(!contains(&overlay, 1));
@@ -457,6 +475,7 @@ mod tests {
 
 		// finalize 1_2. 1_1 and all its children should be discarded
 		db.commit(&overlay.finalize(&h_1_2));
+		overlay.clear_overlay();
 		assert_eq!(overlay.levels.len(), 1);
 		assert_eq!(overlay.parents.len(), 3);
 		assert!(!contains(&overlay, 11));
@@ -467,6 +486,7 @@ mod tests {
 
 		// finalize 1_2_2
 		db.commit(&overlay.finalize(&h_1_2_2));
+		overlay.clear_overlay();
 		assert_eq!(overlay.levels.len(), 0);
 		assert_eq!(overlay.parents.len(), 0);
 		assert!(db.data_eq(&make_db(&[1, 12, 122])));