miden_client/rpc/domain/
smt.rs1use alloc::string::ToString;
2
3use miden_protocol::Word;
4use miden_protocol::crypto::merkle::smt::{LeafIndex, SMT_DEPTH, SmtLeaf, SmtProof};
5
6use crate::rpc::domain::MissingFieldHelper;
7use crate::rpc::errors::RpcConversionError;
8use crate::rpc::generated as proto;
9
10impl From<&(Word, Word)> for proto::primitives::SmtLeafEntry {
14 fn from(value: &(Word, Word)) -> Self {
15 proto::primitives::SmtLeafEntry {
16 key: Some(value.0.into()),
17 value: Some(value.1.into()),
18 }
19 }
20}
21
22impl TryFrom<&proto::primitives::SmtLeafEntry> for (Word, Word) {
23 type Error = RpcConversionError;
24
25 fn try_from(value: &proto::primitives::SmtLeafEntry) -> Result<Self, Self::Error> {
26 let key = match value.key {
27 Some(key) => key.try_into()?,
28 None => return Err(proto::primitives::SmtLeafEntry::missing_field(stringify!(key))),
29 };
30
31 let value: Word = match value.value {
32 Some(value) => value.try_into()?,
33 None => return Err(proto::primitives::SmtLeafEntry::missing_field(stringify!(value))),
34 };
35
36 Ok((key, value))
37 }
38}
39
40impl From<SmtLeaf> for proto::primitives::SmtLeaf {
44 fn from(value: SmtLeaf) -> Self {
45 (&value).into()
46 }
47}
48
49impl From<&SmtLeaf> for proto::primitives::SmtLeaf {
50 fn from(value: &SmtLeaf) -> Self {
51 match value {
52 SmtLeaf::Empty(index) => proto::primitives::SmtLeaf {
53 leaf: Some(proto::primitives::smt_leaf::Leaf::EmptyLeafIndex(index.value())),
54 },
55 SmtLeaf::Single(entry) => proto::primitives::SmtLeaf {
56 leaf: Some(proto::primitives::smt_leaf::Leaf::Single(entry.into())),
57 },
58 SmtLeaf::Multiple(entries) => proto::primitives::SmtLeaf {
59 leaf: Some(proto::primitives::smt_leaf::Leaf::Multiple(
60 proto::primitives::SmtLeafEntryList {
61 entries: entries.iter().map(Into::into).collect(),
62 },
63 )),
64 },
65 }
66 }
67}
68
69impl TryFrom<&proto::primitives::SmtLeaf> for SmtLeaf {
70 type Error = RpcConversionError;
71
72 fn try_from(value: &proto::primitives::SmtLeaf) -> Result<Self, Self::Error> {
73 match &value.leaf {
74 Some(proto::primitives::smt_leaf::Leaf::EmptyLeafIndex(index)) => Ok(SmtLeaf::Empty(
75 LeafIndex::<SMT_DEPTH>::new(*index)
76 .map_err(|err| RpcConversionError::InvalidField(err.to_string()))?,
77 )),
78 Some(proto::primitives::smt_leaf::Leaf::Single(entry)) => {
79 Ok(SmtLeaf::Single(entry.try_into()?))
80 },
81 Some(proto::primitives::smt_leaf::Leaf::Multiple(entries)) => {
82 let entries =
83 entries.entries.iter().map(TryInto::try_into).collect::<Result<_, _>>()?;
84 Ok(SmtLeaf::Multiple(entries))
85 },
86 None => Err(proto::primitives::SmtLeaf::missing_field(stringify!(leaf))),
87 }
88 }
89}
90
91impl From<SmtProof> for proto::primitives::SmtOpening {
95 fn from(value: SmtProof) -> Self {
96 let (path, leaf) = value.into_parts();
97
98 proto::primitives::SmtOpening {
99 leaf: Some(leaf.into()),
100 path: Some(path.into()),
101 }
102 }
103}
104
105impl TryFrom<proto::primitives::SmtOpening> for SmtProof {
106 type Error = RpcConversionError;
107
108 fn try_from(value: proto::primitives::SmtOpening) -> Result<Self, Self::Error> {
109 let leaf = match &value.leaf {
110 Some(leaf) => leaf.try_into()?,
111 None => return Err(proto::primitives::SmtOpening::missing_field(stringify!(leaf))),
112 };
113
114 let path = match value.path {
115 Some(path) => path.try_into()?,
116 None => return Err(proto::primitives::SmtOpening::missing_field(stringify!(path))),
117 };
118
119 SmtProof::new(path, leaf).map_err(|err| RpcConversionError::InvalidField(err.to_string()))
120 }
121}