diff --git a/substrate/core/client/db/src/lib.rs b/substrate/core/client/db/src/lib.rs
index eb63f60e3ae8990f7ccedbfb4c4e81987eeecb63..2fd965fd6d3470d7fc0255dd7b7fa742418c139f 100644
--- a/substrate/core/client/db/src/lib.rs
+++ b/substrate/core/client/db/src/lib.rs
@@ -374,9 +374,7 @@ impl<Block: BlockT> state_machine::ChangesTrieRootsStorage<Blake2Hasher> for DbC
 					.map(Some),
 				None => Ok(None)
 			})?
-			.and_then(|header| header.digest().logs().iter()
-				.find(|log| log.as_changes_trie_root().is_some())
-				.and_then(DigestItem::as_changes_trie_root)
+			.and_then(|header| header.digest().log(DigestItem::as_changes_trie_root)
 				.map(|root| H256::from_slice(root.as_ref()))))
 	}
 }
diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs
index 0e2ca94259048dc8be687cff3a94b6db2cad73d7..989cfcadc82ea52e03181045d34334fbaeaa8114 100644
--- a/substrate/core/client/src/client.rs
+++ b/substrate/core/client/src/client.rs
@@ -1091,9 +1091,7 @@ pub(crate) mod tests {
 			remote_client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap();
 
 			let header = remote_client.header(&BlockId::Number(i as u64 + 1)).unwrap().unwrap();
-			let trie_root = header.digest().logs().iter()
-				.find(|l| l.as_changes_trie_root().is_some())
-				.and_then(DigestItem::as_changes_trie_root)
+			let trie_root = header.digest().log(DigestItem::as_changes_trie_root)
 				.map(|root| H256::from_slice(root.as_ref()))
 				.unwrap();
 			local_roots.push(trie_root);
diff --git a/substrate/core/client/src/in_mem.rs b/substrate/core/client/src/in_mem.rs
index c938a6dbd357171ef4a4ad60eb4d76507ef1a177..29bf8afdba0607d4662990d75b53df49653fd225 100644
--- a/substrate/core/client/src/in_mem.rs
+++ b/substrate/core/client/src/in_mem.rs
@@ -474,10 +474,7 @@ where
 
 			self.states.write().insert(hash, operation.new_state.unwrap_or_else(|| old_state.clone()));
 
-			let changes_trie_root = header.digest().logs().iter()
-				.find(|log| log.as_changes_trie_root().is_some())
-				.and_then(DigestItem::as_changes_trie_root)
-				.cloned();
+			let changes_trie_root = header.digest().log(DigestItem::as_changes_trie_root).cloned();
 			if let Some(changes_trie_root) = changes_trie_root {
 				if let Some(changes_trie_update) = operation.changes_trie_update {
 					let changes_trie_root: H::Out = changes_trie_root.into();
diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index 75a543850ff3de58dd637e0ed8a66e267fb1cec5..50775921052595e4f002c267eb0ff6739bf16ee8 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -503,6 +503,13 @@ pub trait Digest: Member + Default {
 	fn logs(&self) -> &[Self::Item];
 	/// Push new digest item.
 	fn push(&mut self, item: Self::Item);
+
+	/// Get reference to the first digest item that matches the passed predicate.
+	fn log<T, F: Fn(&Self::Item) -> Option<&T>>(&self, predicate: F) -> Option<&T> {
+		self.logs().iter()
+			.filter_map(predicate)
+			.next()
+	}
 }
 
 /// Single digest item. Could be any type that implements `Member` and provides methods