miden_objects/conversion/
merkle.rs1use alloc::vec::Vec;
2
3use miden_protocol::Word;
4use miden_protocol::crypto::merkle::mmr::{MmrDelta, PartialMmr};
5use miden_protocol::crypto::merkle::smt::{PartialSmt, SmtLeaf, SmtProof, UniqueNodes};
6use miden_protocol::crypto::merkle::{MerklePath, SparseMerklePath};
7
8use crate::proto;
9
10#[cfg(test)]
11mod tests;
12
13impl From<&MerklePath> for proto::primitives::MerklePath {
17 fn from(value: &MerklePath) -> Self {
18 let siblings = value.nodes().iter().map(Into::into).collect();
19 proto::primitives::MerklePath { siblings }
20 }
21}
22
23impl From<MerklePath> for proto::primitives::MerklePath {
24 fn from(value: MerklePath) -> Self {
25 (&value).into()
26 }
27}
28
29impl From<SparseMerklePath> for proto::primitives::SparseMerklePath {
33 fn from(value: SparseMerklePath) -> Self {
34 let (empty_nodes_mask, siblings) = value.into_parts();
35 proto::primitives::SparseMerklePath {
36 empty_nodes_mask,
37 siblings: siblings.into_iter().map(Into::into).collect(),
38 }
39 }
40}
41
42impl From<&PartialMmr> for proto::primitives::PartialMmr {
46 fn from(mmr: &PartialMmr) -> Self {
47 let tracked_leaves = mmr
48 .leaves()
49 .map(|(position, leaf)| {
50 let proof = mmr
51 .open(position)
52 .expect("tracked MMR position must be in bounds")
53 .expect("tracked MMR leaf must have an opening");
54 proto::primitives::TrackedMmrLeaf {
55 position: position as u64,
56 leaf: Some(leaf.into()),
57 path: proof.merkle_path().nodes().iter().map(Into::into).collect(),
58 }
59 })
60 .collect();
61 Self {
62 forest: mmr.forest().num_leaves() as u64,
63 peaks: mmr.peaks().peaks().iter().map(Into::into).collect(),
64 tracked_leaves,
65 }
66 }
67}
68
69impl From<PartialMmr> for proto::primitives::PartialMmr {
70 fn from(mmr: PartialMmr) -> Self {
71 (&mmr).into()
72 }
73}
74
75impl From<MmrDelta> for proto::primitives::MmrDelta {
79 fn from(value: MmrDelta) -> Self {
80 let update_data = value.data.into_iter().map(Into::into).collect();
81 proto::primitives::MmrDelta {
82 forest: value.forest.num_leaves() as u64,
83 update_data,
84 }
85 }
86}
87
88impl From<SmtLeaf> for proto::primitives::SmtLeaf {
95 fn from(smt_leaf: SmtLeaf) -> Self {
96 use proto::primitives::smt_leaf::Leaf;
97
98 let leaf = match smt_leaf {
99 SmtLeaf::Empty(leaf_index) => Leaf::EmptyLeafIndex(leaf_index.position()),
100 SmtLeaf::Single(entry) => Leaf::Single(entry.into()),
101 SmtLeaf::Multiple(entries) => Leaf::Multiple(proto::primitives::SmtLeafEntryList {
102 entries: entries.into_iter().map(Into::into).collect(),
103 }),
104 };
105
106 Self { leaf: Some(leaf) }
107 }
108}
109
110impl From<(Word, Word)> for proto::primitives::SmtLeafEntry {
114 fn from((key, value): (Word, Word)) -> Self {
115 Self {
116 key: Some(key.into()),
117 value: Some(value.into()),
118 }
119 }
120}
121
122impl From<SmtProof> for proto::primitives::SmtOpening {
126 fn from(proof: SmtProof) -> Self {
127 let (path, leaf) = proof.into_parts();
128 Self {
129 path: Some(path.into()),
130 leaf: Some(leaf.into()),
131 }
132 }
133}
134
135impl From<UniqueNodes> for proto::primitives::PartialSmt {
139 fn from(unique_nodes: UniqueNodes) -> Self {
140 let UniqueNodes { root, nodes, leaves, value_only_leaves } = unique_nodes;
141
142 let mut node_levels = Vec::new();
143 let mut nodes = nodes.into_iter().peekable();
144 while let Some((index, _)) = nodes.peek() {
145 let depth = index.depth();
146 let mut level_nodes = Vec::new();
147 while let Some((index, digest)) = nodes.next_if(|(index, _)| index.depth() == depth) {
148 level_nodes.push(proto::primitives::PartialSmtNode {
149 index: index.position(),
150 digest: Some(digest.into()),
151 });
152 }
153 node_levels.push(proto::primitives::PartialSmtNodeLevel {
154 depth: u32::from(depth),
155 nodes: level_nodes,
156 });
157 }
158 let leaves = leaves
159 .into_iter()
160 .map(|(index, leaf)| proto::primitives::IndexedSmtLeaf {
161 index,
162 leaf: Some(leaf.into()),
163 })
164 .collect();
165
166 let value_only_leaves = value_only_leaves
167 .into_iter()
168 .map(|(index, value)| proto::primitives::IndexedDigest {
169 index,
170 value: Some(value.into()),
171 })
172 .collect();
173
174 Self {
175 root: Some(root.into()),
176 node_levels,
177 leaves,
178 value_only_leaves,
179 }
180 }
181}
182
183impl From<PartialSmt> for proto::primitives::PartialSmt {
184 fn from(partial_smt: PartialSmt) -> Self {
185 partial_smt.to_unique_nodes().into()
186 }
187}