Skip to main content

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