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

Commit

Permalink
handle gas uint overflow (ErrorGasUintOverflow) (#1564)
Browse files Browse the repository at this point in the history
### Description

currently ErrorGasUintOverflow is handled within normal OOG cases, so
distribute ErrorGasUintOverflow checking within each OOG gadgets (oog
sha3, oog static/dynamic memory expansion, oog log etc.)
the `MemoryExpandedAddressGadget` is responsible for overflow status.

### Issue Link

[_link issue here_]

### Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update



### How Has This Been Tested?
all tests pass

This PR contains:
- Cleanup of xxxx, yyyy
- Changed xxxx to yyyy in order to bla bla
- Added xxxx function to ...
- Refactored ....
```
  • Loading branch information
DreamWuGit authored Sep 13, 2023
1 parent 610acc2 commit c67b4e8
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 174 deletions.
19 changes: 10 additions & 9 deletions zkevm-circuits/src/evm_circuit/execution/callop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
math_gadget::{
ConstantDivisionGadget, IsZeroGadget, LtGadget, LtWordGadget, MinMaxGadget,
},
memory_gadget::CommonMemoryAddressGadget,
memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget},
not, or, select, CachedRegion, Cell, StepRws,
},
},
Expand Down Expand Up @@ -46,7 +46,7 @@ pub(crate) struct CallOpGadget<F> {
current_caller_address: WordCell<F>,
is_static: Cell<F>,
depth: Cell<F>,
call: CommonCallGadget<F, true>,
call: CommonCallGadget<F, MemoryAddressGadget<F>, true>,
current_value: WordCell<F>,
is_warm: Cell<F>,
is_warm_prev: Cell<F>,
Expand Down Expand Up @@ -93,13 +93,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_word(
"for non call/call code, value is zero",
Expand Down
78 changes: 65 additions & 13 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::{ConstrainBuilderCommon, EVMConstraintBuilder},
math_gadget::{IsZeroGadget, LtGadget},
CachedRegion, Cell,
memory_gadget::MemoryExpandedAddressGadget,
or, CachedRegion, Cell,
},
},
table::CallContextFieldTag,
Expand All @@ -30,7 +31,7 @@ pub(crate) struct ErrorOOGCallGadget<F> {
is_staticcall: IsZeroGadget<F>,
tx_id: Cell<F>,
is_static: Cell<F>,
call: CommonCallGadget<F, false>,
call: CommonCallGadget<F, MemoryExpandedAddressGadget<F>, false>,
is_warm: Cell<F>,
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 @@ -78,16 +80,24 @@ 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(),
);

// Both CALL and CALLCODE opcodes have an extra stack pop `value` relative to
// DELEGATECALL and STATICCALL.
let common_error_gadget =
CommonErrorGadget::construct(cb, opcode.expr(), cb.rw_counter_offset());
let common_error_gadget = CommonErrorGadget::construct(
cb,
opcode.expr(),
11.expr() + is_call.expr() + is_callcode.expr(),
);

Self {
opcode,
Expand Down Expand Up @@ -364,4 +374,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 c67b4e8

Please sign in to comment.