Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

implement ErrorOutOfGasCREATE error gadget #1562

Merged
merged 14 commits into from
Sep 8, 2023
10 changes: 4 additions & 6 deletions bus-mapping/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ pub enum OogError {
SloadSstore,
/// Out of Gas for CALL, CALLCODE, DELEGATECALL and STATICCALL
Call,
/// Out of Gas for CREATE2
Create2,
/// Out of Gas for CREATE and CREATE2
Create,
/// Out of Gas for SELFDESTRUCT
SelfDestruct,
}
Expand All @@ -105,9 +105,7 @@ impl From<&OpcodeId> for OogError {
OpcodeId::MLOAD | OpcodeId::MSTORE | OpcodeId::MSTORE8 => {
OogError::StaticMemoryExpansion
}
OpcodeId::CREATE | OpcodeId::RETURN | OpcodeId::REVERT => {
OogError::DynamicMemoryExpansion
}
OpcodeId::RETURN | OpcodeId::REVERT => OogError::DynamicMemoryExpansion,
OpcodeId::CALLDATACOPY
| OpcodeId::CODECOPY
| OpcodeId::EXTCODECOPY
Expand All @@ -124,7 +122,7 @@ impl From<&OpcodeId> for OogError {
OogError::Call
}
OpcodeId::SLOAD | OpcodeId::SSTORE => OogError::SloadSstore,
OpcodeId::CREATE2 => OogError::Create2,
OpcodeId::CREATE | OpcodeId::CREATE2 => OogError::Create,
OpcodeId::SELFDESTRUCT => OogError::SelfDestruct,
_ => OogError::Constant,
}
Expand Down
12 changes: 10 additions & 2 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,20 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps {
}
}

