Skip to main content

miden_protocol/note/
partial.rs

1use super::{
2    ByteReader,
3    ByteWriter,
4    Deserializable,
5    DeserializationError,
6    NoteAssets,
7    NoteAttachments,
8    NoteDetailsCommitment,
9    NoteHeader,
10    NoteId,
11    NoteMetadata,
12    PartialNoteMetadata,
13    Serializable,
14};
15use crate::Word;
16
17// PARTIAL NOTE
18// ================================================================================================
19
20/// A note without detailed recipient information.
21///
22/// A partial note consists of [`PartialNoteMetadata`], [`NoteAssets`], [`NoteAttachments`], and a
23/// commitment to the [`NoteRecipient`](super::NoteRecipient)). However, it does not contain
24/// the full recipient, including note script, note storage, and note's serial number. This
25/// means that a partial note is sufficient to compute note ID and note header, but not sufficient
26/// to compute note nullifier, and generally does not have enough info to execute the note.
27///
28/// One use case for the [`PartialNote`] is to return the details of a private note created during a
29/// transaction, where the assets and attachments are known, but the recipient is not.
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct PartialNote {
32    header: NoteHeader,
33    recipient_digest: Word,
34    assets: NoteAssets,
35    attachments: NoteAttachments,
36}
37
38impl PartialNote {
39    /// Returns a new [PartialNote] instantiated from the provided parameters.
40    pub fn new(
41        partial_metadata: PartialNoteMetadata,
42        recipient_digest: Word,
43        assets: NoteAssets,
44        attachments: NoteAttachments,
45    ) -> Self {
46        let details_commitment =
47            NoteDetailsCommitment::from_raw_commitments(recipient_digest, assets.commitment());
48        let metadata = NoteMetadata::new(partial_metadata, &attachments);
49        let header = NoteHeader::new(details_commitment, metadata);
50        Self {
51            header,
52            recipient_digest,
53            assets,
54            attachments,
55        }
56    }
57
58    /// Returns the ID corresponding to this note.
59    pub fn id(&self) -> NoteId {
60        self.header.id()
61    }
62
63    /// Returns the commitment to the note's details, excluding metadata.
64    pub fn details_commitment(&self) -> NoteDetailsCommitment {
65        self.header.details_commitment()
66    }
67
68    /// Returns a reference to the [`NoteMetadata`] of this note.
69    pub fn metadata(&self) -> &NoteMetadata {
70        self.header.metadata()
71    }
72
73    /// Returns the partial metadata associated with this note.
74    pub fn partial_metadata(&self) -> &PartialNoteMetadata {
75        self.header.metadata().partial_metadata()
76    }
77
78    /// Returns the digest of the recipient associated with this note.
79    ///
80    /// See [super::NoteRecipient] for more info.
81    pub fn recipient_digest(&self) -> Word {
82        self.recipient_digest
83    }
84
85    /// Returns a list of assets associated with this note.
86    pub fn assets(&self) -> &NoteAssets {
87        &self.assets
88    }
89
90    /// Returns the note's attachments.
91    pub fn attachments(&self) -> &NoteAttachments {
92        &self.attachments
93    }
94
95    /// Returns the [`NoteHeader`] of this note.
96    pub fn header(&self) -> &NoteHeader {
97        &self.header
98    }
99
100    /// Consumes self and returns the non-Copy parts of this note.
101    pub fn into_parts(self) -> (NoteAssets, NoteHeader, NoteAttachments) {
102        (self.assets, self.header, self.attachments)
103    }
104}
105
106// SERIALIZATION
107// ================================================================================================
108
109impl Serializable for PartialNote {
110    fn write_into<W: ByteWriter>(&self, target: &mut W) {
111        // Serialize only partial metadata since note ID can be recomputed from the note details and
112        // attachment schemes and commitments can be reconstructed from attachments
113        self.header().metadata().partial_metadata().write_into(target);
114        self.recipient_digest.write_into(target);
115        self.assets.write_into(target);
116        self.attachments.write_into(target);
117    }
118
119    fn get_size_hint(&self) -> usize {
120        self.partial_metadata().get_size_hint()
121            + Word::SERIALIZED_SIZE
122            + self.assets.get_size_hint()
123            + self.attachments.get_size_hint()
124    }
125}
126
127impl Deserializable for PartialNote {
128    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
129        let partial_metadata = PartialNoteMetadata::read_from(source)?;
130        let recipient_digest = Word::read_from(source)?;
131        let assets = NoteAssets::read_from(source)?;
132        let attachments = NoteAttachments::read_from(source)?;
133
134        Ok(Self::new(partial_metadata, recipient_digest, assets, attachments))
135    }
136}