Skip to content

Commit

Permalink
feat(tx): Include all errors in asm dir, group errors by category
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippGackstatter committed Oct 7, 2024
1 parent 3796c17 commit eab26e0
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 37 deletions.
12 changes: 6 additions & 6 deletions miden-lib/asm/kernels/transaction/lib/account.masm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions miden-lib/asm/kernels/transaction/lib/memory.masm
Original file line number Diff line number Diff line change
Expand Up @@ -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
# =================================================================================================
Expand Down Expand Up @@ -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.
Expand Down
16 changes: 8 additions & 8 deletions miden-lib/asm/kernels/transaction/lib/tx.masm
Original file line number Diff line number Diff line change
Expand Up @@ -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:
#
Expand Down Expand Up @@ -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
# =================================================================================================
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion miden-lib/asm/note_scripts/P2ID.masm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions miden-lib/asm/note_scripts/P2IDR.masm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
43 changes: 37 additions & 6 deletions miden-tx/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()> {
Expand All @@ -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(())
}
Expand Down Expand Up @@ -111,28 +109,61 @@ 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<String, (String, String)>) -> Result<String> {
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_<CATEGORY>_...`.
// 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
// ================================================================================================
"
)
.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()?;
}

Expand Down
Loading

0 comments on commit eab26e0

Please sign in to comment.