1use crate::hasher::NodeHasher;
4use crate::trie::{self, InternalData, KeyPath, LeafData, Node, NodeKind, TERMINATOR};
5use crate::trie_pos::TriePosition;
6
7use bitvec::prelude::*;
8use core::fmt;
9
10#[cfg(not(feature = "std"))]
11use alloc::vec::Vec;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
16#[cfg_attr(
17 feature = "borsh",
18 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
19)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub enum PathProofTerminal {
22 Leaf(LeafData),
23 Terminator(TriePosition),
24}
25
26impl PathProofTerminal {
27 pub fn path(&self) -> &BitSlice<u8, Msb0> {
29 match self {
30 Self::Leaf(leaf_data) => &leaf_data.key_path.view_bits(),
31 Self::Terminator(key_path) => key_path.path(),
32 }
33 }
34
35 pub fn node<H: NodeHasher>(&self) -> Node {
36 match self {
37 Self::Leaf(leaf_data) => H::hash_leaf(leaf_data),
38 Self::Terminator(_key_path) => TERMINATOR,
39 }
40 }
41
42 pub fn as_leaf_option(&self) -> Option<LeafData> {
44 match self {
45 Self::Leaf(leaf_data) => Some(leaf_data.clone()),
46 Self::Terminator(_) => None,
47 }
48 }
49}
50
51#[derive(Debug, Clone)]
53#[cfg_attr(
54 feature = "borsh",
55 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
56)]
57#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58pub struct PathProof {
59 pub terminal: PathProofTerminal,
62 pub siblings: Vec<Node>,
64}
65
66impl PathProof {
67 pub fn verify<H: NodeHasher>(
76 &self,
77 key_path: &BitSlice<u8, Msb0>,
78 root: Node,
79 ) -> Result<VerifiedPathProof, PathProofVerificationError> {
80 if self.siblings.len() > core::cmp::min(key_path.len(), 256) {
81 return Err(PathProofVerificationError::TooManySiblings);
82 }
83 let relevant_path = &key_path[..self.siblings.len()];
84
85 let cur_node = self.terminal.node::<H>();
86
87 let new_root = hash_path::<H>(cur_node, relevant_path, self.siblings.iter().rev().cloned());
88
89 if new_root == root {
90 Ok(VerifiedPathProof {
91 key_path: relevant_path.into(),
92 terminal: match &self.terminal {
93 PathProofTerminal::Leaf(leaf_data) => Some(leaf_data.clone()),
94 PathProofTerminal::Terminator(_) => None,
95 },
96 siblings: self.siblings.clone(),
97 root,
98 })
99 } else {
100 Err(PathProofVerificationError::RootMismatch)
101 }
102 }
103}
104
105pub fn hash_path<H: NodeHasher>(
109 mut node: Node,
110 path: &BitSlice<u8, Msb0>,
111 siblings: impl IntoIterator<Item = Node>,
112) -> Node {
113 for (bit, sibling) in path.iter().by_vals().rev().zip(siblings) {
114 let (left, right) = if bit {
115 (sibling, node)
116 } else {
117 (node, sibling)
118 };
119
120 let next = InternalData {
121 left: left.clone(),
122 right: right.clone(),
123 };
124 node = H::hash_internal(&next);
125 }
126
127 node
128}
129
130#[derive(Debug, Clone, Copy)]
132pub struct KeyOutOfScope;
133
134#[derive(Debug, Clone, Copy)]
136pub enum PathProofVerificationError {
137 TooManySiblings,
139 RootMismatch,
141}
142
143#[derive(Clone)]
155#[must_use = "VerifiedPathProof only checks the trie path, not whether it actually looks up to your expected value."]
156pub struct VerifiedPathProof {
157 key_path: BitVec<u8, Msb0>,
158 terminal: Option<LeafData>,
159 siblings: Vec<Node>,
160 root: Node,
161}
162
163impl VerifiedPathProof {
164 pub fn terminal(&self) -> Option<&LeafData> {
166 self.terminal.as_ref()
167 }
168
169 pub fn path(&self) -> &BitSlice<u8, Msb0> {
171 &self.key_path[..]
172 }
173
174 pub fn root(&self) -> Node {
176 self.root
177 }
178
179 pub fn confirm_value(&self, expected_leaf: &LeafData) -> Result<bool, KeyOutOfScope> {
186 self.in_scope(&expected_leaf.key_path)
187 .map(|_| self.terminal() == Some(expected_leaf))
188 }
189
190 pub fn confirm_nonexistence(&self, key_path: &KeyPath) -> Result<bool, KeyOutOfScope> {
197 self.in_scope(key_path).map(|_| {
198 self.terminal()
199 .as_ref()
200 .map_or(true, |d| &d.key_path != key_path)
201 })
202 }
203
204 fn in_scope(&self, key_path: &KeyPath) -> Result<(), KeyOutOfScope> {
205 let this_path = self.path();
206 let other_path = &key_path.view_bits::<Msb0>()[..self.key_path.len()];
207 if this_path == other_path {
208 Ok(())
209 } else {
210 Err(KeyOutOfScope)
211 }
212 }
213}
214
215impl fmt::Debug for VerifiedPathProof {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 f.debug_struct("VerifiedPathProof")
218 .field("path", &self.path())
219 .field("terminal", &self.terminal())
220 .field("root", &self.root())
221 .finish()
222 }
223}
224
225#[derive(Debug, Clone, Copy)]
227pub enum VerifyUpdateError {
228 PathsOutOfOrder,
230 OpsOutOfOrder,
232 OpOutOfScope,
234 PathWithoutOps,
236 RootMismatch,
238}
239
240pub struct PathUpdate {
242 pub inner: VerifiedPathProof,
244 pub ops: Vec<(KeyPath, Option<trie::ValueHash>)>,
246}
247
248impl fmt::Debug for PathUpdate {
249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
250 f.debug_struct("PathUpdate")
251 .field("inner", &self.inner)
252 .field("ops", &self.ops)
253 .finish()
254 }
255}
256
257pub fn verify_update<H: NodeHasher>(
268 prev_root: Node,
269 paths: &[PathUpdate],
270) -> Result<Node, VerifyUpdateError> {
271 if paths.is_empty() {
272 return Ok(prev_root);
273 }
274
275 for (i, path) in paths.iter().enumerate() {
277 if path.inner.root() != prev_root {
279 return Err(VerifyUpdateError::RootMismatch);
280 }
281
282 if i != 0 && paths[i - 1].inner.path() >= path.inner.path() {
284 return Err(VerifyUpdateError::PathsOutOfOrder);
285 }
286
287 if path.ops.is_empty() {
289 return Err(VerifyUpdateError::PathWithoutOps);
290 }
291
292 for (j, (key, _value)) in path.ops.iter().enumerate() {
293 if j != 0 && &path.ops[j - 1].0 >= key {
294 return Err(VerifyUpdateError::OpsOutOfOrder);
295 }
296
297 if !key.view_bits::<Msb0>().starts_with(path.inner.path()) {
298 return Err(VerifyUpdateError::OpOutOfScope);
299 }
300 }
301 }
302
303 let mut pending_siblings: Vec<(Node, usize)> = Vec::new();
305 for (i, path) in paths.iter().enumerate() {
306 let leaf = path.inner.terminal().map(|x| x.clone());
307 let ops = &path.ops;
308 let skip = path.inner.path().len();
309
310 let up_layers = match paths.get(i + 1) {
311 None => skip, Some(p) => {
313 let n = shared_bits(p.inner.path(), path.inner.path());
314 skip - (n + 1)
317 }
318 };
319
320 let ops = crate::update::leaf_ops_spliced(leaf, ops);
321 let sub_root = crate::update::build_trie::<H>(skip, ops, |_| {});
322
323 let mut cur_node = sub_root;
324 let mut cur_layer = skip;
325 let end_layer = skip - up_layers;
326 for (bit, sibling) in path
330 .inner
331 .path()
332 .iter()
333 .by_vals()
334 .rev()
335 .take(up_layers)
336 .zip(path.inner.siblings.iter().rev())
337 {
338 let sibling = if pending_siblings.last().map_or(false, |p| p.1 == cur_layer) {
339 pending_siblings.pop().unwrap().0
341 } else {
342 *sibling
343 };
344
345 match (NodeKind::of::<H>(&cur_node), NodeKind::of::<H>(&sibling)) {
346 (NodeKind::Terminator, NodeKind::Terminator) => {}
347 (NodeKind::Leaf, NodeKind::Terminator) => {}
348 (NodeKind::Terminator, NodeKind::Leaf) => {
349 cur_node = sibling;
351 }
352 _ => {
353 let node_data = if bit {
355 trie::InternalData {
356 left: sibling,
357 right: cur_node,
358 }
359 } else {
360 trie::InternalData {
361 left: cur_node,
362 right: sibling,
363 }
364 };
365 cur_node = H::hash_internal(&node_data);
366 }
367 }
368 cur_layer -= 1;
369 }
370 pending_siblings.push((cur_node, end_layer));
371 }
372
373 Ok(pending_siblings.pop().map(|n| n.0).unwrap())
376}
377
378pub fn shared_bits(a: &BitSlice<u8, Msb0>, b: &BitSlice<u8, Msb0>) -> usize {
380 a.iter().zip(b.iter()).take_while(|(a, b)| a == b).count()
381}