redgold_schema/
merkle_proof.rs

1use crate::structs::MerkleProof;
2use prost::DecodeError;
3
4use crate::{ErrorInfo, SafeOption};
5use prost::Message;
6
7impl MerkleProof {
8    pub fn proto_serialize(&self) -> Vec<u8> {
9        return self.encode_to_vec();
10    }
11
12    pub fn proto_deserialize(bytes: Vec<u8>) -> Result<Self, DecodeError> {
13        return MerkleProof::decode(&*bytes);
14    }
15}
16
17
18impl MerkleProof {
19    pub fn verify(&self) -> Result<(), ErrorInfo> {
20        let len = self.nodes.len();
21        for i in (0..len).step_by(2) {
22            let left = self.nodes[i].clone();
23            let right = self.nodes[i + 1].clone();
24            let parent = left.merkle_combine(right.clone());
25            let parent_vec = parent.vec();
26
27            if i == 0 {
28                let leaf = self.leaf.safe_get_msg("leaf missing")?.vec();
29                if !(leaf == left.vec() || leaf == right.vec()) {
30                    return Err(ErrorInfo::error_info("Leaf not found at proof start"));
31                }
32            }
33
34            if i+1 == (len-1) {
35                if parent_vec != self.root.safe_get_msg("Root")?.vec() {
36                    return Err(ErrorInfo::error_info("Last intermediate hash merge does not match root"));
37                }
38            } else {
39                let next_left = self.nodes[i + 2].clone();
40                let next_right = self.nodes[i + 3].clone();
41                let next = vec![next_left.vec(), next_right.vec()];
42                if !next.contains(&parent_vec) {
43                    return Err(ErrorInfo::error_info(
44                        format!("Intermediate hash mismatch on parent: {} with next_left: {} next_right: {}",
45                                parent.hex(), next_left.hex(), next_right.hex())));
46
47                }
48            }
49        }
50        Ok(())
51    }
52}
53