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

Commit

Permalink
update oog call, callcommongadget
Browse files Browse the repository at this point in the history
  • Loading branch information
DreamWuGit committed Aug 15, 2023
1 parent 566a36a commit 9fa7d9e
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 111 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,
},
},
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
3 changes: 2 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/error_oog_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
common_gadget::{CommonCallGadget, CommonErrorGadget},
constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder},
math_gadget::{IsZeroGadget, LtGadget},
memory_gadget::MemoryAddressGadget,
CachedRegion, Cell,
},
},
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, MemoryAddressGadget<F>, false>,
is_warm: Cell<F>,
insufficient_gas: LtGadget<F, N_BYTES_GAS>,
common_error_gadget: CommonErrorGadget<F>,
Expand Down
210 changes: 123 additions & 87 deletions zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use crate::{
constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder},
math_gadget::LtGadget,
memory_gadget::{
CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget, MemoryExpandedAddressGadget,
CommonMemoryAddressGadget, MemoryExpandedAddressGadget, MemoryExpansionGadget,
},
CachedRegion, Cell, or,
or, CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
},
table::CallContextFieldTag,
util::{word::WordExpr, Expr},
util::Expr,
};
use eth_types::{
evm_types::{GasCost, OpcodeId},
Expand Down Expand Up @@ -43,9 +43,9 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGLogGadget<F> {

fn configure(cb: &mut EVMConstraintBuilder<F>) -> Self {
let opcode = cb.query_cell();
// check memory
// memory expand gadget
let memory_address = MemoryExpandedAddressGadget::construct_self(cb);

// Pop mstart_address, msize from stack
cb.stack_pop(memory_address.offset_word());
cb.stack_pop(memory_address.length_word());
Expand Down Expand Up @@ -140,33 +140,69 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGLogGadget<F> {
#[cfg(test)]
mod test {
use crate::test_util::CircuitTestBuilder;

use bus_mapping::evm::OpcodeId;
use eth_types::{
self, address, bytecode, bytecode::Bytecode, evm_types::GasCost, geth_types::Account,
Address, ToWord, Word,
address, bytecode, bytecode::Bytecode, evm_types::GasCost, geth_types::Account, Address,
ToWord, Transaction, Word, U256,
};

use mock::{
eth, gwei, test_ctx::helpers::account_0_code_account_1_no_code, TestContext, MOCK_ACCOUNTS,
};

fn gas(call_data: &[u8]) -> Word {
Word::from(
GasCost::TX
+ 2 * OpcodeId::PUSH32.constant_gas_cost()
+ call_data
.iter()
.map(|&x| if x == 0 { 4 } else { 16 })
.sum::<u64>(),
)
#[test]
fn test_oog_log_root_simple() {
test_root(100.into(), 0.into());
}

#[test]
fn test_oog_log_internal_simple() {
let bytecode = bytecode! {
PUSH32(Word::from(0))
PUSH32(Word::from(10))
PUSH32(Word::from(224))
PUSH32(Word::from(1025))
PUSH32(Word::from(5089))
LOG2
STOP
};
let callee = callee(bytecode);
test_internal(caller(), callee);
}

#[test]
fn test_oog_log_max_expanded_address() {
// 0xffffffff1 + 0xffffffff0 = 0x1fffffffe1
// > MAX_EXPANDED_MEMORY_ADDRESS (0x1fffffffe0)
test_root(0xffffffff1_u64.into(), 0xffffffff0_u64.into());
}

#[test]
fn test_oog_log_max_u64_address() {
test_root(u64::MAX.into(), u64::MAX.into());
}

#[test]
fn test_oog_log_max_word_address() {
test_root(U256::MAX, U256::MAX);
}

fn test_oog_log(tx: eth_types::Transaction) {
#[derive(Clone, Copy, Debug, Default)]
struct Stack {
gas: u64,
value: Word,
cd_offset: u64,
cd_length: u64,
rd_offset: u64,
rd_length: u64,
}

fn test_root(offset: U256, size: U256) {
let tx = mock_tx(eth(1), gwei(2), vec![]);

let code = bytecode! {
PUSH1(0)
PUSH1(0)
PUSH1(100)
PUSH32(size)
PUSH32(offset)
LOG0
};

Expand All @@ -180,7 +216,7 @@ mod test {
.from(tx.from)
.gas_price(tx.gas_price.unwrap())
.gas(tx.gas + 5)
.input(tx.input)
.input(tx.input.clone())
.value(tx.value);
},
|block, _tx| block.number(0xcafeu64),
Expand All @@ -190,34 +226,35 @@ mod test {
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

fn mock_tx(value: Word, gas_price: Word, calldata: Vec<u8>) -> eth_types::Transaction {
let from = MOCK_ACCOUNTS[1];
let to = MOCK_ACCOUNTS[0];
eth_types::Transaction {
from,
to: Some(to),
value,
gas: gas(&calldata),
gas_price: Some(gas_price),
input: calldata.into(),
..Default::default()
}
}

#[test]
// test oog log in root call
fn test_oog_log_root() {
test_oog_log(mock_tx(eth(1), gwei(2), vec![]));
}
fn test_internal(caller: Account, callee: Account) {
let ctx = TestContext::<3, 1>::new(
None,
|accs| {
accs[0]
.address(address!("0x000000000000000000000000000000000000cafe"))
.balance(Word::from(10u64.pow(19)));
accs[1]
.address(caller.address)
.code(caller.code)
.nonce(caller.nonce.as_u64())
.balance(caller.balance);
accs[2]
.address(callee.address)
.code(callee.code)
.nonce(callee.nonce.as_u64())
.balance(callee.balance);
},
|mut txs, accs| {
txs[0]
.from(accs[0].address)
.to(accs[1].address)
.gas(24000.into());
},
|block, _tx| block.number(0xcafeu64),
)
.unwrap();

#[derive(Clone, Copy, Debug, Default)]
struct Stack {
gas: u64,
value: Word,
cd_offset: u64,
cd_length: u64,
rd_offset: u64,
rd_length: u64,
CircuitTestBuilder::new_from_test_ctx(ctx).run();
}

fn caller() -> Account {
Expand Down Expand Up @@ -251,49 +288,48 @@ mod test {
.write_op(terminator)
};

Account::mock_100_ether(bytecode)
Account {
address: Address::repeat_byte(0xfe),
balance: Word::from(10).pow(20.into()),
code: bytecode.code().into(),
..Default::default()
}
}

fn oog_log_internal_call(caller: Account, callee: Account) {
let ctx = TestContext::<3, 1>::new(
None,
|accs| {
accs[0]
.address(address!("0x000000000000000000000000000000000000cafe"))
.balance(Word::from(10u64.pow(19)));
accs[1].account(&caller);
accs[2].account(&callee);
},
|mut txs, accs| {
txs[0]
.from(accs[0].address)
.to(accs[1].address)
.gas(24000.into());
},
|block, _tx| block.number(0xcafeu64),
)
.unwrap();

CircuitTestBuilder::new_from_test_ctx(ctx).run();
fn callee(code: Bytecode) -> Account {
let code = code.code();
let is_empty = code.is_empty();
Account {
address: Address::repeat_byte(0xff),
code: code.into(),
nonce: if is_empty { 0 } else { 1 }.into(),
balance: if is_empty { 0 } else { 0xdeadbeefu64 }.into(),
..Default::default()
}
}

fn callee(code: Bytecode) -> Account {
Account::mock_code_balance(code)
fn gas(call_data: &[u8]) -> Word {
Word::from(
GasCost::TX
+ 2 * OpcodeId::PUSH32.constant_gas_cost()
+ call_data
.iter()
.map(|&x| if x == 0 { 4 } else { 16 })
.sum::<u64>(),
)
}

#[test]
// test oog log in internal call
fn test_oog_log_internal() {
let bytecode = bytecode! {
PUSH32(Word::from(0))
PUSH32(Word::from(10))
PUSH32(Word::from(224))
PUSH32(Word::from(1025))
PUSH32(Word::from(5089))
LOG2
STOP
};
let callee = callee(bytecode);
oog_log_internal_call(caller(), callee);
fn mock_tx(value: Word, gas_price: Word, calldata: Vec<u8>) -> Transaction {
let from = MOCK_ACCOUNTS[1];
let to = MOCK_ACCOUNTS[0];
Transaction {
from,
to: Some(to),
value,
gas: gas(&calldata),
gas_price: Some(gas_price),
input: calldata.into(),
..Default::default()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use crate::{
constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder},
math_gadget::{IsZeroGadget, LtGadget},
memory_gadget::{
CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget,
MemoryExpansionGadget, MemoryExpandedAddressGadget,
CommonMemoryAddressGadget, MemoryCopierGasGadget,
MemoryExpandedAddressGadget, MemoryExpansionGadget,
},
select, or, AccountAddress, CachedRegion, Cell,
or, select, AccountAddress, CachedRegion, Cell,
},
witness::{Block, Call, ExecStep, Transaction},
},
Expand Down Expand Up @@ -41,7 +41,7 @@ pub(crate) struct ErrorOOGMemoryCopyGadget<F> {
/// Source offset
src_offset: WordCell<F>,
/// Destination offset and size to copy
//dst_memory_addr: MemoryAddressGadget<F>,
// dst_memory_addr: MemoryAddressGadget<F>,
dst_memory_addr: MemoryExpandedAddressGadget<F>,
memory_expansion: MemoryExpansionGadget<F, 1, N_BYTES_MEMORY_WORD_SIZE>,
memory_copier_gas: MemoryCopierGasGadget<F, { GasCost::COPY }>,
Expand All @@ -68,9 +68,9 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGMemoryCopyGadget<F> {
],
);

//let dst_offset = cb.query_word_unchecked();
// let dst_offset = cb.query_word_unchecked();
let src_offset = cb.query_word_unchecked();
//let copy_size = cb.query_memory_address();
// let copy_size = cb.query_memory_address();
let external_address = cb.query_account_address();
let is_warm = cb.query_bool();
let tx_id = cb.query_cell();
Expand All @@ -92,7 +92,7 @@ impl<F: Field> ExecutionGadget<F> for ErrorOOGMemoryCopyGadget<F> {
cb.stack_pop(external_address.to_word());
});

//let dst_memory_addr = MemoryAddressGadget::construct(cb, dst_offset, copy_size);
// let dst_memory_addr = MemoryAddressGadget::construct(cb, dst_offset, copy_size);
let dst_memory_addr = MemoryExpandedAddressGadget::construct_self(cb);
cb.stack_pop(dst_memory_addr.offset_word());
cb.stack_pop(src_offset.to_word());
Expand Down
Loading

0 comments on commit 9fa7d9e

Please sign in to comment.