cfx_storage/impls/
node_merkle_proof.rs1#[derive(Clone, Debug, Default, PartialEq, RlpEncodable, RlpDecodable)]
6pub struct NodeMerkleProof {
7 pub delta_proof: Option<TrieProof>,
8 pub intermediate_proof: Option<TrieProof>,
9 pub snapshot_proof: Option<TrieProof>,
10}
11
12pub type StorageRootProof = NodeMerkleProof;
13
14impl NodeMerkleProof {
15 pub fn with_delta(
16 &mut self, maybe_delta_proof: Option<TrieProof>,
17 ) -> &mut Self {
18 self.delta_proof = maybe_delta_proof;
19 self
20 }
21
22 pub fn with_intermediate(
23 &mut self, maybe_intermediate_proof: Option<TrieProof>,
24 ) -> &mut Self {
25 self.intermediate_proof = maybe_intermediate_proof;
26 self
27 }
28
29 pub fn with_snapshot(
30 &mut self, maybe_snapshot_proof: Option<TrieProof>,
31 ) -> &mut Self {
32 self.snapshot_proof = maybe_snapshot_proof;
33 self
34 }
35
36 pub fn is_valid(
37 &self, key: &Vec<u8>, storage_root: &StorageRoot,
38 state_root: StateRoot,
39 maybe_intermediate_padding: Option<DeltaMptKeyPadding>,
40 ) -> bool {
41 let delta_root = &state_root.delta_root;
42 let intermediate_root = &state_root.intermediate_delta_root;
43 let snapshot_root = &state_root.snapshot_root;
44
45 let storage_key =
46 match StorageKeyWithSpace::from_key_bytes::<CheckInput>(&key) {
47 Ok(k) => k,
48 Err(e) => {
49 warn!("Checking proof with invalid key: {:?}", e);
50 return false;
51 }
52 };
53
54 match self.delta_proof {
55 None => {
56 if delta_root.ne(&MERKLE_NULL_NODE) {
58 return false;
59 }
60
61 if storage_root.delta != MptValue::None {
63 return false;
64 }
65 }
66
67 Some(ref proof) => {
68 let padding = StorageKeyWithSpace::delta_mpt_padding(
70 &snapshot_root,
71 &intermediate_root,
72 );
73
74 let key = storage_key.to_delta_mpt_key_bytes(&padding);
75
76 if !proof.is_valid_node_merkle(
78 &key,
79 &storage_root.delta,
80 delta_root,
81 ) {
82 return false;
83 }
84 }
85 }
86
87 match self.intermediate_proof {
88 None => {
89 if intermediate_root.ne(&MERKLE_NULL_NODE) {
91 return false;
92 }
93
94 if storage_root.intermediate != MptValue::None {
96 return false;
97 }
98 }
99
100 Some(ref proof) => {
101 let key = match maybe_intermediate_padding {
103 None => return false,
104 Some(p) => storage_key.to_delta_mpt_key_bytes(&p),
105 };
106
107 if !proof.is_valid_node_merkle(
109 &key,
110 &storage_root.intermediate,
111 intermediate_root,
112 ) {
113 return false;
114 }
115 }
116 }
117
118 match self.snapshot_proof {
119 None => {
120 if snapshot_root.ne(&MERKLE_NULL_NODE) {
122 return false;
123 }
124
125 if storage_root.snapshot != None {
127 return false;
128 }
129 }
130
131 Some(ref proof) => {
132 if !proof.is_valid_node_merkle(
134 &key,
135 &storage_root.snapshot.into(),
136 snapshot_root,
137 ) {
138 return false;
139 }
140 }
141 }
142
143 true
144 }
145}
146
147use super::merkle_patricia_trie::TrieProof;
148use primitives::{
149 CheckInput, DeltaMptKeyPadding, MptValue, StateRoot, StorageKeyWithSpace,
150 StorageRoot, MERKLE_NULL_NODE,
151};
152use rlp_derive::{RlpDecodable, RlpEncodable};