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.into_inner())
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.into_inner())?)
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 = self.attachments.verify()?;
57        Ok(Self::Verified::new(attachments)?)
58    }
59}
60
61pub use proto::note::DecodedNoteScript as NoteScript;
62
63impl Verify for NoteScript {
64    type Verified = miden_protocol::note::NoteScript;
65    type Error = VerificationError;
66    fn verify(self) -> Result<Self::Verified, Self::Error> {
67        let mast = self.mast.verify()?;
68        let entrypoint = miden_protocol::MastNodeId::from_u32_safe(self.entrypoint, &mast)?;
69        Ok(Self::Verified::from_parts(alloc::sync::Arc::new(mast), entrypoint)?)
70    }
71}
72
73pub use proto::note::DecodedNoteRecipient as NoteRecipient;
74
75impl Verify for NoteRecipient {
76    type Verified = miden_protocol::note::NoteRecipient;
77    type Error = VerificationError;
78    fn verify(self) -> Result<Self::Verified, Self::Error> {
79        Ok(Self::Verified::new(
80            self.serial_num,
81            self.script.verify()?,
82            self.storage.verify()?,
83        ))
84    }
85}
86
87pub use proto::note::DecodedNoteInclusionProof as NoteInclusionProof;
88
89impl Verify for NoteInclusionProof {
90    type Verified = (miden_protocol::note::NoteId, miden_protocol::note::NoteInclusionProof);
91    type Error = VerificationError;
92    fn verify(self) -> Result<Self::Verified, Self::Error> {
93        Ok((
94            unwrap_infallible(self.note_id.verify()),
95            miden_protocol::note::NoteInclusionProof::new(
96                unwrap_infallible(self.block_num.verify()),
97                self.note_index_in_block.try_into()?,
98                self.inclusion_path.verify()?,
99            )?,
100        ))
101    }
102}
103
104pub use proto::note::DecodedNoteMetadata as NoteMetadata;
105
106impl Verify for NoteMetadata {
107    type Verified = miden_protocol::note::NoteMetadata;
108    type Error = VerificationError;
109    fn verify(self) -> Result<Self::Verified, Self::Error> {
110        use miden_protocol::note::{
111            NoteAttachmentHeader,
112            NoteAttachmentScheme,
113            NoteAttachments,
114            NoteTag,
115            NoteType,
116            PartialNoteMetadata,
117        };
118        match self.version {
119            proto::note::NoteVersion::V1 => {},
120            proto::note::NoteVersion::Unspecified => {
121                return Err(NoteMetadataError::UnspecifiedVersion.into());
122            },
123        }
124        let note_type = match self.note_type {
125            proto::note::NoteType::Private => NoteType::Private,
126            proto::note::NoteType::Public => NoteType::Public,
127            proto::note::NoteType::Unspecified => {
128                return Err(NoteMetadataError::UnspecifiedNoteType.into());
129            },
130        };
131        let partial = PartialNoteMetadata::new(self.sender.verify()?, note_type)
132            .with_tag(NoteTag::new(self.tag));
133        if self.attachment_schemes.as_slice().len() > NoteAttachments::MAX_COUNT {
134            return Err(NoteMetadataError::TooManyAttachmentSchemes.into());
135        }
136        let mut headers = [NoteAttachmentHeader::absent(); NoteAttachments::MAX_COUNT];
137        for (header, raw) in headers.iter_mut().zip(self.attachment_schemes.into_inner()) {
138            let scheme: u16 = raw.try_into()?;
139            if scheme != 0 {
140                *header = NoteAttachmentHeader::new(NoteAttachmentScheme::new(scheme)?);
141            }
142        }
143        Ok(Self::Verified::from_parts(partial, headers, self.attachments_commitment))
144    }
145}
146
147pub use proto::note::DecodedNoteDetails as NoteDetails;
148
149impl Verify for NoteDetails {
150    type Verified = miden_protocol::note::NoteDetails;
151    type Error = VerificationError;
152    fn verify(self) -> Result<Self::Verified, Self::Error> {
153        let assets = self.assets.verify()?;
154        let assets = miden_protocol::note::NoteAssets::new(assets)?;
155        Ok(Self::Verified::new(assets, self.recipient.verify()?))
156    }
157}
158
159pub use proto::note::DecodedNoteHeader as NoteHeader;
160
161impl Verify for NoteHeader {
162    type Verified = miden_protocol::note::NoteHeader;
163    type Error = VerificationError;
164    fn verify(self) -> Result<Self::Verified, Self::Error> {
165        Ok(Self::Verified::new(
166            miden_protocol::note::NoteDetailsCommitment::from_raw(self.details_commitment),
167            self.metadata.verify()?,
168        ))
169    }
170}
171
172pub use proto::note::DecodedPartialNoteMetadata as PartialNoteMetadata;
173
174impl Verify for PartialNoteMetadata {
175    type Verified = miden_protocol::note::PartialNoteMetadata;
176    type Error = VerificationError;
177    fn verify(self) -> Result<Self::Verified, Self::Error> {
178        use miden_protocol::note::{NoteTag, NoteType};
179        if self.version != proto::note::NoteVersion::V1 {
180            return Err(NoteMetadataError::UnspecifiedVersion.into());
181        }
182        let note_type = match self.note_type {
183            proto::note::NoteType::Private => NoteType::Private,
184            proto::note::NoteType::Public => NoteType::Public,
185            proto::note::NoteType::Unspecified => {
186                return Err(NoteMetadataError::UnspecifiedNoteType.into());
187            },
188        };
189        Ok(Self::Verified::new(self.sender.verify()?, note_type).with_tag(NoteTag::new(self.tag)))
190    }
191}
192
193pub use proto::note::DecodedNote as Note;
194
195impl Verify for Note {
196    type Verified = miden_protocol::note::Note;
197    type Error = VerificationError;
198    fn verify(self) -> Result<Self::Verified, Self::Error> {
199        let (assets, recipient) = self.note_details.verify()?.into_parts();
200        Ok(Self::Verified::with_attachments(
201            assets,
202            self.metadata.verify()?,
203            recipient,
204            self.note_attachments.verify()?,
205        ))
206    }
207}
208
209pub use proto::note::DecodedPartialNote as PartialNote;
210
211impl Verify for PartialNote {
212    type Verified = miden_protocol::note::PartialNote;
213    type Error = VerificationError;
214    fn verify(self) -> Result<Self::Verified, Self::Error> {
215        let assets = miden_protocol::note::NoteAssets::new(self.assets.verify()?)?;
216        Ok(Self::Verified::new(
217            self.metadata.verify()?,
218            self.recipient_digest,
219            assets,
220            self.attachments.verify()?,
221        ))
222    }
223}