miden_lib/transaction/
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// Here the "end address" is the last memory address occupied by the current data
16//
17// | Section            | Start address, pointer (word pointer) | End address, pointer (word pointer) | Comment                                     |
18// | ------------------ | :-----------------------------------: | :---------------------------------: | ------------------------------------------- |
19// | Bookkeeping        | 0 (0)                                 | 287 (71)                            |                                             |
20// | Global inputs      | 400 (100)                             | 427 (106)                           |                                             |
21// | Block header       | 800 (200)                             | 835 (208)                           |                                             |
22// | Partial blockchain | 1_200 (300)                           | 1_331? (332?)                       |                                             |
23// | Kernel data        | 1_600 (400)                           | 1_739 (434)                         | 34 procedures in total, 4 elements each     |
24// | Accounts data      | 8_192 (2048)                          | 532_479 (133_119)                   | 64 accounts max, 8192 elements each         |
25// | Account delta      | 532_480 (133_120)                     | 532_746 (133_186)                   |                                             |
26// | Input notes        | 4_194_304 (1_048_576)                 | ?                                   |                                             |
27// | Output notes       | 16_777_216 (4_194_304)                | ?                                   |                                             |
28// | Link Map Memory    | 33_554_432 (8_388_608)                | 67_108_863 (16_777_215)               | Enough for 2_097_151 key-value pairs        |
29
30// Relative layout of one account
31//
32// Here the "end pointer" is the last memory pointer occupied by the current data
33//
34// | Section           | Start address, pointer (word pointer) | End address, pointer (word pointer) | Comment                             |
35// | ----------------- | :-----------------------------------: | :---------------------------------: | ----------------------------------- |
36// | ID and nonce      | 0 (0)                                 | 3 (0)                               |                                     |
37// | Vault root        | 4 (1)                                 | 7 (1)                               |                                     |
38// | Storage root      | 8 (2)                                 | 11 (2)                              |                                     |
39// | Code root         | 12 (3)                                | 15 (3)                              |                                     |
40// | Padding           | 16 (4)                                | 27 (6)                              |                                     |
41// | Num procedures    | 28 (7)                                | 31 (7)                              |                                     |
42// | Procedures info   | 32 (8)                                | 2_079 (519)                         | 255 procedures max, 8 elements each |
43// | Padding           | 2_080 (520)                           | 2_083 (520)                         |                                     |
44// | Proc tracking     | 2_084 (521)                           | 2_339 (584)                         | 255 procedures max, 1 element each  |
45// | Num storage slots | 2_340 (585)                           | 2_343 (585)                         |                                     |
46// | Storage slot info | 2_344 (586)                           | 4_383 (1095)                        | 255 slots max, 8 elements each      |
47// | Initial slot info | 4_384 (1096)                          | 6_423 (1545)                        | Only present on the native account  |
48// | Padding           | 6_424 (1545)                          | 8_191 (2047)                        |                                     |
49
50// Relative layout of the native account's delta.
51//
52// Here the "end pointer" is the last memory pointer occupied by the current data
53//
54// For now each Storage Map pointer (a link map ptr) occupies a single element.
55//
56// | Section                      | Start address (word pointer) | End address (word pointer) | Comment                             |
57// | ---------------------------- | :--------------------------: | :------------------------: | ----------------------------------- |
58// | Nonce                        | 0 (0)                        | 3 (0)                      |                                     |
59// | Fungible Asset Delta Ptr     | 4 (1)                        | 7 (1)                      |                                     |
60// | Non-Fungible Asset Delta Ptr | 8 (2)                        | 11 (2)                     |                                     |
61// | Storage Map Delta Ptrs       | 12 (3)                       | 267 (66)                   | Max 255 storage map deltas          |
62
63// RESERVED ACCOUNT STORAGE SLOTS
64// ------------------------------------------------------------------------------------------------
65
66/// The account storage slot at which faucet data is stored.
67///
68/// - Fungible faucet: The faucet data consists of [0, 0, 0, total_issuance].
69/// - Non-fungible faucet: The faucet data consists of SMT root containing minted non-fungible
70///   assets.
71pub const FAUCET_STORAGE_DATA_SLOT: StorageSlot = 0;
72
73// BOOKKEEPING
74// ------------------------------------------------------------------------------------------------
75
76/// The memory address at which the transaction vault root is stored.
77pub const TX_VAULT_ROOT_PTR: MemoryAddress = 0;
78
79/// The memory address at which a pointer to the input note being executed is stored.
80pub const CURRENT_INPUT_NOTE_PTR: MemoryAddress = 4;
81
82/// The memory address at which the number of output notes is stored.
83pub const NUM_OUTPUT_NOTES_PTR: MemoryAddress = 8;
84
85/// The memory address at which the input vault root is stored.
86pub const INPUT_VAULT_ROOT_PTR: MemoryAddress = 12;
87
88/// The memory address at which the output vault root is stored.
89pub const OUTPUT_VAULT_ROOT_PTR: MemoryAddress = 16;
90
91/// The memory address at which the native account's new code commitment is stored.
92pub const NEW_CODE_ROOT_PTR: MemoryAddress = 20;
93
94/// The memory address at which the transaction expiration block number is stored.
95pub const TX_EXPIRATION_BLOCK_NUM_PTR: MemoryAddress = 24;
96
97/// The memory address at which the pointer to the stack element containing the pointer to the
98/// currently active account data is stored.
99///
100/// The stack starts at the address `29`. Stack has a length of `64` elements meaning that the
101/// maximum depth of FPI calls is `63` — the first slot is always occupied by the native account
102/// data pointer.
103///
104/// ```text
105/// ┌───────────────┬────────────────┬───────────────────┬─────┬────────────────────┐
106/// │ STACK TOP PTR │ NATIVE ACCOUNT │ FOREIGN ACCOUNT 1 │ ... │ FOREIGN ACCOUNT 63 │
107/// ├───────────────┼────────────────┼───────────────────┼─────┼────────────────────┤
108///        28               29                30                         92
109/// ```
110pub const ACCOUNT_STACK_TOP_PTR: MemoryAddress = 28;
111
112// GLOBAL INPUTS
113// ------------------------------------------------------------------------------------------------
114
115/// The memory address at which the global inputs section begins.
116pub const GLOBAL_INPUTS_SECTION_OFFSET: MemoryOffset = 400;
117
118/// The memory address at which the commitment of the transaction's reference block is stored.
119pub const BLOCK_COMMITMENT_PTR: MemoryAddress = 400;
120
121/// The memory address at which the account ID is stored.
122pub const ACCT_ID_PTR: MemoryAddress = 404;
123
124/// The memory address at which the initial account commitment is stored.
125pub const INIT_ACCT_COMMITMENT_PTR: MemoryAddress = 408;
126
127/// The memory address at which the input notes commitment is stored.
128pub const INPUT_NOTES_COMMITMENT_PTR: MemoryAddress = 412;
129
130/// The memory address at which the initial nonce is stored.
131pub const INIT_NONCE_PTR: MemoryAddress = 416;
132
133/// The memory address at which the transaction script mast root is store
134pub const TX_SCRIPT_ROOT_PTR: MemoryAddress = 420;
135
136/// The memory address at which the key of the transaction script arguments is stored.
137pub const TX_SCRIPT_ARGS_KEY: MemoryAddress = 424;
138
139// BLOCK DATA
140// ------------------------------------------------------------------------------------------------
141
142/// The memory address at which the block data section begins
143pub const BLOCK_DATA_SECTION_OFFSET: MemoryOffset = 800;
144
145/// The memory address at which the previous block commitment is stored
146pub const PREV_BLOCK_COMMITMENT_PTR: MemoryAddress = 800;
147
148/// The memory address at which the chain commitment is stored
149pub const CHAIN_COMMITMENT_PTR: MemoryAddress = 804;
150
151/// The memory address at which the state root is stored
152pub const ACCT_DB_ROOT_PTR: MemoryAddress = 808;
153
154/// The memory address at which the nullifier db root is store
155pub const NULLIFIER_DB_ROOT_PTR: MemoryAddress = 812;
156
157/// The memory address at which the TX commitment is stored
158pub const TX_COMMITMENT_PTR: MemoryAddress = 816;
159
160/// The memory address at which the transaction kernel commitment is stored
161pub const TX_KERNEL_COMMITMENT_PTR: MemoryAddress = 820;
162
163/// The memory address at which the proof commitment is stored
164pub const PROOF_COMMITMENT_PTR: MemoryAddress = 824;
165
166/// The memory address at which the block number is stored
167pub const BLOCK_METADATA_PTR: MemoryAddress = 828;
168
169/// The index of the block number within the block metadata
170pub const BLOCK_NUMBER_IDX: DataIndex = 0;
171
172/// The index of the protocol version within the block metadata
173pub const PROTOCOL_VERSION_IDX: DataIndex = 1;
174
175/// The index of the timestamp within the block metadata
176pub const TIMESTAMP_IDX: DataIndex = 2;
177
178/// The memory address at which the note root is stored
179pub const NOTE_ROOT_PTR: MemoryAddress = 832;
180
181// CHAIN DATA
182// ------------------------------------------------------------------------------------------------
183
184/// The memory address at which the chain data section begins
185pub const PARTIAL_BLOCKCHAIN_PTR: MemoryAddress = 1200;
186
187/// The memory address at which the total number of leaves in the partial blockchain is stored
188pub const PARTIAL_BLOCKCHAIN_NUM_LEAVES_PTR: MemoryAddress = 1200;
189
190/// The memory address at which the partial blockchain peaks are stored
191pub const PARTIAL_BLOCKCHAIN_PEAKS_PTR: MemoryAddress = 1204;
192
193// KERNEL DATA
194// ------------------------------------------------------------------------------------------------
195
196/// The memory address at which the number of the procedures of the selected kernel is stored.
197pub const NUM_KERNEL_PROCEDURES_PTR: MemoryAddress = 1600;
198
199/// The memory address at which the section, where the hashes of the kernel procedures are stored,
200/// begins
201pub const KERNEL_PROCEDURES_PTR: MemoryAddress = 1604;
202
203// ACCOUNT DATA
204// ------------------------------------------------------------------------------------------------
205
206/// The size of the memory segment allocated to core account data (excluding new code commitment)
207pub const ACCT_DATA_MEM_SIZE: MemSize = 16;
208
209/// The memory address at which the native account is stored.
210pub const NATIVE_ACCOUNT_DATA_PTR: MemoryAddress = 8192;
211
212/// The length of the memory interval that the account data occupies.
213pub const ACCOUNT_DATA_LENGTH: MemSize = 8192;
214
215/// The offset at which the account ID and nonce are stored relative to the start of
216/// the account data segment.
217pub const ACCT_ID_AND_NONCE_OFFSET: MemoryOffset = 0;
218
219/// The memory address at which the account ID and nonce are stored in the native account.
220pub const NATIVE_ACCT_ID_AND_NONCE_PTR: MemoryAddress =
221    NATIVE_ACCOUNT_DATA_PTR + ACCT_ID_AND_NONCE_OFFSET;
222
223/// The index of the account ID within the account ID and nonce data.
224pub const ACCT_ID_SUFFIX_IDX: DataIndex = 0;
225pub const ACCT_ID_PREFIX_IDX: DataIndex = 1;
226
227/// The index of the account nonce within the account ID and nonce data.
228pub const ACCT_NONCE_IDX: DataIndex = 3;
229
230/// The offset at which the account vault root is stored relative to the start of the account
231/// data segment.
232pub const ACCT_VAULT_ROOT_OFFSET: MemoryOffset = 4;
233
234/// The memory address at which the account vault root is stored in the native account.
235pub const NATIVE_ACCT_VAULT_ROOT_PTR: MemoryAddress =
236    NATIVE_ACCOUNT_DATA_PTR + ACCT_VAULT_ROOT_OFFSET;
237
238/// The offset at which the account storage commitment is stored relative to the start of the
239/// account data segment.
240pub const ACCT_STORAGE_COMMITMENT_OFFSET: MemoryOffset = 8;
241
242/// The memory address at which the account storage commitment is stored in the native account.
243pub const NATIVE_ACCT_STORAGE_COMMITMENT_PTR: MemoryAddress =
244    NATIVE_ACCOUNT_DATA_PTR + ACCT_STORAGE_COMMITMENT_OFFSET;
245
246/// The offset at which the account code commitment is stored relative to the start of the account
247/// data segment.
248pub const ACCT_CODE_COMMITMENT_OFFSET: MemoryOffset = 12;
249
250/// The memory address at which the account code commitment is stored in the native account.
251pub const NATIVE_ACCT_CODE_COMMITMENT_PTR: MemoryAddress =
252    NATIVE_ACCOUNT_DATA_PTR + ACCT_CODE_COMMITMENT_OFFSET;
253
254/// The offset at which the number of procedures contained in the account code is stored relative to
255/// the start of the account data segment.
256pub const NUM_ACCT_PROCEDURES_OFFSET: MemoryAddress = 28;
257
258/// The memory address at which the number of procedures contained in the account code is stored in
259/// the native account.
260pub const NATIVE_NUM_ACCT_PROCEDURES_PTR: MemoryAddress =
261    NATIVE_ACCOUNT_DATA_PTR + NUM_ACCT_PROCEDURES_OFFSET;
262
263/// The offset at which the account procedures section begins relative to the start of the account
264/// data segment.
265pub const ACCT_PROCEDURES_SECTION_OFFSET: MemoryAddress = 32;
266
267/// The memory address at which the account procedures section begins in the native account.
268pub const NATIVE_ACCT_PROCEDURES_SECTION_PTR: MemoryAddress =
269    NATIVE_ACCOUNT_DATA_PTR + ACCT_PROCEDURES_SECTION_OFFSET;
270
271/// The offset at which the account procedures call tracking section begins relative to the start of
272/// the account data segment.
273pub const ACCT_PROCEDURES_CALL_TRACKING_OFFSET: MemoryAddress = 2084;
274
275/// The memory address at which the account procedures call tracking section begins in the native
276/// account.
277pub const NATIVE_ACCT_PROCEDURES_CALL_TRACKING_PTR: MemoryAddress =
278    NATIVE_ACCOUNT_DATA_PTR + ACCT_PROCEDURES_CALL_TRACKING_OFFSET;
279
280/// The offset at which the number of storage slots contained in the account storage is stored
281/// relative to the start of the account data segment.
282pub const NUM_ACCT_STORAGE_SLOTS_OFFSET: MemoryAddress = 2340;
283
284/// The memory address at which number of storage slots contained in the account storage is stored
285/// in the native account.
286pub const NATIVE_NUM_ACCT_STORAGE_SLOTS_PTR: MemoryAddress =
287    NATIVE_ACCOUNT_DATA_PTR + NUM_ACCT_STORAGE_SLOTS_OFFSET;
288
289/// The offset at which the account storage slots section begins relative to the start of the
290/// account data segment.
291pub const ACCT_STORAGE_SLOTS_SECTION_OFFSET: MemoryAddress = 2344;
292
293/// The number of elements that each storage slot takes up in memory.
294pub const ACCT_STORAGE_SLOT_NUM_ELEMENTS: u8 = 8;
295
296/// The memory address at which the account storage slots section begins in the native account.
297pub const NATIVE_ACCT_STORAGE_SLOTS_SECTION_PTR: MemoryAddress =
298    NATIVE_ACCOUNT_DATA_PTR + ACCT_STORAGE_SLOTS_SECTION_OFFSET;
299
300// ACCOUNT DELTA
301// ------------------------------------------------------------------------------------------------
302
303/// The memory address at which the nonce delta is stored.
304pub const ACCOUNT_DELTA_NONCE_PTR: MemoryAddress = 532_480;
305
306// NOTES DATA
307// ================================================================================================
308
309/// The size of the memory segment allocated to each note.
310pub const NOTE_MEM_SIZE: MemoryAddress = 2048;
311
312#[allow(clippy::empty_line_after_outer_attr)]
313#[rustfmt::skip]
314// INPUT NOTES DATA
315// ------------------------------------------------------------------------------------------------
316// Inputs note section contains data of all notes consumed by a transaction. The section starts at
317// memory offset 4_194_304 with a word containing the total number of input notes and is followed
318// by note nullifiers and note data like so:
319//
320// ┌─────────┬───────────┬───────────┬─────┬───────────┬─────────┬────────┬────────┬───────┬────────┐
321// │   NUM   │  NOTE 0   │  NOTE 1   │ ... │  NOTE n   │ PADDING │ NOTE 0 │ NOTE 1 │  ...  │ NOTE n │
322// │  NOTES  │ NULLIFIER │ NULLIFIER │     │ NULLIFIER │         │  DATA  │  DATA  │       │  DATA  │
323// └─────────┴───────────┴───────────┴─────┴───────────┴─────────┴────────┴────────┴───────┴────────┘
324//  4_194_304  4_194_308  4_194_312    4_194_304+4(n+1)      4_259_840  +2048    +4096  +2048(n+1)
325//
326// Each nullifier occupies a single word. A data section for each note consists of exactly 512
327// words and is laid out like so:
328//
329// ┌──────┬────────┬────────┬────────┬────────┬──────┬───────┬────────┬────────┬───────┬─────┬───────┬─────────┬
330// │ NOTE │ SERIAL │ SCRIPT │ INPUTS │ ASSETS │ META │ NOTE  │  NUM   │  NUM   │ ASSET │ ... │ ASSET │ PADDING │
331// │  ID  │  NUM   │  ROOT  │  HASH  │  HASH  │ DATA │ ARGS  │ INPUTS │ ASSETS │   0   │     │   n   │         │
332// ├──────┼────────┼────────┼────────┼────────┼──────┼───────┼────────┼────────┼───────┼─────┼───────┼─────────┤
333// 0      4        8        12       16       20     24      28       32       36 + 4n
334//
335// - NUM_INPUTS is encoded as [num_inputs, 0, 0, 0].
336// - NUM_ASSETS is encoded as [num_assets, 0, 0, 0].
337// - INPUTS_COMMITMENT is the key to look up note inputs in the advice map.
338// - ASSETS_HASH is the key to look up note assets in the advice map.
339//
340// Notice that note input values are not loaded to the memory, only their length. In order to obtain
341// the input values the advice map should be used: they are stored there as 
342// `INPUTS_COMMITMENT -> INPUTS || PADDING`. 
343// 
344// As opposed to the asset values, input values are never used in kernel memory, so their presence 
345// there is unnecessary. 
346
347/// The memory address at which the input note section begins.
348pub const INPUT_NOTE_SECTION_PTR: MemoryAddress = 4_194_304;
349
350/// The memory address at which the nullifier section of the input notes begins.
351pub const INPUT_NOTE_NULLIFIER_SECTION_PTR: MemoryAddress = 4_194_308;
352
353/// The memory address at which the input note data section begins.
354pub const INPUT_NOTE_DATA_SECTION_OFFSET: MemoryAddress = 4_259_840;
355
356/// The memory address at which the number of input notes is stored.
357pub const NUM_INPUT_NOTES_PTR: MemoryAddress = INPUT_NOTE_SECTION_PTR;
358
359/// The offsets at which data of an input note is stored relative to the start of its data segment.
360pub const INPUT_NOTE_ID_OFFSET: MemoryOffset = 0;
361pub const INPUT_NOTE_SERIAL_NUM_OFFSET: MemoryOffset = 4;
362pub const INPUT_NOTE_SCRIPT_ROOT_OFFSET: MemoryOffset = 8;
363pub const INPUT_NOTE_INPUTS_COMMITMENT_OFFSET: MemoryOffset = 12;
364pub const INPUT_NOTE_ASSETS_HASH_OFFSET: MemoryOffset = 16;
365pub const INPUT_NOTE_METADATA_OFFSET: MemoryOffset = 20;
366pub const INPUT_NOTE_ARGS_OFFSET: MemoryOffset = 24;
367pub const INPUT_NOTE_NUM_INPUTS_OFFSET: MemoryOffset = 28;
368pub const INPUT_NOTE_NUM_ASSETS_OFFSET: MemoryOffset = 32;
369pub const INPUT_NOTE_ASSETS_OFFSET: MemoryOffset = 36;
370
371// OUTPUT NOTES DATA
372// ------------------------------------------------------------------------------------------------
373// Output notes section contains data of all notes produced by a transaction. The section starts at
374// memory offset 16_777_216 with each note data laid out one after another in 512 word increments.
375//
376//     ┌─────────────┬─────────────┬───────────────┬─────────────┐
377//     │ NOTE 0 DATA │ NOTE 1 DATA │      ...      │ NOTE n DATA │
378//     └─────────────┴─────────────┴───────────────┴─────────────┘
379// 16_777_216      +2048         +4096           +2048n
380//
381// The total number of output notes for a transaction is stored in the bookkeeping section of the
382// memory. Data section of each note is laid out like so:
383//
384// ┌─────────┬──────────┬───────────┬─────────────┬────────────┬─────────┬─────┬─────────┬─────────┐
385// │ NOTE ID │ METADATA │ RECIPIENT │ ASSETS HASH │ NUM ASSETS │ ASSET 0 │ ... │ ASSET n │ PADDING │
386// ├─────────┼──────────┼───────────┼─────────────┼────────────┼─────────┼─────┼─────────┼─────────┤
387//      0          1          2            3            4           5             5 + n
388//
389// Even though NUM_ASSETS takes up a whole word, the actual value of this variable is stored in the
390// first element of the word.
391
392/// The memory address at which the output notes section begins.
393pub const OUTPUT_NOTE_SECTION_OFFSET: MemoryOffset = 16_777_216;
394
395/// The size of the core output note data segment.
396pub const OUTPUT_NOTE_CORE_DATA_SIZE: MemSize = 16;
397
398/// The offsets at which data of an output note is stored relative to the start of its data segment.
399pub const OUTPUT_NOTE_ID_OFFSET: MemoryOffset = 0;
400pub const OUTPUT_NOTE_METADATA_OFFSET: MemoryOffset = 4;
401pub const OUTPUT_NOTE_RECIPIENT_OFFSET: MemoryOffset = 8;
402pub const OUTPUT_NOTE_ASSET_COMMITMENT_OFFSET: MemoryOffset = 12;
403pub const OUTPUT_NOTE_NUM_ASSETS_OFFSET: MemoryOffset = 16;
404pub const OUTPUT_NOTE_ASSETS_OFFSET: MemoryOffset = 20;
405
406// LINK MAP
407// ------------------------------------------------------------------------------------------------
408
409/// The inclusive start of the link map dynamic memory region.
410pub const LINK_MAP_REGION_START_PTR: MemoryAddress = 33_554_448;
411
412/// The non-inclusive end of the link map dynamic memory region.
413pub const LINK_MAP_REGION_END_PTR: MemoryAddress = 67_108_864;
414
415/// [`LINK_MAP_REGION_START_PTR`] + the currently used size stored at this pointer defines the next
416/// entry pointer that will be allocated.
417pub const LINK_MAP_USED_MEMORY_SIZE: MemoryAddress = 33_554_432;
418
419/// The size of each map entry, i.e. four words.
420pub const LINK_MAP_ENTRY_SIZE: MemoryOffset = 16;
421
422const _: () = assert!(
423    LINK_MAP_REGION_START_PTR % LINK_MAP_ENTRY_SIZE == 0,
424    "link map region start ptr should be aligned to entry size"
425);
426
427const _: () = assert!(
428    (LINK_MAP_REGION_END_PTR - LINK_MAP_REGION_START_PTR) % LINK_MAP_ENTRY_SIZE == 0,
429    "the link map memory range should cleanly contain a multiple of the entry size"
430);