miden_protocol/transaction/kernel/memory.rs
1// TYPE ALIASES
2// ================================================================================================
3
4pub type MemoryAddress = u32;
5pub type MemoryOffset = u32;
6pub type DataIndex = usize;
7pub type MemSize = usize;
8pub type StorageSlot = u8;
9
10// PUBLIC CONSTANTS
11// ================================================================================================
12
13// General layout
14//
15// | Section | Start address | Size in elements | Comment |
16// | ------------------ | ------------- | ---------------- | ------------------------------------------ |
17// | Bookkeeping | 0 | 85 | |
18// | Global inputs | 400 | 40 | |
19// | Block header | 800 | 44 | |
20// | Partial blockchain | 1_200 | 132 | |
21// | Kernel data | 1_600 | 224 | 56 procedures in total, 4 elements each |
22// | Accounts data | 8_192 | 524_288 | 64 accounts max, 8192 elements each |
23// | Account delta | 532_480 | 264 | fungible + non-fungible ptr + 256 patches |
24// | Account upgrade | 532_744 | 8 | code + storage upgrade commitment |
25// | Input notes | 4_194_304 | 1_114_112 | nullifiers data segment (2^16 elements) |
26// | | | | + 1024 input notes max, 1024 elements each |
27// | Output notes | 16_777_216 | 1_048_576 | 1024 output notes max, 1024 elements each |
28// | Link Map Memory | 33_554_432 | 33_554_432 | Enough for 2_097_151 key-value pairs |
29
30// Relative layout of one account
31//
32// | Section | Start address | Size in elements | Comment |
33// | ------------------ | ------------- | ---------------- | -------------------------------------- |
34// | ID and nonce | 0 | 4 | |
35// | Vault root | 4 | 4 | |
36// | Storage commitment | 8 | 4 | |
37// | Code commitment | 12 | 4 | |
38// | Padding | 16 | 12 | |
39// | Num procedures | 28 | 4 | |
40// | Procedures roots | 32 | 1_024 | 256 procedures max, 4 elements each |
41// | Padding | 1_056 | 4 | |
42// | Proc tracking | 1_060 | 256 | 256 procedures max, 1 element each |
43// | Num storage slots | 1_316 | 4 | |
44// | Initial slot info | 1_320 | 2_040 | Only initialized on the native account |
45// | Active slot info | 3_360 | 2_040 | 255 slots max, 8 elements each |
46// | Padding | 5_400 | 2_792 | |
47//
48// Storage slots are laid out as [[0, slot_type, slot_id_suffix, slot_id_prefix], SLOT_VALUE].
49
50// Relative layout of the native account's delta.
51//
52// For now each Storage Map pointer (a link map ptr) occupies a single element.
53//
54// | Section | Start address | Size in elements | Comment |
55// | ---------------------------- | ------------- | ---------------- | ----------------------------------- |
56// | Fungible Asset Delta Ptr | 0 | 4 | |
57// | Non-Fungible Asset Delta Ptr | 4 | 4 | |
58// | Storage Map Patch Ptrs | 8 | 256 | Max 255 storage map patches |
59
60// BOOKKEEPING
61// ------------------------------------------------------------------------------------------------
62
63/// The memory address at which a pointer to the currently active input note is stored.
64pub const ACTIVE_INPUT_NOTE_PTR: MemoryAddress = 0;
65
66/// The memory address at which the number of output notes is stored.
67pub const NUM_OUTPUT_NOTES_PTR: MemoryAddress = 1;
68
69/// The memory address at which the transaction expiration block number is stored.
70pub const TX_EXPIRATION_BLOCK_NUM_PTR: MemoryAddress = 2;
71
72/// The memory address at which the dirty flag of the storage commitment of the native account is
73/// stored.
74///
75/// This binary flag specifies whether the commitment is outdated: it holds 1 if some changes were
76/// made to the account storage since the last re-computation, and 0 otherwise.
77pub const NATIVE_ACCT_STORAGE_COMMITMENT_DIRTY_FLAG_PTR: MemoryAddress = 3;
78
79/// The memory address at which the input vault root is stored.
80pub const INPUT_VAULT_ROOT_PTR: MemoryAddress = 4;
81
82/// The memory address at which the output vault root is stored.
83pub const OUTPUT_VAULT_ROOT_PTR: MemoryAddress = 8;
84
85// Pointer to the suffix and prefix of the ID of the foreign account which will be loaded during the
86// upcoming FPI call. This ID is updated during the `prepare_fpi_call` kernel procedure.
87pub const UPCOMING_FOREIGN_ACCOUNT_PREFIX_PTR: MemoryAddress = 12;
88pub const UPCOMING_FOREIGN_ACCOUNT_SUFFIX_PTR: MemoryAddress =
89 UPCOMING_FOREIGN_ACCOUNT_PREFIX_PTR + 1;
90
91// Pointer to the 16th input value of the foreign procedure which will be loaded during the upcoming
92// FPI call. This "buffer" value helps to work around the 15 value limitation of the
93// `exec_kernel_proc` kernel procedure, so that any account procedure, even if it has 16 input
94// values, could be executed as foreign.
95pub const UPCOMING_FOREIGN_PROC_INPUT_VALUE_15_PTR: MemoryAddress = 14;
96
97// The memory address at which the flag indicating that the epilogue is running the account's
98// authentication procedure is stored.
99pub const EPILOGUE_AUTH_IN_PROGRESS_FLAG_PTR: MemoryAddress = 15;
100
101// Pointer to the root of the foreign procedure which will be executed during the upcoming FPI call.
102// This root is updated during the `prepare_fpi_call` kernel procedure.
103pub const UPCOMING_FOREIGN_PROCEDURE_PTR: MemoryAddress = 16;
104
105/// The memory address at which the pointer to the stack element containing the pointer to the
106/// active account data is stored.
107///
108/// The stack starts at the address `29`. Stack has a length of `64` elements meaning that the
109/// maximum depth of FPI calls is `63` — the first slot is always occupied by the native account
110/// data pointer.
111///
112/// ```text
113/// ┌───────────────┬────────────────┬───────────────────┬─────┬────────────────────┐
114/// │ STACK TOP PTR │ NATIVE ACCOUNT │ FOREIGN ACCOUNT 1 │ ... │ FOREIGN ACCOUNT 63 │
115/// ├───────────────┼────────────────┼───────────────────┼─────┼────────────────────┤
116/// 20 21 22 84
117/// ```
118pub const ACCOUNT_STACK_TOP_PTR: MemoryAddress = 20;
119
120// GLOBAL INPUTS
121// ------------------------------------------------------------------------------------------------
122
123/// The memory address at which the global inputs section begins.
124pub const GLOBAL_INPUTS_SECTION_OFFSET: MemoryOffset = 400;
125
126/// The memory address at which the commitment of the transaction's reference block is stored.
127pub const BLOCK_COMMITMENT_PTR: MemoryAddress = 400;
128
129/// The memory address at which the native account ID suffix provided as a global transaction input
130/// is stored.
131pub const GLOBAL_ACCOUNT_ID_SUFFIX_PTR: MemoryAddress = 404;
132/// The memory address at which the native account ID prefix provided as a global transaction input
133/// is stored.
134pub const GLOBAL_ACCOUNT_ID_PREFIX_PTR: MemoryAddress = GLOBAL_ACCOUNT_ID_SUFFIX_PTR + 1;
135
136/// The memory address at which the initial account commitment is stored.
137pub const INIT_ACCT_COMMITMENT_PTR: MemoryAddress = 408;
138
139/// The memory address at which the initial nonce is stored.
140pub const INIT_NONCE_PTR: MemoryAddress = 412;
141
142/// The memory address at which the initial vault root of the native account is stored.
143pub const INIT_NATIVE_ACCT_VAULT_ROOT_PTR: MemoryAddress = 416;
144
145/// The memory address at which the initial storage commitment of the native account is stored.
146pub const INIT_NATIVE_ACCT_STORAGE_COMMITMENT_PTR: MemoryAddress = 420;
147
148/// The memory address at which the input notes commitment is stored.
149pub const INPUT_NOTES_COMMITMENT_PTR: MemoryAddress = 424;
150
151/// The memory address at which the transaction script mast root is store
152pub const TX_SCRIPT_ROOT_PTR: MemoryAddress = 428;
153
154/// The memory address at which the transaction script arguments are stored.
155pub const TX_SCRIPT_ARGS: MemoryAddress = 432;
156
157/// The memory address at which the key of the auth procedure arguments is stored.
158pub const AUTH_ARGS_PTR: MemoryAddress = 436;
159
160// BLOCK DATA
161// ------------------------------------------------------------------------------------------------
162
163/// The memory address at which the block data section begins.
164pub const BLOCK_DATA_SECTION_OFFSET: MemoryOffset = 800;
165
166/// The memory address at which the previous block commitment is stored.
167pub const PREV_BLOCK_COMMITMENT_PTR: MemoryAddress = 800;
168
169/// The memory address at which the chain commitment is stored.
170pub const CHAIN_COMMITMENT_PTR: MemoryAddress = 804;
171
172/// The memory address at which the state root is stored.
173pub const ACCT_DB_ROOT_PTR: MemoryAddress = 808;
174
175/// The memory address at which the nullifier db root is store.
176pub const NULLIFIER_DB_ROOT_PTR: MemoryAddress = 812;
177
178/// The memory address at which the TX commitment is stored.
179pub const TX_COMMITMENT_PTR: MemoryAddress = 816;
180
181/// The memory address at which the transaction kernel commitment is stored.
182pub const TX_KERNEL_COMMITMENT_PTR: MemoryAddress = 820;
183
184/// The memory address at which the public key is stored.
185pub const VALIDATOR_KEY_COMMITMENT_PTR: MemoryAddress = 824;
186
187/// The memory address at which the block number is stored.
188pub const BLOCK_METADATA_PTR: MemoryAddress = 828;
189
190/// The index of the block number within the block metadata.
191pub const BLOCK_NUMBER_IDX: DataIndex = 0;
192
193/// The index of the protocol version within the block metadata.
194pub const PROTOCOL_VERSION_IDX: DataIndex = 1;
195
196/// The index of the timestamp within the block metadata.
197pub const TIMESTAMP_IDX: DataIndex = 2;
198
199/// The memory address at which the fee parameters are stored. These occupy a double word.
200pub const FEE_PARAMETERS_PTR: MemoryAddress = 832;
201
202/// The index of the verification base fee within the block fee parameters.
203pub const VERIFICATION_BASE_FEE_IDX: DataIndex = 1;
204
205/// The index of the fee faucet ID suffix within the block fee parameters.
206pub const FEE_FAUCET_ID_SUFFIX_IDX: DataIndex = 2;
207
208/// The index of the fee faucet ID prefix within the block fee parameters.
209pub const FEE_FAUCET_ID_PREFIX_IDX: DataIndex = 3;
210
211/// The memory address at which the note root is stored.
212pub const NOTE_ROOT_PTR: MemoryAddress = 840;
213
214// CHAIN DATA
215// ------------------------------------------------------------------------------------------------
216
217/// The memory address at which the chain data section begins.
218pub const PARTIAL_BLOCKCHAIN_PTR: MemoryAddress = 1200;
219
220/// The memory address at which the total number of leaves in the partial blockchain is stored.
221pub const PARTIAL_BLOCKCHAIN_NUM_LEAVES_PTR: MemoryAddress = 1200;
222
223/// The memory address at which the partial blockchain peaks are stored.
224pub const PARTIAL_BLOCKCHAIN_PEAKS_PTR: MemoryAddress = 1204;
225
226// KERNEL DATA
227// ------------------------------------------------------------------------------------------------
228
229/// The memory address at which the number of the kernel procedures is stored.
230pub const NUM_KERNEL_PROCEDURES_PTR: MemoryAddress = 1600;
231
232/// The memory address at which the section, where the hashes of the kernel procedures are stored,
233/// begins.
234pub const KERNEL_PROCEDURES_PTR: MemoryAddress = 1604;
235
236// ACCOUNT DATA
237// ------------------------------------------------------------------------------------------------
238
239/// The size of the memory segment allocated to core account data (excluding new code commitment).
240pub const ACCT_DATA_MEM_SIZE: MemSize = 16;
241
242/// The memory address at which the native account is stored.
243pub const NATIVE_ACCOUNT_DATA_PTR: MemoryAddress = 8192;
244
245/// The length of the memory interval that the account data occupies.
246pub const ACCOUNT_DATA_LENGTH: MemSize = 8192;
247
248/// The offset at which the account ID and nonce are stored relative to the start of
249/// the account data segment.
250pub const ACCT_ID_AND_NONCE_OFFSET: MemoryOffset = 0;
251
252/// The memory address at which the account ID and nonce are stored in the native account.
253pub const NATIVE_ACCT_ID_AND_NONCE_PTR: MemoryAddress =
254 NATIVE_ACCOUNT_DATA_PTR + ACCT_ID_AND_NONCE_OFFSET;
255
256/// The index of the account nonce within the account ID and nonce data.
257pub const ACCT_NONCE_IDX: DataIndex = 0;
258
259/// The index of the account ID within the account ID and nonce data.
260pub const ACCT_ID_SUFFIX_IDX: DataIndex = 2;
261pub const ACCT_ID_PREFIX_IDX: DataIndex = 3;
262
263/// The offset at which the account vault root is stored relative to the start of the account
264/// data segment.
265pub const ACCT_VAULT_ROOT_OFFSET: MemoryOffset = 4;
266
267/// The memory address at which the account vault root is stored in the native account.
268pub const NATIVE_ACCT_VAULT_ROOT_PTR: MemoryAddress =
269 NATIVE_ACCOUNT_DATA_PTR + ACCT_VAULT_ROOT_OFFSET;
270
271/// The offset at which the account storage commitment is stored relative to the start of the
272/// account data segment.
273pub const ACCT_STORAGE_COMMITMENT_OFFSET: MemoryOffset = 8;
274
275/// The memory address at which the account storage commitment is stored in the native account.
276pub const NATIVE_ACCT_STORAGE_COMMITMENT_PTR: MemoryAddress =
277 NATIVE_ACCOUNT_DATA_PTR + ACCT_STORAGE_COMMITMENT_OFFSET;
278
279/// The offset at which the account code commitment is stored relative to the start of the account
280/// data segment.
281pub const ACCT_CODE_COMMITMENT_OFFSET: MemoryOffset = 12;
282
283/// The memory address at which the account code commitment is stored in the native account.
284pub const NATIVE_ACCT_CODE_COMMITMENT_PTR: MemoryAddress =
285 NATIVE_ACCOUNT_DATA_PTR + ACCT_CODE_COMMITMENT_OFFSET;
286
287/// The offset at which the number of procedures contained in the account code is stored relative to
288/// the start of the account data segment.
289pub const ACCT_NUM_PROCEDURES_OFFSET: MemoryAddress = 28;
290
291/// The memory address at which the number of procedures contained in the account code is stored in
292/// the native account.
293pub const NATIVE_NUM_ACCT_PROCEDURES_PTR: MemoryAddress =
294 NATIVE_ACCOUNT_DATA_PTR + ACCT_NUM_PROCEDURES_OFFSET;
295
296/// The offset at which the account procedures section begins relative to the start of the account
297/// data segment.
298pub const ACCT_PROCEDURES_SECTION_OFFSET: MemoryAddress = 32;
299
300/// The memory address at which the account procedures section begins in the native account.
301pub const NATIVE_ACCT_PROCEDURES_SECTION_PTR: MemoryAddress =
302 NATIVE_ACCOUNT_DATA_PTR + ACCT_PROCEDURES_SECTION_OFFSET;
303
304/// The offset at which the account procedures call tracking section begins relative to the start of
305/// the account data segment.
306pub const ACCT_PROCEDURES_CALL_TRACKING_OFFSET: MemoryAddress = 1060;
307
308/// The memory address at which the account procedures call tracking section begins in the native
309/// account.
310pub const NATIVE_ACCT_PROCEDURES_CALL_TRACKING_PTR: MemoryAddress =
311 NATIVE_ACCOUNT_DATA_PTR + ACCT_PROCEDURES_CALL_TRACKING_OFFSET;
312
313/// The offset at which the number of storage slots contained in the account storage is stored
314/// relative to the start of the account data segment.
315pub const ACCT_NUM_STORAGE_SLOTS_OFFSET: MemoryAddress = 1316;
316
317/// The memory address at which number of storage slots contained in the account storage is stored
318/// in the native account.
319pub const NATIVE_NUM_ACCT_STORAGE_SLOTS_PTR: MemoryAddress =
320 NATIVE_ACCOUNT_DATA_PTR + ACCT_NUM_STORAGE_SLOTS_OFFSET;
321
322/// The number of elements that each storage slot takes up in memory.
323pub const ACCT_STORAGE_SLOT_NUM_ELEMENTS: u8 = 8;
324
325/// The offset of the slot type in the storage slot.
326pub const ACCT_STORAGE_SLOT_TYPE_OFFSET: u8 = 1;
327
328/// The offset of the slot's ID suffix in the storage slot.
329pub const ACCT_STORAGE_SLOT_ID_SUFFIX_OFFSET: u8 = 2;
330
331/// The offset of the slot's ID prefix in the storage slot.
332pub const ACCT_STORAGE_SLOT_ID_PREFIX_OFFSET: u8 = 3;
333
334/// The offset of the slot value in the storage slot.
335pub const ACCT_STORAGE_SLOT_VALUE_OFFSET: u8 = 4;
336
337/// The offset at which the account's active storage slots section begins relative to the start of
338/// the account data segment.
339///
340/// This section contains the current values of the account storage slots.
341pub const ACCT_ACTIVE_STORAGE_SLOTS_SECTION_OFFSET: MemoryAddress = 3360;
342
343/// The memory address at which the account's active storage slots section begins in the native
344/// account.
345pub const NATIVE_ACCT_STORAGE_SLOTS_SECTION_PTR: MemoryAddress =
346 NATIVE_ACCOUNT_DATA_PTR + ACCT_ACTIVE_STORAGE_SLOTS_SECTION_OFFSET;
347
348// UPGRADE COMMITMENTS
349// ------------------------------------------------------------------------------------------------
350
351/// The memory address at which the native account code upgrade commitment is stored.
352pub const CODE_UPGRADE_COMMITMENT_PTR: MemoryAddress = 532_744;
353
354/// The memory address at which the native account storage upgrade commitment is stored.
355pub const STORAGE_UPGRADE_COMMITMENT_PTR: MemoryAddress = 532_748;
356
357// NOTES DATA
358// ================================================================================================
359
360/// The size of the memory segment allocated to each note.
361pub const NOTE_MEM_SIZE: MemoryAddress = 1024;
362
363#[allow(clippy::empty_line_after_outer_attr)]
364#[rustfmt::skip]
365// INPUT NOTES DATA
366// ------------------------------------------------------------------------------------------------
367// Inputs note section contains data of all notes consumed by a transaction. The section starts at
368// memory offset 4_194_304 with a word containing the total number of input notes and is followed
369// by note nullifiers and note data like so:
370//
371// ┌──────────┬───────────┬───────────┬─────┬────────────────┬─────────┬──────────┬────────┬───────┬────────┐
372// │ NUM │ NOTE 0 │ NOTE 1 │ ... │ NOTE n │ PADDING │ NOTE 0 │ NOTE 1 │ ... │ NOTE n │
373// │ NOTES │ NULLIFIER │ NULLIFIER │ │ NULLIFIER │ │ DATA │ DATA │ │ DATA │
374// ├──────────┼───────────┼───────────┼─────┼────────────────┼─────────┼──────────┼────────┼───────┼────────┤
375// 4_194_304 4_194_308 4_194_312 4_194_304+4(n+1) 4_259_840 +1024 +2048 +1024n
376//
377// Here `n` represents number of input notes.
378//
379// Each nullifier occupies a single word. A data section for each note consists of exactly 1024
380// elements and is laid out like so:
381//
382// ┌──────────────┬────────┬────────┬────────────┬────────────┬──────────┬─────────────┬───────────┬──────┬
383// │ NOTE DETAILS │ SERIAL │ SCRIPT │ STORAGE │ ASSETS │ METADATA │ ATTACHMENTS │ RECIPIENT │ NOTE │
384// │ COMMITMENT │ NUM │ ROOT │ COMMITMENT │ COMMITMENT │ │ COMMITMENT │ │ ID │
385// ├──────────────┼────────┼────────┼────────────┼────────────┼──────────┼─────────────┼───────────┼──────┼
386// 0 4 8 12 16 20 24 28 32
387//
388// ┬───────┬─────────┬────────┬───────┬─────────┬─────┬────────┬─────────┬─────────┐
389// │ NOTE │ STORAGE │ NUM │ ASSET │ ASSET │ ... │ ASSET │ ASSET │ PADDING │
390// │ ARGS │ LENGTH │ ASSETS │ KEY 0 │ VALUE 0 │ │ KEY n │ VALUE n │ │
391// ┼───────┼─────────┼────────┼───────┼─────────┼─────┼────────┼─────────┼─────────┘
392// 36 40 44 48 52 48 + 8n 52 + 8n
393//
394// - NUM_STORAGE_ITEMS is encoded as [num_storage_items, 0, 0, 0].
395// - NUM_ASSETS is encoded as [num_assets, 0, 0, 0].
396// - NOTE ID is computed and cached by the transaction prologue; asset removals only mutate the
397// assets region and do not invalidate it.
398// - STORAGE_COMMITMENT is the key to look up note storage in the advice map.
399// - ASSETS_COMMITMENT is the key to look up note assets in the advice map.
400//
401// Notice that note storage item are not loaded to the memory, only their length. In order to obtain
402// the storage values the advice map should be used: they are stored there as
403// `STORAGE_COMMITMENT -> STORAGE`.
404//
405// As opposed to the asset values, storage items are never used in kernel memory, so their presence
406// there is unnecessary.
407
408/// The memory address at which the input note section begins.
409pub const INPUT_NOTE_SECTION_PTR: MemoryAddress = 4_194_304;
410
411/// The memory address at which the nullifier section of the input notes begins.
412pub const INPUT_NOTE_NULLIFIER_SECTION_PTR: MemoryAddress = 4_194_308;
413
414/// The memory address at which the input note data section begins.
415pub const INPUT_NOTE_DATA_SECTION_OFFSET: MemoryAddress = 4_259_840;
416
417/// The memory address at which the number of input notes is stored.
418pub const NUM_INPUT_NOTES_PTR: MemoryAddress = INPUT_NOTE_SECTION_PTR;
419
420/// The offsets at which data of an input note is stored relative to the start of its data segment.
421pub const INPUT_NOTE_DETAILS_COMMITMENT_OFFSET: MemoryOffset = 0;
422pub const INPUT_NOTE_SERIAL_NUM_OFFSET: MemoryOffset = 4;
423pub const INPUT_NOTE_SCRIPT_ROOT_OFFSET: MemoryOffset = 8;
424pub const INPUT_NOTE_STORAGE_COMMITMENT_OFFSET: MemoryOffset = 12;
425pub const INPUT_NOTE_ASSETS_COMMITMENT_OFFSET: MemoryOffset = 16;
426pub const INPUT_NOTE_METADATA_OFFSET: MemoryOffset = 20;
427pub const INPUT_NOTE_ATTACHMENTS_COMMITMENT_OFFSET: MemoryOffset = 24;
428pub const INPUT_NOTE_RECIPIENT_OFFSET: MemoryOffset = 28;
429pub const INPUT_NOTE_ID_OFFSET: MemoryOffset = 32;
430pub const INPUT_NOTE_ARGS_OFFSET: MemoryOffset = 36;
431pub const INPUT_NOTE_NUM_STORAGE_ITEMS_OFFSET: MemoryOffset = 40;
432pub const INPUT_NOTE_NUM_ASSETS_OFFSET: MemoryOffset = 44;
433pub const INPUT_NOTE_ASSETS_OFFSET: MemoryOffset = 48;
434
435#[allow(clippy::empty_line_after_outer_attr)]
436#[rustfmt::skip]
437// OUTPUT NOTES DATA
438// ------------------------------------------------------------------------------------------------
439// Output notes section contains data of all notes produced by a transaction. The section starts at
440// memory offset 16_777_216 with each note data laid out one after another in 1024 elements chunks.
441//
442// ┌─────────────┬─────────────┬───────────────┬─────────────┐
443// │ NOTE 0 DATA │ NOTE 1 DATA │ ... │ NOTE n DATA │
444// └─────────────┴─────────────┴───────────────┴─────────────┘
445// 16_777_216 +1024 +2048 +1024n
446//
447// The total number of output notes for a transaction is stored in the bookkeeping section of the
448// memory. Data section of each note is laid out like so:
449//
450// ┌──────────────┬──────────┬───────────┬───────────────────────────────────────────┬
451// │ NOTE DETAILS │ METADATA │ RECIPIENT │ [dirty_flag, num_assets, │
452// │ COMMITMENT │ │ │ num_attachments, total_attachment_words] │
453// ├──────────────┼──────────┼───────────┼───────────────────────────────────────────┼
454// 0 4 8 12
455//
456// ┬────────────┬────────────┬────────────┬────────────┬────────────┬
457// │ ATTACHMENT │ ATTACHMENT │ ATTACHMENT │ ATTACHMENT │ ASSETS │
458// │ 0 │ 1 │ 2 │ 3 │ COMMITMENT │
459// ┼────────────┼────────────┼────────────┼────────────┼────────────┼
460// 16 20 24 28 32
461//
462// ┬───────┬─────────┬─────┬────────┬─────────┬─────────┐
463// │ ASSET │ ASSET │ ... │ ASSET │ ASSET │ PADDING │
464// │ KEY 0 │ VALUE 0 │ │ KEY n │ VALUE n │ │
465// ┼───────┼─────────┼─────┼────────┼─────────┼─────────┘
466// 36 40 36 + 8n 40 + 8n
467//
468// The DIRTY_FLAG is the binary flag which specifies whether the assets commitment stored in this
469// note is outdated. It holds 1 if some changes were made to the note assets since the last
470// re-computation, and 0 otherwise.
471// It is set to 0 after every recomputation of the assets commitment in the
472// `miden::tx_kernel_core::note::compute_output_note_assets_commitment` procedure. It is set to 1 in the
473// `miden::tx_kernel_core::output_note::add_asset` procedure after any change was made to the assets data.
474
475/// The memory address at which the output notes section begins.
476pub const OUTPUT_NOTE_SECTION_OFFSET: MemoryOffset = 16_777_216;
477
478/// The offsets at which data of an output note is stored relative to the start of its data segment.
479pub const OUTPUT_NOTE_DETAILS_COMMITMENT_OFFSET: MemoryOffset = 0;
480pub const OUTPUT_NOTE_METADATA_OFFSET: MemoryOffset = 4;
481pub const OUTPUT_NOTE_RECIPIENT_OFFSET: MemoryOffset = 8;
482pub const OUTPUT_NOTE_DIRTY_FLAG_OFFSET: MemoryOffset = 12;
483pub const OUTPUT_NOTE_NUM_ASSETS_OFFSET: MemoryOffset = 13;
484pub const OUTPUT_NOTE_NUM_ATTACHMENTS_OFFSET: MemoryOffset = 14;
485pub const OUTPUT_NOTE_TOTAL_ATTACHMENT_WORDS_OFFSET: MemoryOffset = 15;
486pub const OUTPUT_NOTE_ATTACHMENT_0_OFFSET: MemoryOffset = 16;
487pub const OUTPUT_NOTE_ATTACHMENT_1_OFFSET: MemoryOffset = 20;
488pub const OUTPUT_NOTE_ATTACHMENT_2_OFFSET: MemoryOffset = 24;
489pub const OUTPUT_NOTE_ATTACHMENT_3_OFFSET: MemoryOffset = 28;
490pub const OUTPUT_NOTE_ASSETS_COMMITMENT_OFFSET: MemoryOffset = 32;
491pub const OUTPUT_NOTE_ASSETS_OFFSET: MemoryOffset = 36;
492
493// ASSETS
494// ------------------------------------------------------------------------------------------------
495
496/// The size of an asset's memory representation.
497#[cfg(any(feature = "testing", test))]
498pub const ASSET_SIZE: MemoryOffset = 8;
499
500/// The offset of the asset value in an asset's memory representation.
501#[cfg(any(feature = "testing", test))]
502pub const ASSET_VALUE_OFFSET: MemoryOffset = 4;
503
504// LINK MAP
505// ------------------------------------------------------------------------------------------------
506
507/// The inclusive start of the link map dynamic memory region.
508pub const LINK_MAP_REGION_START_PTR: MemoryAddress = 33_554_448;
509
510/// The non-inclusive end of the link map dynamic memory region.
511pub const LINK_MAP_REGION_END_PTR: MemoryAddress = 67_108_864;
512
513/// [`LINK_MAP_REGION_START_PTR`] + the currently used size stored at this pointer defines the next
514/// entry pointer that will be allocated.
515pub const LINK_MAP_USED_MEMORY_SIZE: MemoryAddress = 33_554_432;
516
517/// The size of each map entry, i.e. four words.
518pub const LINK_MAP_ENTRY_SIZE: MemoryOffset = 16;
519
520const _: () = assert!(
521 LINK_MAP_REGION_START_PTR.is_multiple_of(LINK_MAP_ENTRY_SIZE),
522 "link map region start ptr should be aligned to entry size"
523);
524
525const _: () = assert!(
526 (LINK_MAP_REGION_END_PTR - LINK_MAP_REGION_START_PTR).is_multiple_of(LINK_MAP_ENTRY_SIZE),
527 "the link map memory range should cleanly contain a multiple of the entry size"
528);