Skip to content

Commit

Permalink
Implement circuit for ErrorGasUintOverflow state. (scroll-tech#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
silathdiir authored Apr 10, 2023
1 parent b0f8cc6 commit f9361ec
Show file tree
Hide file tree
Showing 28 changed files with 814 additions and 653 deletions.
4 changes: 2 additions & 2 deletions bus-mapping/src/circuit_input_builder/tracer_tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;
use crate::{
circuit_input_builder::access::gen_state_access_trace,
error::{ExecError, InsufficientBalanceError},
error::{ExecError, InsufficientBalanceError, OogError},
geth_errors::{
GETH_ERR_GAS_UINT_OVERFLOW, GETH_ERR_OUT_OF_GAS, GETH_ERR_STACK_OVERFLOW,
GETH_ERR_STACK_UNDERFLOW,
Expand Down Expand Up @@ -1411,7 +1411,7 @@ fn tracer_err_gas_uint_overflow() {
let mut builder = CircuitInputBuilderTx::new(&block, step);
assert_eq!(
builder.state_ref().get_step_err(step, next_step).unwrap(),
Some(ExecError::GasUintOverflow)
Some(ExecError::OutOfGas(OogError::StaticMemoryExpansion))
);
}

Expand Down
7 changes: 1 addition & 6 deletions bus-mapping/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,12 @@ pub enum ExecError {
/// For CALL, CALLCODE, DELEGATECALL, STATICCALL
PrecompileFailed,
/// ..
GasUintOverflow,
/// ..
NonceUintOverflow,
}

// TODO: Move to impl block.
pub(crate) fn get_step_reported_error(op: &OpcodeId, error: &str) -> ExecError {
if error == GETH_ERR_GAS_UINT_OVERFLOW {
return ExecError::GasUintOverflow;
}
if error == GETH_ERR_OUT_OF_GAS {
if [GETH_ERR_OUT_OF_GAS, GETH_ERR_GAS_UINT_OVERFLOW].contains(&error) {
// NOTE: We report a GasUintOverflow error as an OutOfGas error
let oog_err = match op {
OpcodeId::MLOAD | OpcodeId::MSTORE | OpcodeId::MSTORE8 => {
Expand Down
1 change: 0 additions & 1 deletion bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ fn fn_gen_error_state_associated_ops(
OpcodeId::CREATE2 => Some(StackOnlyOpcode::<4, 1>::gen_associated_ops),
_ => unreachable!(),
},
ExecError::GasUintOverflow => Some(StackOnlyOpcode::<0, 0, true>::gen_associated_ops),
ExecError::InvalidCreationCode => Some(ErrorCreationCode::gen_associated_ops),
// more future errors place here
_ => {
Expand Down
3 changes: 3 additions & 0 deletions mock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub(crate) use block::MockBlock;
pub use test_ctx::TestContext;
pub use transaction::{AddrOrWallet, MockTransaction, CORRECT_MOCK_TXS};

/// Mock block gas limit
pub const MOCK_BLOCK_GAS_LIMIT: u64 = 10_000_000_000_000_000;

lazy_static! {
/// Mock 1 ETH
pub static ref MOCK_1_ETH: Word = eth(1);
Expand Down
5 changes: 0 additions & 5 deletions zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,6 @@ pub(crate) struct ExecutionConfig<F> {
error_invalid_creation_code: Box<ErrorInvalidCreationCodeGadget<F>>,
error_precompile_failed: Box<ErrorPrecompileFailedGadget<F>>,
error_return_data_out_of_bound: Box<ErrorReturnDataOutOfBoundGadget<F>>,
error_gas_uint_overflow: Box<DummyGadget<F, 0, 0, { ExecutionState::ErrorGasUintOverflow }>>,
}

impl<F: Field> ExecutionConfig<F> {
Expand Down Expand Up @@ -603,7 +602,6 @@ impl<F: Field> ExecutionConfig<F> {
error_invalid_creation_code: configure_gadget!(),
error_return_data_out_of_bound: configure_gadget!(),
error_precompile_failed: configure_gadget!(),
error_gas_uint_overflow: configure_gadget!(),
// step and presets
step: step_curr,
height_map,
Expand Down Expand Up @@ -1448,9 +1446,6 @@ impl<F: Field> ExecutionConfig<F> {
ExecutionState::ErrorPrecompileFailed => {
assign_exec_step!(self.error_precompile_failed)
}
ExecutionState::ErrorGasUintOverflow => {
assign_exec_step!(self.error_gas_uint_overflow)
}
}

// Fill in the witness values for stored expressions
Expand Down
5 changes: 4 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use crate::{
ConstraintBuilder, StepStateTransition,
Transition::{Delta, To},
},
memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget},
memory_gadget::{
CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget,
MemoryExpansionGadget,
},
not, select, CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
Expand Down
18 changes: 10 additions & 8 deletions zkevm-circuits/src/evm_circuit/execution/callop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
math_gadget::{
ConstantDivisionGadget, IsZeroGadget, LtGadget, LtWordGadget, MinMaxGadget,
},
memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget},
not, or, select, CachedRegion, Cell, Word,
},
witness::{Block, Call, ExecStep, Transaction},
Expand Down Expand Up @@ -43,7 +44,7 @@ pub(crate) struct CallOpGadget<F> {
current_caller_address: Cell<F>,
is_static: Cell<F>,
depth: Cell<F>,
call: CommonCallGadget<F, true>,
call: CommonCallGadget<F, MemoryAddressGadget<F>, true>,
current_value: Word<F>,
is_warm: Cell<F>,
is_warm_prev: Cell<F>,
Expand Down Expand Up @@ -99,13 +100,14 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
)
});

let call_gadget = CommonCallGadget::construct(
cb,
is_call.expr(),
is_callcode.expr(),
is_delegatecall.expr(),
is_staticcall.expr(),
);
let call_gadget: CommonCallGadget<F, MemoryAddressGadget<F>, true> =
CommonCallGadget::construct(
cb,
is_call.expr(),
is_callcode.expr(),
is_delegatecall.expr(),
is_staticcall.expr(),
);
cb.condition(not::expr(is_call.expr() + is_callcode.expr()), |cb| {
cb.require_zero(
"for non call/call code, value is zero",
Expand Down
5 changes: 4 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/codecopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use crate::{
util::{
common_gadget::{SameContextGadget, WordByteCapGadget},
constraint_builder::{ConstraintBuilder, StepStateTransition, Transition},
memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget},
memory_gadget::{
CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget,
MemoryExpansionGadget,
},
not, select, CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
Expand Down
4 changes: 3 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use crate::{
math_gadget::{
ConstantDivisionGadget, ContractCreateGadget, IsZeroGadget, LtWordGadget,
},
memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget},
memory_gadget::{
CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget,
},
not, select, CachedRegion, Cell, Word,
},
witness::{Block, Call, ExecStep, Transaction},
Expand Down
7 changes: 5 additions & 2 deletions zkevm-circuits/src/evm_circuit/execution/error_code_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use crate::{
param::{N_BYTES_GAS, N_BYTES_U64},
step::ExecutionState,
util::{
common_gadget::CommonErrorGadget, constraint_builder::ConstraintBuilder,
math_gadget::LtGadget, memory_gadget::MemoryAddressGadget, CachedRegion, Cell,
common_gadget::CommonErrorGadget,
constraint_builder::ConstraintBuilder,
math_gadget::LtGadget,
memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget},
CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ use crate::{
execution::ExecutionGadget,
step::ExecutionState,
util::{
common_gadget::CommonErrorGadget, constraint_builder::ConstraintBuilder,
math_gadget::IsEqualGadget, memory_gadget::MemoryAddressGadget, CachedRegion, Cell,
common_gadget::CommonErrorGadget,
constraint_builder::ConstraintBuilder,
math_gadget::IsEqualGadget,
memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget},
CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
},
Expand Down
73 changes: 61 additions & 12 deletions zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::{
common_gadget::{CommonCallGadget, CommonErrorGadget},
constraint_builder::ConstraintBuilder,
math_gadget::{IsZeroGadget, LtGadget},
CachedRegion, Cell,
memory_gadget::MemoryExpandedAddressGadget,
or, CachedRegion, Cell,
},
},
table::CallContextFieldTag,
Expand All @@ -30,8 +31,8 @@ pub(crate) struct ErrorOOGCallGadget<F> {
is_staticcall: IsZeroGadget<F>,
tx_id: Cell<F>,
is_static: Cell<F>,
call: CommonCallGadget<F, false>,
is_warm: Cell<F>,
call: CommonCallGadget<F, MemoryExpandedAddressGadget<F>, false>,
insufficient_gas: LtGadget<F, N_BYTES_GAS>,
common_error_gadget: CommonErrorGadget<F>,
}
Expand All @@ -54,13 +55,14 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
let tx_id = cb.call_context(None, CallContextFieldTag::TxId);
let is_static = cb.call_context(None, CallContextFieldTag::IsStatic);

let call_gadget = CommonCallGadget::construct(
cb,
is_call.expr(),
is_callcode.expr(),
is_delegatecall.expr(),
is_staticcall.expr(),
);
let call_gadget: CommonCallGadget<F, MemoryExpandedAddressGadget<F>, false> =
CommonCallGadget::construct(
cb,
is_call.expr(),
is_callcode.expr(),
is_delegatecall.expr(),
is_staticcall.expr(),
);

// Add callee to access list
let is_warm = cb.query_bool();
Expand All @@ -82,9 +84,14 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {

// Check if the amount of gas available is less than the amount of gas required
let insufficient_gas = LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_cost);

cb.require_equal(
"gas left is less than gas required",
insufficient_gas.expr(),
"Either Memory address is overflow or gas left is less than cost",
or::expr([
call_gadget.cd_address.overflow(),
call_gadget.rd_address.overflow(),
insufficient_gas.expr(),
]),
1.expr(),
);

Expand All @@ -104,8 +111,8 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGCallGadget<F> {
is_staticcall,
tx_id,
is_static,
call: call_gadget,
is_warm,
call: call_gadget,
insufficient_gas,
common_error_gadget,
}
Expand Down Expand Up @@ -401,4 +408,46 @@ mod test {
});
test_oog(&caller(OpcodeId::CALL, stack), &callee, true);
}

#[test]
fn test_oog_call_max_expanded_address() {
// 0xffffffff1 + 0xffffffff0 = 0x1fffffffe1
// > MAX_EXPANDED_MEMORY_ADDRESS (0x1fffffffe0)
let stack = Stack {
gas: Word::MAX,
cd_offset: 0xffffffff1,
cd_length: 0xffffffff0,
rd_offset: 0xffffffff1,
rd_length: 0xffffffff0,
..Default::default()
};
let callee = callee(bytecode! {
PUSH32(Word::from(0))
PUSH32(Word::from(0))
STOP
});
for opcode in TEST_CALL_OPCODES {
test_oog(&caller(*opcode, stack), &callee, true);
}
}

#[test]
fn test_oog_call_max_u64_address() {
let stack = Stack {
gas: Word::MAX,
cd_offset: u64::MAX,
cd_length: u64::MAX,
rd_offset: u64::MAX,
rd_length: u64::MAX,
..Default::default()
};
let callee = callee(bytecode! {
PUSH32(Word::from(0))
PUSH32(Word::from(0))
STOP
});
for opcode in TEST_CALL_OPCODES {
test_oog(&caller(*opcode, stack), &callee, true);
}
}
}
Loading

0 comments on commit f9361ec

Please sign in to comment.