Skip to main content

miden_base_sys/bindings/
input_note.rs

1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word, WordAligned};
5
6use super::{
7    MAX_ATTACHMENT_WORDS, MAX_ATTACHMENTS_PER_NOTE, assert_attachment_count,
8    assert_attachment_word_count,
9    types::{
10        AccountId, Asset, NoteIdx, NoteMetadata, RawAccountId, RawAttachmentLocation, Recipient,
11    },
12};
13
14#[allow(improper_ctypes)]
15unsafe extern "C" {
16    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
17    #[link_name = "miden::protocol::input_note::get_initial_assets_info"]
18    fn extern_input_note_get_initial_assets_info(note_index: Felt, ptr: *mut (Word, Felt));
19    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
20    #[link_name = "miden::protocol::input_note::get_initial_assets"]
21    fn extern_input_note_get_initial_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
22    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
23    #[link_name = "miden::protocol::input_note::get_recipient"]
24    fn extern_input_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
25    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
26    #[link_name = "miden::protocol::input_note::get_metadata"]
27    fn extern_input_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
28    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
29    #[link_name = "miden::protocol::input_note::get_sender"]
30    fn extern_input_note_get_sender(note_index: Felt, ptr: *mut RawAccountId);
31    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
32    #[link_name = "miden::protocol::input_note::get_storage_info"]
33    fn extern_input_note_get_storage_info(note_index: Felt, ptr: *mut (Word, Felt));
34    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
35    #[link_name = "miden::protocol::input_note::get_script_root"]
36    fn extern_input_note_get_script_root(note_index: Felt, ptr: *mut Word);
37    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
38    #[link_name = "miden::protocol::input_note::get_serial_number"]
39    fn extern_input_note_get_serial_number(note_index: Felt, ptr: *mut Word);
40    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
41    #[link_name = "miden::protocol::input_note::get_attachments_commitment"]
42    fn extern_input_note_get_attachments_commitment(note_index: Felt, ptr: *mut Word);
43    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
44    #[link_name = "miden::protocol::input_note::get_attachments_commitment_raw"]
45    fn extern_input_note_get_attachments_commitment_raw(
46        is_active_note: Felt,
47        note_index: Felt,
48        ptr: *mut Word,
49    );
50    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
51    #[link_name = "miden::protocol::input_note::write_attachment_commitments_to_memory"]
52    fn extern_input_note_write_attachment_commitments_to_memory(
53        dest_ptr: *mut Felt,
54        note_index: Felt,
55    ) -> usize;
56    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
57    #[link_name = "miden::protocol::input_note::write_attachment_to_memory"]
58    fn extern_input_note_write_attachment_to_memory(
59        dest_ptr: *mut Felt,
60        attachment_idx: Felt,
61        note_index: Felt,
62    ) -> usize;
63    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
64    #[link_name = "miden::protocol::input_note::find_attachment"]
65    fn extern_input_note_find_attachment(
66        attachment_scheme: Felt,
67        note_index: Felt,
68        ptr: *mut RawAttachmentLocation,
69    );
70}
71
72/// Contains summary information about the assets stored in an input note.
73pub struct InputNoteAssetsInfo {
74    pub commitment: Word,
75    pub num_assets: u32,
76}
77
78/// Contains summary information about the storage stored in an input note.
79pub struct InputNoteStorageInfo {
80    pub commitment: Word,
81    pub num_storage_items: u32,
82}
83
84/// Returns the initial assets commitment and asset count for the input note at `note_index`.
85///
86/// These describe the note's assets at creation time, unaffected by in-transaction removal.
87pub fn get_initial_assets_info(note_index: NoteIdx) -> InputNoteAssetsInfo {
88    unsafe {
89        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<(Word, Felt)>::uninit());
90        extern_input_note_get_initial_assets_info(note_index.inner, ret_area.as_mut_ptr());
91        let (commitment, num_assets) = ret_area.into_inner().assume_init();
92        InputNoteAssetsInfo {
93            commitment,
94            // The transaction kernel guarantees asset counts fit in a u32.
95            num_assets: num_assets.as_canonical_u64() as u32,
96        }
97    }
98}
99
100/// Returns the initial assets contained in the input note at `note_index`.
101///
102/// These are the note's assets at creation time, unaffected by in-transaction removal.
103pub fn get_initial_assets(note_index: NoteIdx) -> Vec<Asset> {
104    const MAX_ASSETS: usize = 256;
105    let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
106    let num_assets = unsafe {
107        let ptr = (assets.as_mut_ptr() as usize) / 4;
108        extern_input_note_get_initial_assets(ptr as *mut Felt, note_index.inner)
109    };
110    unsafe {
111        assets.set_len(num_assets);
112    }
113    assets
114}
115
116/// Returns the recipient of the input note at `note_index`.
117pub fn get_recipient(note_index: NoteIdx) -> Recipient {
118    unsafe {
119        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
120        extern_input_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
121        ret_area.into_inner().assume_init()
122    }
123}
124
125/// Returns the metadata header of the input note at `note_index`.
126pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
127    unsafe {
128        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteMetadata>::uninit());
129        extern_input_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
130        ret_area.into_inner().assume_init()
131    }
132}
133
134/// Returns the sender of the input note at `note_index`.
135pub fn get_sender(note_index: NoteIdx) -> AccountId {
136    unsafe {
137        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawAccountId>::uninit());
138        extern_input_note_get_sender(note_index.inner, ret_area.as_mut_ptr());
139        ret_area.into_inner().assume_init().into_account_id()
140    }
141}
142
143/// Returns the storage commitment and storage item count for the input note at `note_index`.
144pub fn get_storage_info(note_index: NoteIdx) -> InputNoteStorageInfo {
145    unsafe {
146        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<(Word, Felt)>::uninit());
147        extern_input_note_get_storage_info(note_index.inner, ret_area.as_mut_ptr());
148        let (commitment, num_storage_items) = ret_area.into_inner().assume_init();
149        InputNoteStorageInfo {
150            commitment,
151            // The transaction kernel guarantees storage item counts fit in a u32.
152            num_storage_items: num_storage_items.as_canonical_u64() as u32,
153        }
154    }
155}
156
157/// Returns the script root of the input note at `note_index`.
158pub fn get_script_root(note_index: NoteIdx) -> Word {
159    unsafe {
160        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
161        extern_input_note_get_script_root(note_index.inner, ret_area.as_mut_ptr());
162        ret_area.into_inner().assume_init()
163    }
164}
165
166/// Returns the serial number of the input note at `note_index`.
167pub fn get_serial_number(note_index: NoteIdx) -> Word {
168    unsafe {
169        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
170        extern_input_note_get_serial_number(note_index.inner, ret_area.as_mut_ptr());
171        ret_area.into_inner().assume_init()
172    }
173}
174
175/// Returns the commitment over all attachments of the input note at `note_index`.
176pub fn get_attachments_commitment(note_index: NoteIdx) -> Word {
177    unsafe {
178        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
179        extern_input_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
180        ret_area.into_inner().assume_init()
181    }
182}
183
184/// Returns the attachment commitment using the protocol's shared active/indexed input-note path.
185pub fn get_attachments_commitment_raw(is_active_note: Felt, note_index: NoteIdx) -> Word {
186    unsafe {
187        let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
188        extern_input_note_get_attachments_commitment_raw(
189            is_active_note,
190            note_index.inner,
191            ret_area.as_mut_ptr(),
192        );
193        ret_area.into_inner().assume_init()
194    }
195}
196
197/// Writes attachment commitments to memory and returns them as protocol words.
198pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
199    let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
200    let num_attachments = unsafe {
201        let ptr = (commitments.as_mut_ptr() as usize) / 4;
202        extern_input_note_write_attachment_commitments_to_memory(ptr as *mut Felt, note_index.inner)
203    };
204    assert_attachment_count(num_attachments);
205    unsafe {
206        commitments.set_len(num_attachments);
207    }
208    commitments
209}
210
211/// Writes the selected input-note attachment to memory and returns it as protocol words.
212pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: u32) -> Vec<Word> {
213    let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
214    let num_words = unsafe {
215        let ptr = (attachment.as_mut_ptr() as usize) / 4;
216        extern_input_note_write_attachment_to_memory(
217            ptr as *mut Felt,
218            Felt::from_u32(attachment_idx),
219            note_index.inner,
220        )
221    };
222    assert_attachment_word_count(num_words);
223    unsafe {
224        attachment.set_len(num_words);
225    }
226    attachment
227}
228
229/// Searches the input note metadata for `attachment_scheme`.
230pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> Option<u32> {
231    unsafe {
232        let mut ret_area =
233            WordAligned::new(::core::mem::MaybeUninit::<RawAttachmentLocation>::uninit());
234        extern_input_note_find_attachment(
235            attachment_scheme,
236            note_index.inner,
237            ret_area.as_mut_ptr(),
238        );
239        ret_area.into_inner().assume_init().into_attachment_index()
240    }
241}