cfx_storage/storage_db/
snapshot_mpt.rs1use cfg_if::cfg_if;
6cfg_if! {
7 if #[cfg(test)] {
8 pub const CHECK_LOADED_SNAPSHOT_MPT_NODE: bool = true;
9 } else {
10 pub const CHECK_LOADED_SNAPSHOT_MPT_NODE: bool = false;
11 }
12}
13
14pub type SnapshotMptDbValue = Box<[u8]>;
15#[derive(Clone, Default, Debug)]
19pub struct SnapshotMptNode(pub VanillaTrieNode<SubtreeMerkleWithSize>);
20
21#[derive(Copy, Clone, PartialEq, Debug, Default)]
22pub struct SubtreeMerkleWithSize {
23 pub merkle: MerkleHash,
24 pub subtree_size: u64,
25 pub delta_subtree_size: u64,
30}
31
32pub trait SnapshotMptTraitRead: AsSnapshotMptTraitRead {
36 fn get_merkle_root(&self) -> MerkleHash;
37 fn load_node(
38 &mut self, path: &dyn CompressedPathTrait,
39 ) -> Result<Option<SnapshotMptNode>>;
40}
41
42pub trait AsSnapshotMptTraitRead {
43 fn as_readonly(&mut self) -> &mut dyn SnapshotMptTraitRead;
44}
45
46impl<T: SnapshotMptTraitRead> AsSnapshotMptTraitRead for T {
47 fn as_readonly(&mut self) -> &mut dyn SnapshotMptTraitRead { self }
48}
49
50pub trait SnapshotMptTraitReadAndIterate: SnapshotMptTraitRead {
51 fn iterate_subtree_trie_nodes_without_root(
52 &mut self, path: &dyn CompressedPathTrait,
53 ) -> Result<Box<dyn SnapshotMptIteraterTrait + '_>>;
54}
55
56pub trait SnapshotMptTraitRw: SnapshotMptTraitReadAndIterate {
57 fn delete_node(&mut self, path: &dyn CompressedPathTrait) -> Result<()>;
58 fn write_node(
59 &mut self, path: &dyn CompressedPathTrait, trie_node: &SnapshotMptNode,
60 ) -> Result<()>;
61}
62
63pub trait SnapshotMptIteraterTrait:
68 FallibleIterator<Item = (CompressedPathRaw, SnapshotMptNode), Error = Error>
69{
70}
71
72impl<
73 T: FallibleIterator<
74 Item = (CompressedPathRaw, SnapshotMptNode),
75 Error = Error,
76 >,
77 > SnapshotMptIteraterTrait for T
78{
79}
80
81impl SnapshotMptNode {
82 pub const NO_CHILD: SubtreeMerkleWithSize = SubtreeMerkleWithSize {
83 merkle: MERKLE_NULL_NODE,
84 subtree_size: 0,
85 delta_subtree_size: 0,
86 };
87
88 pub fn is_valid(&self, path_to_node: &dyn CompressedPathTrait) -> bool {
89 let mut valid = true;
90
91 let children_merkles = self.get_children_merkles();
92 let merkle_hash = self.compute_merkle(
93 children_merkles.as_ref(),
94 CompressedPathRaw::second_nibble(
95 self.compressed_path_ref().path_mask(),
96 ) != CompressedPathRaw::NO_MISSING_NIBBLE,
97 );
98 if self.get_merkle().ne(&merkle_hash) {
99 error!(
100 "merkle hash mismatch, expected {:?}, got {:?}, path_to_node {:?}",
101 merkle_hash, self.get_merkle(), path_to_node,
102 );
103 valid = false;
104 }
105 let actual_children_count = children_merkles.as_ref().map_or(0, |v| {
106 v.iter().filter(|&x| x.ne(&MERKLE_NULL_NODE)).count()
107 });
108 if self.get_children_count() as usize != actual_children_count {
109 error!(
110 "children count is wrong: expected {} got {}",
111 actual_children_count,
112 self.get_children_count(),
113 );
114 valid = false;
115 }
116 if path_to_node.path_size() > 0
117 && !self.has_value()
118 && self.get_children_count() <= 1
119 {
120 error!(
121 "node should not exists due to path compressing rule, path_to_node {:?}, {:?}",
122 path_to_node, self
123 );
124 valid = false
125 }
126
127 valid
128 }
129
130 pub fn load_rlp_and_check(
131 rlp_bytes: &[u8], path_to_node: &dyn CompressedPathTrait,
132 ) -> Result<Self> {
133 let node = Self(Rlp::new(rlp_bytes).as_val()?);
134
135 if CHECK_LOADED_SNAPSHOT_MPT_NODE {
136 node.is_valid(path_to_node);
137 }
138 Ok(node)
139 }
140
141 pub fn subtree_size(&self, full_path: &dyn CompressedPathTrait) -> u64 {
142 Self::initial_subtree_size(&self.0, full_path)
143 }
144
145 fn initial_subtree_size(
146 node: &VanillaTrieNode<SubtreeMerkleWithSize>,
147 full_path: &dyn CompressedPathTrait,
148 ) -> u64 {
149 let mut size = match node.value_as_slice().into_option() {
150 None => 0,
151 Some(value) => {
152 rlp_key_value_len(full_path.path_size(), value.len())
153 }
154 };
155 for (
156 _child_index,
157 &SubtreeMerkleWithSize {
158 ref subtree_size, ..
159 },
160 ) in node.get_children_table_ref().iter()
161 {
162 size += subtree_size;
163 }
164
165 size
166 }
167
168 pub fn get_children_merkles(&self) -> MaybeMerkleTable {
169 if self.get_children_count() > 0 {
170 let mut merkle_table = Some(
171 [ChildrenTableItem::<MerkleHash>::no_child().clone();
172 CHILDREN_COUNT],
173 );
174 for (child_index, &SubtreeMerkleWithSize { ref merkle, .. }) in
175 self.get_children_table_ref().iter()
176 {
177 merkle_table.as_mut().unwrap()[child_index as usize] = *merkle;
178 }
179 merkle_table
180 } else {
181 None
182 }
183 }
184
185 pub fn get_merkle_hash_wo_compressed_path(&self) -> MerkleHash {
186 compute_node_merkle(
187 self.get_children_merkles().as_ref(),
188 self.0.value_as_slice().into_option(),
189 )
190 }
191}
192
193impl Decodable for SnapshotMptNode {
194 fn decode(rlp: &Rlp) -> std::result::Result<Self, DecoderError> {
195 Ok(Self(rlp.as_val()?))
196 }
197}
198
199impl Deref for SnapshotMptNode {
200 type Target = VanillaTrieNode<SubtreeMerkleWithSize>;
201
202 fn deref(&self) -> &Self::Target { &self.0 }
203}
204
205impl DerefMut for SnapshotMptNode {
206 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
207}
208
209impl Decodable for SubtreeMerkleWithSize {
210 fn decode(rlp: &Rlp) -> std::result::Result<Self, DecoderError> {
211 Ok(Self {
212 merkle: rlp.val_at(0)?,
213 subtree_size: rlp.val_at::<u64>(1)?,
214 delta_subtree_size: rlp.val_at::<u64>(2)?,
215 })
216 }
217}
218
219impl Encodable for SubtreeMerkleWithSize {
220 fn rlp_append(&self, s: &mut RlpStream) {
221 s.begin_list(3)
222 .append(&self.merkle)
223 .append(&self.subtree_size)
224 .append(&self.delta_subtree_size);
225 }
226}
227
228impl NodeRefTrait for SubtreeMerkleWithSize {}
229
230impl DefaultChildrenItem<SubtreeMerkleWithSize>
231 for ChildrenTableItem<SubtreeMerkleWithSize>
232{
233 fn no_child() -> &'static SubtreeMerkleWithSize {
234 &SnapshotMptNode::NO_CHILD
235 }
236}
237
238use super::super::impls::{
239 errors::*,
240 merkle_patricia_trie::{
241 merkle::{compute_node_merkle, MaybeMerkleTable},
242 mpt_cursor::rlp_key_value_len,
243 ChildrenTableItem, CompressedPathRaw, CompressedPathTrait,
244 DefaultChildrenItem, NodeRefTrait, TrieNodeTrait, VanillaTrieNode,
245 CHILDREN_COUNT,
246 },
247};
248use fallible_iterator::FallibleIterator;
249use primitives::{MerkleHash, MERKLE_NULL_NODE};
250use rlp::*;
251use std::ops::{Deref, DerefMut};