warg_transparency/map/
proof_bundle.rs

1use alloc::vec::Vec;
2use anyhow::Error;
3use prost::Message;
4use warg_crypto::{
5    hash::{Hash, SupportedDigest},
6    VisitBytes,
7};
8use warg_protobuf::transparency as protobuf;
9
10use crate::map::proof::Proof;
11
12/// A collection of inclusion proof info
13pub struct ProofBundle<D, K, V>
14where
15    D: SupportedDigest,
16    K: VisitBytes,
17    V: VisitBytes,
18{
19    proofs: Vec<Proof<D, K, V>>,
20}
21
22impl<D, K, V> ProofBundle<D, K, V>
23where
24    D: SupportedDigest,
25    K: VisitBytes,
26    V: VisitBytes,
27{
28    /// Bundles inclusion proofs together
29    pub fn bundle(proofs: Vec<Proof<D, K, V>>) -> Self {
30        ProofBundle { proofs }
31    }
32
33    /// Splits a bundle into its constituent inclusion proofs
34    pub fn unbundle(self) -> Vec<Proof<D, K, V>> {
35        self.proofs
36    }
37
38    /// Turn a bundle into bytes using protobuf
39    pub fn encode(self) -> Vec<u8> {
40        let proto: protobuf::MapProofBundle = self.into();
41        proto.encode_to_vec()
42    }
43
44    /// Parse a bundle from bytes using protobuf
45    pub fn decode(bytes: &[u8]) -> Result<Self, Error> {
46        let proto = protobuf::MapProofBundle::decode(bytes)?;
47        let bundle = proto.try_into()?;
48        Ok(bundle)
49    }
50}
51
52impl<D, K, V> From<ProofBundle<D, K, V>> for protobuf::MapProofBundle
53where
54    D: SupportedDigest,
55    K: VisitBytes,
56    V: VisitBytes,
57{
58    fn from(value: ProofBundle<D, K, V>) -> Self {
59        let proofs = value.proofs.into_iter().map(|proof| proof.into()).collect();
60        protobuf::MapProofBundle { proofs }
61    }
62}
63
64impl<D, K, V> From<Proof<D, K, V>> for protobuf::MapInclusionProof
65where
66    D: SupportedDigest,
67    K: VisitBytes,
68    V: VisitBytes,
69{
70    fn from(value: Proof<D, K, V>) -> Self {
71        let peers: Vec<Option<Hash<D>>> = value.into();
72        protobuf::MapInclusionProof {
73            hashes: peers.into_iter().map(|h| h.into()).collect(),
74        }
75    }
76}
77
78impl<D, K, V> TryFrom<protobuf::MapProofBundle> for ProofBundle<D, K, V>
79where
80    D: SupportedDigest,
81    K: VisitBytes,
82    V: VisitBytes,
83{
84    type Error = Error;
85
86    fn try_from(value: protobuf::MapProofBundle) -> Result<Self, Self::Error> {
87        let mut proofs = Vec::new();
88        for entry in value.proofs {
89            proofs.push(entry.try_into()?);
90        }
91        let bundle = ProofBundle { proofs };
92        Ok(bundle)
93    }
94}
95
96impl<D, K, V> TryFrom<protobuf::MapInclusionProof> for Proof<D, K, V>
97where
98    D: SupportedDigest,
99    K: VisitBytes,
100    V: VisitBytes,
101{
102    type Error = Error;
103
104    fn try_from(value: protobuf::MapInclusionProof) -> Result<Self, Self::Error> {
105        let peers: Result<Vec<Option<Hash<D>>>, Error> =
106            value.hashes.into_iter().map(|h| h.try_into()).collect();
107        let proof = Proof::new(peers?);
108        Ok(proof)
109    }
110}