use super::{Digest, Store, Trie, TrieStore, NAME};
use crate::storage::{error::in_memory::Error, transaction_source::in_memory::InMemoryEnvironment};
pub struct InMemoryTrieStore {
maybe_name: Option<String>,
}
impl InMemoryTrieStore {
pub(crate) fn new(_env: &InMemoryEnvironment, maybe_name: Option<&str>) -> Self {
let name = maybe_name
.map(|name| format!("{}-{}", NAME, name))
.unwrap_or_else(|| String::from(NAME));
InMemoryTrieStore {
maybe_name: Some(name),
}
}
}
impl<K, V> Store<Digest, Trie<K, V>> for InMemoryTrieStore {
type Error = Error;
type Handle = Option<String>;
fn handle(&self) -> Self::Handle {
self.maybe_name.to_owned()
}
}
impl<K, V> TrieStore<K, V> for InMemoryTrieStore {}
#[cfg(test)]
mod tests {
use casper_hashing::Digest;
use casper_types::bytesrepr::{Bytes, ToBytes};
use crate::storage::{
store::Store,
transaction_source::{in_memory::InMemoryEnvironment, Transaction, TransactionSource},
trie::{Pointer, PointerBlock, Trie},
trie_store::in_memory::InMemoryTrieStore,
};
#[test]
fn test_in_memory_trie_store() {
let leaf_1 = Trie::Leaf {
key: Bytes::from(vec![0u8, 0, 0]),
value: Bytes::from(b"val_1".to_vec()),
};
let leaf_2 = Trie::Leaf {
key: Bytes::from(vec![1u8, 0, 0]),
value: Bytes::from(b"val_2".to_vec()),
};
let leaf_1_hash = Digest::hash(&leaf_1.to_bytes().unwrap());
let leaf_2_hash = Digest::hash(&leaf_2.to_bytes().unwrap());
let node: Trie<Bytes, Bytes> = {
let mut pointer_block = PointerBlock::new();
pointer_block[0] = Some(Pointer::LeafPointer(leaf_1_hash));
pointer_block[1] = Some(Pointer::LeafPointer(leaf_2_hash));
let pointer_block = Box::new(pointer_block);
Trie::Node { pointer_block }
};
let node_hash = Digest::hash(&node.to_bytes().unwrap());
let env = InMemoryEnvironment::new();
let store = InMemoryTrieStore::new(&env, None);
{
let mut txn = env.create_read_write_txn().unwrap();
store.put(&mut txn, &leaf_1_hash, &leaf_1).unwrap();
store.put(&mut txn, &leaf_2_hash, &leaf_2).unwrap();
store.put(&mut txn, &node_hash, &node).unwrap();
}
{
let txn = env.create_read_txn().unwrap();
for hash in [&leaf_1_hash, &leaf_2_hash, &node_hash].iter() {
let maybe_trie: Option<Trie<Bytes, Bytes>> = store.get(&txn, hash).unwrap();
assert!(maybe_trie.is_none());
}
txn.commit().unwrap();
}
{
let mut txn = env.create_read_write_txn().unwrap();
store.put(&mut txn, &leaf_1_hash, &leaf_1).unwrap();
store.put(&mut txn, &leaf_2_hash, &leaf_2).unwrap();
store.put(&mut txn, &node_hash, &node).unwrap();
txn.commit().unwrap();
}
{
let txn = env.create_read_txn().unwrap();
assert_eq!(Some(leaf_1), store.get(&txn, &leaf_1_hash).unwrap());
assert_eq!(Some(leaf_2), store.get(&txn, &leaf_2_hash).unwrap());
assert_eq!(Some(node), store.get(&txn, &node_hash).unwrap());
txn.commit().unwrap();
}
}
}