diff --git a/trie-db/src/lookup.rs b/trie-db/src/lookup.rs index 5e34055f..90bdcb5e 100644 --- a/trie-db/src/lookup.rs +++ b/trie-db/src/lookup.rs @@ -367,7 +367,6 @@ where NodeOwned::Leaf(slice, value) => return if partial == *slice { let value = (*value).clone(); - drop(node); load_value_owned( value, nibble_key.original_data_as_prefix(), @@ -395,7 +394,6 @@ where NodeOwned::Branch(children, value) => if partial.is_empty() { return if let Some(value) = value.clone() { - drop(node); load_value_owned( value, nibble_key.original_data_as_prefix(), @@ -433,7 +431,6 @@ where if partial.len() == slice.len() { return if let Some(value) = value.clone() { - drop(node); load_value_owned( value, nibble_key.original_data_as_prefix(), diff --git a/trie-db/src/triedbmut.rs b/trie-db/src/triedbmut.rs index bf3edbcb..acbd0fe9 100644 --- a/trie-db/src/triedbmut.rs +++ b/trie-db/src/triedbmut.rs @@ -852,6 +852,7 @@ where handle: &NodeHandle>, ) -> Result, TrieHash, CError> { let mut handle = handle; + // prefix only use for value node access, so this is always correct. let prefix = (full_key, None); loop { let (mid, child) = match handle { @@ -871,8 +872,8 @@ where }, NodeHandle::InMemory(handle) => match &self.storage[handle] { Node::Empty => return Ok(None), - Node::Leaf(key, value) => - if NibbleSlice::from_stored(key) == partial { + Node::Leaf(slice, value) => + if NibbleSlice::from_stored(slice) == partial { return Ok(value.in_memory_fetched_value( prefix, self.db, @@ -923,7 +924,7 @@ where None }) } else if partial.starts_with(&slice) { - let idx = partial.at(0); + let idx = partial.at(slice.len()); match children[idx as usize].as_ref() { Some(child) => (1 + slice.len(), child), None => return Ok(None), @@ -1911,7 +1912,6 @@ where cache_child_values::(&node, &mut values_to_cache, full_key.clone()); } - drop(node); values_to_cache.into_iter().for_each(|(k, v)| cache.cache_value_for_key(&k, v)); } } diff --git a/trie-db/test/src/triedbmut.rs b/trie-db/test/src/triedbmut.rs index 02316892..5a5ac57a 100644 --- a/trie-db/test/src/triedbmut.rs +++ b/trie-db/test/src/triedbmut.rs @@ -99,6 +99,13 @@ fn playpen_internal() { let mut root = Default::default(); let mut memtrie = populate_trie::(&mut memdb, &mut root, &x); + // avoid duplicate + let value_set: std::collections::BTreeMap<&[u8], &[u8]> = + x.iter().map(|(k, v)| (k.as_slice(), v.as_slice())).collect(); + for (k, v) in value_set { + assert_eq!(memtrie.get(k).unwrap().unwrap(), v); + } + memtrie.commit(); if *memtrie.root() != real { println!("TRIE MISMATCH"); @@ -836,3 +843,50 @@ fn test_insert_remove_data_with_cache_internal() { assert!(cache.lookup_value_for_key(key).is_none()); } } + +#[test] +fn test_two_assets_memory_db() { + test_two_assets_memory_db_inner_1::>(); + test_two_assets_memory_db_inner_2::>(); +} +fn test_two_assets_memory_db_inner_1() { + let mut memdb = PrefixedMemoryDB::::new(&[0u8]); + let mut root = Default::default(); + let mut state = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + + let key1 = [1u8; 3]; + let data1 = [1u8; 2]; + state.insert(key1.as_ref(), &data1).unwrap(); + assert_eq!(state.get(key1.as_ref()).unwrap().unwrap(), data1); //PASSING + let key2 = [2u8; 3]; + let data2 = [2u8; 2]; + state.insert(key2.as_ref(), &data2).unwrap(); + assert_eq!(state.get(key1.as_ref()).unwrap().unwrap(), data1); + + state.commit(); +} + +fn test_two_assets_memory_db_inner_2() { + let mut memdb = PrefixedMemoryDB::::new(&[0u8]); + let mut root = Default::default(); + let mut state = TrieDBMutBuilder::::new(&mut memdb, &mut root).build(); + + let key1 = [1u8]; + let data1 = [1u8; 2]; + state.insert(key1.as_ref(), &data1).unwrap(); + assert_eq!(state.get(key1.as_ref()).unwrap().unwrap(), data1); + let key2 = [1u8, 2]; + let data2 = [2u8; 2]; + state.insert(key2.as_ref(), &data2).unwrap(); + assert_eq!(state.get(key1.as_ref()).unwrap().unwrap(), data1); + assert_eq!(state.get(key2.as_ref()).unwrap().unwrap(), data2); + + state.commit(); + + let key3 = [1u8, 3]; + let data3 = [3u8; 2]; + state.insert(key3.as_ref(), &data3).unwrap(); + assert_eq!(state.get(key1.as_ref()).unwrap().unwrap(), data1); + assert_eq!(state.get(key2.as_ref()).unwrap().unwrap(), data2); + assert_eq!(state.get(key3.as_ref()).unwrap().unwrap(), data3); +}