cloud_mmr/
merkle_proof.rs1use crate::hash::Hash;
18use crate::pmmr;
19use crate::ser::{self, PMMRIndexHashable, Readable, Reader, Writeable, Writer};
20
21#[derive(Clone, Debug, PartialEq)]
23pub enum MerkleProofError {
24 RootMismatch,
26}
27
28#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, PartialOrd, Ord)]
30pub struct MerkleProof {
31 pub mmr_size: u64,
33 pub path: Vec<Hash>,
36}
37
38impl Writeable for MerkleProof {
39 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
40 writer.write_u64(self.mmr_size)?;
41 writer.write_u64(self.path.len() as u64)?;
42 self.path.write(writer)?;
43 Ok(())
44 }
45}
46
47impl Readable for MerkleProof {
48 fn read<R: Reader>(reader: &mut R) -> Result<MerkleProof, ser::Error> {
49 let mmr_size = reader.read_u64()?;
50 let path_len = reader.read_u64()?;
51 let mut path = Vec::with_capacity(path_len as usize);
52 for _ in 0..path_len {
53 let hash = Hash::read(reader)?;
54 path.push(hash);
55 }
56
57 Ok(MerkleProof { mmr_size, path })
58 }
59}
60
61impl Default for MerkleProof {
62 fn default() -> MerkleProof {
63 MerkleProof::empty()
64 }
65}
66
67impl MerkleProof {
68 pub fn empty() -> MerkleProof {
70 MerkleProof {
71 mmr_size: 0,
72 path: Vec::default(),
73 }
74 }
75
76 pub fn to_hex(&self) -> String {
78 let mut vec: Vec<u8> = Vec::new();
79 ser::serialize_default(&mut vec, &self).expect("serialization failed");
80 hex::encode(&vec)
81 }
82
83 pub fn from_hex(hex: &str) -> Result<MerkleProof, String> {
85 let bytes = hex::decode(hex).unwrap();
86 let res = ser::deserialize_default(&mut &bytes[..])
87 .map_err(|_| "failed to deserialize a Merkle Proof".to_string())?;
88 Ok(res)
89 }
90
91 pub fn verify(
94 &self,
95 root: Hash,
96 element: &dyn PMMRIndexHashable,
97 node_pos: u64,
98 ) -> Result<(), MerkleProofError> {
99 let mut proof = self.clone();
100 let peaks_pos = pmmr::peaks(self.mmr_size);
103 proof.verify_consume(root, element, node_pos, &peaks_pos)
104 }
105
106 fn verify_consume(
110 &mut self,
111 root: Hash,
112 element: &dyn PMMRIndexHashable,
113 node_pos0: u64,
114 peaks_pos0: &[u64],
115 ) -> Result<(), MerkleProofError> {
116 let node_hash = if node_pos0 >= self.mmr_size {
117 element.hash_with_index(self.mmr_size)
118 } else {
119 element.hash_with_index(node_pos0)
120 };
121
122 if self.path.is_empty() {
125 if root == node_hash {
126 return Ok(());
127 } else {
128 return Err(MerkleProofError::RootMismatch);
129 }
130 }
131
132 let sibling = self.path.remove(0);
133 let (parent_pos0, sibling_pos0) = pmmr::family(node_pos0);
134
135 if let Ok(x) = peaks_pos0.binary_search(&(node_pos0)) {
136 let parent = if x == peaks_pos0.len() - 1 {
137 (sibling, node_hash)
138 } else {
139 (node_hash, sibling)
140 };
141 self.verify(root, &parent, parent_pos0)
142 } else if parent_pos0 >= self.mmr_size {
143 let parent = (sibling, node_hash);
144 self.verify(root, &parent, parent_pos0)
145 } else {
146 let parent = if pmmr::is_left_sibling(sibling_pos0) {
147 (sibling, node_hash)
148 } else {
149 (node_hash, sibling)
150 };
151 self.verify(root, &parent, parent_pos0)
152 }
153 }
154}