cfx_storage/impls/snapshot_sync/offer/
mpt_slicer.rs1pub struct MptSlicer<'a> {
6 cursor: MptCursor<
7 &'a mut dyn SnapshotMptTraitRead,
8 BasicPathNode<&'a mut dyn SnapshotMptTraitRead>,
9 >,
10}
11
12impl<'a> MptSlicer<'a> {
13 pub fn new(mpt: &'a mut dyn SnapshotMptTraitRead) -> Result<Self> {
14 let mut cursor = MptCursor::new(mpt);
15 cursor.load_root()?;
16 Ok(Self { cursor })
17 }
18
19 pub fn new_from_key(
20 mpt: &'a mut dyn SnapshotMptTraitRead, key: &[u8],
21 ) -> Result<Self> {
22 let mut slicer = Self::new(mpt)?;
23 slicer.cursor.open_path_for_key::<access_mode::Read>(key)?;
24 Ok(slicer)
25 }
26
27 pub fn to_proof(&self) -> TrieProof { self.cursor.to_proof() }
28
29 pub fn get_range_end_key(&self) -> Option<&[u8]> {
30 let key = self
33 .cursor
34 .get_path_nodes()
35 .last()
36 .unwrap()
37 .get_path_to_node()
38 .path_slice();
39 if key.len() == 0 {
40 None
41 } else {
42 Some(key)
43 }
44 }
45
46 pub fn advance(&mut self, mut rlp_size_limit: u64) -> Result<()> {
47 let current_node = self.cursor.current_node_mut();
48 if current_node.next_child_index == 0 {
51 let maybe_value = current_node.value_as_slice();
52 match maybe_value {
53 MptValue::Some(value) => {
54 let key_value_size = rlp_key_value_len(
55 current_node.get_path_to_node().path_size(),
56 value.len(),
57 );
58 if rlp_size_limit <= key_value_size {
59 return Ok(());
60 } else {
61 rlp_size_limit -= key_value_size;
62 }
63 }
64 _ => {}
65 }
66 }
67
68 for (
69 this_child_index,
70 &SubtreeMerkleWithSize {
71 ref subtree_size, ..
72 },
73 ) in current_node
74 .trie_node
75 .get_children_table_ref()
76 .iter()
77 .set_start_index(current_node.next_child_index)
78 {
79 if *subtree_size <= rlp_size_limit {
80 rlp_size_limit -= *subtree_size;
81 } else {
82 let child_node = unsafe {
83 &mut *(current_node
89 as *const BasicPathNode<
90 &'a mut dyn SnapshotMptTraitRead,
91 >
92 as *mut BasicPathNode<&'a mut dyn SnapshotMptTraitRead>)
93 }
94 .open_child_index(this_child_index)?
95 .unwrap();
97
98 self.cursor.push_node(child_node);
99 return self.advance(rlp_size_limit);
100 }
101 }
102
103 if rlp_size_limit > 0 && self.cursor.get_path_nodes().len() > 1 {
105 self.cursor.pop_one_node()?;
106 return self.advance(rlp_size_limit);
107 }
108
109 Ok(())
110 }
111}
112
113use super::super::super::{
114 super::{
115 storage_db::snapshot_mpt::{
116 SnapshotMptTraitRead, SubtreeMerkleWithSize,
117 },
118 utils::access_mode,
119 },
120 errors::*,
121 merkle_patricia_trie::{mpt_cursor::*, *},
122};
123use primitives::MptValue;