Skip to content
Snippets Groups Projects
Commit 77407e16 authored by thiolliere's avatar thiolliere Committed by Gavin Wood
Browse files

fix inmemory (#4049)

parent 5a266964
Branches
No related merge requests found
...@@ -246,10 +246,11 @@ impl error::Error for Void { ...@@ -246,10 +246,11 @@ impl error::Error for Void {
fn description(&self) -> &str { "unreachable error" } fn description(&self) -> &str { "unreachable error" }
} }
/// In-memory backend. Fully recomputes tries on each commit but useful for /// In-memory backend. Fully recomputes tries each time `as_trie_backend` is called but useful for
/// tests. /// tests and proof checking.
pub struct InMemory<H: Hasher> { pub struct InMemory<H: Hasher> {
inner: HashMap<Option<Vec<u8>>, HashMap<Vec<u8>, Vec<u8>>>, inner: HashMap<Option<Vec<u8>>, HashMap<Vec<u8>, Vec<u8>>>,
// This field is only needed for returning reference in `as_trie_backend`.
trie: Option<TrieBackend<MemoryDB<H>, H>>, trie: Option<TrieBackend<MemoryDB<H>, H>>,
_hasher: PhantomData<H>, _hasher: PhantomData<H>,
} }
...@@ -467,7 +468,6 @@ impl<H: Hasher> Backend<H> for InMemory<H> { ...@@ -467,7 +468,6 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
fn as_trie_backend(&mut self)-> Option<&TrieBackend<Self::TrieBackendStorage, H>> { fn as_trie_backend(&mut self)-> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
let mut mdb = MemoryDB::default(); let mut mdb = MemoryDB::default();
let mut root = None;
let mut new_child_roots = Vec::new(); let mut new_child_roots = Vec::new();
let mut root_map = None; let mut root_map = None;
for (storage_key, map) in &self.inner { for (storage_key, map) in &self.inner {
...@@ -478,16 +478,15 @@ impl<H: Hasher> Backend<H> for InMemory<H> { ...@@ -478,16 +478,15 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
root_map = Some(map); root_map = Some(map);
} }
} }
// root handling let root = match root_map {
if let Some(map) = root_map.take() { Some(map) => insert_into_memory_db::<H, _>(
root = Some(insert_into_memory_db::<H, _>(
&mut mdb, &mut mdb,
map.clone().into_iter().chain(new_child_roots.into_iter()) map.clone().into_iter().chain(new_child_roots.into_iter()),
)?); )?,
} None => insert_into_memory_db::<H, _>(
let root = match root { &mut mdb,
Some(root) => root, new_child_roots.into_iter(),
None => insert_into_memory_db::<H, _>(&mut mdb, ::std::iter::empty())?, )?,
}; };
self.trie = Some(TrieBackend::new(mdb, root)); self.trie = Some(TrieBackend::new(mdb, root));
self.trie.as_ref() self.trie.as_ref()
...@@ -513,3 +512,20 @@ pub(crate) fn insert_into_memory_db<H, I>(mdb: &mut MemoryDB<H>, input: I) -> Op ...@@ -513,3 +512,20 @@ pub(crate) fn insert_into_memory_db<H, I>(mdb: &mut MemoryDB<H>, input: I) -> Op
Some(root) Some(root)
} }
#[cfg(test)]
mod tests {
use super::*;
/// Assert in memory backend with only child trie keys works as trie backend.
#[test]
fn in_memory_with_child_trie_only() {
let storage = InMemory::<primitives::Blake2Hasher>::default();
let mut storage = storage.update(
vec![(Some(b"1".to_vec()), b"2".to_vec(), Some(b"3".to_vec()))]
);
let trie_backend = storage.as_trie_backend().unwrap();
assert_eq!(trie_backend.child_storage(b"1", b"2").unwrap(), Some(b"3".to_vec()));
assert!(trie_backend.storage(b"1").unwrap().is_some());
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment