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