miden_node_proto/domain/
merkle.rs1use 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
11impl 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
43impl 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
72impl 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 Ok(MmrDelta {
97 forest: Forest::new(value.forest as usize),
98 data,
99 })
100 }
101}
102
103impl 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
114 .leaf
115 .ok_or(ConversionError::missing_field::<proto::primitives::SmtLeaf>("leaf"))?;
116
117 match leaf {
118 proto::primitives::smt_leaf::Leaf::EmptyLeafIndex(leaf_index) => {
119 Ok(Self::new_empty(LeafIndex::new_max_depth(leaf_index)))
120 },
121 proto::primitives::smt_leaf::Leaf::Single(entry) => {
122 let (key, value): (Word, Word) = entry.try_into().context("entry")?;
123
124 Ok(SmtLeaf::new_single(key, value))
125 },
126 proto::primitives::smt_leaf::Leaf::Multiple(entries) => {
127 let domain_entries: Vec<(Word, Word)> =
128 try_convert(entries.entries).collect::<Result<_, _>>().context("entries")?;
129
130 Ok(SmtLeaf::new_multiple(domain_entries)?)
131 },
132 }
133 }
134}
135
136impl From<SmtLeaf> for proto::primitives::SmtLeaf {
137 fn from(smt_leaf: SmtLeaf) -> Self {
138 use proto::primitives::smt_leaf::Leaf;
139
140 let leaf = match smt_leaf {
141 SmtLeaf::Empty(leaf_index) => Leaf::EmptyLeafIndex(leaf_index.position()),
142 SmtLeaf::Single(entry) => Leaf::Single(entry.into()),
143 SmtLeaf::Multiple(entries) => Leaf::Multiple(proto::primitives::SmtLeafEntryList {
144 entries: convert(entries).collect(),
145 }),
146 };
147
148 Self { leaf: Some(leaf) }
149 }
150}
151
152impl TryFrom<proto::primitives::SmtLeafEntry> for (Word, Word) {
156 type Error = ConversionError;
157
158 fn try_from(entry: proto::primitives::SmtLeafEntry) -> Result<Self, Self::Error> {
159 let decoder = entry.decoder();
160 let key: Word = decode!(decoder, entry.key)?;
161 let value: Word = decode!(decoder, entry.value)?;
162
163 Ok((key, value))
164 }
165}
166
167impl From<(Word, Word)> for proto::primitives::SmtLeafEntry {
168 fn from((key, value): (Word, Word)) -> Self {
169 Self {
170 key: Some(key.into()),
171 value: Some(value.into()),
172 }
173 }
174}
175
176impl TryFrom<proto::primitives::SmtOpening> for SmtProof {
180 type Error = ConversionError;
181
182 fn try_from(opening: proto::primitives::SmtOpening) -> Result<Self, Self::Error> {
183 let decoder = opening.decoder();
184 let path: SparseMerklePath = decode!(decoder, opening.path)?;
185 let leaf: SmtLeaf = decode!(decoder, opening.leaf)?;
186
187 Ok(SmtProof::new(path, leaf)?)
188 }
189}
190
191impl From<SmtProof> for proto::primitives::SmtOpening {
192 fn from(proof: SmtProof) -> Self {
193 let (path, leaf) = proof.into_parts();
194 Self {
195 path: Some(path.into()),
196 leaf: Some(leaf.into()),
197 }
198 }
199}