From ba91f2b01b19ec3b56c5e1f0f5a8b0de404f9363 Mon Sep 17 00:00:00 2001 From: sergerad Date: Thu, 6 Feb 2025 14:31:06 +1300 Subject: [PATCH 01/10] Update kernel inputs --- crates/miden-lib/src/transaction/mod.rs | 3 +++ crates/miden-tx/src/verifier/mod.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/crates/miden-lib/src/transaction/mod.rs b/crates/miden-lib/src/transaction/mod.rs index 275007d13..c31023b98 100644 --- a/crates/miden-lib/src/transaction/mod.rs +++ b/crates/miden-lib/src/transaction/mod.rs @@ -99,6 +99,7 @@ impl TransactionKernel { account.init_hash(), tx_inputs.input_notes().commitment(), tx_inputs.block_header().hash(), + tx_inputs.block_header().block_num(), ); let mut advice_inputs = init_advice_inputs.unwrap_or_default(); @@ -147,6 +148,7 @@ impl TransactionKernel { init_acct_hash: Digest, input_notes_hash: Digest, block_hash: Digest, + block_num: BlockNumber, ) -> StackInputs { // Note: Must be kept in sync with the transaction's kernel prepare_transaction procedure let mut inputs: Vec = Vec::with_capacity(14); @@ -155,6 +157,7 @@ impl TransactionKernel { inputs.push(account_id.suffix()); inputs.push(account_id.prefix().as_felt()); inputs.extend_from_slice(block_hash.as_elements()); + inputs.push(Felt::from(block_num)); StackInputs::new(inputs) .map_err(|e| e.to_string()) .expect("Invalid stack input") diff --git a/crates/miden-tx/src/verifier/mod.rs b/crates/miden-tx/src/verifier/mod.rs index d42b4944c..ce113c1db 100644 --- a/crates/miden-tx/src/verifier/mod.rs +++ b/crates/miden-tx/src/verifier/mod.rs @@ -37,6 +37,7 @@ impl TransactionVerifier { transaction.account_update().init_state_hash(), transaction.input_notes().commitment(), transaction.block_ref(), + transaction.block_num(), ); let stack_outputs = TransactionKernel::build_output_stack( transaction.account_update().final_state_hash(), From debd48d80257feaeac80be5472596d1516f4594e Mon Sep 17 00:00:00 2001 From: sergerad Date: Thu, 6 Feb 2025 20:26:16 +1300 Subject: [PATCH 02/10] Add block_num as a public input to the transaction kernel --- .../asm/kernels/transaction/lib/memory.masm | 49 +++++++++------ .../asm/kernels/transaction/lib/prologue.masm | 61 ++++++++++--------- crates/miden-lib/src/transaction/memory.rs | 3 + crates/miden-lib/src/transaction/mod.rs | 6 +- docs/architecture/transactions/kernel.md | 6 +- 5 files changed, 74 insertions(+), 51 deletions(-) diff --git a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm index fd11e6d01..1d9413514 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm @@ -43,25 +43,28 @@ const.TX_EXPIRATION_BLOCK_NUM_PTR=28 # GLOBAL INPUTS # ------------------------------------------------------------------------------------------------- -# The memory address at which the global inputs section begins +# The memory address at which the global inputs section begins. const.GLOBAL_INPUTS_SECTION_OFFSET=400 -# The memory address at which the latest known block hash is stored +# The memory address at which the latest known block hash is stored. const.BLK_HASH_PTR=400 +# The memory address at which the latest known block number is stored. +const.BLK_NUM_PTR=404 + # The memory address at which the account ID felts are stored. const.ACCT_ID_PTR=404 -# The memory address at which the initial account hash is stored +# The memory address at which the initial account hash is stored. const.INIT_ACCT_HASH_PTR=408 -# The memory address at which the input notes commitment is stored +# The memory address at which the input notes commitment is stored. const.INPUT_NOTES_COMMITMENT_PTR=412 -# The memory address at which the initial nonce is stored +# The memory address at which the initial nonce is stored. const.INIT_NONCE_PTR=416 -# The memory address at which the transaction script mast root is stored +# The memory address at which the transaction script mast root is stored. const.TX_SCRIPT_ROOT_PTR=420 # GLOBAL BLOCK DATA @@ -123,14 +126,14 @@ const.KERNEL_PROCEDURES_PTR=1604 # ------------------------------------------------------------------------------------------------- # The largest memory address which can be used to load the foreign account data. -# It is computed as `2048 * 64 * 4` -- this is the memory address where the data block of the 64th +# It is computed as `2048 * 64 * 4` -- this is the memory address where the data block of the 64th # account starts. const.MAX_FOREIGN_ACCOUNT_PTR=524288 # The memory address at which the native account data is stored. const.NATIVE_ACCOUNT_DATA_PTR=8192 -# The length of the memory interval that the account data occupies. +# The length of the memory interval that the account data occupies. const.ACCOUNT_DATA_LENGTH=8192 # The offsets at which the account data is stored relative to the start of the account data segment. @@ -241,7 +244,7 @@ end #! Outputs: [input_vault_root_ptr] #! #! Where: -#! - input_vault_root_ptr is a pointer to the memory address at which the input vault root is +#! - input_vault_root_ptr is a pointer to the memory address at which the input vault root is #! stored. export.get_input_vault_root_ptr push.INPUT_VAULT_ROOT_PTR @@ -331,16 +334,26 @@ export.get_block_hash padw push.BLK_HASH_PTR mem_loadw end +#! Returns the block number of the reference block. +#! +#! Inputs: [] +#! Outputs: [block_num] +#! +#! Where: +#! - block_num is the number of the reference block for the transaction execution. +export.get_block_num + push.BLK_NUM_PTR mem_load +end + #! Sets the account ID. #! -#! Inputs: [acct_id_prefix, acct_id_suffix] +#! Inputs: [block_num, 0, acct_id_prefix, acct_id_suffix] #! Outputs: [] #! #! Where: #! - acct_id_{prefix,suffix} are the prefix and suffix felts of the account ID. export.set_global_acct_id - push.0.0 - # => [0, 0, acct_id_prefix, acct_id_suffix] + # => [block_num, 0, acct_id_prefix, acct_id_suffix] mem_storew.ACCT_ID_PTR dropw # => [] @@ -355,7 +368,7 @@ end #! - acct_id_{prefix,suffix} are the prefix and suffix felts of the account ID. export.get_global_acct_id padw mem_loadw.ACCT_ID_PTR - # => [0, 0, acct_id_prefix, acct_id_suffix] + # => [block_num, 0, acct_id_prefix, acct_id_suffix] drop drop end @@ -649,7 +662,7 @@ export.get_native_account_data_ptr push.NATIVE_ACCOUNT_DATA_PTR end -#! Returns the length of the memory interval that the account data occupies. +#! Returns the length of the memory interval that the account data occupies. #! #! Inputs: [] #! Outputs: [acct_data_length] @@ -666,7 +679,7 @@ end #! Outputs: [max_foreign_acct_ptr] #! #! Where: -#! - max_foreign_acct_ptr is the largest memory address which can be used to load the foreign +#! - max_foreign_acct_ptr is the largest memory address which can be used to load the foreign #! account data. export.get_max_foreign_account_ptr push.MAX_FOREIGN_ACCOUNT_PTR @@ -1063,7 +1076,7 @@ export.set_input_note_id mem_storew end -#! Computes a pointer to the memory address at which the nullifier associated a note with `idx` is +#! Computes a pointer to the memory address at which the nullifier associated a note with `idx` is #! stored. #! #! Inputs: [idx] @@ -1221,7 +1234,7 @@ export.set_input_note_num_assets mem_store end -#! Returns a pointer to the start of the assets segment for the input note located at the specified +#! Returns a pointer to the start of the assets segment for the input note located at the specified #! memory address. #! #! Inputs: [note_ptr] @@ -1449,7 +1462,7 @@ end #! Outputs: [kernel_procedures_ptr] #! #! Where: -#! - kernel_procedures_ptr is the memory address where the hashes of the kernel procedures are +#! - kernel_procedures_ptr is the memory address where the hashes of the kernel procedures are #! stored. export.get_kernel_procedures_ptr push.KERNEL_PROCEDURES_PTR diff --git a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm index 2fff6b96a..1cbaf264f 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm @@ -66,16 +66,17 @@ const.ERR_PROLOGUE_NEW_ACCOUNT_NONCE_MUST_BE_ZERO=0x0002005B #! Saves global inputs to memory. #! -#! Inputs: [BLOCK_HASH, account_id_prefix, account_id_suffix, INITIAL_ACCOUNT_HASH, INPUT_NOTES_COMMITMENT] +#! Inputs: [BLOCK_HASH, block_num, 0, account_id_prefix, account_id_suffix, INITIAL_ACCOUNT_HASH, INPUT_NOTES_COMMITMENT] #! Outputs: [] #! #! Where: #! - BLOCK_HASH is the reference block for the transaction execution. -#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account ID of the account +#! - block_num is the number of the reference block. +#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account ID of the account #! that the transaction is being executed against. -#! - INITIAL_ACCOUNT_HASH is the account state prior to the transaction, EMPTY_WORD for new +#! - INITIAL_ACCOUNT_HASH is the account state prior to the transaction, EMPTY_WORD for new #! accounts. -#! - INPUT_NOTES_COMMITMENT is the commitment to the input notes. See the +#! - INPUT_NOTES_COMMITMENT is the commitment to the input notes. See the #! `tx_get_input_notes_commitment` kernel procedure for details. proc.process_global_inputs exec.memory::set_block_hash dropw @@ -102,7 +103,7 @@ end #! Outputs: #! Operand stack: [] #! Advice stack: [] -#! +#! #! Where: #! - kernel_version is the index of the desired kernel in the array of all kernels available for the #! current transaction. @@ -154,7 +155,7 @@ proc.process_kernel_data # AS => [] # get the hash of the kernel which will be used in the current transaction - exec.memory::get_kernel_procedures_ptr add + exec.memory::get_kernel_procedures_ptr add # OS => [kernel_ptr] # AS => [] @@ -196,7 +197,7 @@ proc.process_kernel_data # assert that the precomputed hash matches the computed one movup.4 drop assert_eqw # OS => [] - # AS => [] + # AS => [] end # BLOCK DATA @@ -224,7 +225,7 @@ end #! - PREVIOUS_BLOCK_HASH is the hash of the previous block. #! - CHAIN_MMR_HASH is the sequential hash of the reference MMR. #! - ACCOUNT_ROOT is the root of the tree with latest account states for all accounts. -#! - NULLIFIER_ROOT is the root of the tree with nullifiers of all notes that have ever been +#! - NULLIFIER_ROOT is the root of the tree with nullifiers of all notes that have ever been #! consumed. #! - TX_HASH is the commitment to a set of IDs of transactions which affected accounts in the block. #! - KERNEL_ROOT is the accumulative hash from all kernel hashes. @@ -357,7 +358,7 @@ proc.validate_new_account if.true # assert the fungible faucet reserved slot is initialized correctly (EMPTY_WORD) # TODO: Switch to standard library implementation when available (miden-vm/#1483) - exec.is_empty_word_dropped not + exec.is_empty_word_dropped not assertz.err=ERR_PROLOGUE_NEW_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_EMPTY # => [] @@ -366,13 +367,13 @@ proc.validate_new_account # => [slot_type] # assert the fungible faucet reserved slot type == value - exec.constants::get_storage_slot_type_value eq + exec.constants::get_storage_slot_type_value eq assert.err=ERR_PROLOGUE_NEW_FUNGIBLE_FAUCET_RESERVED_SLOT_INVALID_TYPE # => [] else # assert the non-fungible faucet reserved slot is initialized correctly (root of # empty SMT) - exec.constants::get_empty_smt_root + exec.constants::get_empty_smt_root assert_eqw.err=ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_SMT # => [] @@ -381,7 +382,7 @@ proc.validate_new_account # => [slot_type] # assert the non-fungible faucet reserved slot type == map - exec.constants::get_storage_slot_type_map eq + exec.constants::get_storage_slot_type_map eq assert.err=ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_INVALID_TYPE # => [] end @@ -421,7 +422,7 @@ end #! This procedure will: #! - Read the account data from the advice stack. #! - Save it to memory. -#! - For new accounts, signaled by having a INITIAL_ACCOUNT_HASH set to EMPTY_WORD as a global +#! - For new accounts, signaled by having a INITIAL_ACCOUNT_HASH set to EMPTY_WORD as a global #! input, validate the account's id and initial state. #! - For existing accounts, verify the INITIAL_ACCOUNT_HASH commitment matches the provided data, #! and the account nonce is not zero. @@ -439,7 +440,7 @@ end #! Advice stack: [] #! #! Where: -#! - account_id_{prefix,suffix} are the prefix and suffix felts of the ID of the account that the +#! - account_id_{prefix,suffix} are the prefix and suffix felts of the ID of the account that the #! transaction is being executed against. #! - account_nonce is the account's nonce. #! - ACCOUNT_VAULT_ROOT is the account's vault root. @@ -482,7 +483,7 @@ proc.process_account_data exec.account::save_account_storage_data # => [ACCT_HASH] - # set the new account code commitment to the initial account code root + # set the new account code commitment to the initial account code root # this is used for managing code commitment updates exec.memory::get_acct_code_commitment exec.memory::set_new_acct_code_commitment @@ -579,7 +580,7 @@ proc.authenticate_note.8 # => [COMPUTED_BLOCK_HASH, PERM, mem_ptr', BLOCK_HASH, NOTE_HASH] # assert the computed block hash matches - movup.8 drop movupw.2 + movup.8 drop movupw.2 assert_eqw.err=ERR_PROLOGUE_MISMATCH_OF_REFERENCE_BLOCK_MMR_AND_NOTE_AUTHENTICATION_MMR # => [PERM, NOTE_HASH] @@ -616,7 +617,7 @@ end #! INPUTS_HASH, #! ASSETS_HASH, #! ] -#! Outputs: +#! Outputs: #! Operand stack: [NULLIFIER] #! Advice stack: [] #! @@ -648,8 +649,8 @@ end #! - The note's ARGS are not authenticated, these are optional arguments the user can provide when #! consuming the note. #! - The note's metadata is authenticated, so the data is returned in the stack. The value is used -#! to compute the NOTE_HASH as `hash(NOTE_ID || NOTE_METADATA)`, which is the leaf value of the -#! note's tree in the contained in the block header. The NOTE_HASH is either verified by this +#! to compute the NOTE_HASH as `hash(NOTE_ID || NOTE_METADATA)`, which is the leaf value of the +#! note's tree in the contained in the block header. The NOTE_HASH is either verified by this #! kernel, or delayed to be verified by another kernel (e.g. block or batch kernels). #! #! Inputs: @@ -691,7 +692,7 @@ proc.process_note_assets adv_push.1 # => [assets_count, note_ptr] - dup exec.constants::get_max_assets_per_note lte + dup exec.constants::get_max_assets_per_note lte assert.err=ERR_PROLOGUE_NUMBER_OF_NOTE_ASSETS_EXCEEDS_LIMIT # => [assets_count, note_ptr] @@ -855,13 +856,13 @@ end #! NOTE_ROOT, #! )? #! ] -#! Outputs: +#! Outputs: #! Operand stack: [PERM, PERM, PERM] #! Advice stack: [] #! #! Where: #! - idx is the index of the input note. -#! - HASHER_CAPACITY is the state of the hasher capacity word, with the commitment to the previous +#! - HASHER_CAPACITY is the state of the hasher capacity word, with the commitment to the previous #! notes. #! - SERIAL_NUMBER is the note's serial. #! - SCRIPT_ROOT is the note's script root. @@ -954,10 +955,10 @@ end #! Inputs: #! Operand stack: [] #! Advice stack: [num_notes], -#! Advice map: { -#! INPUT_NOTES_COMMITMENT: [NOTE_DATA] +#! Advice map: { +#! INPUT_NOTES_COMMITMENT: [NOTE_DATA] #! } -#! Outputs: +#! Outputs: #! Operand stack: [] #! Advice stack: [] #! @@ -973,7 +974,7 @@ proc.process_input_notes_data # assert the number of input notes is within limits; since max number of input notes is # expected to be smaller than 2^32, we can use a more efficient u32 comparison dup - exec.constants::get_max_num_input_notes + exec.constants::get_max_num_input_notes u32assert2.err=ERR_PROLOGUE_NUMBER_OF_INPUT_NOTES_EXCEEDS_LIMIT u32lte assert.err=ERR_PROLOGUE_NUMBER_OF_INPUT_NOTES_EXCEEDS_LIMIT # => [num_notes] @@ -1086,7 +1087,7 @@ end #! Inputs: #! Operand stack: [ #! BLOCK_HASH, -#! account_id_prefix, account_id_suffix, +#! block_num, 0, account_id_prefix, account_id_suffix, #! INITIAL_ACCOUNT_HASH, #! INPUT_NOTES_COMMITMENT, #! ] @@ -1122,16 +1123,16 @@ end #! #! Where: #! - BLOCK_HASH is the reference block for the transaction execution. -#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account that the transaction +#! - account_id_{prefix,suffix} are the prefix and suffix felts of the account that the transaction #! is being executed against. -#! - INITIAL_ACCOUNT_HASH is the account state prior to the transaction, EMPTY_WORD for new +#! - INITIAL_ACCOUNT_HASH is the account state prior to the transaction, EMPTY_WORD for new #! accounts. #! - INPUT_NOTES_COMMITMENT, see `transaction::api::get_input_notes_commitment`. #! - KERNEL_ROOT is the accumulative hash from all kernel hashes. #! - PREVIOUS_BLOCK_HASH is the hash of the previous block. #! - CHAIN_MMR_HASH is the sequential hash of the reference MMR. #! - ACCOUNT_ROOT is the root of the tree with latest account states for all accounts. -#! - NULLIFIER_ROOT is the root of the tree with nullifiers of all notes that have ever been +#! - NULLIFIER_ROOT is the root of the tree with nullifiers of all notes that have ever been #! consumed. #! - TX_HASH is the commitment to a set of IDs of transactions which affected accounts in the block. #! - PROOF_HASH is the hash of the block's stark proof. diff --git a/crates/miden-lib/src/transaction/memory.rs b/crates/miden-lib/src/transaction/memory.rs index 6e0ca413c..04c4fa9e0 100644 --- a/crates/miden-lib/src/transaction/memory.rs +++ b/crates/miden-lib/src/transaction/memory.rs @@ -89,6 +89,9 @@ pub const GLOBAL_INPUTS_SECTION_OFFSET: MemoryOffset = 400; /// The memory address at which the latest known block hash is stored. pub const BLK_HASH_PTR: MemoryAddress = 400; +/// The memory address at which the block num is stored. +pub const BLK_NUM_PTR: MemoryAddress = 404; + /// The memory address at which the account ID is stored. pub const ACCT_ID_PTR: MemoryAddress = 404; diff --git a/crates/miden-lib/src/transaction/mod.rs b/crates/miden-lib/src/transaction/mod.rs index c31023b98..754e22145 100644 --- a/crates/miden-lib/src/transaction/mod.rs +++ b/crates/miden-lib/src/transaction/mod.rs @@ -132,7 +132,7 @@ impl TransactionKernel { /// ```text /// [ /// BLOCK_HASH, - /// acct_id, + /// block_num, 0, acct_id, /// INITIAL_ACCOUNT_HASH, /// INPUT_NOTES_COMMITMENT, /// ] @@ -140,6 +140,7 @@ impl TransactionKernel { /// /// Where: /// - BLOCK_HASH, reference block for the transaction execution. + /// - block_num, number of the reference block. /// - acct_id, the account that the transaction is being executed against. /// - INITIAL_ACCOUNT_HASH, account state prior to the transaction, EMPTY_WORD for new accounts. /// - INPUT_NOTES_COMMITMENT, see `transaction::api::get_input_notes_commitment`. @@ -156,8 +157,9 @@ impl TransactionKernel { inputs.extend_from_slice(init_acct_hash.as_elements()); inputs.push(account_id.suffix()); inputs.push(account_id.prefix().as_felt()); - inputs.extend_from_slice(block_hash.as_elements()); + inputs.push(Felt::new(0)); inputs.push(Felt::from(block_num)); + inputs.extend_from_slice(block_hash.as_elements()); StackInputs::new(inputs) .map_err(|e| e.to_string()) .expect("Invalid stack input") diff --git a/docs/architecture/transactions/kernel.md b/docs/architecture/transactions/kernel.md index f6e55d1cf..3c814c400 100644 --- a/docs/architecture/transactions/kernel.md +++ b/docs/architecture/transactions/kernel.md @@ -7,6 +7,7 @@ The kernel provides context-sensitive security, preventing unwanted read and wri In general, the kernel's procedures must reflect everything users might want to do while executing transactions—from transferring assets to complex smart contract interactions with custom code. > **Info** +> > - Learn more about Miden transaction [procedures](procedures.md) and [contexts](contexts.md). The kernel has a well-defined structure which does the following: @@ -43,7 +44,7 @@ Tracks variables used internally by the transaction kernel. ### Global inputs -Stored in pre-defined memory slots. Global inputs include the block hash, account ID, initial account hash, and nullifier commitment. +Stored in pre-defined memory slots. Global inputs include the block hash, block number, account ID, initial account hash, and nullifier commitment. ### Block data @@ -62,6 +63,7 @@ Reads data from the advice provider, stores it in memory, and computes the accou Processes input notes by reading data from advice providers and storing it in memory. It computes the note's hash and nullifier, forming a transaction nullifier commitment. > **Info** +> > - Note data is required for computing the nullifier (e.g., the [note script](../notes.md#main-script) and serial number). > - Note recipients define the set of users who can consume specific notes. @@ -84,6 +86,7 @@ end When processing a note, new note creation may be triggered, and information about the new note is stored in the output note data. > **Info** +> > - Notes can only call account interfaces to trigger write operations, preventing direct access to account storage. ## Transaction Script Processing @@ -101,6 +104,7 @@ end ``` > **Note** +> > - The account must expose the `auth_tx_rpo_falcon512` function for the transaction script to call it. ## Epilogue From 518c06290554ebdf3785ea3cecebad3bc7cee5e3 Mon Sep 17 00:00:00 2001 From: sergerad Date: Fri, 7 Feb 2025 14:23:40 +1300 Subject: [PATCH 03/10] Add unit test --- .../src/tests/kernel_tests/test_prologue.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs b/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs index 2e490c888..a637f62de 100644 --- a/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs +++ b/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs @@ -10,11 +10,11 @@ use miden_lib::{ }, transaction::{ memory::{ - MemoryOffset, ACCT_DB_ROOT_PTR, ACCT_ID_PTR, BLK_HASH_PTR, BLOCK_METADATA_PTR, - BLOCK_NUMBER_IDX, CHAIN_MMR_NUM_LEAVES_PTR, CHAIN_MMR_PEAKS_PTR, CHAIN_ROOT_PTR, - INIT_ACCT_HASH_PTR, INIT_NONCE_PTR, INPUT_NOTES_COMMITMENT_PTR, INPUT_NOTE_ARGS_OFFSET, - INPUT_NOTE_ASSETS_HASH_OFFSET, INPUT_NOTE_ASSETS_OFFSET, INPUT_NOTE_ID_OFFSET, - INPUT_NOTE_INPUTS_HASH_OFFSET, INPUT_NOTE_METADATA_OFFSET, + MemoryOffset, ACCT_DB_ROOT_PTR, ACCT_ID_PTR, BLK_HASH_PTR, BLK_NUM_PTR, + BLOCK_METADATA_PTR, BLOCK_NUMBER_IDX, CHAIN_MMR_NUM_LEAVES_PTR, CHAIN_MMR_PEAKS_PTR, + CHAIN_ROOT_PTR, INIT_ACCT_HASH_PTR, INIT_NONCE_PTR, INPUT_NOTES_COMMITMENT_PTR, + INPUT_NOTE_ARGS_OFFSET, INPUT_NOTE_ASSETS_HASH_OFFSET, INPUT_NOTE_ASSETS_OFFSET, + INPUT_NOTE_ID_OFFSET, INPUT_NOTE_INPUTS_HASH_OFFSET, INPUT_NOTE_METADATA_OFFSET, INPUT_NOTE_NULLIFIER_SECTION_PTR, INPUT_NOTE_NUM_ASSETS_OFFSET, INPUT_NOTE_SCRIPT_ROOT_OFFSET, INPUT_NOTE_SECTION_PTR, INPUT_NOTE_SERIAL_NUM_OFFSET, KERNEL_ROOT_PTR, NATIVE_ACCT_CODE_COMMITMENT_PTR, NATIVE_ACCT_ID_AND_NONCE_PTR, @@ -114,6 +114,11 @@ fn global_input_memory_assertions(process: &Process, inputs: &TransactionContext inputs.tx_inputs().block_header().hash().as_elements(), "The block hash should be stored at the BLK_HASH_PTR" ); + assert_eq!( + read_root_mem_word(&process.into(), BLK_NUM_PTR)[3], + inputs.tx_inputs().block_header().block_num().into(), + "The block number should be stored at the BLK_NUM_PTR[3]" + ); assert_eq!( read_root_mem_word(&process.into(), ACCT_ID_PTR)[0], @@ -657,7 +662,7 @@ fn test_get_blk_version() { exec.prologue::prepare_transaction exec.memory::get_blk_version - # truncate the stack + # truncate the stack swap drop end "; @@ -678,7 +683,7 @@ fn test_get_blk_timestamp() { exec.prologue::prepare_transaction exec.memory::get_blk_timestamp - # truncate the stack + # truncate the stack swap drop end "; From 3623293f5d7acd45b8cfd5b42cb7e9af0ee3135a Mon Sep 17 00:00:00 2001 From: sergerad Date: Fri, 7 Feb 2025 17:43:16 +1300 Subject: [PATCH 04/10] Rename get blk num fn --- crates/miden-lib/asm/kernels/transaction/lib/memory.masm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm index 1d9413514..2cecab9dc 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm @@ -341,7 +341,7 @@ end #! #! Where: #! - block_num is the number of the reference block for the transaction execution. -export.get_block_num +export.get_global_blk_num push.BLK_NUM_PTR mem_load end From 9f11c2fc6314e2cf459d9a04e59e6200a10b3331 Mon Sep 17 00:00:00 2001 From: sergerad Date: Fri, 7 Feb 2025 22:05:27 +1300 Subject: [PATCH 05/10] Do not store block_num and assert equality --- .../asm/kernels/transaction/lib/memory.masm | 25 +++++------------- .../asm/kernels/transaction/lib/prologue.masm | 26 ++++++++++++------- crates/miden-lib/src/transaction/memory.rs | 3 --- crates/miden-lib/src/transaction/mod.rs | 9 +++---- .../src/tests/kernel_tests/test_prologue.rs | 15 ++++------- 5 files changed, 31 insertions(+), 47 deletions(-) diff --git a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm index 2cecab9dc..65f06fed0 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm @@ -49,9 +49,6 @@ const.GLOBAL_INPUTS_SECTION_OFFSET=400 # The memory address at which the latest known block hash is stored. const.BLK_HASH_PTR=400 -# The memory address at which the latest known block number is stored. -const.BLK_NUM_PTR=404 - # The memory address at which the account ID felts are stored. const.ACCT_ID_PTR=404 @@ -334,29 +331,19 @@ export.get_block_hash padw push.BLK_HASH_PTR mem_loadw end -#! Returns the block number of the reference block. -#! -#! Inputs: [] -#! Outputs: [block_num] -#! -#! Where: -#! - block_num is the number of the reference block for the transaction execution. -export.get_global_blk_num - push.BLK_NUM_PTR mem_load -end - #! Sets the account ID. #! -#! Inputs: [block_num, 0, acct_id_prefix, acct_id_suffix] -#! Outputs: [] +#! Inputs: [acct_id_prefix, acct_id_suffix, block_num] +#! Outputs: [block_num] #! #! Where: #! - acct_id_{prefix,suffix} are the prefix and suffix felts of the account ID. export.set_global_acct_id - # => [block_num, 0, acct_id_prefix, acct_id_suffix] + push.0.0 + # => [0, 0, acct_id_prefix, acct_id_suffix, block_num] mem_storew.ACCT_ID_PTR dropw - # => [] + # => [block_num] end #! Returns the global account ID. @@ -368,7 +355,7 @@ end #! - acct_id_{prefix,suffix} are the prefix and suffix felts of the account ID. export.get_global_acct_id padw mem_loadw.ACCT_ID_PTR - # => [block_num, 0, acct_id_prefix, acct_id_suffix] + # => [0, 0, acct_id_prefix, acct_id_suffix] drop drop end diff --git a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm index 1cbaf264f..ddb61d523 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm @@ -66,8 +66,8 @@ const.ERR_PROLOGUE_NEW_ACCOUNT_NONCE_MUST_BE_ZERO=0x0002005B #! Saves global inputs to memory. #! -#! Inputs: [BLOCK_HASH, block_num, 0, account_id_prefix, account_id_suffix, INITIAL_ACCOUNT_HASH, INPUT_NOTES_COMMITMENT] -#! Outputs: [] +#! Inputs: [BLOCK_HASH, INITIAL_ACCOUNT_HASH, INPUT_NOTES_COMMITMENT, account_id_prefix, account_id_suffix, block_num] +#! Outputs: [block_num] #! #! Where: #! - BLOCK_HASH is the reference block for the transaction execution. @@ -80,9 +80,9 @@ const.ERR_PROLOGUE_NEW_ACCOUNT_NONCE_MUST_BE_ZERO=0x0002005B #! `tx_get_input_notes_commitment` kernel procedure for details. proc.process_global_inputs exec.memory::set_block_hash dropw - exec.memory::set_global_acct_id exec.memory::set_init_acct_hash dropw exec.memory::set_nullifier_commitment dropw + exec.memory::set_global_acct_id end # KERNEL DATA @@ -206,7 +206,7 @@ end #! Saves block data to memory and verifies that it matches the BLOCK_HASH public input. #! #! Inputs: -#! Operand stack: [] +#! Operand stack: [block_num] #! Advice stack: [ #! PREVIOUS_BLOCK_HASH, #! CHAIN_MMR_HASH, @@ -236,7 +236,7 @@ end #! - NOTE_ROOT is the root of the tree with all notes created in the block. proc.process_block_data exec.memory::get_block_data_ptr - # => [block_data_ptr] + # => [block_data_ptr, block_num] # read block data and compute its subhash. See `Advice stack` above for details. padw padw padw @@ -245,21 +245,27 @@ proc.process_block_data adv_pipe hperm adv_pipe hperm exec.rpo::squeeze_digest - # => [DIG, block_data_ptr'] + # => [DIG, block_data_ptr', block_num] # store the note root in memory padw adv_loadw dupw exec.memory::set_note_root dropw - # => [NOTE_ROOT, DIG, block_data_ptr'] + # => [NOTE_ROOT, DIG, block_data_ptr', block_num] # merge the note root with the block data digest hmerge - # => [BLOCK_HASH, block_data_ptr'] + # => [BLOCK_HASH, block_data_ptr', block_num] # assert that the block hash matches the hash in global inputs exec.memory::get_block_hash assert_eqw.err=ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT - # => [block_data_ptr'] + # => [block_data_ptr', block_num] + + drop + # => [block_num] + + exec.memory::get_blk_num + assert_eq.err=ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT # TODO error drop # => [] @@ -1159,7 +1165,7 @@ end #! - any of the input notes do note exist in the note db. export.prepare_transaction exec.process_global_inputs - # => [] + # => [block_num] exec.process_block_data exec.process_kernel_data diff --git a/crates/miden-lib/src/transaction/memory.rs b/crates/miden-lib/src/transaction/memory.rs index 04c4fa9e0..6e0ca413c 100644 --- a/crates/miden-lib/src/transaction/memory.rs +++ b/crates/miden-lib/src/transaction/memory.rs @@ -89,9 +89,6 @@ pub const GLOBAL_INPUTS_SECTION_OFFSET: MemoryOffset = 400; /// The memory address at which the latest known block hash is stored. pub const BLK_HASH_PTR: MemoryAddress = 400; -/// The memory address at which the block num is stored. -pub const BLK_NUM_PTR: MemoryAddress = 404; - /// The memory address at which the account ID is stored. pub const ACCT_ID_PTR: MemoryAddress = 404; diff --git a/crates/miden-lib/src/transaction/mod.rs b/crates/miden-lib/src/transaction/mod.rs index 754e22145..985901571 100644 --- a/crates/miden-lib/src/transaction/mod.rs +++ b/crates/miden-lib/src/transaction/mod.rs @@ -132,9 +132,9 @@ impl TransactionKernel { /// ```text /// [ /// BLOCK_HASH, - /// block_num, 0, acct_id, /// INITIAL_ACCOUNT_HASH, /// INPUT_NOTES_COMMITMENT, + /// acct_id, block_num /// ] /// ``` /// @@ -153,12 +153,11 @@ impl TransactionKernel { ) -> StackInputs { // Note: Must be kept in sync with the transaction's kernel prepare_transaction procedure let mut inputs: Vec = Vec::with_capacity(14); - inputs.extend(input_notes_hash); - inputs.extend_from_slice(init_acct_hash.as_elements()); + inputs.push(Felt::from(block_num)); inputs.push(account_id.suffix()); inputs.push(account_id.prefix().as_felt()); - inputs.push(Felt::new(0)); - inputs.push(Felt::from(block_num)); + inputs.extend(input_notes_hash); + inputs.extend_from_slice(init_acct_hash.as_elements()); inputs.extend_from_slice(block_hash.as_elements()); StackInputs::new(inputs) .map_err(|e| e.to_string()) diff --git a/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs b/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs index a637f62de..0fb99ae72 100644 --- a/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs +++ b/crates/miden-tx/src/tests/kernel_tests/test_prologue.rs @@ -10,11 +10,11 @@ use miden_lib::{ }, transaction::{ memory::{ - MemoryOffset, ACCT_DB_ROOT_PTR, ACCT_ID_PTR, BLK_HASH_PTR, BLK_NUM_PTR, - BLOCK_METADATA_PTR, BLOCK_NUMBER_IDX, CHAIN_MMR_NUM_LEAVES_PTR, CHAIN_MMR_PEAKS_PTR, - CHAIN_ROOT_PTR, INIT_ACCT_HASH_PTR, INIT_NONCE_PTR, INPUT_NOTES_COMMITMENT_PTR, - INPUT_NOTE_ARGS_OFFSET, INPUT_NOTE_ASSETS_HASH_OFFSET, INPUT_NOTE_ASSETS_OFFSET, - INPUT_NOTE_ID_OFFSET, INPUT_NOTE_INPUTS_HASH_OFFSET, INPUT_NOTE_METADATA_OFFSET, + MemoryOffset, ACCT_DB_ROOT_PTR, ACCT_ID_PTR, BLK_HASH_PTR, BLOCK_METADATA_PTR, + BLOCK_NUMBER_IDX, CHAIN_MMR_NUM_LEAVES_PTR, CHAIN_MMR_PEAKS_PTR, CHAIN_ROOT_PTR, + INIT_ACCT_HASH_PTR, INIT_NONCE_PTR, INPUT_NOTES_COMMITMENT_PTR, INPUT_NOTE_ARGS_OFFSET, + INPUT_NOTE_ASSETS_HASH_OFFSET, INPUT_NOTE_ASSETS_OFFSET, INPUT_NOTE_ID_OFFSET, + INPUT_NOTE_INPUTS_HASH_OFFSET, INPUT_NOTE_METADATA_OFFSET, INPUT_NOTE_NULLIFIER_SECTION_PTR, INPUT_NOTE_NUM_ASSETS_OFFSET, INPUT_NOTE_SCRIPT_ROOT_OFFSET, INPUT_NOTE_SECTION_PTR, INPUT_NOTE_SERIAL_NUM_OFFSET, KERNEL_ROOT_PTR, NATIVE_ACCT_CODE_COMMITMENT_PTR, NATIVE_ACCT_ID_AND_NONCE_PTR, @@ -114,11 +114,6 @@ fn global_input_memory_assertions(process: &Process, inputs: &TransactionContext inputs.tx_inputs().block_header().hash().as_elements(), "The block hash should be stored at the BLK_HASH_PTR" ); - assert_eq!( - read_root_mem_word(&process.into(), BLK_NUM_PTR)[3], - inputs.tx_inputs().block_header().block_num().into(), - "The block number should be stored at the BLK_NUM_PTR[3]" - ); assert_eq!( read_root_mem_word(&process.into(), ACCT_ID_PTR)[0], From 593e96b5b4d7f133121f72ef2ed881c31cc25517 Mon Sep 17 00:00:00 2001 From: sergerad Date: Sat, 8 Feb 2025 13:52:43 +1300 Subject: [PATCH 06/10] PR comment fixes --- crates/miden-lib/asm/kernels/transaction/lib/memory.masm | 8 ++++---- .../miden-lib/asm/kernels/transaction/lib/prologue.masm | 5 +---- crates/miden-lib/src/transaction/mod.rs | 2 +- docs/architecture/transactions/kernel.md | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm index 65f06fed0..ec7be8704 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/memory.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/memory.masm @@ -333,17 +333,17 @@ end #! Sets the account ID. #! -#! Inputs: [acct_id_prefix, acct_id_suffix, block_num] -#! Outputs: [block_num] +#! Inputs: [acct_id_prefix, acct_id_suffix] +#! Outputs: [] #! #! Where: #! - acct_id_{prefix,suffix} are the prefix and suffix felts of the account ID. export.set_global_acct_id push.0.0 - # => [0, 0, acct_id_prefix, acct_id_suffix, block_num] + # => [0, 0, acct_id_prefix, acct_id_suffix] mem_storew.ACCT_ID_PTR dropw - # => [block_num] + # => [] end #! Returns the global account ID. diff --git a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm index ddb61d523..b66326eae 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm @@ -266,9 +266,6 @@ proc.process_block_data exec.memory::get_blk_num assert_eq.err=ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT # TODO error - - drop - # => [] end # CHAIN DATA @@ -1093,9 +1090,9 @@ end #! Inputs: #! Operand stack: [ #! BLOCK_HASH, -#! block_num, 0, account_id_prefix, account_id_suffix, #! INITIAL_ACCOUNT_HASH, #! INPUT_NOTES_COMMITMENT, +#! account_id_prefix, account_id_suffix, block_num, #! ] #! Advice stack: [ #! PREVIOUS_BLOCK_HASH, diff --git a/crates/miden-lib/src/transaction/mod.rs b/crates/miden-lib/src/transaction/mod.rs index 985901571..6810144e0 100644 --- a/crates/miden-lib/src/transaction/mod.rs +++ b/crates/miden-lib/src/transaction/mod.rs @@ -134,7 +134,7 @@ impl TransactionKernel { /// BLOCK_HASH, /// INITIAL_ACCOUNT_HASH, /// INPUT_NOTES_COMMITMENT, - /// acct_id, block_num + /// acct_id_prefix, acct_id_suffix, block_num /// ] /// ``` /// diff --git a/docs/architecture/transactions/kernel.md b/docs/architecture/transactions/kernel.md index 3c814c400..6424ffc11 100644 --- a/docs/architecture/transactions/kernel.md +++ b/docs/architecture/transactions/kernel.md @@ -44,7 +44,7 @@ Tracks variables used internally by the transaction kernel. ### Global inputs -Stored in pre-defined memory slots. Global inputs include the block hash, block number, account ID, initial account hash, and nullifier commitment. +Stored in pre-defined memory slots. Global inputs include the block hash, account ID, initial account hash, and nullifier commitment. ### Block data From 2b1048d317c60f3378adfdb72d974606e1ca8362 Mon Sep 17 00:00:00 2001 From: sergerad Date: Sat, 8 Feb 2025 13:57:26 +1300 Subject: [PATCH 07/10] Block number global input error --- .../asm/kernels/transaction/lib/prologue.masm | 5 +++- .../miden-lib/src/errors/tx_kernel_errors.rs | 23 +++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm index b66326eae..f52dc4baf 100644 --- a/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm +++ b/crates/miden-lib/asm/kernels/transaction/lib/prologue.masm @@ -19,6 +19,9 @@ const.MAX_BLOCK_NUM=0xFFFFFFFF # The provided global inputs do not match the block hash commitment const.ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT=0x00020034 +# The provided global inputs do not match the block number commitment +const.ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_NUMBER_COMMITMENT=0x00020134 + # New account must have an empty vault const.ERR_PROLOGUE_NEW_ACCOUNT_VAULT_MUST_BE_EMPTY=0x00020035 @@ -265,7 +268,7 @@ proc.process_block_data # => [block_num] exec.memory::get_blk_num - assert_eq.err=ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT # TODO error + assert_eq.err=ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_NUMBER_COMMITMENT end # CHAIN DATA diff --git a/crates/miden-lib/src/errors/tx_kernel_errors.rs b/crates/miden-lib/src/errors/tx_kernel_errors.rs index e3e9441b0..2f51222a8 100644 --- a/crates/miden-lib/src/errors/tx_kernel_errors.rs +++ b/crates/miden-lib/src/errors/tx_kernel_errors.rs @@ -35,7 +35,8 @@ pub const ERR_ACCOUNT_TOTAL_ISSUANCE_PROC_CAN_ONLY_BE_CALLED_ON_FUNGIBLE_FAUCET: pub const ERR_EPILOGUE_TOTAL_NUMBER_OF_ASSETS_MUST_STAY_THE_SAME: u32 = 0x00020029; pub const ERR_FAUCET_BURN_CANNOT_EXCEED_EXISTING_TOTAL_SUPPLY: u32 = 0x0002002B; -pub const ERR_FAUCET_BURN_NON_FUNGIBLE_ASSET_CAN_ONLY_BE_CALLED_ON_NON_FUNGIBLE_FAUCET: u32 = 0x0002002D; +pub const ERR_FAUCET_BURN_NON_FUNGIBLE_ASSET_CAN_ONLY_BE_CALLED_ON_NON_FUNGIBLE_FAUCET: u32 = + 0x0002002D; pub const ERR_FAUCET_INVALID_STORAGE_OFFSET: u32 = 0x0002000E; pub const ERR_FAUCET_NEW_TOTAL_SUPPLY_WOULD_EXCEED_MAX_ASSET_AMOUNT: u32 = 0x0002002A; pub const ERR_FAUCET_NON_FUNGIBLE_ASSET_ALREADY_ISSUED: u32 = 0x0002002C; @@ -51,7 +52,8 @@ pub const ERR_FUNGIBLE_ASSET_AMOUNT_EXCEEDS_MAX_ALLOWED_AMOUNT: u32 = 0x0002004C pub const ERR_FUNGIBLE_ASSET_DISTRIBUTE_WOULD_CAUSE_MAX_SUPPLY_TO_BE_EXCEEDED: u32 = 0x0002004A; pub const ERR_FUNGIBLE_ASSET_FAUCET_IS_NOT_ORIGIN: u32 = 0x00020026; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ONE_MUST_BE_ZERO: u32 = 0x00020020; -pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_TWO_AND_THREE_MUST_BE_FUNGIBLE_FAUCET_ID: u32 = 0x00020022; +pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_TWO_AND_THREE_MUST_BE_FUNGIBLE_FAUCET_ID: u32 = + 0x00020022; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ZERO_MUST_BE_WITHIN_LIMITS: u32 = 0x00020023; pub const ERR_FUNGIBLE_ASSET_PROVIDED_FAUCET_ID_IS_INVALID: u32 = 0x0002004B; @@ -83,15 +85,20 @@ pub const ERR_P2ID_WRONG_NUMBER_OF_INPUTS: u32 = 0x00020050; pub const ERR_PROLOGUE_EXISTING_ACCOUNT_MUST_HAVE_NON_ZERO_NONCE: u32 = 0x0002003B; pub const ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT: u32 = 0x00020034; +pub const ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_NUMBER_COMMITMENT: u32 = + 0x00020134; pub const ERR_PROLOGUE_INPUT_NOTES_COMMITMENT_MISMATCH: u32 = 0x00020041; -pub const ERR_PROLOGUE_MISMATCH_OF_ACCOUNT_IDS_FROM_GLOBAL_INPUTS_AND_ADVICE_PROVIDER: u32 = 0x0002003C; -pub const ERR_PROLOGUE_MISMATCH_OF_REFERENCE_BLOCK_MMR_AND_NOTE_AUTHENTICATION_MMR: u32 = 0x0002003D; +pub const ERR_PROLOGUE_MISMATCH_OF_ACCOUNT_IDS_FROM_GLOBAL_INPUTS_AND_ADVICE_PROVIDER: u32 = + 0x0002003C; +pub const ERR_PROLOGUE_MISMATCH_OF_REFERENCE_BLOCK_MMR_AND_NOTE_AUTHENTICATION_MMR: u32 = + 0x0002003D; pub const ERR_PROLOGUE_NEW_ACCOUNT_NONCE_MUST_BE_ZERO: u32 = 0x0002005B; pub const ERR_PROLOGUE_NEW_ACCOUNT_VAULT_MUST_BE_EMPTY: u32 = 0x00020035; pub const ERR_PROLOGUE_NEW_FUNGIBLE_FAUCET_RESERVED_SLOT_INVALID_TYPE: u32 = 0x00020037; pub const ERR_PROLOGUE_NEW_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_EMPTY: u32 = 0x00020036; pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_INVALID_TYPE: u32 = 0x00020039; -pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_SMT: u32 = 0x00020038; +pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_SMT: u32 = + 0x00020038; pub const ERR_PROLOGUE_NUMBER_OF_INPUT_NOTES_EXCEEDS_LIMIT: u32 = 0x00020040; pub const ERR_PROLOGUE_NUMBER_OF_NOTE_ASSETS_EXCEEDS_LIMIT: u32 = 0x0002003E; pub const ERR_PROLOGUE_NUMBER_OF_NOTE_INPUTS_EXCEEDED_LIMIT: u32 = 0x0002004F; @@ -110,12 +117,13 @@ pub const ERR_VAULT_ADD_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID: u32 = 0x000 pub const ERR_VAULT_FUNGIBLE_ASSET_AMOUNT_LESS_THAN_AMOUNT_TO_WITHDRAW: u32 = 0x0002001D; pub const ERR_VAULT_FUNGIBLE_MAX_AMOUNT_EXCEEDED: u32 = 0x0002001A; pub const ERR_VAULT_GET_BALANCE_PROC_CAN_ONLY_BE_CALLED_ON_FUNGIBLE_FAUCET: u32 = 0x00020018; -pub const ERR_VAULT_HAS_NON_FUNGIBLE_ASSET_PROC_CAN_BE_CALLED_ONLY_WITH_NON_FUNGIBLE_ASSET: u32 = 0x00020019; +pub const ERR_VAULT_HAS_NON_FUNGIBLE_ASSET_PROC_CAN_BE_CALLED_ONLY_WITH_NON_FUNGIBLE_ASSET: u32 = + 0x00020019; pub const ERR_VAULT_NON_FUNGIBLE_ASSET_ALREADY_EXISTS: u32 = 0x0002001C; pub const ERR_VAULT_NON_FUNGIBLE_ASSET_TO_REMOVE_NOT_FOUND: u32 = 0x0002001F; pub const ERR_VAULT_REMOVE_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID: u32 = 0x0002001E; -pub const TX_KERNEL_ERRORS: [(u32, &str); 90] = [ +pub const TX_KERNEL_ERRORS: [(u32, &str); 91] = [ (ERR_ACCOUNT_ANCHOR_BLOCK_HASH_MUST_NOT_BE_EMPTY, "Anchor block hash must not be empty"), (ERR_ACCOUNT_CODE_COMMITMENT_MISMATCH, "Computed account code commitment does not match recorded account code commitment"), (ERR_ACCOUNT_CODE_IS_NOT_UPDATABLE, "Account code must be updatable for it to be possible to set new code"), @@ -189,6 +197,7 @@ pub const TX_KERNEL_ERRORS: [(u32, &str); 90] = [ (ERR_PROLOGUE_EXISTING_ACCOUNT_MUST_HAVE_NON_ZERO_NONCE, "Existing accounts must have a non-zero nonce"), (ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT, "The provided global inputs do not match the block hash commitment"), + (ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_NUMBER_COMMITMENT, "The provided global inputs do not match the block number commitment"), (ERR_PROLOGUE_INPUT_NOTES_COMMITMENT_MISMATCH, "Note commitment computed from the input note data does not match given note commitment"), (ERR_PROLOGUE_MISMATCH_OF_ACCOUNT_IDS_FROM_GLOBAL_INPUTS_AND_ADVICE_PROVIDER, "Account IDs provided via global inputs and advice provider do not match"), (ERR_PROLOGUE_MISMATCH_OF_REFERENCE_BLOCK_MMR_AND_NOTE_AUTHENTICATION_MMR, "Reference block MMR and note's authentication MMR must match"), From 6add0c1da9f03497fba58fa5577b98a82d2c2513 Mon Sep 17 00:00:00 2001 From: sergerad Date: Sat, 8 Feb 2025 14:17:46 +1300 Subject: [PATCH 08/10] Lint --- .../miden-lib/src/errors/tx_kernel_errors.rs | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/crates/miden-lib/src/errors/tx_kernel_errors.rs b/crates/miden-lib/src/errors/tx_kernel_errors.rs index 2f51222a8..40d07b4fa 100644 --- a/crates/miden-lib/src/errors/tx_kernel_errors.rs +++ b/crates/miden-lib/src/errors/tx_kernel_errors.rs @@ -35,8 +35,7 @@ pub const ERR_ACCOUNT_TOTAL_ISSUANCE_PROC_CAN_ONLY_BE_CALLED_ON_FUNGIBLE_FAUCET: pub const ERR_EPILOGUE_TOTAL_NUMBER_OF_ASSETS_MUST_STAY_THE_SAME: u32 = 0x00020029; pub const ERR_FAUCET_BURN_CANNOT_EXCEED_EXISTING_TOTAL_SUPPLY: u32 = 0x0002002B; -pub const ERR_FAUCET_BURN_NON_FUNGIBLE_ASSET_CAN_ONLY_BE_CALLED_ON_NON_FUNGIBLE_FAUCET: u32 = - 0x0002002D; +pub const ERR_FAUCET_BURN_NON_FUNGIBLE_ASSET_CAN_ONLY_BE_CALLED_ON_NON_FUNGIBLE_FAUCET: u32 = 0x0002002D; pub const ERR_FAUCET_INVALID_STORAGE_OFFSET: u32 = 0x0002000E; pub const ERR_FAUCET_NEW_TOTAL_SUPPLY_WOULD_EXCEED_MAX_ASSET_AMOUNT: u32 = 0x0002002A; pub const ERR_FAUCET_NON_FUNGIBLE_ASSET_ALREADY_ISSUED: u32 = 0x0002002C; @@ -52,8 +51,7 @@ pub const ERR_FUNGIBLE_ASSET_AMOUNT_EXCEEDS_MAX_ALLOWED_AMOUNT: u32 = 0x0002004C pub const ERR_FUNGIBLE_ASSET_DISTRIBUTE_WOULD_CAUSE_MAX_SUPPLY_TO_BE_EXCEEDED: u32 = 0x0002004A; pub const ERR_FUNGIBLE_ASSET_FAUCET_IS_NOT_ORIGIN: u32 = 0x00020026; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ONE_MUST_BE_ZERO: u32 = 0x00020020; -pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_TWO_AND_THREE_MUST_BE_FUNGIBLE_FAUCET_ID: u32 = - 0x00020022; +pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_TWO_AND_THREE_MUST_BE_FUNGIBLE_FAUCET_ID: u32 = 0x00020022; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ZERO_MUST_BE_WITHIN_LIMITS: u32 = 0x00020023; pub const ERR_FUNGIBLE_ASSET_PROVIDED_FAUCET_ID_IS_INVALID: u32 = 0x0002004B; @@ -85,20 +83,16 @@ pub const ERR_P2ID_WRONG_NUMBER_OF_INPUTS: u32 = 0x00020050; pub const ERR_PROLOGUE_EXISTING_ACCOUNT_MUST_HAVE_NON_ZERO_NONCE: u32 = 0x0002003B; pub const ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT: u32 = 0x00020034; -pub const ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_NUMBER_COMMITMENT: u32 = - 0x00020134; +pub const ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_NUMBER_COMMITMENT: u32 = 0x00020134; pub const ERR_PROLOGUE_INPUT_NOTES_COMMITMENT_MISMATCH: u32 = 0x00020041; -pub const ERR_PROLOGUE_MISMATCH_OF_ACCOUNT_IDS_FROM_GLOBAL_INPUTS_AND_ADVICE_PROVIDER: u32 = - 0x0002003C; -pub const ERR_PROLOGUE_MISMATCH_OF_REFERENCE_BLOCK_MMR_AND_NOTE_AUTHENTICATION_MMR: u32 = - 0x0002003D; +pub const ERR_PROLOGUE_MISMATCH_OF_ACCOUNT_IDS_FROM_GLOBAL_INPUTS_AND_ADVICE_PROVIDER: u32 = 0x0002003C; +pub const ERR_PROLOGUE_MISMATCH_OF_REFERENCE_BLOCK_MMR_AND_NOTE_AUTHENTICATION_MMR: u32 = 0x0002003D; pub const ERR_PROLOGUE_NEW_ACCOUNT_NONCE_MUST_BE_ZERO: u32 = 0x0002005B; pub const ERR_PROLOGUE_NEW_ACCOUNT_VAULT_MUST_BE_EMPTY: u32 = 0x00020035; pub const ERR_PROLOGUE_NEW_FUNGIBLE_FAUCET_RESERVED_SLOT_INVALID_TYPE: u32 = 0x00020037; pub const ERR_PROLOGUE_NEW_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_EMPTY: u32 = 0x00020036; pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_INVALID_TYPE: u32 = 0x00020039; -pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_SMT: u32 = - 0x00020038; +pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_SMT: u32 = 0x00020038; pub const ERR_PROLOGUE_NUMBER_OF_INPUT_NOTES_EXCEEDS_LIMIT: u32 = 0x00020040; pub const ERR_PROLOGUE_NUMBER_OF_NOTE_ASSETS_EXCEEDS_LIMIT: u32 = 0x0002003E; pub const ERR_PROLOGUE_NUMBER_OF_NOTE_INPUTS_EXCEEDED_LIMIT: u32 = 0x0002004F; @@ -117,8 +111,7 @@ pub const ERR_VAULT_ADD_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID: u32 = 0x000 pub const ERR_VAULT_FUNGIBLE_ASSET_AMOUNT_LESS_THAN_AMOUNT_TO_WITHDRAW: u32 = 0x0002001D; pub const ERR_VAULT_FUNGIBLE_MAX_AMOUNT_EXCEEDED: u32 = 0x0002001A; pub const ERR_VAULT_GET_BALANCE_PROC_CAN_ONLY_BE_CALLED_ON_FUNGIBLE_FAUCET: u32 = 0x00020018; -pub const ERR_VAULT_HAS_NON_FUNGIBLE_ASSET_PROC_CAN_BE_CALLED_ONLY_WITH_NON_FUNGIBLE_ASSET: u32 = - 0x00020019; +pub const ERR_VAULT_HAS_NON_FUNGIBLE_ASSET_PROC_CAN_BE_CALLED_ONLY_WITH_NON_FUNGIBLE_ASSET: u32 = 0x00020019; pub const ERR_VAULT_NON_FUNGIBLE_ASSET_ALREADY_EXISTS: u32 = 0x0002001C; pub const ERR_VAULT_NON_FUNGIBLE_ASSET_TO_REMOVE_NOT_FOUND: u32 = 0x0002001F; pub const ERR_VAULT_REMOVE_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID: u32 = 0x0002001E; From 7cddb475b92209941d5ab1f7db554429fd588381 Mon Sep 17 00:00:00 2001 From: sergerad Date: Sat, 8 Feb 2025 14:19:49 +1300 Subject: [PATCH 09/10] markdown fmt --- docs/architecture/transactions/kernel.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/architecture/transactions/kernel.md b/docs/architecture/transactions/kernel.md index 6424ffc11..f6e55d1cf 100644 --- a/docs/architecture/transactions/kernel.md +++ b/docs/architecture/transactions/kernel.md @@ -7,7 +7,6 @@ The kernel provides context-sensitive security, preventing unwanted read and wri In general, the kernel's procedures must reflect everything users might want to do while executing transactions—from transferring assets to complex smart contract interactions with custom code. > **Info** -> > - Learn more about Miden transaction [procedures](procedures.md) and [contexts](contexts.md). The kernel has a well-defined structure which does the following: @@ -63,7 +62,6 @@ Reads data from the advice provider, stores it in memory, and computes the accou Processes input notes by reading data from advice providers and storing it in memory. It computes the note's hash and nullifier, forming a transaction nullifier commitment. > **Info** -> > - Note data is required for computing the nullifier (e.g., the [note script](../notes.md#main-script) and serial number). > - Note recipients define the set of users who can consume specific notes. @@ -86,7 +84,6 @@ end When processing a note, new note creation may be triggered, and information about the new note is stored in the output note data. > **Info** -> > - Notes can only call account interfaces to trigger write operations, preventing direct access to account storage. ## Transaction Script Processing @@ -104,7 +101,6 @@ end ``` > **Note** -> > - The account must expose the `auth_tx_rpo_falcon512` function for the transaction script to call it. ## Epilogue From 6fd1233989d8438b55543ac723e2b8d686ab8b05 Mon Sep 17 00:00:00 2001 From: sergerad Date: Sat, 8 Feb 2025 14:24:02 +1300 Subject: [PATCH 10/10] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f8f4f4b..ae5e4c23b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [BREAKING] Renamed `AccountData` to `AccountFile` (#1116). - Implement transaction batch prover in Rust (#1112). - [BREAKING] Refactored config file for `miden-proving-service` to be based on environment variables (#1120). +- Added block number as a public input to the transaction kernel. Updated prologue logic to validate the global input block number is consistent with the commitment block number (#1126). ## 0.7.2 (2025-01-28) - `miden-objects` crate only