From eab26e082297d6f6331ad911b3c988e1b0603c64 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Mon, 7 Oct 2024 17:14:15 +0200 Subject: [PATCH] feat(tx): Include all errors in `asm` dir, group errors by category --- .../asm/kernels/transaction/lib/account.masm | 12 +-- .../asm/kernels/transaction/lib/memory.masm | 4 +- miden-lib/asm/kernels/transaction/lib/tx.masm | 16 ++-- miden-lib/asm/note_scripts/P2ID.masm | 2 +- miden-lib/asm/note_scripts/P2IDR.masm | 4 +- miden-tx/build.rs | 43 +++++++-- miden-tx/src/errors/tx_kernel_errors.rs | 91 +++++++++++++++++-- miden-tx/src/host/mod.rs | 4 +- miden-tx/src/lib.rs | 2 +- .../src/tests/kernel_tests/test_epilogue.rs | 4 +- 10 files changed, 145 insertions(+), 37 deletions(-) diff --git a/miden-lib/asm/kernels/transaction/lib/account.masm b/miden-lib/asm/kernels/transaction/lib/account.masm index aafe6f51f..93a70bfbe 100644 --- a/miden-lib/asm/kernels/transaction/lib/account.masm +++ b/miden-lib/asm/kernels/transaction/lib/account.masm @@ -29,16 +29,16 @@ const.ERR_ACCOUNT_SETTING_VALUE_ITEM_ON_NON_VALUE_SLOT=0x00020047 const.ERR_ACCOUNT_SETTING_MAP_ITEM_ON_NON_MAP_SLOT=0x00020048 # Account procedure is not part of the account code -const.ERR_PROC_NOT_PART_OF_ACCOUNT_CODE=0x0002004A +const.ERR_ACCOUNT_PROC_NOT_PART_OF_ACCOUNT_CODE=0x0002004A # Provided procedure index is out of bounds -const.ERR_PROC_INDEX_OUT_OF_BOUNDS=0x0002004B +const.ERR_ACCOUNT_PROC_INDEX_OUT_OF_BOUNDS=0x0002004B # Provided storage slot index is out of bounds const.ERR_STORAGE_SLOT_INDEX_OUT_OF_BOUNDS=0x0002004E # Storage offset is invalid for a faucet account (0 is prohibited as it is the reserved data slot for faucets) -const.ERR_INVALID_FAUCET_STORAGE_OFFSET=0x0002004F +const.ERR_FAUCET_INVALID_STORAGE_OFFSET=0x0002004F # Storage offset is invalid for 0 storage size (should be 0) const.ERR_INVALID_STORAGE_OFFSET_FOR_SIZE=0x00020056 @@ -359,7 +359,7 @@ export.validate_procedure_metadata # => [storage_offset, storage_size, index, num_storage_slots, num_account_procedures] # assert that storage offset is not 0 - dup push.0 neq assert.err=ERR_INVALID_FAUCET_STORAGE_OFFSET + dup push.0 neq assert.err=ERR_FAUCET_INVALID_STORAGE_OFFSET # => [storage_offset, storage_size, index, num_storage_slots, num_account_procedures] # TODO: This is a temporary check for faucets. We add 1 to all faucet offsets @@ -583,7 +583,7 @@ end #! - index is out of bounds export.get_procedure_info # check that index < number of procedures contained in the account code - dup exec.memory::get_num_account_procedures lt assert.err=ERR_PROC_INDEX_OUT_OF_BOUNDS + dup exec.memory::get_num_account_procedures lt assert.err=ERR_ACCOUNT_PROC_INDEX_OUT_OF_BOUNDS # => [index] # get procedure pointer @@ -621,7 +621,7 @@ export.authenticate_procedure # => [MEM_PROC_ROOT, storage_offset, storage_size, PROC_ROOT] # verify that PROC_ROOT exists in memory at index - movup.4 movdn.9 movup.4 movdn.9 assert_eqw.err=ERR_PROC_NOT_PART_OF_ACCOUNT_CODE + movup.4 movdn.9 movup.4 movdn.9 assert_eqw.err=ERR_ACCOUNT_PROC_NOT_PART_OF_ACCOUNT_CODE # => [storage_offset, storage_size] end diff --git a/miden-lib/asm/kernels/transaction/lib/memory.masm b/miden-lib/asm/kernels/transaction/lib/memory.masm index 4b7a56be8..6e1e889e6 100644 --- a/miden-lib/asm/kernels/transaction/lib/memory.masm +++ b/miden-lib/asm/kernels/transaction/lib/memory.masm @@ -7,7 +7,7 @@ use.kernel::constants const.ERR_NOTE_NUM_OF_ASSETS_EXCEED_LIMIT=0x0002002A # The current account is not native -const.ERR_CURRENT_ACCOUNT_IS_NOT_NATIVE=0x00020054 +const.ERR_ACCOUNT_IS_NOT_NATIVE=0x00020054 # MEMORY ADDRESS CONSTANTS # ================================================================================================= @@ -657,7 +657,7 @@ end export.assert_native_account push.CURRENT_ACCOUNT_DATA_PTR mem_load push.NATIVE_ACCOUNT_DATA_PTR - assert_eq.err=ERR_CURRENT_ACCOUNT_IS_NOT_NATIVE + assert_eq.err=ERR_ACCOUNT_IS_NOT_NATIVE end #! Returns a pointer to the end of the core account data section. diff --git a/miden-lib/asm/kernels/transaction/lib/tx.masm b/miden-lib/asm/kernels/transaction/lib/tx.masm index 219240314..630d52463 100644 --- a/miden-lib/asm/kernels/transaction/lib/tx.masm +++ b/miden-lib/asm/kernels/transaction/lib/tx.masm @@ -28,7 +28,7 @@ const.ALL_NOTE_TYPES_ALLOWED=3 # 0b11 const.ERR_TX_NUMBER_OF_OUTPUT_NOTES_EXCEEDS_LIMIT=0x00020020 # Invalid note type -const.ERR_INVALID_NOTE_TYPE=0x00020044 +const.ERR_NOTE_INVALID_TYPE=0x00020044 # The 2 highest bits in the u32 tag have the following meaning: # @@ -63,10 +63,10 @@ const.ERR_NOTE_FUNGIBLE_MAX_AMOUNT_EXCEEDED=0x00020050 const.ERR_NON_FUNGIBLE_ASSET_ALREADY_EXISTS=0x00020051 # Failed to find note at the given index; index must be within [0, num_of_notes] -const.ERR_INVALID_NOTE_IDX=0x00020052 +const.ERR_NOTE_INVALID_INDEX=0x00020052 -# Input transaction expiration block delta is not within 0x1 and 0xFFFF. -const.ERR_INVALID_TX_EXPIRATION_DELTA=0x00020055 +# Transaction expiration block delta must be within 0x1 and 0xFFFF. +const.ERR_TX_INVALID_EXPIRATION_DELTA=0x00020055 # EVENTS # ================================================================================================= @@ -198,8 +198,8 @@ end #! - block_height_delta is the desired expiration time delta (1 to 0xFFFF). export.update_expiration_block_num # Ensure block_height_delta is between 1 and 0xFFFF (inclusive) - dup neq.0 assert.err=ERR_INVALID_TX_EXPIRATION_DELTA - dup push.EXPIRY_UPPER_LIMIT lt assert.err=ERR_INVALID_TX_EXPIRATION_DELTA + dup neq.0 assert.err=ERR_TX_INVALID_EXPIRATION_DELTA + dup push.EXPIRY_UPPER_LIMIT lt assert.err=ERR_TX_INVALID_EXPIRATION_DELTA # => [block_height_delta] exec.get_block_number add @@ -316,7 +316,7 @@ end proc.build_note_metadata # validate the note type # NOTE: encrypted notes are currently unsupported - dup.2 push.PRIVATE_NOTE eq dup.3 push.PUBLIC_NOTE eq or assert.err=ERR_INVALID_NOTE_TYPE + dup.2 push.PRIVATE_NOTE eq dup.3 push.PUBLIC_NOTE eq or assert.err=ERR_NOTE_INVALID_TYPE # => [tag, aux, note_type, execution_hint] # copy data to validate the tag @@ -405,7 +405,7 @@ end #! - the total number of ASSETs exceeds the maximum of 256. export.add_asset_to_note # check if the note exists, it must be within [0, num_of_notes] - dup exec.memory::get_num_output_notes lte assert.err=ERR_INVALID_NOTE_IDX + dup exec.memory::get_num_output_notes lte assert.err=ERR_NOTE_INVALID_INDEX # => [note_idx, ASSET] # get a pointer to the memory address of the note at which the asset will be stored diff --git a/miden-lib/asm/note_scripts/P2ID.masm b/miden-lib/asm/note_scripts/P2ID.masm index 54e91e1d5..f00696d4b 100644 --- a/miden-lib/asm/note_scripts/P2ID.masm +++ b/miden-lib/asm/note_scripts/P2ID.masm @@ -5,7 +5,7 @@ use.miden::contracts::wallets::basic->wallet # ERRORS # ================================================================================================= -# P2ID scripts expect exactly 1 note input +# P2ID script expects exactly 1 note input const.ERR_P2ID_WRONG_NUMBER_OF_INPUTS=0x00020002 # P2ID's target account address and transaction address do not match diff --git a/miden-lib/asm/note_scripts/P2IDR.masm b/miden-lib/asm/note_scripts/P2IDR.masm index 5666c10bc..09945cda8 100644 --- a/miden-lib/asm/note_scripts/P2IDR.masm +++ b/miden-lib/asm/note_scripts/P2IDR.masm @@ -9,10 +9,10 @@ use.miden::contracts::wallets::basic->wallet # P2IDR scripts expect exactly 2 note inputs const.ERR_P2IDR_WRONG_NUMBER_OF_INPUTS=0x00020004 -# P2IDR's can only be reclaimed by the sender +# P2IDR's reclaimer is not the original sender const.ERR_P2IDR_RECLAIM_ACCT_IS_NOT_SENDER=0x00020005 -# Transaction's reference block is lower than reclaim height. The P2IDR can not be reclaimed +# P2IDR can not be reclaimed as the transaction's reference block is lower than the reclaim height const.ERR_P2IDR_RECLAIM_HEIGHT_NOT_REACHED=0x00020006 #! Helper procedure to add all assets of a note to an account. diff --git a/miden-tx/build.rs b/miden-tx/build.rs index 4ea8a6ca2..197e9657d 100644 --- a/miden-tx/build.rs +++ b/miden-tx/build.rs @@ -8,7 +8,6 @@ use regex::Regex; use walkdir::WalkDir; const ASM_DIR: &str = "../miden-lib/asm"; -const ASM_TX_KERNEL_DIR: &str = "kernels/transaction"; const KERNEL_ERRORS_FILE: &str = "src/errors/tx_kernel_errors.rs"; fn main() -> Result<()> { @@ -19,10 +18,9 @@ fn main() -> Result<()> { // Copies the MASM code to the build directory let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let asm_dir = Path::new(&crate_dir).join(ASM_DIR); - let kernel_directory = asm_dir.join(ASM_TX_KERNEL_DIR); // Generate kernel error constants. - generate_kernel_error_constants(&kernel_directory)?; + generate_kernel_error_constants(&asm_dir)?; Ok(()) } @@ -111,12 +109,35 @@ fn extract_kernel_errors( Ok(()) } +fn is_new_error_category<'a>(last_error: &mut Option<&'a str>, current_error: &'a str) -> bool { + let is_new = match last_error { + Some(last_err) => { + let last_category = + last_err.split("_").next().expect("there should be at least one entry"); + let new_category = + current_error.split("_").next().expect("there should be at least one entry"); + last_category != new_category + }, + None => false, + }; + + last_error.replace(current_error); + + is_new +} + fn generate_kernel_errors(errors: BTreeMap) -> Result { let mut output = String::new(); writeln!( output, - "// This file is generated by build.rs, do not modify. + "// This file is generated by build.rs, do not modify manually. +// It is generated by extracting errors from the masm files in the `miden-lib/asm` directory. +// +// To add a new error, define a constant in masm of the pattern `const.ERR__...`. +// Try to fit the error into a pre-existing category if possible (e.g. Account, Prologue, Non-Fungible-Asset, ...). +// +// The comment directly above the constant will be interpreted as the error message for that error. // KERNEL ASSERTION ERROR // ================================================================================================ @@ -124,15 +145,25 @@ fn generate_kernel_errors(errors: BTreeMap) -> Result< ) .into_diagnostic()?; + let mut last_error = None; for (error_name, (error_code, _)) in errors.iter() { + // Group errors into blocks separate by newlines. + if is_new_error_category(&mut last_error, error_name) { + writeln!(output).into_diagnostic()?; + } writeln!(output, "pub const ERR_{error_name}: u32 = 0x{error_code};").into_diagnostic()?; } writeln!(output).into_diagnostic()?; - writeln!(output, "pub const KERNEL_ERRORS: [(u32, &str); {}] = [", errors.len()) + writeln!(output, "pub const VM_ERRORS: [(u32, &str); {}] = [", errors.len()) .into_diagnostic()?; - for (error_name, (_, error_message)) in errors { + let mut last_error = None; + for (error_name, (_, error_message)) in errors.iter() { + // Group errors into blocks separate by newlines. + if is_new_error_category(&mut last_error, error_name) { + writeln!(output).into_diagnostic()?; + } writeln!(output, r#" (ERR_{error_name}, "{error_message}"),"#).into_diagnostic()?; } diff --git a/miden-tx/src/errors/tx_kernel_errors.rs b/miden-tx/src/errors/tx_kernel_errors.rs index a529b1362..710a30f22 100644 --- a/miden-tx/src/errors/tx_kernel_errors.rs +++ b/miden-tx/src/errors/tx_kernel_errors.rs @@ -1,4 +1,11 @@ -// This file is generated by build.rs, do not modify. +// This file is generated by build.rs, do not modify manually. +// It is generated by extracting errors from the masm files in the `miden-lib/asm` directory. +// +// To add a new error, define a constant in masm of the pattern `const.ERR__...`. +// Try to fit the error into a pre-existing category if possible (e.g. Account, Prologue, +// Non-Fungible-Asset, ...). +// +// The comment directly above the constant will be interpreted as the error message for that error. // KERNEL ASSERTION ERROR // ================================================================================================ @@ -6,9 +13,12 @@ pub const ERR_ACCOUNT_CODE_COMMITMENT_MISMATCH: u32 = 0x0002004c; pub const ERR_ACCOUNT_CODE_IS_NOT_UPDATABLE: u32 = 0x0002003d; pub const ERR_ACCOUNT_INSUFFICIENT_NUMBER_OF_ONES: u32 = 0x0002003c; +pub const ERR_ACCOUNT_IS_NOT_NATIVE: u32 = 0x00020054; pub const ERR_ACCOUNT_NONCE_DID_NOT_INCREASE_AFTER_STATE_CHANGE: u32 = 0x00020009; pub const ERR_ACCOUNT_NONCE_INCREASE_MUST_BE_U32: u32 = 0x0002003b; pub const ERR_ACCOUNT_POW_IS_INSUFFICIENT: u32 = 0x0002003f; +pub const ERR_ACCOUNT_PROC_INDEX_OUT_OF_BOUNDS: u32 = 0x0002004b; +pub const ERR_ACCOUNT_PROC_NOT_PART_OF_ACCOUNT_CODE: u32 = 0x0002004a; pub const ERR_ACCOUNT_READING_MAP_VALUE_FROM_NON_MAP_SLOT: u32 = 0x00020049; pub const ERR_ACCOUNT_SEED_DIGEST_MISMATCH: u32 = 0x0002003e; pub const ERR_ACCOUNT_SETTING_MAP_ITEM_ON_NON_MAP_SLOT: u32 = 0x00020048; @@ -17,39 +27,61 @@ pub const ERR_ACCOUNT_STORAGE_COMMITMENT_MISMATCH: u32 = 0x00020050; pub const ERR_ACCOUNT_TOO_MANY_PROCEDURES: u32 = 0x0002004d; pub const ERR_ACCOUNT_TOO_MANY_STORAGE_SLOTS: u32 = 0x0002004f; pub const ERR_ACCOUNT_TOTAL_ISSUANCE_PROC_CAN_ONLY_BE_CALLED_ON_FUNGIBLE_FAUCET: u32 = 0x00020001; -pub const ERR_CURRENT_ACCOUNT_IS_NOT_NATIVE: u32 = 0x00020054; + pub const ERR_EPILOGUE_TOTAL_NUMBER_OF_ASSETS_MUST_STAY_THE_SAME: u32 = 0x0002000a; + pub const ERR_FAUCET_BURN_CANNOT_EXCEED_EXISTING_TOTAL_SUPPLY: u32 = 0x00020023; pub const ERR_FAUCET_BURN_NON_FUNGIBLE_ASSET_CAN_ONLY_BE_CALLED_ON_NON_FUNGIBLE_FAUCET: u32 = 0x00020025; +pub const ERR_FAUCET_INVALID_STORAGE_OFFSET: u32 = 0x0002004f; pub const ERR_FAUCET_NEW_TOTAL_SUPPLY_WOULD_EXCEED_MAX_ASSET_AMOUNT: u32 = 0x00020022; pub const ERR_FAUCET_NON_FUNGIBLE_ASSET_ALREADY_ISSUED: u32 = 0x00020024; pub const ERR_FAUCET_NON_FUNGIBLE_ASSET_TO_BURN_NOT_FOUND: u32 = 0x00020026; pub const ERR_FAUCET_STORAGE_DATA_SLOT_IS_RESERVED: u32 = 0x00020000; + +pub const ERR_FUNGIBLE_ASSET_AMOUNT_EXCEEDS_MAX_ALLOWED_AMOUNT: u32 = 0x00020042; +pub const ERR_FUNGIBLE_ASSET_DISTRIBUTE_WOULD_CAUSE_MAX_SUPPLY_TO_BE_EXCEEDED: u32 = 0x00020021; pub const ERR_FUNGIBLE_ASSET_FAUCET_IS_NOT_ORIGIN: u32 = 0x00020039; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ONE_MUST_BE_ZERO: u32 = 0x00020033; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_THREE_MUST_BE_FUNGIBLE_FAUCET_ID: u32 = 0x00020035; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_TWO_MUST_BE_ZERO: u32 = 0x00020034; pub const ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ZERO_MUST_BE_WITHIN_LIMITS: u32 = 0x00020036; +<<<<<<< HEAD pub const ERR_INVALID_FAUCET_STORAGE_OFFSET: u32 = 0x0002004f; pub const ERR_INVALID_NOTE_IDX: u32 = 0x00020052; pub const ERR_INVALID_NOTE_TYPE: u32 = 0x00020044; pub const ERR_INVALID_STORAGE_OFFSET_FOR_SIZE: u32 = 0x00020056; pub const ERR_INVALID_TX_EXPIRATION_DELTA: u32 = 0x00020055; +======= +pub const ERR_FUNGIBLE_ASSET_PROVIDED_FAUCET_ID_IS_INVALID: u32 = 0x00020041; + +>>>>>>> 6acc61a (feat(tx): Include all errors in `asm` dir, group errors by category) pub const ERR_KERNEL_PROCEDURE_OFFSET_OUT_OF_BOUNDS: u32 = 0x00020053; + pub const ERR_NON_FUNGIBLE_ASSET_ALREADY_EXISTS: u32 = 0x00020051; pub const ERR_NON_FUNGIBLE_ASSET_FAUCET_IS_NOT_ORIGIN: u32 = 0x0002003a; pub const ERR_NON_FUNGIBLE_ASSET_FORMAT_ELEMENT_ONE_MUST_BE_FUNGIBLE_FAUCET_ID: u32 = 0x00020037; pub const ERR_NON_FUNGIBLE_ASSET_FORMAT_MOST_SIGNIFICANT_BIT_MUST_BE_ZERO: u32 = 0x00020038; +pub const ERR_NON_FUNGIBLE_ASSET_PROVIDED_FAUCET_ID_IS_INVALID: u32 = 0x00020043; + pub const ERR_NOTE_ATTEMPT_TO_ACCESS_NOTE_ASSETS_FROM_INCORRECT_CONTEXT: u32 = 0x00020028; pub const ERR_NOTE_ATTEMPT_TO_ACCESS_NOTE_INPUTS_FROM_INCORRECT_CONTEXT: u32 = 0x00020029; pub const ERR_NOTE_ATTEMPT_TO_ACCESS_NOTE_SENDER_FROM_INCORRECT_CONTEXT: u32 = 0x00020027; +pub const ERR_NOTE_DATA_DOES_NOT_MATCH_COMMITMENT: u32 = 0x00020040; pub const ERR_NOTE_FUNGIBLE_MAX_AMOUNT_EXCEEDED: u32 = 0x00020050; +pub const ERR_NOTE_INVALID_INDEX: u32 = 0x00020052; pub const ERR_NOTE_INVALID_NOTE_TYPE_FOR_NOTE_TAG_PREFIX: u32 = 0x00020045; +pub const ERR_NOTE_INVALID_TYPE: u32 = 0x00020044; pub const ERR_NOTE_NUM_OF_ASSETS_EXCEED_LIMIT: u32 = 0x0002002a; pub const ERR_NOTE_TAG_MUST_BE_U32: u32 = 0x00020046; -pub const ERR_PROC_INDEX_OUT_OF_BOUNDS: u32 = 0x0002004b; -pub const ERR_PROC_NOT_PART_OF_ACCOUNT_CODE: u32 = 0x0002004a; + +pub const ERR_P2IDR_RECLAIM_ACCT_IS_NOT_SENDER: u32 = 0x00020005; +pub const ERR_P2IDR_RECLAIM_HEIGHT_NOT_REACHED: u32 = 0x00020006; +pub const ERR_P2IDR_WRONG_NUMBER_OF_INPUTS: u32 = 0x00020004; + +pub const ERR_P2ID_TARGET_ACCT_MISMATCH: u32 = 0x00020003; +pub const ERR_P2ID_WRONG_NUMBER_OF_INPUTS: u32 = 0x00020002; + pub const ERR_PROLOGUE_EXISTING_ACCOUNT_MUST_HAVE_NON_ZERO_NONCE: u32 = 0x00020018; pub const ERR_PROLOGUE_GLOBAL_INPUTS_PROVIDED_DO_NOT_MATCH_BLOCK_HASH_COMMITMENT: u32 = 0x0002000b; pub const ERR_PROLOGUE_INPUT_NOTES_COMMITMENT_MISMATCH: u32 = 0x0002001f; @@ -65,10 +97,18 @@ pub const ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_ 0x00020014; pub const ERR_PROLOGUE_NUMBER_OF_INPUT_NOTES_EXCEEDS_LIMIT: u32 = 0x0002001e; pub const ERR_PROLOGUE_NUMBER_OF_NOTE_ASSETS_EXCEEDS_LIMIT: u32 = 0x0002001c; +pub const ERR_PROLOGUE_NUMBER_OF_NOTE_INPUTS_EXCEEDED_LIMIT: u32 = 0x0002001b; pub const ERR_PROLOGUE_PROVIDED_ACCOUNT_DATA_DOES_NOT_MATCH_ON_CHAIN_COMMITMENT: u32 = 0x00020017; pub const ERR_PROLOGUE_PROVIDED_INPUT_ASSETS_INFO_DOES_NOT_MATCH_ITS_COMMITMENT: u32 = 0x0002001d; + pub const ERR_STORAGE_SLOT_INDEX_OUT_OF_BOUNDS: u32 = 0x0002004e; + +pub const ERR_SWAP_WRONG_NUMBER_OF_ASSETS: u32 = 0x00020008; +pub const ERR_SWAP_WRONG_NUMBER_OF_INPUTS: u32 = 0x00020007; + +pub const ERR_TX_INVALID_EXPIRATION_DELTA: u32 = 0x00020055; pub const ERR_TX_NUMBER_OF_OUTPUT_NOTES_EXCEEDS_LIMIT: u32 = 0x00020020; + pub const ERR_VAULT_ADD_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID: u32 = 0x0002002e; pub const ERR_VAULT_FUNGIBLE_ASSET_AMOUNT_LESS_THAN_AMOUNT_TO_WITHDRAW: u32 = 0x00020030; pub const ERR_VAULT_FUNGIBLE_MAX_AMOUNT_EXCEEDED: u32 = 0x0002002d; @@ -79,13 +119,20 @@ pub const ERR_VAULT_NON_FUNGIBLE_ASSET_ALREADY_EXISTS: u32 = 0x0002002f; pub const ERR_VAULT_NON_FUNGIBLE_ASSET_TO_REMOVE_NOT_FOUND: u32 = 0x00020032; pub const ERR_VAULT_REMOVE_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID: u32 = 0x00020031; +<<<<<<< HEAD pub const KERNEL_ERRORS: [(u32, &str); 70] = [ +======= +pub const VM_ERRORS: [(u32, &str); 82] = [ +>>>>>>> 6acc61a (feat(tx): Include all errors in `asm` dir, group errors by category) (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"), (ERR_ACCOUNT_INSUFFICIENT_NUMBER_OF_ONES, "Account ID must contain at least MIN_ACCOUNT_ONES number of ones"), + (ERR_ACCOUNT_IS_NOT_NATIVE, "The current account is not native"), (ERR_ACCOUNT_NONCE_DID_NOT_INCREASE_AFTER_STATE_CHANGE, "Account nonce did not increase after a state changing transaction"), (ERR_ACCOUNT_NONCE_INCREASE_MUST_BE_U32, "Account nonce cannot be increased by a greater than u32 value"), (ERR_ACCOUNT_POW_IS_INSUFFICIENT, "Account proof of work is insufficient"), + (ERR_ACCOUNT_PROC_INDEX_OUT_OF_BOUNDS, "Provided procedure index is out of bounds"), + (ERR_ACCOUNT_PROC_NOT_PART_OF_ACCOUNT_CODE, "Account procedure is not part of the account code"), (ERR_ACCOUNT_READING_MAP_VALUE_FROM_NON_MAP_SLOT, "Failed to read an account map item from a non-map storage slot"), (ERR_ACCOUNT_SEED_DIGEST_MISMATCH, "ID of the new account does not match the ID computed from the seed"), (ERR_ACCOUNT_SETTING_MAP_ITEM_ON_NON_MAP_SLOT, "Failed to write an account map item to a non-map storage slot"), @@ -94,38 +141,60 @@ pub const KERNEL_ERRORS: [(u32, &str); 70] = [ (ERR_ACCOUNT_TOO_MANY_PROCEDURES, "Number of account procedures exceeds the maximum limit of 256"), (ERR_ACCOUNT_TOO_MANY_STORAGE_SLOTS, "Number of account storage slots exceeds the maximum limit of 255"), (ERR_ACCOUNT_TOTAL_ISSUANCE_PROC_CAN_ONLY_BE_CALLED_ON_FUNGIBLE_FAUCET, "The get_fungible_faucet_total_issuance procedure can only be called on a fungible faucet"), - (ERR_CURRENT_ACCOUNT_IS_NOT_NATIVE, "The current account is not native"), + (ERR_EPILOGUE_TOTAL_NUMBER_OF_ASSETS_MUST_STAY_THE_SAME, "Total number of assets in the account and all involved notes must stay the same"), + (ERR_FAUCET_BURN_CANNOT_EXCEED_EXISTING_TOTAL_SUPPLY, "Asset amount to burn can not exceed the existing total supply"), (ERR_FAUCET_BURN_NON_FUNGIBLE_ASSET_CAN_ONLY_BE_CALLED_ON_NON_FUNGIBLE_FAUCET, "The burn_non_fungible_asset procedure can only be called on a non-fungible faucet"), + (ERR_FAUCET_INVALID_STORAGE_OFFSET, "Storage offset is invalid for a faucet account (0 is prohibited as it is the reserved data slot for faucets)"), (ERR_FAUCET_NEW_TOTAL_SUPPLY_WOULD_EXCEED_MAX_ASSET_AMOUNT, "Asset mint operation would cause the new total supply to exceed the maximum allowed asset amount"), (ERR_FAUCET_NON_FUNGIBLE_ASSET_ALREADY_ISSUED, "Failed to mint new non-fungible asset because it was already issued"), (ERR_FAUCET_NON_FUNGIBLE_ASSET_TO_BURN_NOT_FOUND, "Failed to burn non-existent non-fungible asset in the vault"), (ERR_FAUCET_STORAGE_DATA_SLOT_IS_RESERVED, "For faucets the FAUCET_STORAGE_DATA_SLOT storage slot is reserved and can not be used with set_account_item"), + + (ERR_FUNGIBLE_ASSET_AMOUNT_EXCEEDS_MAX_ALLOWED_AMOUNT, "Fungible asset build operation called with amount that exceeds the maximum allowed asset amount"), + (ERR_FUNGIBLE_ASSET_DISTRIBUTE_WOULD_CAUSE_MAX_SUPPLY_TO_BE_EXCEEDED, "Distribute would cause the maximum supply to be exceeded"), (ERR_FUNGIBLE_ASSET_FAUCET_IS_NOT_ORIGIN, "The origin of the fungible asset is not this faucet"), (ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ONE_MUST_BE_ZERO, "Malformed fungible asset: ASSET[1] must be 0"), (ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_THREE_MUST_BE_FUNGIBLE_FAUCET_ID, "Malformed fungible asset: ASSET[3] must be a valide fungible faucet id"), (ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_TWO_MUST_BE_ZERO, "Malformed fungible asset: ASSET[2] must be 0"), (ERR_FUNGIBLE_ASSET_FORMAT_ELEMENT_ZERO_MUST_BE_WITHIN_LIMITS, "Malformed fungible asset: ASSET[0] exceeds the maximum allowed amount"), +<<<<<<< HEAD (ERR_INVALID_FAUCET_STORAGE_OFFSET, "Storage offset is invalid for a faucet account (0 is prohibited as it is the reserved data slot for faucets)"), (ERR_INVALID_NOTE_IDX, "Failed to find note at the given index; index must be within [0, num_of_notes]"), (ERR_INVALID_NOTE_TYPE, "Invalid note type"), (ERR_INVALID_STORAGE_OFFSET_FOR_SIZE, "Storage offset is invalid for 0 storage size (should be 0)"), (ERR_INVALID_TX_EXPIRATION_DELTA, "Input transaction expiration block delta is not within 0x1 and 0xFFFF."), +======= + (ERR_FUNGIBLE_ASSET_PROVIDED_FAUCET_ID_IS_INVALID, "Failed to build the fungible asset because the provided faucet id is not from a fungible faucet"), + +>>>>>>> 6acc61a (feat(tx): Include all errors in `asm` dir, group errors by category) (ERR_KERNEL_PROCEDURE_OFFSET_OUT_OF_BOUNDS, "Provided kernel procedure offset is out of bounds"), + (ERR_NON_FUNGIBLE_ASSET_ALREADY_EXISTS, "Non-fungible asset that already exists in the note cannot be added again"), (ERR_NON_FUNGIBLE_ASSET_FAUCET_IS_NOT_ORIGIN, "The origin of the non-fungible asset is not this faucet"), (ERR_NON_FUNGIBLE_ASSET_FORMAT_ELEMENT_ONE_MUST_BE_FUNGIBLE_FAUCET_ID, "Malformed non-fungible asset: ASSET[1] is not a valid non-fungible faucet id"), (ERR_NON_FUNGIBLE_ASSET_FORMAT_MOST_SIGNIFICANT_BIT_MUST_BE_ZERO, "Malformed non-fungible asset: the most significant bit must be 0"), + (ERR_NON_FUNGIBLE_ASSET_PROVIDED_FAUCET_ID_IS_INVALID, "Failed to build the non-fungible asset because the provided faucet id is not from a non-fungible faucet"), + (ERR_NOTE_ATTEMPT_TO_ACCESS_NOTE_ASSETS_FROM_INCORRECT_CONTEXT, "Attempted to access note assets from incorrect context"), (ERR_NOTE_ATTEMPT_TO_ACCESS_NOTE_INPUTS_FROM_INCORRECT_CONTEXT, "Attempted to access note inputs from incorrect context"), (ERR_NOTE_ATTEMPT_TO_ACCESS_NOTE_SENDER_FROM_INCORRECT_CONTEXT, "Attempted to access note sender from incorrect context"), + (ERR_NOTE_DATA_DOES_NOT_MATCH_COMMITMENT, "Note data does not match the commitment"), (ERR_NOTE_FUNGIBLE_MAX_AMOUNT_EXCEEDED, "Adding a fungible asset to a note cannot exceed the max_amount of 9223372036854775807"), + (ERR_NOTE_INVALID_INDEX, "Failed to find note at the given index; index must be within [0, num_of_notes]"), (ERR_NOTE_INVALID_NOTE_TYPE_FOR_NOTE_TAG_PREFIX, "Invalid note type for the given note tag prefix"), + (ERR_NOTE_INVALID_TYPE, "Invalid note type"), (ERR_NOTE_NUM_OF_ASSETS_EXCEED_LIMIT, "Number of assets in a note exceed 255"), (ERR_NOTE_TAG_MUST_BE_U32, "The note's tag must fit into a u32 so the 32 most significant bits must be zero."), - (ERR_PROC_INDEX_OUT_OF_BOUNDS, "Provided procedure index is out of bounds"), - (ERR_PROC_NOT_PART_OF_ACCOUNT_CODE, "Account procedure is not part of the account code"), + + (ERR_P2IDR_RECLAIM_ACCT_IS_NOT_SENDER, "P2IDR's reclaimer is not the original sender"), + (ERR_P2IDR_RECLAIM_HEIGHT_NOT_REACHED, "P2IDR can not be reclaimed as the transaction's reference block is lower than the reclaim height"), + (ERR_P2IDR_WRONG_NUMBER_OF_INPUTS, "P2IDR scripts expect exactly 2 note inputs"), + + (ERR_P2ID_TARGET_ACCT_MISMATCH, "P2ID's target account address and transaction address do not match"), + (ERR_P2ID_WRONG_NUMBER_OF_INPUTS, "P2ID script expects exactly 1 note input"), + (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_INPUT_NOTES_COMMITMENT_MISMATCH, "Note commitment computed from the input note data does not match given note commitment"), @@ -138,10 +207,18 @@ pub const KERNEL_ERRORS: [(u32, &str); 70] = [ (ERR_PROLOGUE_NEW_NON_FUNGIBLE_FAUCET_RESERVED_SLOT_MUST_BE_VALID_EMPY_SMT, "Reserved slot for non-fungible faucet is not a valid empty SMT"), (ERR_PROLOGUE_NUMBER_OF_INPUT_NOTES_EXCEEDS_LIMIT, "Number of input notes exceeds the kernel's maximum limit of 1024"), (ERR_PROLOGUE_NUMBER_OF_NOTE_ASSETS_EXCEEDS_LIMIT, "Number of note assets exceeds the maximum limit of 256"), + (ERR_PROLOGUE_NUMBER_OF_NOTE_INPUTS_EXCEEDED_LIMIT, "Number of note inputs exceeded the maximum limit of 128"), (ERR_PROLOGUE_PROVIDED_ACCOUNT_DATA_DOES_NOT_MATCH_ON_CHAIN_COMMITMENT, "Account data provided does not match the commitment recorded on-chain"), (ERR_PROLOGUE_PROVIDED_INPUT_ASSETS_INFO_DOES_NOT_MATCH_ITS_COMMITMENT, "Provided info about assets of an input does not match its commitment"), + (ERR_STORAGE_SLOT_INDEX_OUT_OF_BOUNDS, "Provided storage slot index is out of bounds"), + + (ERR_SWAP_WRONG_NUMBER_OF_ASSETS, "SWAP script requires exactly 1 note asset"), + (ERR_SWAP_WRONG_NUMBER_OF_INPUTS, "SWAP script expects exactly 10 note inputs"), + + (ERR_TX_INVALID_EXPIRATION_DELTA, "Transaction expiration block delta must be within 0x1 and 0xFFFF."), (ERR_TX_NUMBER_OF_OUTPUT_NOTES_EXCEEDS_LIMIT, "Number of output notes in the transaction exceeds the maximum limit of 1024"), + (ERR_VAULT_ADD_FUNGIBLE_ASSET_FAILED_INITIAL_VALUE_INVALID, "Failed to add fungible asset to the asset vault due to the initial value being invalid"), (ERR_VAULT_FUNGIBLE_ASSET_AMOUNT_LESS_THAN_AMOUNT_TO_WITHDRAW, "Failed to remove the fungible asset from the vault since the amount of the asset in the vault is less than the amount to remove"), (ERR_VAULT_FUNGIBLE_MAX_AMOUNT_EXCEEDED, "Adding the fungible asset to the vault would exceed the max amount of 9223372036854775807"), diff --git a/miden-tx/src/host/mod.rs b/miden-tx/src/host/mod.rs index 553bdbc93..7e3925c62 100644 --- a/miden-tx/src/host/mod.rs +++ b/miden-tx/src/host/mod.rs @@ -31,7 +31,7 @@ pub use tx_progress::TransactionProgress; use crate::{ auth::TransactionAuthenticator, errors::TransactionHostError, executor::TransactionMastStore, - KERNEL_ERRORS, + VM_ERRORS, }; // TRANSACTION HOST @@ -95,7 +95,7 @@ impl TransactionHost { ) -> Result { let proc_index_map = AccountProcedureIndexMap::new(account.code_commitment(), &adv_provider)?; - let kernel_assertion_errors = BTreeMap::from(KERNEL_ERRORS); + let kernel_assertion_errors = BTreeMap::from(VM_ERRORS); Ok(Self { adv_provider, mast_store, diff --git a/miden-tx/src/lib.rs b/miden-tx/src/lib.rs index 94f547642..edb5ddef8 100644 --- a/miden-tx/src/lib.rs +++ b/miden-tx/src/lib.rs @@ -22,7 +22,7 @@ pub use verifier::TransactionVerifier; mod errors; pub use errors::{ - tx_kernel_errors::KERNEL_ERRORS, AuthenticationError, DataStoreError, TransactionExecutorError, + tx_kernel_errors::VM_ERRORS, AuthenticationError, DataStoreError, TransactionExecutorError, TransactionProverError, TransactionVerifierError, }; diff --git a/miden-tx/src/tests/kernel_tests/test_epilogue.rs b/miden-tx/src/tests/kernel_tests/test_epilogue.rs index 03f8da2a9..58ab507be 100644 --- a/miden-tx/src/tests/kernel_tests/test_epilogue.rs +++ b/miden-tx/src/tests/kernel_tests/test_epilogue.rs @@ -15,7 +15,7 @@ use crate::{ assert_execution_error, errors::tx_kernel_errors::{ ERR_ACCOUNT_NONCE_DID_NOT_INCREASE_AFTER_STATE_CHANGE, - ERR_EPILOGUE_TOTAL_NUMBER_OF_ASSETS_MUST_STAY_THE_SAME, ERR_INVALID_TX_EXPIRATION_DELTA, + ERR_EPILOGUE_TOTAL_NUMBER_OF_ASSETS_MUST_STAY_THE_SAME, ERR_TX_INVALID_EXPIRATION_DELTA, }, testing::TransactionContextBuilder, tests::kernel_tests::read_root_mem_value, @@ -251,7 +251,7 @@ fn test_invalid_expiration_deltas() { let code = &code_template.replace("{value_1}", &value.to_string()); let process = tx_context.execute_code(code); - assert_execution_error!(process, ERR_INVALID_TX_EXPIRATION_DELTA); + assert_execution_error!(process, ERR_TX_INVALID_EXPIRATION_DELTA); } }