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
//! An in-memory trie store, intended to be used for testing.
//!
//! # Usage
//!
//! ```
//! use casper_execution_engine::storage::store::Store;
//! use casper_execution_engine::storage::transaction_source::{Transaction, TransactionSource};
//! use casper_execution_engine::storage::transaction_source::in_memory::InMemoryEnvironment;
//! use casper_execution_engine::storage::trie::{Pointer, PointerBlock, Trie};
//! use casper_execution_engine::storage::trie_store::in_memory::InMemoryTrieStore;
//! use casper_execution_engine::shared::newtypes::Blake2bHash;
//! use casper_types::bytesrepr::{ToBytes, Bytes};
//!
//! // Create some leaves
//! 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()) };
//!
//! // Get their hashes
//! let leaf_1_hash = Blake2bHash::new(&leaf_1.to_bytes().unwrap());
//! let leaf_2_hash = Blake2bHash::new(&leaf_2.to_bytes().unwrap());
//!
//! // Create a node
//! 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 }
//! };
//!
//! // Get its hash
//! let node_hash = Blake2bHash::new(&node.to_bytes().unwrap());
//!
//! // Create the environment and the store. For both the in-memory and
//! // LMDB-backed implementations, the environment is the source of
//! // transactions.
//! let env = InMemoryEnvironment::new();
//! let store = InMemoryTrieStore::new(&env, None);
//!
//! // First let's create a read-write transaction, persist the values, but
//! // forget to commit the transaction.
//! {
//! // Create a read-write transaction
//! let mut txn = env.create_read_write_txn().unwrap();
//!
//! // Put the values in the store
//! 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();
//!
//! // Here we forget to commit the transaction before it goes out of scope
//! }
//!
//! // Now let's check to see if the values were stored
//! {
//! // Create a read transaction
//! let txn = env.create_read_txn().unwrap();
//!
//! // Observe that nothing has been persisted to the store
//! for hash in vec![&leaf_1_hash, &leaf_2_hash, &node_hash].iter() {
//! // We need to use a type annotation here to help the compiler choose
//! // a suitable FromBytes instance
//! let maybe_trie: Option<Trie<Bytes, Bytes>> = store.get(&txn, hash).unwrap();
//! assert!(maybe_trie.is_none());
//! }
//!
//! // Commit the read transaction. Not strictly necessary, but better to be hygienic.
//! txn.commit().unwrap();
//! }
//!
//! // Now let's try that again, remembering to commit the transaction this time
//! {
//! // Create a read-write transaction
//! let mut txn = env.create_read_write_txn().unwrap();
//!
//! // Put the values in the store
//! 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();
//!
//! // Commit the transaction.
//! txn.commit().unwrap();
//! }
//!
//! // Now let's check to see if the values were stored again
//! {
//! // Create a read transaction
//! let txn = env.create_read_txn().unwrap();
//!
//! // Get the values in the store
//! 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());
//!
//! // Commit the read transaction.
//! txn.commit().unwrap();
//! }
//! ```
use ;
use crate;
/// An in-memory trie store.