Skip to main content

miden_objects/decoded/
note.rs

1//! Domain construction for decoded note messages.
2use miden_protobuf::unwrap_infallible;
3pub use proto::note::DecodedNoteId as NoteId;
4
5use crate::decoded::VerificationError;
6use crate::{Verify, proto};
7
8#[cfg(test)]
9mod tests;
10
11impl Verify for NoteId {
12    type Verified = miden_protocol::note::NoteId;
13    type Error = core::convert::Infallible;
14    fn verify(self) -> Result<Self::Verified, Self::Error> {
15        Ok(Self::Verified::from_raw(self.id))
16    }
17}
18
19pub use proto::note::DecodedNoteStorage as NoteStorage;
20
21impl Verify for NoteStorage {
22    type Verified = miden_protocol::note::NoteStorage;
23    type Error = miden_protocol::errors::NoteError;
24    fn verify(self) -> Result<Self::Verified, Self::Error> {
25        Self::Verified::new(self.items)
26    }
27}
28
29pub use proto::note::DecodedNoteAttachment as NoteAttachment;
30
31impl Verify for NoteAttachment {
32    type Verified = miden_protocol::note::NoteAttachment;
33    type Error = VerificationError;
34    fn verify(self) -> Result<Self::Verified, Self::Error> {
35        let scheme = miden_protocol::note::NoteAttachmentScheme::new(self.scheme.try_into()?)?;
36        Ok(Self::Verified::with_words(scheme, self.words)?)
37    }
38}
39
40#[derive(Debug, thiserror::Error)]
41pub enum NoteMetadataError {
42    #[error("note metadata version is unspecified")]
43    UnspecifiedVersion,
44    #[error("note type is unspecified")]
45    UnspecifiedNoteType,
46    #[error("too many attachment schemes")]
47    TooManyAttachmentSchemes,
48}
49
50pub use proto::note::DecodedNoteAttachments as NoteAttachments;
51
52impl Verify for NoteAttachments {
53    type Verified = miden_protocol::note::NoteAttachments;
54    type Error = VerificationError;
55    fn verify(self) -> Result<Self::Verified, Self::Error> {
56        let attachments =
57            self.attachments.into_iter().map(Verify::verify).collect::<Result<_, _>>()?;
58        Ok(Self::Verified::new(attachments)?)
59    }
60}
61
62pub use proto::note::DecodedNoteScript as NoteScript;
63
64impl Verify for NoteScript {
65    type Verified = miden_protocol::note::NoteScript;
66    type Error = VerificationError;
67    fn verify(self) -> Result<Self::Verified, Self::Error> {
68        let mast = self.mast.verify()?;
69        let entrypoint = miden_protocol::MastNodeId::from_u32_safe(self.entrypoint, &mast)?;
70        Ok(Self::Verified::from_parts(alloc::sync::Arc::new(mast), entrypoint)?)
71    }
72}
73
74pub use proto::note::DecodedNoteRecipient as NoteRecipient;
75
76impl Verify for NoteRecipient {
77    type Verified = miden_protocol::note::NoteRecipient;
78    type Error = VerificationError;
79    fn verify(self) -> Result<Self::Verified, Self::Error> {
80        Ok(Self::Verified::new(
81            self.serial_num,
82            self.script.verify()?,
83            self.storage.verify()?,
84        ))
85    }
86}
87
88pub use proto::note::DecodedNoteInclusionProof as NoteInclusionProof;
89
90impl Verify for NoteInclusionProof {
91    type Verified = (miden_protocol::note::NoteId, miden_protocol::note::NoteInclusionProof);
92    type Error = VerificationError;
93    fn verify(self) -> Result<Self::Verified, Self::Error> {
94        Ok((
95            unwrap_infallible(self.note_id.verify()),
96            miden_protocol::note::NoteInclusionProof::new(
97                unwrap_infallible(self.block_num.verify()),
98                self.note_index_in_block.try_into()?,
99                self.inclusion_path.verify()?,
100            )?,
101        ))
102    }
103}
104
105pub use proto::note::DecodedNoteMetadata as NoteMetadata;
106
107impl Verify for NoteMetadata {
108    type Verified = miden_protocol::note::NoteMetadata;
109    type Error = VerificationError;
110    fn verify(self) -> Result<Self::Verified, Self::Error> {
111        use miden_protocol::note::{
112            NoteAttachmentHeader,
113            NoteAttachmentScheme,
114            NoteAttachments,
115            NoteTag,
116            NoteType,
117            PartialNoteMetadata,
118        };
119        match self.version {
120            proto::note::NoteVersion::V1 => {},
121            proto::note::NoteVersion::Unspecified => {
122                return Err(NoteMetadataError::UnspecifiedVersion.into());
123            },
124        }
125        let note_type = match self.note_type {
126            proto::note::NoteType::Private => NoteType::Private,
127            proto::note::NoteType::Public => NoteType::Public,
128            proto::note::NoteType::Unspecified => {
129                return Err(NoteMetadataError::UnspecifiedNoteType.into());
130            },
131        };
132        let partial = PartialNoteMetadata::new(self.sender.verify()?, note_type)
133            .with_tag(NoteTag::new(self.tag));
134        if self.attachment_schemes.len() > NoteAttachments::MAX_COUNT {
135            return Err(NoteMetadataError::TooManyAttachmentSchemes.into());
136        }
137        let mut headers = [NoteAttachmentHeader::absent(); NoteAttachments::MAX_COUNT];
138        for (header, raw) in headers.iter_mut().zip(self.attachment_schemes) {
139            let scheme: u16 = raw.try_into()?;
140            if scheme != 0 {
141                *header = NoteAttachmentHeader::new(NoteAttachmentScheme::new(scheme)?);
142            }
143        }
144        Ok(Self::Verified::from_parts(partial, headers, self.attachments_commitment))
145    }
146}
147
148pub use proto::note::DecodedNoteDetails as NoteDetails;
149
150impl Verify for NoteDetails {
151    type Verified = miden_protocol::note::NoteDetails;
152    type Error = VerificationError;
153    fn verify(self) -> Result<Self::Verified, Self::Error> {
154        let assets = self.assets.into_iter().map(Verify::verify).collect::<Result<_, _>>()?;
155        let assets = miden_protocol::note::NoteAssets::new(assets)?;
156        Ok(Self::Verified::new(assets, self.recipient.verify()?))
157    }
158}
159
160pub use proto::note::DecodedNoteHeader as NoteHeader;
161
162impl Verify for NoteHeader {
163    type Verified = miden_protocol::note::NoteHeader;
164    type Error = VerificationError;
165    fn verify(self) -> Result<Self::Verified, Self::Error> {
166        Ok(Self::Verified::new(
167            miden_protocol::note::NoteDetailsCommitment::from_raw(self.details_commitment),
168            self.metadata.verify()?,
169        ))
170    }
171}
172
173pub use proto::note::DecodedPartialNoteMetadata as PartialNoteMetadata;
174
175impl Verify for PartialNoteMetadata {
176    type Verified = miden_protocol::note::PartialNoteMetadata;
177    type Error = VerificationError;
178    fn verify(self) -> Result<Self::Verified, Self::Error> {
179        use miden_protocol::note::{NoteTag, NoteType};
180        if self.version != proto::note::NoteVersion::V1 {
181            return Err(NoteMetadataError::UnspecifiedVersion.into());
182        }
183        let note_type = match self.note_type {
184            proto::note::NoteType::Private => NoteType::Private,
185            proto::note::NoteType::Public => NoteType::Public,
186            proto::note::NoteType::Unspecified => {
187                return Err(NoteMetadataError::UnspecifiedNoteType.into());
188            },
189        };
190        Ok(Self::Verified::new(self.sender.verify()?, note_type).with_tag(NoteTag::new(self.tag)))
191    }
192}
193
194pub use proto::note::DecodedNote as Note;
195
196impl Verify for Note {
197    type Verified = miden_protocol::note::Note;
198    type Error = VerificationError;
199    fn verify(self) -> Result<Self::Verified, Self::Error> {
200        let (assets, recipient) = self.note_details.verify()?.into_parts();
201        Ok(Self::Verified::with_attachments(
202            assets,
203            self.metadata.verify()?,
204            recipient,
205            self.note_attachments.verify()?,
206        ))
207    }
208}