miden_client/rpc/domain/
merkle.rs1use alloc::vec::Vec;
2
3use miden_protocol::Word;
4use miden_protocol::crypto::merkle::mmr::{Forest, MmrDelta};
5use miden_protocol::crypto::merkle::{MerklePath, SparseMerklePath};
6
7use crate::rpc::errors::RpcConversionError;
8use crate::rpc::generated as proto;
9
10const MAX_MERKLE_PATH_SIBLINGS: usize = u8::MAX as usize;
16
17impl From<MerklePath> for proto::primitives::MerklePath {
21 fn from(value: MerklePath) -> Self {
22 (&value).into()
23 }
24}
25
26impl From<&MerklePath> for proto::primitives::MerklePath {
27 fn from(value: &MerklePath) -> Self {
28 let siblings = value.nodes().iter().map(proto::primitives::Digest::from).collect();
29 proto::primitives::MerklePath { siblings }
30 }
31}
32
33impl TryFrom<&proto::primitives::MerklePath> for MerklePath {
34 type Error = RpcConversionError;
35
36 fn try_from(merkle_path: &proto::primitives::MerklePath) -> Result<Self, Self::Error> {
37 if merkle_path.siblings.len() > MAX_MERKLE_PATH_SIBLINGS {
40 return Err(RpcConversionError::InvalidField(format!(
41 "MerklePath has {} siblings but at most {MAX_MERKLE_PATH_SIBLINGS} are allowed",
42 merkle_path.siblings.len(),
43 )));
44 }
45
46 merkle_path.siblings.iter().map(Word::try_from).collect()
47 }
48}
49
50impl TryFrom<proto::primitives::MerklePath> for MerklePath {
51 type Error = RpcConversionError;
52
53 fn try_from(merkle_path: proto::primitives::MerklePath) -> Result<Self, Self::Error> {
54 MerklePath::try_from(&merkle_path)
55 }
56}
57
58impl From<SparseMerklePath> for proto::primitives::SparseMerklePath {
63 fn from(value: SparseMerklePath) -> Self {
64 let (empty_nodes_mask, siblings) = value.into_parts();
65
66 proto::primitives::SparseMerklePath {
67 empty_nodes_mask,
68
69 siblings: siblings.into_iter().map(proto::primitives::Digest::from).collect(),
70 }
71 }
72}
73
74impl TryFrom<proto::primitives::SparseMerklePath> for SparseMerklePath {
75 type Error = RpcConversionError;
76
77 fn try_from(merkle_path: proto::primitives::SparseMerklePath) -> Result<Self, Self::Error> {
78 Ok(SparseMerklePath::from_parts(
79 merkle_path.empty_nodes_mask,
80 merkle_path
81 .siblings
82 .into_iter()
83 .map(Word::try_from)
84 .collect::<Result<Vec<_>, _>>()?,
85 )?)
86 }
87}
88
89impl TryFrom<MmrDelta> for proto::primitives::MmrDelta {
93 type Error = RpcConversionError;
94
95 fn try_from(value: MmrDelta) -> Result<Self, Self::Error> {
96 let data = value.data.into_iter().map(proto::primitives::Digest::from).collect();
97 Ok(proto::primitives::MmrDelta {
98 forest: u64::try_from(value.forest.num_leaves())?,
99 data,
100 })
101 }
102}
103
104impl TryFrom<proto::primitives::MmrDelta> for MmrDelta {
105 type Error = RpcConversionError;
106
107 fn try_from(value: proto::primitives::MmrDelta) -> Result<Self, Self::Error> {
108 let data: Result<Vec<_>, RpcConversionError> =
109 value.data.into_iter().map(Word::try_from).collect();
110
111 let num_leaves = usize::try_from(value.forest).map_err(|_| {
112 RpcConversionError::InvalidField("MmrDelta forest value exceeds usize".into())
113 })?;
114 Ok(MmrDelta {
115 forest: Forest::new(num_leaves)
116 .map_err(|_| RpcConversionError::InvalidField("MmrDelta forest invalid".into()))?,
117 data: data?,
118 })
119 }
120}
121
122#[cfg(test)]
126mod tests {
127 use super::*;
128
129 fn proto_merkle_path(siblings: usize) -> proto::primitives::MerklePath {
130 proto::primitives::MerklePath {
131 siblings: vec![proto::primitives::Digest::default(); siblings],
132 }
133 }
134
135 #[test]
136 fn merkle_path_conversion_accepts_the_maximum_sibling_count() {
137 let path = MerklePath::try_from(&proto_merkle_path(MAX_MERKLE_PATH_SIBLINGS))
138 .expect("the maximum sibling count must convert");
139
140 assert_eq!(path.depth(), u8::MAX);
141 }
142
143 #[test]
144 fn merkle_path_conversion_rejects_an_oversized_sibling_count() {
145 let oversized = proto_merkle_path(MAX_MERKLE_PATH_SIBLINGS + 1);
146
147 assert!(MerklePath::try_from(&oversized).is_err());
148 }
149}