Skip to main content

miden_node_proto/domain/
merkle.rs

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