fn fn_gen_error_state_associated_ops(error: &ExecError) -> Option<FnGenAssociatedOps> {
fn fn_gen_error_state_associated_ops(
geth_step: &GethExecStep,
error: &ExecError,
) -> Option<FnGenAssociatedOps> {
match error {
ExecError::InvalidJump => Some(InvalidJump::gen_associated_ops),
ExecError::InvalidOpcode => Some(ErrorSimple::gen_associated_ops),
ExecError::OutOfGas(OogError::Call) => Some(OOGCall::gen_associated_ops),
ExecError::OutOfGas(OogError::Constant) => Some(ErrorSimple::gen_associated_ops),
ExecError::OutOfGas(OogError::Create) => match geth_step.op {
OpcodeId::CREATE => Some(StackOnlyOpcode::<3, 0, true>::gen_associated_ops),
OpcodeId::CREATE2 => Some(StackOnlyOpcode::<4, 0, true>::gen_associated_ops),
op => unreachable!("OOG Create cannot occur in {op}"),
},
ExecError::OutOfGas(OogError::Exp) => Some(OOGExp::gen_associated_ops),
ExecError::OutOfGas(OogError::Log) => Some(ErrorOOGLog::gen_associated_ops),
ExecError::OutOfGas(OogError::MemoryCopy) => Some(OOGMemoryCopy::gen_associated_ops),
Expand Down Expand Up @@ -367,7 +375,7 @@ pub fn gen_associated_ops(
// TODO: after more error state handled, refactor all error handling in
// fn_gen_error_state_associated_ops method
// For exceptions that have been implemented
if let Some(fn_gen_error_ops) = fn_gen_error_state_associated_ops(&exec_error) {
if let Some(fn_gen_error_ops) = fn_gen_error_state_associated_ops(geth_step, &exec_error) {
return fn_gen_error_ops(state, geth_steps);
} else {
// For exceptions that fail to enter next call context, we need
Expand Down
33 changes: 33 additions & 0 deletions eth-types/src/evm_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,39 @@ pub const GAS_STIPEND_CALL_WITH_VALUE: u64 = 2300;
/// <https://github.com/ethereum/go-ethereum/blob/e6b6a8b738069ad0579f6798ee59fde93ed13b43/core/vm/gas_table.go#L38>
pub const MAX_EXPANDED_MEMORY_ADDRESS: u64 = 0x1FFFFFFFE0;

#[cfg(feature = "shanghai")]
mod gas_create {
// For EIP-3860, there are 2 special gas cost constraints in geth
// [gasCreate2Eip3860](https://github.com/ethereum/go-ethereum/blob/eb83e7c54021573eaceb14236af3a7a8c64f6027/core/vm/gas_table.go#L321)
// (similar for CREATE).
// 1. size <= 49152 (MaxInitCodeSize)
// 2. gasCost = memoryGasCost + (2 + 6) * ((size + 31) / 32) should not
// overflow for Uint64.
// No need to constrain the second condition, since the maximum gas cost
// cannot overflow for Uint64 (36028809887100925 calculated by
// `memorySize = 0x1FFFFFFFE0` and `size = 49152`) if the first condition is
// satisfied.

/// Maximum init code size to permit in a creation transaction and create instructions.
pub const MAX_INIT_CODE_SIZE: u64 = 2 * super::MAX_CODE_SIZE;
/// Once per word of the init code when creating a contract.
pub const INIT_CODE_WORD_GAS: u64 = 2;
/// Gas per code word for CREATE.
pub const CREATE_GAS_PER_CODE_WORD: u64 = INIT_CODE_WORD_GAS;
/// Gas per code word for CREATE2.
pub const CREATE2_GAS_PER_CODE_WORD: u64 = INIT_CODE_WORD_GAS + super::GasCost::COPY_SHA3.0;
}
#[cfg(not(feature = "shanghai"))]
mod gas_create {
/// Maximum init code size (0x1FFFFFFFE0) if not EIP-3860.
pub use super::MAX_EXPANDED_MEMORY_ADDRESS as MAX_INIT_CODE_SIZE;
/// Gas per code word for CREATE if not EIP-3860.
pub const CREATE_GAS_PER_CODE_WORD: u64 = 0;
/// Gas per code word for CREATE2 if not EIP-3860.
pub const CREATE2_GAS_PER_CODE_WORD: u64 = super::GasCost::COPY_SHA3;
}
pub use gas_create::*;

/// Defines the gas consumption.
pub struct GasCost;

Expand Down
10 changes: 6 additions & 4 deletions zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ mod error_invalid_opcode;
mod error_oog_account_access;
mod error_oog_call;
mod error_oog_constant;
mod error_oog_create;
mod error_oog_exp;
mod error_oog_log;
mod error_oog_memory_copy;
Expand Down Expand Up @@ -150,6 +151,7 @@ use error_invalid_opcode::ErrorInvalidOpcodeGadget;
use error_oog_account_access::ErrorOOGAccountAccessGadget;
use error_oog_call::ErrorOOGCallGadget;
use error_oog_constant::ErrorOOGConstantGadget;
use error_oog_create::ErrorOOGCreateGadget;
use error_oog_exp::ErrorOOGExpGadget;
use error_oog_log::ErrorOOGLogGadget;
use error_oog_memory_copy::ErrorOOGMemoryCopyGadget;
Expand Down Expand Up @@ -310,7 +312,7 @@ pub struct ExecutionConfig<F> {
error_oog_sha3: Box<ErrorOOGSha3Gadget<F>>,
error_oog_account_access: Box<ErrorOOGAccountAccessGadget<F>>,
error_oog_ext_codecopy: Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasEXTCODECOPY }>>,
error_oog_create2: Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasCREATE2 }>>,
error_oog_create: Box<ErrorOOGCreateGadget<F>>,
error_oog_self_destruct:
Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasSELFDESTRUCT }>>,
error_oog_code_store: Box<ErrorCodeStoreGadget<F>>,
Expand Down Expand Up @@ -575,7 +577,7 @@ impl<F: Field> ExecutionConfig<F> {
error_oog_sha3: configure_gadget!(),
error_oog_ext_codecopy: configure_gadget!(),
error_oog_exp: configure_gadget!(),
error_oog_create2: configure_gadget!(),
error_oog_create: configure_gadget!(),
error_oog_self_destruct: configure_gadget!(),
error_oog_code_store: configure_gadget!(),
error_invalid_jump: configure_gadget!(),
Expand Down Expand Up @@ -1315,8 +1317,8 @@ impl<F: Field> ExecutionConfig<F> {
ExecutionState::ErrorOutOfGasEXP => {
assign_exec_step!(self.error_oog_exp)
}
ExecutionState::ErrorOutOfGasCREATE2 => {
assign_exec_step!(self.error_oog_create2)
ExecutionState::ErrorOutOfGasCREATE => {
assign_exec_step!(self.error_oog_create)
}
ExecutionState::ErrorOutOfGasSELFDESTRUCT => {
assign_exec_step!(self.error_oog_self_destruct)
Expand Down
Loading