From 47fac8e35b6d408dee568c2bf19f5cb8a0004454 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 19 Mar 2023 22:35:53 -0700 Subject: [PATCH] Couple fixes & minor refactor --- evm/src/cpu/kernel/aggregator.rs | 1 + evm/src/cpu/kernel/asm/core/gas.asm | 49 +++++++++++++++++++ evm/src/cpu/kernel/asm/core/syscall_stubs.asm | 10 ---- evm/src/cpu/kernel/asm/core/terminate.asm | 2 +- .../kernel/asm/curve/secp256k1/ecrecover.asm | 14 +----- evm/src/cpu/kernel/asm/memory/metadata.asm | 13 +++++ evm/src/cpu/kernel/asm/memory/syscalls.asm | 6 +++ evm/src/cpu/kernel/asm/util/basic_macros.asm | 25 ---------- evm/src/cpu/kernel/asm/util/keccak.asm | 18 +++++++ 9 files changed, 89 insertions(+), 49 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/core/gas.asm diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 80dd9392..34e3ce43 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -17,6 +17,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/core/call.asm"), include_str!("asm/core/create.asm"), include_str!("asm/core/create_addresses.asm"), + include_str!("asm/core/gas.asm"), include_str!("asm/core/intrinsic_gas.asm"), include_str!("asm/core/invalid.asm"), include_str!("asm/core/jumpdest_analysis.asm"), diff --git a/evm/src/cpu/kernel/asm/core/gas.asm b/evm/src/cpu/kernel/asm/core/gas.asm new file mode 100644 index 00000000..0cc62e4a --- /dev/null +++ b/evm/src/cpu/kernel/asm/core/gas.asm @@ -0,0 +1,49 @@ +global sys_gas: + // stack: kexit_info + %charge_gas_const(@GAS_BASE) + // stack: kexit_info + DUP1 %shr_const(192) + // stack: gas_used, kexit_info + %ctx_gas_limit + // stack: gas_limit, gas_used, kexit_info + SUB + // stack: gas_remaining, kexit_info + SWAP1 + EXIT_KERNEL + +%macro ctx_gas_limit + %mload_context_metadata(@CTX_METADATA_GAS_LIMIT) +%endmacro + +// Charge gas. Faults if we exceed the limit for the current context. +%macro charge_gas + // stack: gas, kexit_info + %shl_const(192) + ADD + // stack: kexit_info' + %ctx_gas_limit + // stack: gas_limit, kexit_info' + DUP2 %shr_const(192) + // stack: gas_used, gas_limit, kexit_info' + GT + // stack: out_of_gas, kexit_info' + %jumpi(fault_exception) + // stack: kexit_info' +%endmacro + +// Charge a constant amount of gas. +%macro charge_gas_const(gas) + // stack: kexit_info + PUSH $gas + // stack: gas, kexit_info + %charge_gas + // stack: kexit_info' +%endmacro + +// Charge gas and exit kernel code. +%macro charge_gas_and_exit + // stack: gas, kexit_info + %charge_gas + // stack: kexit_info' + EXIT_KERNEL +%endmacro diff --git a/evm/src/cpu/kernel/asm/core/syscall_stubs.asm b/evm/src/cpu/kernel/asm/core/syscall_stubs.asm index d7f29081..624bd9c6 100644 --- a/evm/src/cpu/kernel/asm/core/syscall_stubs.asm +++ b/evm/src/cpu/kernel/asm/core/syscall_stubs.asm @@ -60,16 +60,6 @@ global sys_selfbalance: PANIC global sys_basefee: PANIC -global sys_gas: - // stack: kexit_info - DUP1 %shr_const(192) - // stack: gas_used, kexit_info - %mload_context_metadata(@CTX_METADATA_GAS_LIMIT) - // stack: gas_limit, gas_used, kexit_info - SUB - // stack: gas_remaining, kexit_info - SWAP1 - EXIT_KERNEL global sys_log0: PANIC global sys_log1: diff --git a/evm/src/cpu/kernel/asm/core/terminate.asm b/evm/src/cpu/kernel/asm/core/terminate.asm index 341884ea..98c65253 100644 --- a/evm/src/cpu/kernel/asm/core/terminate.asm +++ b/evm/src/cpu/kernel/asm/core/terminate.asm @@ -37,7 +37,7 @@ global sys_revert: PUSH 0 // success %jump(terminate_common) -// The execution is in an exceptional halt-ing state if +// The execution is in an exceptional halting state if // - there is insufficient gas // - the instruction is invalid // - there are insufficient stack items diff --git a/evm/src/cpu/kernel/asm/curve/secp256k1/ecrecover.asm b/evm/src/cpu/kernel/asm/curve/secp256k1/ecrecover.asm index 11ec27c8..6e9df123 100644 --- a/evm/src/cpu/kernel/asm/curve/secp256k1/ecrecover.asm +++ b/evm/src/cpu/kernel/asm/curve/secp256k1/ecrecover.asm @@ -106,19 +106,7 @@ ecdsa_after_precompute_loop_end: // Take a public key (PKx, PKy) and return the associated address KECCAK256(PKx || PKy)[-20:]. pubkey_to_addr: // stack: PKx, PKy, retdest - PUSH 0 - // stack: 0, PKx, PKy, retdest - MSTORE // TODO: switch to kernel memory (like `%mstore_kernel(@SEGMENT_KERNEL_GENERAL)`). - // stack: PKy, retdest - PUSH 0x20 - // stack: 0x20, PKy, retdest - MSTORE - // stack: retdest - PUSH 0x40 - // stack: 0x40, retdest - PUSH 0 - // stack: 0, 0x40, retdest - KECCAK256 + %keccak256_u256_pair // stack: hash, retdest PUSH 0xffffffffffffffffffffffffffffffffffffffff // stack: 2^160-1, hash, retdest diff --git a/evm/src/cpu/kernel/asm/memory/metadata.asm b/evm/src/cpu/kernel/asm/memory/metadata.asm index 9b9ce7c2..55c8bebc 100644 --- a/evm/src/cpu/kernel/asm/memory/metadata.asm +++ b/evm/src/cpu/kernel/asm/memory/metadata.asm @@ -147,3 +147,16 @@ global sys_msize: ADD // stack: cost = num_words^2 / 512 + num_words * GAS_MEMORY %endmacro + +// Faults if the given offset is "unreasonable", i.e. the associated memory expansion cost +// would exceed any reasonable block limit. +// We do this to avoid overflows in future gas-related calculations. +%macro ensure_reasonable_offset + // stack: offset + // The memory expansion cost, (50000000 / 32)^2 / 512, is around 2^32 gas, + // i.e. greater than any reasonable block limit. + %gt_const(50000000) + // stack: is_unreasonable + %jumpi(fault_exception) + // stack: (empty) +%endmacro diff --git a/evm/src/cpu/kernel/asm/memory/syscalls.asm b/evm/src/cpu/kernel/asm/memory/syscalls.asm index 03cf3421..af8b6f27 100644 --- a/evm/src/cpu/kernel/asm/memory/syscalls.asm +++ b/evm/src/cpu/kernel/asm/memory/syscalls.asm @@ -1,4 +1,6 @@ global sys_mload: + // stack: kexit_info, offset + DUP2 %ensure_reasonable_offset // stack: kexit_info, offset %charge_gas_const(@GAS_VERYLOW) // stack: kexit_info, offset @@ -44,6 +46,8 @@ global sys_mload: EXIT_KERNEL global sys_mstore: + // stack: kexit_info, offset, value + DUP2 %ensure_reasonable_offset // stack: kexit_info, offset, value %charge_gas_const(@GAS_VERYLOW) // stack: kexit_info, offset, value @@ -87,6 +91,8 @@ global sys_mstore: EXIT_KERNEL global sys_mstore8: + // stack: kexit_info, offset, value + DUP2 %ensure_reasonable_offset // stack: kexit_info, offset, value %charge_gas_const(@GAS_VERYLOW) // stack: kexit_info, offset, value diff --git a/evm/src/cpu/kernel/asm/util/basic_macros.asm b/evm/src/cpu/kernel/asm/util/basic_macros.asm index 50857eaa..476f1c74 100644 --- a/evm/src/cpu/kernel/asm/util/basic_macros.asm +++ b/evm/src/cpu/kernel/asm/util/basic_macros.asm @@ -345,28 +345,3 @@ %endrep // stack: a || b || c || d %endmacro - -// Charge gas. -%macro charge_gas - // stack: gas, kexit_info - %shl_const(192) - ADD - // stack: kexit_info' -%endmacro - -// Charge a constant amount of gas. -%macro charge_gas_const(gas) - // stack: kexit_info - PUSH $gas - // stack: gas, kexit_info - %charge_gas - // stack: kexit_info' -%endmacro - -// Charge gas and exit kernel code. -%macro charge_gas_and_exit - // stack: gas, kexit_info - %charge_gas - // stack: kexit_info' - EXIT_KERNEL -%endmacro diff --git a/evm/src/cpu/kernel/asm/util/keccak.asm b/evm/src/cpu/kernel/asm/util/keccak.asm index 7922e8ce..5665ad3b 100644 --- a/evm/src/cpu/kernel/asm/util/keccak.asm +++ b/evm/src/cpu/kernel/asm/util/keccak.asm @@ -23,3 +23,21 @@ global sys_keccak256: %stack (offset) -> (0, @SEGMENT_KERNEL_GENERAL, 0, $num_bytes) // context, segment, offset, len KECCAK_GENERAL %endmacro + +// Computes Keccak256(a || b). Clobbers @SEGMENT_KERNEL_GENERAL. +// +// Pre stack: a, b +// Post stack: hash +%macro keccak256_u256_pair + // Since KECCAK_GENERAL takes its input from memory, we will first write + // a's bytes to @SEGMENT_KERNEL_GENERAL[0..32], then b's bytes to + // @SEGMENT_KERNEL_GENERAL[32..64]. + %stack (a) -> (0, @SEGMENT_KERNEL_GENERAL, 0, a, 32, %%after_mstore_a) + %jump(mstore_unpacking) +%%after_mstore_a: + %stack (offset, b) -> (0, @SEGMENT_KERNEL_GENERAL, 32, b, 32, %%after_mstore_b) + %jump(mstore_unpacking) +%%after_mstore_b: + %stack (offset) -> (0, @SEGMENT_KERNEL_GENERAL, 0, 64) // context, segment, offset, len + KECCAK_GENERAL +%endmacro