Skip to content

Commit

Permalink
Implement circuit for ErrorOutOfGasSHA3 state (scroll-tech#419)
Browse files Browse the repository at this point in the history
* Implement circuit for `ErrorOutOfGasSHA3` state.

* Add `MemoryExpandedAddressGadget` to support memory offset plus length greater than `0x1FFFFFFFE0`.
  • Loading branch information
silathdiir authored Mar 22, 2023
1 parent 29af2d5 commit 4b071a6
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 9 deletions.
3 changes: 3 additions & 0 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ mod error_oog_dynamic_memory;
mod error_oog_exp;
mod error_oog_log;
mod error_oog_memory_copy;
mod error_oog_sha3;
mod error_oog_sload_sstore;
mod error_oog_static_memory;
mod error_precompile_failed;
Expand Down Expand Up @@ -96,6 +97,7 @@ use error_oog_dynamic_memory::OOGDynamicMemory;
use error_oog_exp::OOGExp;
use error_oog_log::ErrorOOGLog;
use error_oog_memory_copy::OOGMemoryCopy;
use error_oog_sha3::OOGSha3;
use error_oog_sload_sstore::OOGSloadSstore;
use error_oog_static_memory::OOGStaticMemory;
use error_precompile_failed::PrecompileFailed;
Expand Down Expand Up @@ -300,6 +302,7 @@ fn fn_gen_error_state_associated_ops(
}
ExecError::OutOfGas(OogError::Exp) => Some(OOGExp::gen_associated_ops),
ExecError::OutOfGas(OogError::MemoryCopy) => Some(OOGMemoryCopy::gen_associated_ops),
ExecError::OutOfGas(OogError::Sha3) => Some(OOGSha3::gen_associated_ops),
ExecError::OutOfGas(OogError::SloadSstore) => Some(OOGSloadSstore::gen_associated_ops),
// ExecError::
ExecError::StackOverflow => Some(ErrorSimple::gen_associated_ops),
Expand Down
38 changes: 38 additions & 0 deletions bus-mapping/src/evm/opcodes/error_oog_sha3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::{
circuit_input_builder::{CircuitInputStateRef, ExecStep},
error::{ExecError, OogError},
evm::Opcode,
Error,
};
use eth_types::{evm_types::OpcodeId, GethExecStep};

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the [`OogError::Sha3`](crate::error::OogError::Sha3).
#[derive(Clone, Copy, Debug)]
pub(crate) struct OOGSha3;

impl Opcode for OOGSha3 {
fn gen_associated_ops(
state: &mut CircuitInputStateRef,
geth_steps: &[GethExecStep],
) -> Result<Vec<ExecStep>, Error> {
let geth_step = &geth_steps[0];
debug_assert_eq!(geth_step.op, OpcodeId::SHA3);

let mut exec_step = state.new_step(geth_step)?;
exec_step.error = Some(ExecError::OutOfGas(OogError::Sha3));

for i in 0..2 {
state.stack_read(
&mut exec_step,
geth_step.stack.nth_last_filled(i),
geth_step.stack.nth_last(i)?,
)?;
}

state.gen_restore_context_ops(&mut exec_step, geth_steps)?;
state.handle_return(geth_step)?;

Ok(vec![exec_step])
}
}
4 changes: 4 additions & 0 deletions eth-types/src/evm_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ impl fmt::Debug for Gas {
}
}

/// This constant ((2^32 - 1) * 32) is the highest number that can be used without overflowing the
/// square operation of gas calculation.
/// https://github.com/ethereum/go-ethereum/blob/e6b6a8b738069ad0579f6798ee59fde93ed13b43/core/vm/gas_table.go#L38
pub const MAX_EXPANDED_MEMORY_ADDRESS: u64 = 0x1FFFFFFFE0;
/// Quotient for max refund of gas used
pub const MAX_REFUND_QUOTIENT_OF_GAS_USED: usize = 5;
/// Gas stipend when CALL or CALLCODE is attached with value.
Expand Down
3 changes: 2 additions & 1 deletion eth-types/src/evm_types/gas_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ pub fn memory_copier_gas_cost(
curr_memory_word_size: u64,
next_memory_word_size: u64,
num_copy_bytes: u64,
per_word_copy_gas: u64,
) -> u64 {
let num_words = (num_copy_bytes + 31) / 32;
num_words * GasCost::COPY.as_u64() +
num_words * per_word_copy_gas +
// Note that opcodes with a byte size parameter of 0 will not trigger
// memory expansion, regardless of their offset parameters.
if num_words > 0 {
Expand Down
4 changes: 3 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ mod error_oog_dynamic_memory;
mod error_oog_exp;
mod error_oog_log;
mod error_oog_memory_copy;
mod error_oog_sha3;
mod error_oog_sload_sstore;
mod error_oog_static_memory;
mod error_precompile_failed;
Expand Down Expand Up @@ -163,6 +164,7 @@ use error_oog_dynamic_memory::ErrorOOGDynamicMemoryGadget;
use error_oog_exp::ErrorOOGExpGadget;
use error_oog_log::ErrorOOGLogGadget;
use error_oog_memory_copy::ErrorOOGMemoryCopyGadget;
use error_oog_sha3::ErrorOOGSha3Gadget;
use error_oog_sload_sstore::ErrorOOGSloadSstoreGadget;
use error_oog_static_memory::ErrorOOGStaticMemoryGadget;
use error_precompile_failed::ErrorPrecompileFailedGadget;
Expand Down Expand Up @@ -319,7 +321,7 @@ pub(crate) struct ExecutionConfig<F> {
error_oog_log: Box<ErrorOOGLogGadget<F>>,
error_oog_account_access:
Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasAccountAccess }>>,
error_oog_sha3: Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasSHA3 }>>,
error_oog_sha3: Box<ErrorOOGSha3Gadget<F>>,
error_oog_create2: Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasCREATE2 }>>,
error_code_store: Box<ErrorCodeStoreGadget<F>>,
error_oog_self_destruct:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ mod tests {

let gas_cost = OpcodeId::PUSH32.constant_gas_cost().0 * 3
+ opcode.constant_gas_cost().0
+ memory_copier_gas_cost(0, memory_word_size, copy_size);
+ memory_copier_gas_cost(0, memory_word_size, copy_size, GasCost::COPY.as_u64());

Self { bytecode, gas_cost }
}
Expand All @@ -323,7 +323,7 @@ mod tests {

let mut gas_cost = OpcodeId::PUSH32.constant_gas_cost().0 * 4
+ GasCost::COLD_ACCOUNT_ACCESS.0
+ memory_copier_gas_cost(0, memory_word_size, copy_size);
+ memory_copier_gas_cost(0, memory_word_size, copy_size, GasCost::COPY.as_u64());

if is_warm {
bytecode.append(&bytecode! {
Expand All @@ -336,7 +336,12 @@ mod tests {

gas_cost += OpcodeId::PUSH32.constant_gas_cost().0 * 4
+ GasCost::WARM_ACCESS.0
+ memory_copier_gas_cost(memory_word_size, memory_word_size, copy_size);
+ memory_copier_gas_cost(
memory_word_size,
memory_word_size,
copy_size,
GasCost::COPY.as_u64(),
);
}

Self { bytecode, gas_cost }
Expand Down
Loading

0 comments on commit 4b071a6

Please sign in to comment.