miden_node_proto/domain/
merkle.rs

1use miden_objects::{
2    crypto::merkle::{LeafIndex, MerklePath, MmrDelta, SmtLeaf, SmtProof},
3    Digest, Word,
4};
5
6use super::{convert, try_convert};
7use crate::{
8    errors::{ConversionError, MissingFieldHelper},
9    generated as proto,
10};
11
12// MERKLE PATH
13// ================================================================================================
14
15impl From<&MerklePath> for proto::merkle::MerklePath {
16    fn from(value: &MerklePath) -> Self {
17        let siblings = value.nodes().iter().map(proto::digest::Digest::from).collect();
18        proto::merkle::MerklePath { siblings }
19    }
20}
21
22impl From<MerklePath> for proto::merkle::MerklePath {
23    fn from(value: MerklePath) -> Self {
24        (&value).into()
25    }
26}
27
28impl TryFrom<&proto::merkle::MerklePath> for MerklePath {
29    type Error = ConversionError;
30
31    fn try_from(merkle_path: &proto::merkle::MerklePath) -> Result<Self, Self::Error> {
32        merkle_path.siblings.iter().map(Digest::try_from).collect()
33    }
34}
35
36// MMR DELTA
37// ================================================================================================
38
39impl From<MmrDelta> for proto::mmr::MmrDelta {
40    fn from(value: MmrDelta) -> Self {
41        let data = value.data.into_iter().map(proto::digest::Digest::from).collect();
42        proto::mmr::MmrDelta { forest: value.forest as u64, data }
43    }
44}
45
46impl TryFrom<proto::mmr::MmrDelta> for MmrDelta {
47    type Error = ConversionError;
48
49    fn try_from(value: proto::mmr::MmrDelta) -> Result<Self, Self::Error> {
50        let data: Result<Vec<_>, ConversionError> =
51            value.data.into_iter().map(Digest::try_from).collect();
52
53        Ok(MmrDelta {
54            forest: value.forest as usize,
55            data: data?,
56        })
57    }
58}
59
60// SPARSE MERKLE TREE
61// ================================================================================================
62
63// SMT LEAF
64// ------------------------------------------------------------------------------------------------
65
66impl TryFrom<proto::smt::SmtLeaf> for SmtLeaf {
67    type Error = ConversionError;
68
69    fn try_from(value: proto::smt::SmtLeaf) -> Result<Self, Self::Error> {
70        let leaf = value.leaf.ok_or(proto::smt::SmtLeaf::missing_field(stringify!(leaf)))?;
71
72        match leaf {
73            proto::smt::smt_leaf::Leaf::Empty(leaf_index) => {
74                Ok(Self::new_empty(LeafIndex::new_max_depth(leaf_index)))
75            },
76            proto::smt::smt_leaf::Leaf::Single(entry) => {
77                let (key, value): (Digest, Word) = entry.try_into()?;
78
79                Ok(SmtLeaf::new_single(key, value))
80            },
81            proto::smt::smt_leaf::Leaf::Multiple(entries) => {
82                let domain_entries: Vec<(Digest, Word)> = try_convert(entries.entries)?;
83
84                Ok(SmtLeaf::new_multiple(domain_entries)?)
85            },
86        }
87    }
88}
89
90impl From<SmtLeaf> for proto::smt::SmtLeaf {
91    fn from(smt_leaf: SmtLeaf) -> Self {
92        use proto::smt::smt_leaf::Leaf;
93
94        let leaf = match smt_leaf {
95            SmtLeaf::Empty(leaf_index) => Leaf::Empty(leaf_index.value()),
96            SmtLeaf::Single(entry) => Leaf::Single(entry.into()),
97            SmtLeaf::Multiple(entries) => {
98                Leaf::Multiple(proto::smt::SmtLeafEntries { entries: convert(entries) })
99            },
100        };
101
102        Self { leaf: Some(leaf) }
103    }
104}
105
106// SMT LEAF ENTRY
107// ------------------------------------------------------------------------------------------------
108
109impl TryFrom<proto::smt::SmtLeafEntry> for (Digest, Word) {
110    type Error = ConversionError;
111
112    fn try_from(entry: proto::smt::SmtLeafEntry) -> Result<Self, Self::Error> {
113        let key: Digest = entry
114            .key
115            .ok_or(proto::smt::SmtLeafEntry::missing_field(stringify!(key)))?
116            .try_into()?;
117        let value: Word = entry
118            .value
119            .ok_or(proto::smt::SmtLeafEntry::missing_field(stringify!(value)))?
120            .try_into()?;
121
122        Ok((key, value))
123    }
124}
125
126impl From<(Digest, Word)> for proto::smt::SmtLeafEntry {
127    fn from((key, value): (Digest, Word)) -> Self {
128        Self {
129            key: Some(key.into()),
130            value: Some(value.into()),
131        }
132    }
133}
134
135// SMT PROOF
136// ------------------------------------------------------------------------------------------------
137
138impl TryFrom<proto::smt::SmtOpening> for SmtProof {
139    type Error = ConversionError;
140
141    fn try_from(opening: proto::smt::SmtOpening) -> Result<Self, Self::Error> {
142        let path: MerklePath = opening
143            .path
144            .as_ref()
145            .ok_or(proto::smt::SmtOpening::missing_field(stringify!(path)))?
146            .try_into()?;
147        let leaf: SmtLeaf = opening
148            .leaf
149            .ok_or(proto::smt::SmtOpening::missing_field(stringify!(leaf)))?
150            .try_into()?;
151
152        Ok(SmtProof::new(path, leaf)?)
153    }
154}
155
156impl From<SmtProof> for proto::smt::SmtOpening {
157    fn from(proof: SmtProof) -> Self {
158        let (ref path, leaf) = proof.into_parts();
159        Self {
160            path: Some(path.into()),
161            leaf: Some(leaf.into()),
162        }
163    }
164}