Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
fix inmemory (#4049)
Browse files Browse the repository at this point in the history
  • Loading branch information
gui1117 authored and gavofyork committed Nov 8, 2019
1 parent 62e9e85 commit 9cda7fa
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions core/state-machine/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,11 @@ impl error::Error for Void {
fn description(&self) -> &str { "unreachable error" }
}

/// In-memory backend. Fully recomputes tries on each commit but useful for
/// tests.
/// In-memory backend. Fully recomputes tries each time `as_trie_backend` is called but useful for
/// tests and proof checking.
pub struct InMemory<H: Hasher> {
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>>,
_hasher: PhantomData<H>,
}
Expand Down Expand Up @@ -467,7 +468,6 @@ impl<H: Hasher> Backend<H> for InMemory<H> {

fn as_trie_backend(&mut self)-> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
let mut mdb = MemoryDB::default();
let mut root = None;
let mut new_child_roots = Vec::new();
let mut root_map = None;
for (storage_key, map) in &self.inner {
Expand All @@ -478,16 +478,15 @@ impl<H: Hasher> Backend<H> for InMemory<H> {
root_map = Some(map);
}
}
// root handling
if let Some(map) = root_map.take() {
root = Some(insert_into_memory_db::<H, _>(
let root = match root_map {
Some(map) => insert_into_memory_db::<H, _>(
&mut mdb,
map.clone().into_iter().chain(new_child_roots.into_iter())
)?);
}
let root = match root {
Some(root) => root,
None => insert_into_memory_db::<H, _>(&mut mdb, ::std::iter::empty())?,
map.clone().into_iter().chain(new_child_roots.into_iter()),
)?,
None => insert_into_memory_db::<H, _>(
&mut mdb,
new_child_roots.into_iter(),
)?,
};
self.trie = Some(TrieBackend::new(mdb, root));
self.trie.as_ref()
Expand All @@ -513,3 +512,20 @@ pub(crate) fn insert_into_memory_db<H, I>(mdb: &mut MemoryDB<H>, input: I) -> Op

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 comments on commit 9cda7fa

Please sign in to comment.