1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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 test {
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 vec![&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();
}
}
}