cfx_storage/impls/merkle_patricia_trie/
simple_mpt.rs1fn min_repr_bytes(number_of_keys: usize) -> usize {
6 let mut largest_value = match number_of_keys {
7 n if n == 0 => return 0,
8 n if n == 1 => return 1,
9 n => n - 1,
10 };
11
12 let mut min_repr_bytes = 0;
13
14 while largest_value != 0 {
15 min_repr_bytes += 1;
16 largest_value >>= 8;
17 }
18
19 min_repr_bytes
20}
21
22fn to_index_bytes(mut index: usize, len: usize) -> Vec<u8> {
23 let mut bytes = vec![0u8; len];
24
25 for i in (0..len).rev() {
26 bytes[i] = index as u8;
27 index >>= 8;
28 }
29
30 bytes
31}
32
33pub fn into_simple_mpt_key(key: usize, num_keys: usize) -> Vec<u8> {
36 let key_length = min_repr_bytes(num_keys);
37 to_index_bytes(key, key_length)
38}
39
40pub fn make_simple_mpt(mut values: Vec<Box<[u8]>>) -> SimpleMpt {
41 let mut mpt = SimpleMpt::default();
42 let keys = values.len();
43 let mut mpt_kvs = Vec::with_capacity(keys);
44
45 let index_byte_len = min_repr_bytes(keys);
46
47 for (index, value) in values.drain(..).enumerate() {
48 mpt_kvs.push((to_index_bytes(index, index_byte_len), value));
49 }
50
51 MptMerger::new(None, &mut mpt)
52 .merge(&DumpedMptKvIterator { kv: mpt_kvs })
53 .expect("SimpleMpt does not fail.");
54
55 mpt
56}
57
58pub fn simple_mpt_merkle_root(simple_mpt: &mut SimpleMpt) -> MerkleHash {
59 let maybe_root_node = simple_mpt
60 .load_node(&CompressedPathRaw::default())
61 .expect("SimpleMpt does not fail.");
62 match maybe_root_node {
63 None => MERKLE_NULL_NODE,
64 Some(root_node) => {
65 if root_node.get_children_count() == 1 {
69 trace!(
70 "debug receipts calculation: root node {:?}",
71 simple_mpt.load_node(
72 &CompressedPathRaw::new_and_apply_mask(
73 &[0],
74 CompressedPathRaw::second_nibble_mask()
75 )
76 )
77 );
78
79 root_node.get_child(0).expect("Child 0 must exist").merkle
80 } else {
81 trace!("debug receipts calculation: root node {:?}", root_node);
82 *root_node.get_merkle()
83 }
84 }
85 }
86}
87
88pub fn simple_mpt_proof(
89 simple_mpt: &mut SimpleMpt, access_key: &[u8],
90) -> TrieProof {
91 let mut cursor = MptCursor::<
92 &mut dyn SnapshotMptTraitRead,
93 BasicPathNode<&mut dyn SnapshotMptTraitRead>,
94 >::new(simple_mpt);
95
96 cursor.load_root().expect("load_root should succeed");
97
98 let remove_root = cursor.current_node_mut().get_children_count() == 1;
100
101 cursor
102 .open_path_for_key::<access_mode::Read>(access_key)
103 .expect("open_path_for_key should succeed");
104
105 let mut proof = cursor.to_proof();
106 cursor.finish().expect("finish should succeed");
107
108 if remove_root {
109 proof = TrieProof::new(proof.get_proof_nodes()[1..].to_vec())
110 .expect("Proof with root removed is still connected");
111 }
112
113 proof
114}
115
116use crate::{
117 impls::merkle_patricia_trie::{
118 mpt_cursor::{BasicPathNode, MptCursor},
119 trie_node::TrieNodeTrait,
120 walk::GetChildTrait,
121 CompressedPathRaw, MptMerger, TrieProof,
122 },
123 storage_db::SnapshotMptTraitRead,
124 tests::DumpedMptKvIterator,
125 utils::access_mode,
126};
127use primitives::{MerkleHash, MERKLE_NULL_NODE};
128
129pub use crate::tests::FakeSnapshotMptDb as SimpleMpt;
130
131#[cfg(test)]
132mod tests {
133 use super::{
134 into_simple_mpt_key, make_simple_mpt, min_repr_bytes,
135 simple_mpt_merkle_root, simple_mpt_proof, MerkleHash,
136 };
137
138 #[test]
139 fn test_min_repr_bytes() {
140 assert_eq!(min_repr_bytes(0x00_00_00_00), 0); assert_eq!(min_repr_bytes(0x00_00_00_01), 1); assert_eq!(min_repr_bytes(0x00_00_01_00), 1); assert_eq!(min_repr_bytes(0x00_00_01_01), 2); assert_eq!(min_repr_bytes(0x00_01_00_00), 2); assert_eq!(min_repr_bytes(0x00_01_00_01), 3); assert_eq!(min_repr_bytes(0x01_00_00_00), 3); }
151
152 #[test]
153 fn test_into_simple_mpt_key() {
154 assert_eq!(into_simple_mpt_key(0x01, 1), vec![0x01]);
155 assert_eq!(into_simple_mpt_key(0x01, 256), vec![0x01]);
156 assert_eq!(into_simple_mpt_key(0x01, 257), vec![0x00, 0x01]);
157 assert_eq!(into_simple_mpt_key(0x01, 65536), vec![0x00, 0x01]);
158 assert_eq!(into_simple_mpt_key(0x01, 65537), vec![0x00, 0x00, 0x01]);
159 }
160
161 #[test]
162 fn test_empty_simple_mpt() {
163 let mut mpt = make_simple_mpt(vec![]);
164 let root = simple_mpt_merkle_root(&mut mpt);
165
166 assert_eq!(
167 root,
168 "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
169 .parse::<MerkleHash>()
170 .unwrap()
171 );
172 }
173
174 fn check_proofs(num_items: usize, proof_size: Vec<usize>) {
175 let value_from_key = |key| into_simple_mpt_key(key, num_items);
181
182 let values: Vec<Box<[u8]>> = (0..num_items)
183 .map(|k| value_from_key(k).into_boxed_slice())
184 .collect();
185
186 let mut mpt = make_simple_mpt(values);
187 let root = simple_mpt_merkle_root(&mut mpt);
188
189 for k in 0..num_items {
190 let key = into_simple_mpt_key(k, num_items);
191 let proof = simple_mpt_proof(&mut mpt, &key);
192
193 assert!(proof_size.contains(&proof.number_nodes()));
194
195 assert!(proof.is_valid_kv(
197 &into_simple_mpt_key(k, num_items),
198 Some(&value_from_key(k)[..]),
199 &root
200 ));
201
202 assert!(!proof.is_valid_kv(
204 &into_simple_mpt_key(k, num_items),
205 Some(&value_from_key(k + 1)[..]),
206 &root
207 ));
208
209 for other in 0..num_items {
211 if k == other {
212 continue;
213 }
214
215 assert!(!proof.is_valid_kv(
216 &into_simple_mpt_key(other, num_items),
217 Some(&value_from_key(other)[..]),
218 &root
219 ));
220 }
221 }
222 }
223
224 #[test]
225 #[rustfmt::skip]
226 fn test_simple_mpt_proof() {
227 check_proofs(0x01, vec![1]);
231
232 check_proofs(0x02, vec![2]);
237
238 check_proofs(0x10, vec![2]);
243
244 check_proofs(0x11, vec![2, 3]);
252
253 check_proofs(0x12, vec![3]);
258
259 check_proofs(0x0100, vec![3]);
264
265 check_proofs(0x0101, vec![2, 4]);
273 }
274}