Skip to main content

miden_objects/conversion/
merkle.rs

1use alloc::vec::Vec;
2
3use miden_protocol::Word;
4use miden_protocol::crypto::merkle::mmr::MmrDelta;
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
13// MERKLE PATH
14// ================================================================================================
15
16impl 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
29// SPARSE MERKLE PATH
30// ================================================================================================
31
32impl 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
42// MMR DELTA
43// ================================================================================================
44
45impl From<MmrDelta> for proto::primitives::MmrDelta {
46    fn from(value: MmrDelta) -> Self {
47        let update_data = value.data.into_iter().map(Into::into).collect();
48        proto::primitives::MmrDelta {
49            forest: value.forest.num_leaves() as u64,
50            update_data,
51        }
52    }
53}
54
55// SPARSE MERKLE TREE
56// ================================================================================================
57
58// SMT LEAF
59// ------------------------------------------------------------------------------------------------
60
61impl From<SmtLeaf> for proto::primitives::SmtLeaf {
62    fn from(smt_leaf: SmtLeaf) -> Self {
63        use proto::primitives::smt_leaf::Leaf;
64
65        let leaf = match smt_leaf {
66            SmtLeaf::Empty(leaf_index) => Leaf::EmptyLeafIndex(leaf_index.position()),
67            SmtLeaf::Single(entry) => Leaf::Single(entry.into()),
68            SmtLeaf::Multiple(entries) => Leaf::Multiple(proto::primitives::SmtLeafEntryList {
69                entries: entries.into_iter().map(Into::into).collect(),
70            }),
71        };
72
73        Self { leaf: Some(leaf) }
74    }
75}
76
77// SMT LEAF ENTRY
78// ------------------------------------------------------------------------------------------------
79
80impl From<(Word, Word)> for proto::primitives::SmtLeafEntry {
81    fn from((key, value): (Word, Word)) -> Self {
82        Self {
83            key: Some(key.into()),
84            value: Some(value.into()),
85        }
86    }
87}
88
89// SMT PROOF
90// ------------------------------------------------------------------------------------------------
91
92impl From<SmtProof> for proto::primitives::SmtOpening {
93    fn from(proof: SmtProof) -> Self {
94        let (path, leaf) = proof.into_parts();
95        Self {
96            path: Some(path.into()),
97            leaf: Some(leaf.into()),
98        }
99    }
100}
101
102// PARTIAL SMT
103// ------------------------------------------------------------------------------------------------
104
105impl From<UniqueNodes> for proto::primitives::PartialSmt {
106    fn from(unique_nodes: UniqueNodes) -> Self {
107        let UniqueNodes { root, nodes, leaves, value_only_leaves } = unique_nodes;
108
109        let mut node_levels = Vec::new();
110        let mut nodes = nodes.into_iter().peekable();
111        while let Some((index, _)) = nodes.peek() {
112            let depth = index.depth();
113            let mut level_nodes = Vec::new();
114            while let Some((index, digest)) = nodes.next_if(|(index, _)| index.depth() == depth) {
115                level_nodes.push(proto::primitives::PartialSmtNode {
116                    index: index.position(),
117                    digest: Some(digest.into()),
118                });
119            }
120            node_levels.push(proto::primitives::PartialSmtNodeLevel {
121                depth: u32::from(depth),
122                nodes: level_nodes,
123            });
124        }
125        let leaves = leaves
126            .into_iter()
127            .map(|(index, leaf)| proto::primitives::IndexedSmtLeaf {
128                index,
129                leaf: Some(leaf.into()),
130            })
131            .collect();
132
133        let value_only_leaves = value_only_leaves
134            .into_iter()
135            .map(|(index, value)| proto::primitives::IndexedDigest {
136                index,
137                value: Some(value.into()),
138            })
139            .collect();
140
141        Self {
142            root: Some(root.into()),
143            node_levels,
144            leaves,
145            value_only_leaves,
146        }
147    }
148}
149
150impl From<PartialSmt> for proto::primitives::PartialSmt {
151    fn from(partial_smt: PartialSmt) -> Self {
152        partial_smt.to_unique_nodes().into()
153    }
154}