nam_sparse_merkle_tree/
proof_ics23.rs1use ics23::{ExistenceProof, HashOp, InnerOp, InnerSpec, LeafOp, LengthOp, ProofSpec};
2
3use crate::collections::VecDeque;
4use crate::error::{Error, Result};
5use crate::{Key, MerkleProof, H256, TREE_HEIGHT, traits::Value};
6
7pub fn convert<K, V, const N: usize>(
8 merkle_proof: MerkleProof,
9 key: &K,
10 value: &V,
11 hash_op: HashOp,
12) -> Result<ExistenceProof>
13where
14 K: Key<N>,
15 V: Value,
16{
17 let (leaves_path, proof) = merkle_proof.take();
18 let mut merge_heights: VecDeque<_> = leaves_path
19 .get(0)
20 .expect("The heights should exist")
21 .clone()
22 .into();
23 let mut proof: VecDeque<_> = proof.into();
24 let mut cur_key = **key;
25 let mut height = 0;
26 let mut path = Vec::new();
27 while !proof.is_empty() {
28 if height == TREE_HEIGHT {
29 if !proof.is_empty() {
30 return Err(Error::CorruptedProof);
31 }
32 break;
33 }
34
35 let merge_height = merge_heights.front().map(|h| *h as usize).unwrap_or(height);
37 if height != merge_height {
38 height = merge_height;
40 continue;
41 }
42
43 let (sibling, sibling_height) = proof.pop_front().expect("no proof");
45 if height < sibling_height as usize {
46 height = sibling_height as usize;
48 }
49 let inner_op = get_inner_op(hash_op, &sibling, cur_key.get_bit(height));
50 path.push(inner_op);
51
52 merge_heights.pop_front();
53 cur_key = cur_key.parent_path(height);
54 height += 1;
55 }
56
57 Ok(ExistenceProof {
58 key: key.to_vec(),
59 value: value.as_slice().to_vec(),
60 leaf: Some(get_leaf_op(hash_op)),
61 path,
62 })
63}
64
65pub fn get_spec(hash_op: HashOp) -> ProofSpec {
66 ProofSpec {
67 leaf_spec: Some(get_leaf_op(hash_op)),
68 inner_spec: Some(get_inner_spec(hash_op)),
69 max_depth: TREE_HEIGHT as i32,
70 min_depth: 0,
71 prehash_key_before_comparison: false,
72 }
73}
74
75fn get_leaf_op(hash_op: HashOp) -> LeafOp {
76 LeafOp {
77 hash: hash_op.into(),
78 prehash_key: HashOp::NoHash.into(),
79 prehash_value: HashOp::NoHash.into(),
80 length: LengthOp::NoPrefix.into(),
81 prefix: H256::zero().as_slice().to_vec(),
82 }
83}
84
85fn get_inner_op(hash_op: HashOp, sibling: &H256, is_right_node: bool) -> InnerOp {
86 let node = sibling.as_slice().to_vec();
87 let (prefix, suffix) = if is_right_node {
88 (node, vec![])
89 } else {
90 (vec![], node)
91 };
92 InnerOp {
93 hash: hash_op.into(),
94 prefix,
95 suffix,
96 }
97}
98
99fn get_inner_spec(hash_op: HashOp) -> InnerSpec {
100 InnerSpec {
101 child_order: vec![0, 1],
102 child_size: 32,
103 min_prefix_length: 0,
104 max_prefix_length: 32,
105 empty_child: vec![],
106 hash: hash_op.into(),
107 }
108}