miden_node_proto/domain/
merkle.rs

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