From 1306fd1900534ca3af941b6099c9cdbcd8b29d5d Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Wed, 9 Aug 2023 15:49:39 +0800 Subject: [PATCH 1/9] implement oog sha3 --- eth-types/src/evm_types.rs | 5 + zkevm-circuits/src/evm_circuit/execution.rs | 4 +- .../evm_circuit/execution/error_oog_sha3.rs | 299 ++++++++++++++++++ .../src/evm_circuit/util/memory_gadget.rs | 236 +++++++++++++- 4 files changed, 528 insertions(+), 16 deletions(-) create mode 100644 zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs diff --git a/eth-types/src/evm_types.rs b/eth-types/src/evm_types.rs index 1ac42477ce..f59c186824 100644 --- a/eth-types/src/evm_types.rs +++ b/eth-types/src/evm_types.rs @@ -23,6 +23,11 @@ pub const MAX_REFUND_QUOTIENT_OF_GAS_USED: usize = 5; /// Gas stipend when CALL or CALLCODE is attached with value. pub const GAS_STIPEND_CALL_WITH_VALUE: u64 = 2300; +/// This constant ((2^32 - 1) * 32) is the highest number that can be used without overflowing the +/// square operation of gas calculation. +/// +pub const MAX_EXPANDED_MEMORY_ADDRESS: u64 = 0x1FFFFFFFE0; + /// Defines the gas consumption. pub struct GasCost; diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index c9af2b18d9..b4a5ff1d03 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -81,6 +81,7 @@ mod error_oog_static_memory; mod error_return_data_oo_bound; mod error_stack; mod error_write_protection; +mod error_oog_sha3; mod exp; mod extcodecopy; mod extcodehash; @@ -154,6 +155,7 @@ use error_oog_sload_sstore::ErrorOOGSloadSstoreGadget; use error_return_data_oo_bound::ErrorReturnDataOutOfBoundGadget; use error_stack::ErrorStackGadget; use error_write_protection::ErrorWriteProtectionGadget; +use error_oog_sha3::ErrorOOGSha3Gadget; use exp::ExponentiationGadget; use extcodecopy::ExtcodecopyGadget; use extcodehash::ExtcodehashGadget; @@ -305,7 +307,7 @@ pub struct ExecutionConfig { error_oog_log: Box>, error_oog_account_access: Box>, - error_oog_sha3: Box>, + error_oog_sha3: Box>, error_oog_ext_codecopy: Box>, error_oog_create2: Box>, error_oog_self_destruct: diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs new file mode 100644 index 0000000000..e58c2cb75a --- /dev/null +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs @@ -0,0 +1,299 @@ +use crate::{ + evm_circuit::{ + execution::ExecutionGadget, + param::{N_BYTES_GAS, N_BYTES_MEMORY_WORD_SIZE}, + step::ExecutionState, + util::{ + common_gadget::CommonErrorGadget, + constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, + math_gadget::LtGadget, + memory_gadget::{ + MemoryCopierGasGadget, MemoryExpandedAddressGadget, + MemoryExpansionGadget, + }, + or, CachedRegion, Cell, + }, + witness::{Block, Call, ExecStep, Transaction}, + }, + util::Expr, +}; +use eth_types::{ + evm_types::{GasCost, OpcodeId}, + Field, +}; +use halo2_proofs::{circuit::Value, plonk::Error}; + +/// Gadget to implement the corresponding out of gas error for +/// [`OpcodeId::SHA3`]. +#[derive(Clone, Debug)] +pub(crate) struct ErrorOOGSha3Gadget { + opcode: Cell, + memory_address: MemoryExpandedAddressGadget, + memory_expansion: MemoryExpansionGadget, + memory_copier_gas: MemoryCopierGasGadget, + insufficient_gas: LtGadget, + common_error_gadget: CommonErrorGadget, +} + +impl ExecutionGadget for ErrorOOGSha3Gadget { + const NAME: &'static str = "ErrorOutOfGasSHA3"; + + const EXECUTION_STATE: ExecutionState = ExecutionState::ErrorOutOfGasSHA3; + + fn configure(cb: &mut EVMConstraintBuilder) -> Self { + let opcode = cb.query_cell(); + cb.require_equal( + "ErrorOutOfGasSHA3 opcode must be SHA3", + opcode.expr(), + OpcodeId::SHA3.expr(), + ); + + let memory_address = MemoryExpandedAddressGadget::construct_self(cb); + cb.stack_pop(memory_address.offset_rlc()); + cb.stack_pop(memory_address.length_rlc()); + + let memory_expansion = MemoryExpansionGadget::construct(cb, [memory_address.address()]); + let memory_copier_gas = MemoryCopierGasGadget::construct( + cb, + memory_address.length(), + memory_expansion.gas_cost(), + ); + + let insufficient_gas = LtGadget::construct( + cb, + cb.curr.state.gas_left.expr(), + OpcodeId::SHA3.constant_gas_cost().expr() + memory_copier_gas.gas_cost(), + ); + + cb.require_equal( + "Memory address is overflow or gas left is less than cost", + or::expr([memory_address.overflow(), insufficient_gas.expr()]), + 1.expr(), + ); + + let common_error_gadget = CommonErrorGadget::construct(cb, opcode.expr(), 4.expr()); + + Self { + opcode, + memory_address, + memory_expansion, + memory_copier_gas, + insufficient_gas, + common_error_gadget, + } + } + + fn assign_exec_step( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + block: &Block, + _tx: &Transaction, + call: &Call, + step: &ExecStep, + ) -> Result<(), Error> { + log::debug!( + "ErrorOutOfGasSHA3: gas_cost = {}, gas_left = {}", + step.gas_cost, + step.gas_left, + ); + + let opcode = step.opcode(); + self.opcode + .assign(region, offset, Value::known(F::from(opcode.unwrap().as_u64())))?; + + // let [memory_offset, memory_length] = + // [0, 1].map(|idx| block.rws[step.rw_indices[idx]].stack_value()); + let [memory_offset, memory_length] = + [0, 1,].map(|idx| block.get_rws(step, idx).stack_value()); + // let memory_address = self + + let expanded_address = + self.memory_address + .assign(region, offset, memory_offset, memory_length)?; + let (_, memory_expansion_cost) = self.memory_expansion.assign( + region, + offset, + step.memory_word_size(), + [expanded_address], + )?; + let memory_copier_gas = self.memory_copier_gas.assign( + region, + offset, + MemoryExpandedAddressGadget::::length_value(memory_offset, memory_length), + memory_expansion_cost, + )?; + self.insufficient_gas.assign_value( + region, + offset, + Value::known(F::from(step.gas_left)), + Value::known(F::from( + OpcodeId::SHA3.constant_gas_cost() + memory_copier_gas, + )), + )?; + + self.common_error_gadget + .assign(region, offset, block, call, step, 4)?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{evm_circuit::test::rand_bytes, test_util::CircuitTestBuilder}; + use eth_types::{ + bytecode, evm_types::gas_utils::memory_copier_gas_cost, Bytecode, ToWord, U256, + }; + use mock::{ + eth, test_ctx::helpers::account_0_code_account_1_no_code, TestContext, MOCK_ACCOUNTS, + MOCK_BLOCK_GAS_LIMIT, + }; + + #[test] + fn test_oog_sha3_less_than_constant_gas() { + let testing_data = TestingData::new(0x20, 0, OpcodeId::SHA3.constant_gas_cost().0); + + test_root(&testing_data); + test_internal(&testing_data); + } + + #[test] + fn test_oog_sha3_less_than_dynamic_gas() { + let testing_data = TestingData::new( + 0x40, + 20, + OpcodeId::SHA3.constant_gas_cost().0 + dynamic_gas_cost(0x40, 20), + ); + + test_root(&testing_data); + test_internal(&testing_data); + } + + #[test] + fn test_oog_sha3_max_expanded_address() { + // 0xffffffff1 + 0xffffffff0 = 0x1fffffffe1 + // > MAX_EXPANDED_MEMORY_ADDRESS (0x1fffffffe0) + let testing_data = TestingData::new(0xffffffff1, 0xffffffff0, MOCK_BLOCK_GAS_LIMIT); + + test_root(&testing_data); + test_internal(&testing_data); + } + + #[test] + fn test_oog_sha3_max_u64_address() { + let testing_data = TestingData::new(u64::MAX, u64::MAX, MOCK_BLOCK_GAS_LIMIT); + + test_root(&testing_data); + test_internal(&testing_data); + } + + struct TestingData { + bytecode: Bytecode, + gas_cost: u64, + } + + impl TestingData { + pub fn new(memory_offset: u64, memory_size: u64, gas_cost: u64) -> Self { + let bytecode = bytecode! { + PUSH32(memory_size) + PUSH32(memory_offset) + SHA3 + }; + + let gas_cost = gas_cost + .checked_add(OpcodeId::PUSH32.constant_gas_cost().0 * 2) + .unwrap_or(MOCK_BLOCK_GAS_LIMIT); + let gas_cost = if gas_cost > MOCK_BLOCK_GAS_LIMIT { + MOCK_BLOCK_GAS_LIMIT + } else { + gas_cost + }; + + Self { bytecode, gas_cost } + } + } + + fn dynamic_gas_cost(memory_offset: u64, memory_size: u64) -> u64 { + let memory_word_size = (memory_offset + memory_size + 31) / 32; + + memory_copier_gas_cost( + 0, + memory_word_size, + memory_size, + GasCost::COPY_SHA3.as_u64(), + ) + } + + fn test_root(testing_data: &TestingData) { + let gas_cost = GasCost::TX + .0 + // Decrease expected gas cost (by 1) to trigger out of gas error. + .checked_add(testing_data.gas_cost - 1) + .unwrap_or(MOCK_BLOCK_GAS_LIMIT); + let gas_cost = if gas_cost > MOCK_BLOCK_GAS_LIMIT { + MOCK_BLOCK_GAS_LIMIT + } else { + gas_cost + }; + + let ctx = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(testing_data.bytecode.clone()), + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .gas(gas_cost.into()); + }, + |block, _tx| block.number(0xcafe_u64), + ) + .unwrap(); + + CircuitTestBuilder::new_from_test_ctx(ctx).run(); + } + + fn test_internal(testing_data: &TestingData) { + let (addr_a, addr_b) = (MOCK_ACCOUNTS[0], MOCK_ACCOUNTS[1]); + + // code B gets called by code A, so the call is an internal call. + let code_b = testing_data.bytecode.clone(); + let gas_cost_b = testing_data.gas_cost; + + // Code A calls code B. + let code_a = bytecode! { + // populate memory in A's context. + PUSH8(U256::from_big_endian(&rand_bytes(8))) + PUSH1(0x00) // offset + MSTORE + // call ADDR_B. + PUSH1(0x00) // retLength + PUSH1(0x00) // retOffset + PUSH32(0x00) // argsLength + PUSH32(0x20) // argsOffset + PUSH1(0x00) // value + PUSH32(addr_b.to_word()) // addr + // Decrease expected gas cost (by 1) to trigger out of gas error. + PUSH32(gas_cost_b - 1) // gas + CALL + STOP + }; + + let ctx = TestContext::<3, 1>::new( + None, + |accs| { + accs[0].address(addr_b).code(code_b); + accs[1].address(addr_a).code(code_a); + accs[2].address(MOCK_ACCOUNTS[2]).balance(eth(10)); + }, + |mut txs, accs| { + txs[0].from(accs[2].address).to(accs[1].address); + }, + |block, _tx| block, + ) + .unwrap(); + + CircuitTestBuilder::new_from_test_ctx(ctx).run(); + } +} diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index f8df9e7eb3..9333c63142 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -1,11 +1,12 @@ use super::{constraint_builder::ConstrainBuilderCommon, CachedRegion, MemoryAddress, WordExpr}; use crate::{ evm_circuit::{ - param::{N_BYTES_GAS, N_BYTES_MEMORY_ADDRESS, N_BYTES_MEMORY_WORD_SIZE}, + param::{N_BYTES_GAS, N_BYTES_U64, N_BYTES_MEMORY_ADDRESS, N_BYTES_MEMORY_WORD_SIZE}, util::{ constraint_builder::EVMConstraintBuilder, - math_gadget::{ConstantDivisionGadget, IsZeroGadget, MinMaxGadget, RangeCheckGadget}, - select, sum, Cell, + math_gadget::{AddWordsGadget, ConstantDivisionGadget, IsZeroGadget, MinMaxGadget, + RangeCheckGadget, LtGadget,}, + select, sum, Cell, or, and, from_bytes, }, }, util::{ @@ -14,7 +15,7 @@ use crate::{ }, }; use array_init::array_init; -use eth_types::{evm_types::GasCost, Field, ToLittleEndian, U256}; +use eth_types::{evm_types::GasCost, evm_types::MAX_EXPANDED_MEMORY_ADDRESS, Field, ToLittleEndian, U256}; use gadgets::util::not; use halo2_proofs::{ circuit::Value, @@ -61,6 +62,32 @@ pub(crate) mod address_high { } } +/// Memory address trait to adapt for right and Uint overflow cases. +pub(crate) trait CommonMemoryAddressGadget { + fn construct_self(cb: &mut EVMConstraintBuilder) -> Self; + + /// Return the memory address (offset + length). + fn assign( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + memory_offset: U256, + memory_length: U256, + ) -> Result; + + /// Return original word of memory offset. + fn offset_rlc(&self) -> Expression; + + /// Return original word of memory length. + fn length_rlc(&self) -> Expression; + + /// Return valid memory length of Uint64. + fn length(&self) -> Expression; + + /// Return valid memory offset plus length. + fn address(&self) -> Expression; +} + /// Convert the dynamic memory offset and length from random linear combination /// to integer. It handles the "no expansion" feature by setting the /// `memory_offset_bytes` to zero when `memory_length` is zero. In this case, @@ -79,7 +106,8 @@ impl MemoryAddressGadget { memory_offset: WordCell, memory_length: MemoryAddress, ) -> Self { - let memory_length_is_zero = IsZeroGadget::construct(cb, memory_length.sum_expr()); + let memory_length_is_zero = + IsZeroGadget::construct(cb, memory_length.sum_expr()); let memory_offset_bytes = cb.query_memory_address(); let has_length = 1.expr() - memory_length_is_zero.expr(); @@ -99,7 +127,25 @@ impl MemoryAddressGadget { } } - pub(crate) fn assign( + pub(crate) fn has_length(&self) -> Expression { + 1.expr() - self.memory_length_is_zero.expr() + } + + // offset is the valid offset. It might not equal the offset pop from stack if + // `self.has_length()` is zero + pub(crate) fn offset(&self) -> Expression { + self.has_length() * self.memory_offset_bytes.expr() + } +} + +impl CommonMemoryAddressGadget for MemoryAddressGadget { + fn construct_self(cb: &mut EVMConstraintBuilder) -> Self { + let offset = cb.query_word_unchecked(); + let length = cb.query_memory_address(); + Self::construct(cb, offset, length) + } + + fn assign( &self, region: &mut CachedRegion<'_, '_, F>, offset: usize, @@ -133,25 +179,185 @@ impl MemoryAddressGadget { }) } - pub(crate) fn has_length(&self) -> Expression { - 1.expr() - self.memory_length_is_zero.expr() + fn offset_rlc(&self) -> Expression { + //self.memory_offset.expr() + self.memory_offset.to_word() } - // offset is the valid offset. It might not equal the offset pop from stack if - // `self.has_length()` is zero - pub(crate) fn offset(&self) -> Expression { - self.has_length() * self.memory_offset_bytes.expr() + fn length_rlc(&self) -> Expression { + //self.memory_length.expr() + self.memory_length.to_word() } - pub(crate) fn length(&self) -> Expression { - self.memory_length.expr() + // real length + fn length(&self) -> Expression { + // todo: check self.memory_length.expr() rlc length ? + self.memory_length.sum_expr() } - pub(crate) fn address(&self) -> Expression { + fn address(&self) -> Expression { self.offset() + self.length() } } +/// Check if memory offset plus length is within range or Uint overflow. +/// The sum of memory offset and length should also be less than or equal to +/// `0x1FFFFFFFE0` (which is less than `u64::MAX - 31`). +/// Reference go-ethereum code as: +/// . [calcMemSize64WithUint](https://github.com/ethereum/go-ethereum/blob/db18293c32f6dc5d6886e5e68ab8bfd12e33cad6/core/vm/common.go#L37) +/// . [memoryGasCost](https://github.com/ethereum/go-ethereum/blob/db18293c32f6dc5d6886e5e68ab8bfd12e33cad6/core/vm/gas_table.go#L38) +/// . [toWordSize](https://github.com/ethereum/go-ethereum/blob/db18293c32f6dc5d6886e5e68ab8bfd12e33cad6/core/vm/common.go#L67) +#[derive(Clone, Debug)] +pub(crate) struct MemoryExpandedAddressGadget { + length_is_zero: IsZeroGadget, + offset_length_sum: AddWordsGadget, + sum_lt_cap: LtGadget, + sum_within_u64: IsZeroGadget, +} + +impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { + fn construct_self(cb: &mut EVMConstraintBuilder) -> Self { + let offset = cb.query_word32(); + let length = cb.query_word32(); + let sum = cb.query_word32(); + + let sum_lt_cap = LtGadget::construct( + cb, + //from_bytes::expr(&sum.cells[..N_BYTES_U64]), + sum::expr(&sum.limbs[..N_BYTES_U64]), + (MAX_EXPANDED_MEMORY_ADDRESS + 1).expr(), + ); + + let sum_overflow_hi = sum::expr(&sum.limbs[N_BYTES_U64..]); + let sum_within_u64 = IsZeroGadget::construct(cb, sum_overflow_hi); + + let length_is_zero = IsZeroGadget::construct(cb, sum::expr(&length.limbs)); + let offset_length_sum = AddWordsGadget::construct(cb, [offset, length], sum); + + Self { + length_is_zero, + offset_length_sum, + sum_lt_cap, + sum_within_u64, + } + } + + fn assign( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + memory_offset: U256, + memory_length: U256, + ) -> Result { + let length_bytes = memory_length + .to_le_bytes() + .iter() + .fold(0, |acc, val| acc + u64::from(*val)); + self.length_is_zero + .assign(region, offset, F::from(length_bytes))?; + + let (sum, sum_word_overflow) = memory_offset.overflowing_add(memory_length); + self.offset_length_sum + .assign(region, offset, [memory_offset, memory_length], sum)?; + + self.sum_lt_cap.assign( + region, + offset, + F::from(sum.low_u64()), + F::from(MAX_EXPANDED_MEMORY_ADDRESS + 1), + )?; + + let sum_overflow_hi_bytes = sum.to_le_bytes()[N_BYTES_U64..] + .iter() + .fold(0, |acc, val| acc + u64::from(*val)); + self.sum_within_u64 + .assign(region, offset, F::from(sum_overflow_hi_bytes))?; + + let address = if length_bytes == 0 + || sum_overflow_hi_bytes != 0 + || sum_word_overflow + || sum.low_u64() > MAX_EXPANDED_MEMORY_ADDRESS + { + 0 + } else { + sum.low_u64() + }; + + Ok(address) + } + + fn offset_rlc(&self) -> Expression { + let addends = self.offset_length_sum.addends(); + //addends[0].expr() + addends[0].to_word() + } + + fn length_rlc(&self) -> Expression { + let addends = self.offset_length_sum.addends(); + //addends[1].expr() + addends[1].expr() + } + + fn length(&self) -> Expression { + let addends = self.offset_length_sum.addends(); + select::expr( + self.within_range(), + from_bytes::expr(&addends[1].limbs[..N_BYTES_U64]), + 0.expr(), + ) + } + + /// Return expanded address if within range, otherwise return 0. + fn address(&self) -> Expression { + select::expr( + self.length_is_zero.expr(), + 0.expr(), + select::expr( + self.within_range(), + sum::expr(&self.offset_length_sum.sum().limbs[..N_BYTES_U64]), + 0.expr(), + ), + ) + } +} + +impl MemoryExpandedAddressGadget { + /// Return the valid length value corresponding to function `length` + /// (which returns an Expression). + pub(crate) fn length_value(memory_offset: U256, memory_length: U256) -> u64 { + if memory_length.is_zero() { + return 0; + } + + memory_offset + .checked_add(memory_length) + .map_or(0, |address| { + if address > MAX_EXPANDED_MEMORY_ADDRESS.into() { + 0 + } else { + memory_length.as_u64() + } + }) + } + + /// Check if overflow. + pub(crate) fn overflow(&self) -> Expression { + not::expr(self.within_range()) + } + + /// Check if within range. + pub(crate) fn within_range(&self) -> Expression { + or::expr([ + self.length_is_zero.expr(), + and::expr([ + self.sum_lt_cap.expr(), + self.sum_within_u64.expr(), + not::expr(self.offset_length_sum.carry().as_ref().unwrap()), + ]), + ]) + } +} + /// Calculates the memory size in words required for a memory access at the /// specified address. /// `memory_word_size = ceil(address/32) = floor((address + 31) / 32)` From 0f862e2f3a6ff3529b18c4782b8434a7cbb0c3d2 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Wed, 9 Aug 2023 16:23:43 +0800 Subject: [PATCH 2/9] use trait CommonMemoryAddressGadget --- .../src/evm_circuit/execution/calldatacopy.rs | 2 +- zkevm-circuits/src/evm_circuit/execution/callop.rs | 1 + .../src/evm_circuit/execution/codecopy.rs | 2 +- zkevm-circuits/src/evm_circuit/execution/create.rs | 2 +- .../src/evm_circuit/execution/error_code_store.rs | 2 +- .../execution/error_invalid_creation_code.rs | 2 +- .../src/evm_circuit/execution/error_oog_log.rs | 2 +- .../evm_circuit/execution/error_oog_memory_copy.rs | 2 +- .../src/evm_circuit/execution/error_oog_sha3.rs | 2 +- .../src/evm_circuit/execution/extcodecopy.rs | 2 +- zkevm-circuits/src/evm_circuit/execution/logs.rs | 2 +- .../src/evm_circuit/execution/return_revert.rs | 2 +- .../src/evm_circuit/execution/returndatacopy.rs | 2 +- zkevm-circuits/src/evm_circuit/execution/sha3.rs | 2 +- .../src/evm_circuit/util/common_gadget.rs | 2 +- .../src/evm_circuit/util/memory_gadget.rs | 14 +++++++------- 16 files changed, 22 insertions(+), 21 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs b/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs index 887bd63d75..e6ca05e44f 100644 --- a/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs @@ -9,7 +9,7 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition::{Delta, To}, }, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, not, select, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index 3258fe88fe..bcf69db7cc 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -10,6 +10,7 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, ReversionInfo, StepStateTransition, Transition::{Delta, To}, }, + memory_gadget::CommonMemoryAddressGadget, math_gadget::{ ConstantDivisionGadget, IsZeroGadget, LtGadget, LtWordGadget, MinMaxGadget, }, diff --git a/zkevm-circuits/src/evm_circuit/execution/codecopy.rs b/zkevm-circuits/src/evm_circuit/execution/codecopy.rs index f0c192852d..2f7bdad1c9 100644 --- a/zkevm-circuits/src/evm_circuit/execution/codecopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/codecopy.rs @@ -11,7 +11,7 @@ use crate::{ constraint_builder::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition, }, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget,MemoryCopierGasGadget, MemoryExpansionGadget}, not, select, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index 14ac7e9603..4067ff028b 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -16,7 +16,7 @@ use crate::{ ConstantDivisionGadget, ContractCreateGadget, IsZeroGadget, IsZeroWordGadget, LtGadget, LtWordGadget, }, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget, MemoryExpansionGadget}, not, AccountAddress, CachedRegion, Cell, Word, WordExpr, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs b/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs index 4388bd2b48..ed8a2ac917 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs @@ -7,7 +7,7 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::LtGadget, - memory_gadget::MemoryAddressGadget, + memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget}, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs b/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs index db2957d53a..e112698768 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs @@ -6,7 +6,7 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::IsEqualGadget, - memory_gadget::MemoryAddressGadget, + memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget}, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs index dd4ef88ad0..a76407bdbd 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs @@ -7,7 +7,7 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::LtGadget, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs index b7f5499540..b6495e6aa3 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs @@ -7,7 +7,7 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::{IsZeroGadget, LtGadget}, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, CommonMemoryAddressGadget, MemoryExpansionGadget}, select, AccountAddress, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs index e58c2cb75a..0b048b6810 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs @@ -9,7 +9,7 @@ use crate::{ math_gadget::LtGadget, memory_gadget::{ MemoryCopierGasGadget, MemoryExpandedAddressGadget, - MemoryExpansionGadget, + MemoryExpansionGadget,CommonMemoryAddressGadget, }, or, CachedRegion, Cell, }, diff --git a/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs b/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs index 803a9fc050..486af16696 100644 --- a/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs @@ -9,7 +9,7 @@ use crate::{ Transition, }, math_gadget::IsZeroWordGadget, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, CommonMemoryAddressGadget, MemoryExpansionGadget}, not, select, AccountAddress, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/logs.rs b/zkevm-circuits/src/evm_circuit/execution/logs.rs index 830a755a08..23d19ae9c3 100644 --- a/zkevm-circuits/src/evm_circuit/execution/logs.rs +++ b/zkevm-circuits/src/evm_circuit/execution/logs.rs @@ -9,7 +9,7 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition::{Delta, To}, }, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, not, sum, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/return_revert.rs b/zkevm-circuits/src/evm_circuit/execution/return_revert.rs index 95ca01cc91..83f0dfa78a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/return_revert.rs +++ b/zkevm-circuits/src/evm_circuit/execution/return_revert.rs @@ -10,7 +10,7 @@ use crate::{ Transition::{Delta, To}, }, math_gadget::{IsEqualGadget, IsZeroGadget, MinMaxGadget}, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, not, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs b/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs index 2c1b973f45..6636aee925 100644 --- a/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs @@ -10,7 +10,7 @@ use crate::{ Transition::{Delta, To}, }, math_gadget::RangeCheckGadget, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget,CommonMemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, CachedRegion, Cell, MemoryAddress, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/sha3.rs b/zkevm-circuits/src/evm_circuit/execution/sha3.rs index cdb885e9cf..6a2a735482 100644 --- a/zkevm-circuits/src/evm_circuit/execution/sha3.rs +++ b/zkevm-circuits/src/evm_circuit/execution/sha3.rs @@ -12,7 +12,7 @@ use crate::{ constraint_builder::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition, }, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, rlc, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index f345e9da19..65a2bd7174 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -2,7 +2,7 @@ use super::{ constraint_builder::ConstrainBuilderCommon, from_bytes, math_gadget::{IsEqualWordGadget, IsZeroGadget, IsZeroWordGadget, LtGadget}, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, AccountAddress, CachedRegion, }; use crate::{ diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index 9333c63142..99360f84a9 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -76,10 +76,10 @@ pub(crate) trait CommonMemoryAddressGadget { ) -> Result; /// Return original word of memory offset. - fn offset_rlc(&self) -> Expression; + fn offset_rlc(&self) -> Word>; /// Return original word of memory length. - fn length_rlc(&self) -> Expression; + fn length_rlc(&self) -> Word>; /// Return valid memory length of Uint64. fn length(&self) -> Expression; @@ -179,12 +179,12 @@ impl CommonMemoryAddressGadget for MemoryAddressGadget { }) } - fn offset_rlc(&self) -> Expression { + fn offset_rlc(&self) -> Word> { //self.memory_offset.expr() self.memory_offset.to_word() } - fn length_rlc(&self) -> Expression { + fn length_rlc(&self) -> Word> { //self.memory_length.expr() self.memory_length.to_word() } @@ -286,16 +286,16 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { Ok(address) } - fn offset_rlc(&self) -> Expression { + fn offset_rlc(&self) -> Word> { let addends = self.offset_length_sum.addends(); //addends[0].expr() addends[0].to_word() } - fn length_rlc(&self) -> Expression { + fn length_rlc(&self) -> Word> { let addends = self.offset_length_sum.addends(); //addends[1].expr() - addends[1].expr() + addends[1].to_word() } fn length(&self) -> Expression { From 378783f68bc2a04b3c1b76d903f15935263b56c0 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Thu, 10 Aug 2023 11:03:24 +0800 Subject: [PATCH 3/9] change stackonlyopcode with err flag & add param --- bus-mapping/src/evm/opcodes.rs | 7 ++++++- bus-mapping/src/evm/opcodes/stackonlyop.rs | 15 +++++++++++++-- mock/src/lib.rs | 3 +++ .../src/evm_circuit/execution/error_oog_sha3.rs | 16 +++++++--------- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 813619ddbd..43de64e188 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -8,6 +8,7 @@ use crate::{ }; use core::fmt::Debug; use eth_types::{evm_unimplemented, GethExecStep, ToAddress}; +use ethers_core::k256::elliptic_curve::consts::False; mod address; mod balance; @@ -44,6 +45,7 @@ mod stackonlyop; mod stop; mod swap; + mod error_code_store; mod error_invalid_creation_code; mod error_invalid_jump; @@ -277,6 +279,9 @@ fn fn_gen_error_state_associated_ops(error: &ExecError) -> Option Some(ErrorOOGLog::gen_associated_ops), ExecError::OutOfGas(OogError::MemoryCopy) => Some(OOGMemoryCopy::gen_associated_ops), ExecError::OutOfGas(OogError::SloadSstore) => Some(OOGSloadSstore::gen_associated_ops), + ExecError::OutOfGas(OogError::Sha3) => { + Some(StackOnlyOpcode::<2, 0, true>::gen_associated_ops) + }, ExecError::StackOverflow => Some(ErrorSimple::gen_associated_ops), ExecError::StackUnderflow => Some(ErrorSimple::gen_associated_ops), // call & callcode can encounter InsufficientBalance error, Use pop-7 generic CallOpcode @@ -344,7 +349,7 @@ pub fn gen_associated_ops( None }; if let Some(exec_error) = state.get_step_err(geth_step, next_step).unwrap() { - log::warn!( + println!( "geth error {:?} occurred in {:?} at pc {:?}", exec_error, geth_step.op, diff --git a/bus-mapping/src/evm/opcodes/stackonlyop.rs b/bus-mapping/src/evm/opcodes/stackonlyop.rs index 26fd8ac6a0..76270075f2 100644 --- a/bus-mapping/src/evm/opcodes/stackonlyop.rs +++ b/bus-mapping/src/evm/opcodes/stackonlyop.rs @@ -12,9 +12,13 @@ use eth_types::GethExecStep; /// - N = 2: BinaryOpcode /// - N = 3: TernaryOpcode #[derive(Debug, Copy, Clone)] -pub(crate) struct StackOnlyOpcode; +pub(crate) struct StackOnlyOpcode< + const N_POP: usize, + const N_PUSH: usize, + const IS_ERR: bool = { false }, +>; -impl Opcode for StackOnlyOpcode { +impl Opcode for StackOnlyOpcode { fn gen_associated_ops( state: &mut CircuitInputStateRef, geth_steps: &[GethExecStep], @@ -39,6 +43,13 @@ impl Opcode for StackOnlyOpcode ExecutionGadget for ErrorOOGSha3Gadget { self.opcode .assign(region, offset, Value::known(F::from(opcode.unwrap().as_u64())))?; - // let [memory_offset, memory_length] = - // [0, 1].map(|idx| block.rws[step.rw_indices[idx]].stack_value()); let [memory_offset, memory_length] = [0, 1,].map(|idx| block.get_rws(step, idx).stack_value()); // let memory_address = self @@ -131,6 +129,8 @@ impl ExecutionGadget for ErrorOOGSha3Gadget { OpcodeId::SHA3.constant_gas_cost() + memory_copier_gas, )), )?; + println!("gas_left {}, gas cost {}", step.gas_left ,OpcodeId::SHA3.constant_gas_cost() + memory_copier_gas); + _tx.steps().into_iter().map(|s| println!("step {:?}",s.exec_state)).count(); self.common_error_gadget .assign(region, offset, block, call, step, 4)?; @@ -153,7 +153,7 @@ mod tests { #[test] fn test_oog_sha3_less_than_constant_gas() { - let testing_data = TestingData::new(0x20, 0, OpcodeId::SHA3.constant_gas_cost().0); + let testing_data = TestingData::new(0x20, 0, OpcodeId::SHA3.constant_gas_cost()); test_root(&testing_data); test_internal(&testing_data); @@ -164,7 +164,7 @@ mod tests { let testing_data = TestingData::new( 0x40, 20, - OpcodeId::SHA3.constant_gas_cost().0 + dynamic_gas_cost(0x40, 20), + OpcodeId::SHA3.constant_gas_cost() + dynamic_gas_cost(0x40, 20), ); test_root(&testing_data); @@ -178,7 +178,7 @@ mod tests { let testing_data = TestingData::new(0xffffffff1, 0xffffffff0, MOCK_BLOCK_GAS_LIMIT); test_root(&testing_data); - test_internal(&testing_data); + //test_internal(&testing_data); } #[test] @@ -186,7 +186,7 @@ mod tests { let testing_data = TestingData::new(u64::MAX, u64::MAX, MOCK_BLOCK_GAS_LIMIT); test_root(&testing_data); - test_internal(&testing_data); + //test_internal(&testing_data); } struct TestingData { @@ -203,7 +203,7 @@ mod tests { }; let gas_cost = gas_cost - .checked_add(OpcodeId::PUSH32.constant_gas_cost().0 * 2) + .checked_add(OpcodeId::PUSH32.constant_gas_cost() * 2) .unwrap_or(MOCK_BLOCK_GAS_LIMIT); let gas_cost = if gas_cost > MOCK_BLOCK_GAS_LIMIT { MOCK_BLOCK_GAS_LIMIT @@ -222,13 +222,11 @@ mod tests { 0, memory_word_size, memory_size, - GasCost::COPY_SHA3.as_u64(), ) } fn test_root(testing_data: &TestingData) { let gas_cost = GasCost::TX - .0 // Decrease expected gas cost (by 1) to trigger out of gas error. .checked_add(testing_data.gas_cost - 1) .unwrap_or(MOCK_BLOCK_GAS_LIMIT); From d3edfef7113c2f8658e174f7488d85ff8a2f7f57 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Fri, 11 Aug 2023 17:25:32 +0800 Subject: [PATCH 4/9] fix --- bus-mapping/src/evm/opcodes.rs | 6 +-- bus-mapping/src/evm/opcodes/stackonlyop.rs | 4 +- zkevm-circuits/src/evm_circuit/execution.rs | 4 +- .../src/evm_circuit/execution/calldatacopy.rs | 5 ++- .../src/evm_circuit/execution/callop.rs | 2 +- .../src/evm_circuit/execution/codecopy.rs | 5 ++- .../src/evm_circuit/execution/create.rs | 4 +- .../evm_circuit/execution/error_code_store.rs | 2 +- .../execution/error_invalid_creation_code.rs | 2 +- .../evm_circuit/execution/error_oog_log.rs | 4 +- .../execution/error_oog_memory_copy.rs | 5 ++- .../evm_circuit/execution/error_oog_sha3.rs | 31 +++++++-------- .../src/evm_circuit/execution/extcodecopy.rs | 5 ++- .../src/evm_circuit/execution/logs.rs | 4 +- .../evm_circuit/execution/return_revert.rs | 4 +- .../evm_circuit/execution/returndatacopy.rs | 5 ++- .../src/evm_circuit/execution/sha3.rs | 5 ++- .../src/evm_circuit/util/common_gadget.rs | 2 +- .../src/evm_circuit/util/memory_gadget.rs | 38 +++++++++++-------- 19 files changed, 83 insertions(+), 54 deletions(-) diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 43de64e188..5616d19699 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -8,7 +8,6 @@ use crate::{ }; use core::fmt::Debug; use eth_types::{evm_unimplemented, GethExecStep, ToAddress}; -use ethers_core::k256::elliptic_curve::consts::False; mod address; mod balance; @@ -45,7 +44,6 @@ mod stackonlyop; mod stop; mod swap; - mod error_code_store; mod error_invalid_creation_code; mod error_invalid_jump; @@ -281,7 +279,7 @@ fn fn_gen_error_state_associated_ops(error: &ExecError) -> Option Some(OOGSloadSstore::gen_associated_ops), ExecError::OutOfGas(OogError::Sha3) => { Some(StackOnlyOpcode::<2, 0, true>::gen_associated_ops) - }, + } ExecError::StackOverflow => Some(ErrorSimple::gen_associated_ops), ExecError::StackUnderflow => Some(ErrorSimple::gen_associated_ops), // call & callcode can encounter InsufficientBalance error, Use pop-7 generic CallOpcode @@ -349,7 +347,7 @@ pub fn gen_associated_ops( None }; if let Some(exec_error) = state.get_step_err(geth_step, next_step).unwrap() { - println!( + log::warn!( "geth error {:?} occurred in {:?} at pc {:?}", exec_error, geth_step.op, diff --git a/bus-mapping/src/evm/opcodes/stackonlyop.rs b/bus-mapping/src/evm/opcodes/stackonlyop.rs index 76270075f2..5b5e20277b 100644 --- a/bus-mapping/src/evm/opcodes/stackonlyop.rs +++ b/bus-mapping/src/evm/opcodes/stackonlyop.rs @@ -18,7 +18,9 @@ pub(crate) struct StackOnlyOpcode< const IS_ERR: bool = { false }, >; -impl Opcode for StackOnlyOpcode { +impl Opcode + for StackOnlyOpcode +{ fn gen_associated_ops( state: &mut CircuitInputStateRef, geth_steps: &[GethExecStep], diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index b4a5ff1d03..53b72e1c34 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -76,12 +76,12 @@ mod error_oog_constant; 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_return_data_oo_bound; mod error_stack; mod error_write_protection; -mod error_oog_sha3; mod exp; mod extcodecopy; mod extcodehash; @@ -151,11 +151,11 @@ use error_oog_constant::ErrorOOGConstantGadget; 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_return_data_oo_bound::ErrorReturnDataOutOfBoundGadget; use error_stack::ErrorStackGadget; use error_write_protection::ErrorWriteProtectionGadget; -use error_oog_sha3::ErrorOOGSha3Gadget; use exp::ExponentiationGadget; use extcodecopy::ExtcodecopyGadget; use extcodehash::ExtcodehashGadget; diff --git a/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs b/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs index e6ca05e44f..e31047b09b 100644 --- a/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs @@ -9,7 +9,10 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition::{Delta, To}, }, - memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget, + MemoryExpansionGadget, + }, not, select, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index bcf69db7cc..abdafcc006 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -10,10 +10,10 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, ReversionInfo, StepStateTransition, Transition::{Delta, To}, }, - memory_gadget::CommonMemoryAddressGadget, math_gadget::{ ConstantDivisionGadget, IsZeroGadget, LtGadget, LtWordGadget, MinMaxGadget, }, + memory_gadget::CommonMemoryAddressGadget, not, or, select, CachedRegion, Cell, }, }, diff --git a/zkevm-circuits/src/evm_circuit/execution/codecopy.rs b/zkevm-circuits/src/evm_circuit/execution/codecopy.rs index 2f7bdad1c9..c310e11281 100644 --- a/zkevm-circuits/src/evm_circuit/execution/codecopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/codecopy.rs @@ -11,7 +11,10 @@ use crate::{ constraint_builder::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition, }, - memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget,MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget, + MemoryExpansionGadget, + }, not, select, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index 4067ff028b..393537eb1c 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -16,7 +16,9 @@ use crate::{ ConstantDivisionGadget, ContractCreateGadget, IsZeroGadget, IsZeroWordGadget, LtGadget, LtWordGadget, }, - memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget, + }, not, AccountAddress, CachedRegion, Cell, Word, WordExpr, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs b/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs index ed8a2ac917..4147f8e109 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_code_store.rs @@ -7,7 +7,7 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::LtGadget, - memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget}, + memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget}, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs b/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs index e112698768..ce6c9a458d 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_invalid_creation_code.rs @@ -6,7 +6,7 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::IsEqualGadget, - memory_gadget::{MemoryAddressGadget, CommonMemoryAddressGadget}, + memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget}, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs index a76407bdbd..b5fcc4b575 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_log.rs @@ -7,7 +7,9 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::LtGadget, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget, + }, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs index b6495e6aa3..dbd568b368 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_memory_copy.rs @@ -7,7 +7,10 @@ use crate::{ common_gadget::CommonErrorGadget, constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::{IsZeroGadget, LtGadget}, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, CommonMemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget, + MemoryExpansionGadget, + }, select, AccountAddress, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs index 0b3a1f9889..cfa51a7bc8 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs @@ -8,8 +8,8 @@ use crate::{ constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, math_gadget::LtGadget, memory_gadget::{ - MemoryCopierGasGadget, MemoryExpandedAddressGadget, - MemoryExpansionGadget,CommonMemoryAddressGadget, + CommonMemoryAddressGadget, MemoryCopierGasGadget, MemoryExpandedAddressGadget, + MemoryExpansionGadget, }, or, CachedRegion, Cell, }, @@ -63,11 +63,13 @@ impl ExecutionGadget for ErrorOOGSha3Gadget { cb, cb.curr.state.gas_left.expr(), OpcodeId::SHA3.constant_gas_cost().expr() + memory_copier_gas.gas_cost(), + // OpcodeId::SHA3.constant_gas_cost().expr(), ); cb.require_equal( "Memory address is overflow or gas left is less than cost", or::expr([memory_address.overflow(), insufficient_gas.expr()]), + // or::expr([memory_address.overflow(), 0.expr()]), 1.expr(), ); @@ -98,13 +100,15 @@ impl ExecutionGadget for ErrorOOGSha3Gadget { step.gas_left, ); - let opcode = step.opcode(); - self.opcode - .assign(region, offset, Value::known(F::from(opcode.unwrap().as_u64())))?; + let opcode = step.opcode(); + self.opcode.assign( + region, + offset, + Value::known(F::from(opcode.unwrap().as_u64())), + )?; let [memory_offset, memory_length] = - [0, 1,].map(|idx| block.get_rws(step, idx).stack_value()); - // let memory_address = self + [0, 1].map(|idx| block.get_rws(step, idx).stack_value()); let expanded_address = self.memory_address @@ -129,9 +133,6 @@ impl ExecutionGadget for ErrorOOGSha3Gadget { OpcodeId::SHA3.constant_gas_cost() + memory_copier_gas, )), )?; - println!("gas_left {}, gas cost {}", step.gas_left ,OpcodeId::SHA3.constant_gas_cost() + memory_copier_gas); - _tx.steps().into_iter().map(|s| println!("step {:?}",s.exec_state)).count(); - self.common_error_gadget .assign(region, offset, block, call, step, 4)?; @@ -178,7 +179,7 @@ mod tests { let testing_data = TestingData::new(0xffffffff1, 0xffffffff0, MOCK_BLOCK_GAS_LIMIT); test_root(&testing_data); - //test_internal(&testing_data); + test_internal(&testing_data); } #[test] @@ -186,7 +187,7 @@ mod tests { let testing_data = TestingData::new(u64::MAX, u64::MAX, MOCK_BLOCK_GAS_LIMIT); test_root(&testing_data); - //test_internal(&testing_data); + test_internal(&testing_data); } struct TestingData { @@ -218,11 +219,7 @@ mod tests { fn dynamic_gas_cost(memory_offset: u64, memory_size: u64) -> u64 { let memory_word_size = (memory_offset + memory_size + 31) / 32; - memory_copier_gas_cost( - 0, - memory_word_size, - memory_size, - ) + memory_copier_gas_cost(0, memory_word_size, memory_size) } fn test_root(testing_data: &TestingData) { diff --git a/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs b/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs index 486af16696..b3e69ccd49 100644 --- a/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/extcodecopy.rs @@ -9,7 +9,10 @@ use crate::{ Transition, }, math_gadget::IsZeroWordGadget, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, CommonMemoryAddressGadget, MemoryExpansionGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget, + MemoryExpansionGadget, + }, not, select, AccountAddress, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/logs.rs b/zkevm-circuits/src/evm_circuit/execution/logs.rs index 23d19ae9c3..23c63bc0f2 100644 --- a/zkevm-circuits/src/evm_circuit/execution/logs.rs +++ b/zkevm-circuits/src/evm_circuit/execution/logs.rs @@ -9,7 +9,9 @@ use crate::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition::{Delta, To}, }, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget, + }, not, sum, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/return_revert.rs b/zkevm-circuits/src/evm_circuit/execution/return_revert.rs index 83f0dfa78a..0df3467253 100644 --- a/zkevm-circuits/src/evm_circuit/execution/return_revert.rs +++ b/zkevm-circuits/src/evm_circuit/execution/return_revert.rs @@ -10,7 +10,9 @@ use crate::{ Transition::{Delta, To}, }, math_gadget::{IsEqualGadget, IsZeroGadget, MinMaxGadget}, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget, + }, not, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs b/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs index 6636aee925..615736859e 100644 --- a/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/returndatacopy.rs @@ -10,7 +10,10 @@ use crate::{ Transition::{Delta, To}, }, math_gadget::RangeCheckGadget, - memory_gadget::{MemoryAddressGadget,CommonMemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget, + MemoryExpansionGadget, + }, CachedRegion, Cell, MemoryAddress, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/execution/sha3.rs b/zkevm-circuits/src/evm_circuit/execution/sha3.rs index 6a2a735482..adffa2acbf 100644 --- a/zkevm-circuits/src/evm_circuit/execution/sha3.rs +++ b/zkevm-circuits/src/evm_circuit/execution/sha3.rs @@ -12,7 +12,10 @@ use crate::{ constraint_builder::{ ConstrainBuilderCommon, EVMConstraintBuilder, StepStateTransition, Transition, }, - memory_gadget::{MemoryAddressGadget, MemoryCopierGasGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryAddressGadget, MemoryCopierGasGadget, + MemoryExpansionGadget, + }, rlc, CachedRegion, Cell, }, witness::{Block, Call, ExecStep, Transaction}, diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 65a2bd7174..4837daa489 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -2,7 +2,7 @@ use super::{ constraint_builder::ConstrainBuilderCommon, from_bytes, math_gadget::{IsEqualWordGadget, IsZeroGadget, IsZeroWordGadget, LtGadget}, - memory_gadget::{MemoryAddressGadget, MemoryExpansionGadget, CommonMemoryAddressGadget}, + memory_gadget::{CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget}, AccountAddress, CachedRegion, }; use crate::{ diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index 99360f84a9..daa32dbac1 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -1,12 +1,16 @@ use super::{constraint_builder::ConstrainBuilderCommon, CachedRegion, MemoryAddress, WordExpr}; use crate::{ evm_circuit::{ - param::{N_BYTES_GAS, N_BYTES_U64, N_BYTES_MEMORY_ADDRESS, N_BYTES_MEMORY_WORD_SIZE}, + param::{N_BYTES_GAS, N_BYTES_MEMORY_ADDRESS, N_BYTES_MEMORY_WORD_SIZE, N_BYTES_U64}, util::{ + and, constraint_builder::EVMConstraintBuilder, - math_gadget::{AddWordsGadget, ConstantDivisionGadget, IsZeroGadget, MinMaxGadget, - RangeCheckGadget, LtGadget,}, - select, sum, Cell, or, and, from_bytes, + from_bytes, + math_gadget::{ + AddWordsGadget, ConstantDivisionGadget, IsZeroGadget, LtGadget, MinMaxGadget, + RangeCheckGadget, + }, + or, select, sum, Cell, }, }, util::{ @@ -15,7 +19,10 @@ use crate::{ }, }; use array_init::array_init; -use eth_types::{evm_types::GasCost, evm_types::MAX_EXPANDED_MEMORY_ADDRESS, Field, ToLittleEndian, U256}; +use eth_types::{ + evm_types::{GasCost, MAX_EXPANDED_MEMORY_ADDRESS}, + Field, ToLittleEndian, U256, +}; use gadgets::util::not; use halo2_proofs::{ circuit::Value, @@ -106,8 +113,7 @@ impl MemoryAddressGadget { memory_offset: WordCell, memory_length: MemoryAddress, ) -> Self { - let memory_length_is_zero = - IsZeroGadget::construct(cb, memory_length.sum_expr()); + let memory_length_is_zero = IsZeroGadget::construct(cb, memory_length.sum_expr()); let memory_offset_bytes = cb.query_memory_address(); let has_length = 1.expr() - memory_length_is_zero.expr(); @@ -136,7 +142,7 @@ impl MemoryAddressGadget { pub(crate) fn offset(&self) -> Expression { self.has_length() * self.memory_offset_bytes.expr() } -} +} impl CommonMemoryAddressGadget for MemoryAddressGadget { fn construct_self(cb: &mut EVMConstraintBuilder) -> Self { @@ -180,12 +186,12 @@ impl CommonMemoryAddressGadget for MemoryAddressGadget { } fn offset_rlc(&self) -> Word> { - //self.memory_offset.expr() + // self.memory_offset.expr() self.memory_offset.to_word() } fn length_rlc(&self) -> Word> { - //self.memory_length.expr() + // self.memory_length.expr() self.memory_length.to_word() } @@ -222,9 +228,9 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { let sum = cb.query_word32(); let sum_lt_cap = LtGadget::construct( - cb, - //from_bytes::expr(&sum.cells[..N_BYTES_U64]), - sum::expr(&sum.limbs[..N_BYTES_U64]), + cb, + from_bytes::expr(&sum.limbs[..N_BYTES_U64]), + // sum::expr(&sum.limbs[..N_BYTES_U64]), (MAX_EXPANDED_MEMORY_ADDRESS + 1).expr(), ); @@ -288,13 +294,13 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { fn offset_rlc(&self) -> Word> { let addends = self.offset_length_sum.addends(); - //addends[0].expr() + // addends[0].expr() addends[0].to_word() } - fn length_rlc(&self) -> Word> { + fn length_rlc(&self) -> Word> { let addends = self.offset_length_sum.addends(); - //addends[1].expr() + // addends[1].expr() addends[1].to_word() } From 97a11638fee7cd78d53719b15505e5c8ec73d395 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Fri, 11 Aug 2023 17:27:39 +0800 Subject: [PATCH 5/9] fix length --- zkevm-circuits/src/evm_circuit/util/memory_gadget.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index daa32dbac1..a4499e553a 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -197,8 +197,7 @@ impl CommonMemoryAddressGadget for MemoryAddressGadget { // real length fn length(&self) -> Expression { - // todo: check self.memory_length.expr() rlc length ? - self.memory_length.sum_expr() + self.memory_length.expr() } fn address(&self) -> Expression { From f299718eae623b889effaba3d89716ef0731ef7e Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Mon, 14 Aug 2023 11:54:25 +0800 Subject: [PATCH 6/9] fix comments --- .../src/evm_circuit/execution/error_oog_sha3.rs | 6 ++---- .../src/evm_circuit/util/memory_gadget.rs | 15 ++++++--------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs index cfa51a7bc8..c77f112a08 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_sha3.rs @@ -49,8 +49,8 @@ impl ExecutionGadget for ErrorOOGSha3Gadget { ); let memory_address = MemoryExpandedAddressGadget::construct_self(cb); - cb.stack_pop(memory_address.offset_rlc()); - cb.stack_pop(memory_address.length_rlc()); + cb.stack_pop(memory_address.offset_word()); + cb.stack_pop(memory_address.length_word()); let memory_expansion = MemoryExpansionGadget::construct(cb, [memory_address.address()]); let memory_copier_gas = MemoryCopierGasGadget::construct( @@ -63,13 +63,11 @@ impl ExecutionGadget for ErrorOOGSha3Gadget { cb, cb.curr.state.gas_left.expr(), OpcodeId::SHA3.constant_gas_cost().expr() + memory_copier_gas.gas_cost(), - // OpcodeId::SHA3.constant_gas_cost().expr(), ); cb.require_equal( "Memory address is overflow or gas left is less than cost", or::expr([memory_address.overflow(), insufficient_gas.expr()]), - // or::expr([memory_address.overflow(), 0.expr()]), 1.expr(), ); diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index a4499e553a..69e998c2e3 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -83,10 +83,10 @@ pub(crate) trait CommonMemoryAddressGadget { ) -> Result; /// Return original word of memory offset. - fn offset_rlc(&self) -> Word>; + fn offset_word(&self) -> Word>; /// Return original word of memory length. - fn length_rlc(&self) -> Word>; + fn length_word(&self) -> Word>; /// Return valid memory length of Uint64. fn length(&self) -> Expression; @@ -185,13 +185,11 @@ impl CommonMemoryAddressGadget for MemoryAddressGadget { }) } - fn offset_rlc(&self) -> Word> { - // self.memory_offset.expr() + fn offset_word(&self) -> Word> { self.memory_offset.to_word() } - fn length_rlc(&self) -> Word> { - // self.memory_length.expr() + fn length_word(&self) -> Word> { self.memory_length.to_word() } @@ -229,7 +227,6 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { let sum_lt_cap = LtGadget::construct( cb, from_bytes::expr(&sum.limbs[..N_BYTES_U64]), - // sum::expr(&sum.limbs[..N_BYTES_U64]), (MAX_EXPANDED_MEMORY_ADDRESS + 1).expr(), ); @@ -291,13 +288,13 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { Ok(address) } - fn offset_rlc(&self) -> Word> { + fn offset_word(&self) -> Word> { let addends = self.offset_length_sum.addends(); // addends[0].expr() addends[0].to_word() } - fn length_rlc(&self) -> Word> { + fn length_word(&self) -> Word> { let addends = self.offset_length_sum.addends(); // addends[1].expr() addends[1].to_word() From ad26de4448416dde2c4539e2d07fe045f660d928 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Mon, 14 Aug 2023 15:22:17 +0800 Subject: [PATCH 7/9] implement oog create error --- bus-mapping/src/error.rs | 8 +- bus-mapping/src/evm/opcodes.rs | 9 +- zkevm-circuits/src/evm_circuit/execution.rs | 10 +- .../evm_circuit/execution/error_oog_create.rs | 387 ++++++++++++++++++ zkevm-circuits/src/evm_circuit/step.rs | 6 +- 5 files changed, 407 insertions(+), 13 deletions(-) create mode 100644 zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs diff --git a/bus-mapping/src/error.rs b/bus-mapping/src/error.rs index 8eb668b2fb..266c74a5ca 100644 --- a/bus-mapping/src/error.rs +++ b/bus-mapping/src/error.rs @@ -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, } @@ -105,7 +105,7 @@ impl From<&OpcodeId> for OogError { OpcodeId::MLOAD | OpcodeId::MSTORE | OpcodeId::MSTORE8 => { OogError::StaticMemoryExpansion } - OpcodeId::CREATE | OpcodeId::RETURN | OpcodeId::REVERT => { + OpcodeId::RETURN | OpcodeId::REVERT => { OogError::DynamicMemoryExpansion } OpcodeId::CALLDATACOPY @@ -124,7 +124,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, } diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index d1ae9c5477..60469dd463 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -269,12 +269,17 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps { } } -fn fn_gen_error_state_associated_ops(error: &ExecError) -> Option { +fn fn_gen_error_state_associated_ops( geth_step: &GethExecStep, error: &ExecError) -> Option { 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), @@ -363,7 +368,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 diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index ff03b22197..dae80f1877 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -83,6 +83,7 @@ mod error_oog_static_memory; mod error_return_data_oo_bound; mod error_stack; mod error_write_protection; +mod error_oog_create; mod exp; mod extcodecopy; mod extcodehash; @@ -158,6 +159,7 @@ use error_oog_sload_sstore::ErrorOOGSloadSstoreGadget; use error_return_data_oo_bound::ErrorReturnDataOutOfBoundGadget; use error_stack::ErrorStackGadget; use error_write_protection::ErrorWriteProtectionGadget; +use error_oog_create::ErrorOOGCreateGadget; use exp::ExponentiationGadget; use extcodecopy::ExtcodecopyGadget; use extcodehash::ExtcodehashGadget; @@ -310,7 +312,7 @@ pub struct ExecutionConfig { error_oog_sha3: Box>, error_oog_account_access: Box>, error_oog_ext_codecopy: Box>, - error_oog_create2: Box>, + error_oog_create: Box>, error_oog_self_destruct: Box>, error_oog_code_store: Box>, @@ -575,7 +577,7 @@ impl ExecutionConfig { 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!(), @@ -1315,8 +1317,8 @@ impl ExecutionConfig { 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) diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs new file mode 100644 index 0000000000..d7b0439ad2 --- /dev/null +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs @@ -0,0 +1,387 @@ +use crate::{ + evm_circuit::{ + execution::ExecutionGadget, + param::{N_BYTES_GAS, N_BYTES_MEMORY_ADDRESS, N_BYTES_MEMORY_WORD_SIZE}, + step::ExecutionState, + util::{ + common_gadget::CommonErrorGadget, + constraint_builder::{ConstrainBuilderCommon, EVMConstraintBuilder}, + math_gadget::{LtGadget, PairSelectGadget}, + memory_gadget::{ + CommonMemoryAddressGadget, MemoryExpandedAddressGadget, MemoryExpansionGadget, + MemoryWordSizeGadget, + }, + or, select, CachedRegion, Cell, Word, + }, + util::{ + word::{Word32Cell, WordCell}, + Expr, + }, + }, + witness::{Block, Call, ExecStep, Transaction}, +}; +use eth_types::{ + evm_types::{ + GasCost, OpcodeId, CREATE2_GAS_PER_CODE_WORD, CREATE_GAS_PER_CODE_WORD, MAX_INIT_CODE_SIZE, + }, + Field, ToLittleEndian, U256, +}; +use gadgets::util::Expr; +use halo2_proofs::{circuit::Value, plonk::Error}; + +#[derive(Clone, Debug)] +pub(crate) struct ErrorOOGCreateGadget { + opcode: Cell, + value: Word, + salt: Word, + is_create2: PairSelectGadget, + minimum_word_size: MemoryWordSizeGadget, + memory_address: MemoryExpandedAddressGadget, + memory_expansion: MemoryExpansionGadget, + // Init code size is overflow when it is greater than 49152 + // (maximum init code size) if Shanghai, otherwise when it is greater than + // 0x1FFFFFFFE0 (maximum value of offset + size). + // Uint64 overflow is checked in `memory_address` (offset + length). + init_code_size_overflow: LtGadget, + insufficient_gas: LtGadget, + common_error_gadget: CommonErrorGadget, +} + +impl ExecutionGadget for ErrorOOGCreateGadget { + const NAME: &'static str = "ErrorOutOfGasCREATE"; + + const EXECUTION_STATE: ExecutionState = ExecutionState::ErrorOutOfGasCREATE; + + fn configure(cb: &mut EVMConstraintBuilder) -> Self { + let opcode = cb.query_cell(); + + let is_create2 = PairSelectGadget::construct( + cb, + opcode.expr(), + OpcodeId::CREATE2.expr(), + OpcodeId::CREATE.expr(), + ); + + let value = cb.query_word32(); + let salt = cb.query_word32(); + + + + + let memory_address = MemoryExpandedAddressGadget::construct_self(cb); + + cb.stack_pop(value.to_word()); + cb.stack_pop(memory_address.offset_word()); + cb.stack_pop(memory_address.length_word()); + cb.condition(is_create2.expr().0, |cb| cb.stack_pop(salt.expr())); + + let init_code_size_overflow = + LtGadget::construct(cb, MAX_INIT_CODE_SIZE.expr(), memory_address.length()); + + let minimum_word_size = MemoryWordSizeGadget::construct(cb, memory_address.length()); + let memory_expansion = MemoryExpansionGadget::construct(cb, [memory_address.end_offset()]); + + let keccak_gas_cost = minimum_word_size.expr() + * select::expr( + is_create2.expr().0, + CREATE2_GAS_PER_CODE_WORD.expr(), + CREATE_GAS_PER_CODE_WORD.expr(), + ); + let gas_cost = GasCost::CREATE.expr() + memory_expansion.gas_cost() + keccak_gas_cost; + let insufficient_gas = LtGadget::construct(cb, cb.curr.state.gas_left.expr(), gas_cost); + + cb.require_equal( + "Memory address is overflow, init code size is overflow, or gas left is less than cost", + or::expr([ + memory_address.overflow(), + init_code_size_overflow.expr(), + insufficient_gas.expr(), + ]), + 1.expr(), + ); + + let common_error_gadget = CommonErrorGadget::construct( + cb, + opcode.expr(), + select::expr(is_create2.expr().0, 6.expr(), 5.expr()), + ); + + Self { + opcode, + value, + salt, + is_create2, + minimum_word_size, + memory_address, + memory_expansion, + init_code_size_overflow, + insufficient_gas, + common_error_gadget, + } + } + + fn assign_exec_step( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + block: &Block, + _: &Transaction, + call: &Call, + step: &ExecStep, + ) -> Result<(), Error> { + log::debug!( + "ErrorOutOfGasCREATE: gas_cost = {}, gas_left = {}", + step.gas_cost, + step.gas_left, + ); + + let opcode = step.opcode().unwrap(); + let is_create2 = opcode == OpcodeId::CREATE2; + self.opcode + .assign(region, offset, Value::known(F::from(opcode.as_u64())))?; + self.is_create2.assign( + region, + offset, + F::from(opcode.as_u64()), + F::from(OpcodeId::CREATE2.as_u64()), + F::from(OpcodeId::CREATE.as_u64()), + )?; + + let [value, memory_offset, memory_length] = + [0, 1, 2].map(|idx| block.rws[step.rw_indices[idx]].stack_value()); + let salt = if is_create2 { + block.rws[step.rw_indices[3]].stack_value() + } else { + U256::zero() + }; + + self.value + .assign(region, offset, Some(value.to_le_bytes()))?; + self.salt.assign(region, offset, Some(salt.to_le_bytes()))?; + + let memory_address = + self.memory_address + .assign(region, offset, memory_offset, memory_length)?; + + let init_code_size = + MemoryExpandedAddressGadget::::length_value(memory_offset, memory_length); + let minimum_word_size = self + .minimum_word_size + .assign(region, offset, init_code_size)?; + let memory_expansion_gas = self + .memory_expansion + .assign(region, offset, step.memory_word_size(), [memory_address])? + .1; + + self.init_code_size_overflow.assign( + region, + offset, + F::from(MAX_INIT_CODE_SIZE), + F::from(init_code_size), + )?; + + let keccak_gas_cost = minimum_word_size + * if is_create2 { + CREATE2_GAS_PER_CODE_WORD + } else { + CREATE_GAS_PER_CODE_WORD + }; + self.insufficient_gas.assign( + region, + offset, + F::from(step.gas_left), + F::from(GasCost::CREATE + memory_expansion_gas + keccak_gas_cost), + )?; + + self.common_error_gadget.assign( + region, + offset, + block, + call, + step, + if is_create2 { 6 } else { 5 }, + )?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_util::CircuitTestBuilder; + use eth_types::{bytecode, word, Bytecode, ToWord}; + use mock::{ + eth, + test_ctx::{helpers::account_0_code_account_1_no_code, LoggerConfig}, + TestContext, MOCK_ACCOUNTS, MOCK_BLOCK_GAS_LIMIT, + }; + + struct TestCase { + bytecode: Bytecode, + gas: u64, + } + + impl TestCase { + pub fn new(is_create2: bool, offset: U256, size: U256, gas: u64) -> Self { + let mut bytecode = Bytecode::default(); + if is_create2 { + bytecode.append(&bytecode! {PUSH1(0)}); // salt; + } + bytecode.append(&bytecode! { + PUSH32(size) // size + PUSH32(offset) // offset + PUSH1(0) // value + }); + bytecode.write_op(if is_create2 { + OpcodeId::CREATE2 + } else { + OpcodeId::CREATE + }); + + Self { bytecode, gas } + } + } + + #[test] + fn test_oog_create_simple() { + let mut cases = vec![]; + for is_create2 in [true, false] { + cases.push(TestCase::new( + is_create2, + 0xffffffff_u64.into(), + 0xff.into(), + 0xffff, + )); + + cases.push(TestCase::new(is_create2, U256::zero(), 4.into(), 0x7d08)); + } + + for case in cases.iter() { + test_root(case); + test_internal(case); + } + } + + #[test] + fn test_oog_create_max_expanded_address() { + for is_create2 in [true, false] { + // 0xffffffff1 + 0xffffffff0 = 0x1fffffffe1 + // > MAX_EXPANDED_MEMORY_ADDRESS (0x1fffffffe0) + let case = TestCase::new( + is_create2, + 0xffffffff1_u64.into(), + 0xffffffff0_u64.into(), + MOCK_BLOCK_GAS_LIMIT, + ); + + test_root(&case); + test_internal(&case); + } + } + + #[test] + fn test_oog_create_max_u64_address() { + for is_create2 in [true, false] { + let case = TestCase::new( + is_create2, + u64::MAX.into(), + u64::MAX.into(), + MOCK_BLOCK_GAS_LIMIT, + ); + + test_root(&case); + test_internal(&case); + } + } + + #[test] + fn test_oog_create_max_word_address() { + for is_create2 in [true, false] { + let case = TestCase::new(is_create2, U256::MAX, U256::MAX, MOCK_BLOCK_GAS_LIMIT); + + test_root(&case); + test_internal(&case); + } + } + + #[test] + fn test_oog_create_max_init_code_size() { + for is_create2 in [true, false] { + // For Shanghai, MAX_INIT_CODE_SIZE is 49152, it is constrained by + // `init_code_size_overflow`. + // For not Shanghai, MAX_INIT_CODE_SIZE is 0x1FFFFFFFE0, it is + // constrained by `memory_address.overflow()` + // (and `init_code_size_overflow`). + let case = TestCase::new( + is_create2, + U256::zero(), + (MAX_INIT_CODE_SIZE + 1).into(), + MOCK_BLOCK_GAS_LIMIT, + ); + + test_root(&case); + test_internal(&case); + } + } + + fn test_root(case: &TestCase) { + let ctx = TestContext::<2, 1>::new_with_logger_config( + None, + account_0_code_account_1_no_code(case.bytecode.clone()), + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .gas(case.gas.into()); + }, + |block, _tx| block, + LoggerConfig { + enable_memory: true, + ..Default::default() + }, + ) + .unwrap(); + + CircuitTestBuilder::new_from_test_ctx(ctx).run(); + } + + fn test_internal(case: &TestCase) { + let code_a = bytecode! { + PUSH1(0x00) // retLength + PUSH1(0x00) // retOffset + PUSH32(0x00) // argsLength + PUSH32(0x00) // argsOffset + PUSH1(0x00) // value + PUSH32(MOCK_ACCOUNTS[1].to_word()) // addr + PUSH32(case.gas) // gas + CALL + STOP + }; + + let ctx = TestContext::<3, 1>::new_with_logger_config( + None, + |accs| { + accs[0].address(MOCK_ACCOUNTS[0]).code(code_a); + accs[1] + .address(MOCK_ACCOUNTS[1]) + .code(case.bytecode.clone()); + accs[2].address(MOCK_ACCOUNTS[2]).balance(eth(1)); + }, + |mut txs, accs| { + txs[0] + .from(accs[2].address) + .to(accs[0].address) + .gas(word!("0xFFFFF")); + }, + |block, _tx| block, + LoggerConfig { + enable_memory: true, + ..Default::default() + }, + ) + .unwrap(); + + CircuitTestBuilder::new_from_test_ctx(ctx).run(); + } +} diff --git a/zkevm-circuits/src/evm_circuit/step.rs b/zkevm-circuits/src/evm_circuit/step.rs index eb381585b2..998223abfa 100644 --- a/zkevm-circuits/src/evm_circuit/step.rs +++ b/zkevm-circuits/src/evm_circuit/step.rs @@ -136,7 +136,7 @@ pub enum ExecutionState { ErrorOutOfGasEXTCODECOPY, ErrorOutOfGasCall, ErrorOutOfGasSloadSstore, - ErrorOutOfGasCREATE2, + ErrorOutOfGasCREATE, ErrorOutOfGasSELFDESTRUCT, } @@ -196,7 +196,7 @@ impl From<&ExecError> for ExecutionState { OogError::Sha3 => ExecutionState::ErrorOutOfGasSHA3, OogError::Call => ExecutionState::ErrorOutOfGasCall, OogError::SloadSstore => ExecutionState::ErrorOutOfGasSloadSstore, - OogError::Create2 => ExecutionState::ErrorOutOfGasCREATE2, + OogError::Create => ExecutionState::ErrorOutOfGasCREATE, OogError::SelfDestruct => ExecutionState::ErrorOutOfGasSELFDESTRUCT, }, } @@ -346,7 +346,7 @@ impl ExecutionState { | Self::ErrorOutOfGasEXTCODECOPY | Self::ErrorOutOfGasCall | Self::ErrorOutOfGasSloadSstore - | Self::ErrorOutOfGasCREATE2 + | Self::ErrorOutOfGasCREATE | Self::ErrorOutOfGasSELFDESTRUCT ) } From ec7f4ea4cb19f6dcc2ac25a488a60e9d8e311499 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Mon, 14 Aug 2023 17:11:44 +0800 Subject: [PATCH 8/9] fix test failures --- bus-mapping/src/error.rs | 6 ++-- eth-types/src/evm_types.rs | 33 +++++++++++++++++++ zkevm-circuits/src/evm_circuit/execution.rs | 4 +-- .../evm_circuit/execution/error_oog_create.rs | 30 +++++++---------- .../src/evm_circuit/util/memory_gadget.rs | 2 +- 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/bus-mapping/src/error.rs b/bus-mapping/src/error.rs index 266c74a5ca..4bec3d713b 100644 --- a/bus-mapping/src/error.rs +++ b/bus-mapping/src/error.rs @@ -105,9 +105,7 @@ impl From<&OpcodeId> for OogError { OpcodeId::MLOAD | OpcodeId::MSTORE | OpcodeId::MSTORE8 => { OogError::StaticMemoryExpansion } - OpcodeId::RETURN | OpcodeId::REVERT => { - OogError::DynamicMemoryExpansion - } + OpcodeId::RETURN | OpcodeId::REVERT => OogError::DynamicMemoryExpansion, OpcodeId::CALLDATACOPY | OpcodeId::CODECOPY | OpcodeId::EXTCODECOPY @@ -124,7 +122,7 @@ impl From<&OpcodeId> for OogError { OogError::Call } OpcodeId::SLOAD | OpcodeId::SSTORE => OogError::SloadSstore, - OpcodeId::CREATE | OpcodeId::CREATE2 => OogError::Create, + OpcodeId::CREATE | OpcodeId::CREATE2 => OogError::Create, OpcodeId::SELFDESTRUCT => OogError::SelfDestruct, _ => OogError::Constant, } diff --git a/eth-types/src/evm_types.rs b/eth-types/src/evm_types.rs index f59c186824..44b1befedf 100644 --- a/eth-types/src/evm_types.rs +++ b/eth-types/src/evm_types.rs @@ -28,6 +28,39 @@ pub const GAS_STIPEND_CALL_WITH_VALUE: u64 = 2300; /// 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; diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index dae80f1877..7e521dfdb1 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -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; @@ -83,7 +84,6 @@ mod error_oog_static_memory; mod error_return_data_oo_bound; mod error_stack; mod error_write_protection; -mod error_oog_create; mod exp; mod extcodecopy; mod extcodehash; @@ -151,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; @@ -159,7 +160,6 @@ use error_oog_sload_sstore::ErrorOOGSloadSstoreGadget; use error_return_data_oo_bound::ErrorReturnDataOutOfBoundGadget; use error_stack::ErrorStackGadget; use error_write_protection::ErrorWriteProtectionGadget; -use error_oog_create::ErrorOOGCreateGadget; use exp::ExponentiationGadget; use extcodecopy::ExtcodecopyGadget; use extcodehash::ExtcodehashGadget; diff --git a/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs b/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs index d7b0439ad2..c9cc03b911 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_oog_create.rs @@ -11,29 +11,25 @@ use crate::{ CommonMemoryAddressGadget, MemoryExpandedAddressGadget, MemoryExpansionGadget, MemoryWordSizeGadget, }, - or, select, CachedRegion, Cell, Word, - }, - util::{ - word::{Word32Cell, WordCell}, - Expr, + or, select, CachedRegion, Cell, WordExpr, }, }, + util::{word::Word32Cell, Expr}, witness::{Block, Call, ExecStep, Transaction}, }; use eth_types::{ evm_types::{ GasCost, OpcodeId, CREATE2_GAS_PER_CODE_WORD, CREATE_GAS_PER_CODE_WORD, MAX_INIT_CODE_SIZE, }, - Field, ToLittleEndian, U256, + Field, U256, }; -use gadgets::util::Expr; use halo2_proofs::{circuit::Value, plonk::Error}; #[derive(Clone, Debug)] pub(crate) struct ErrorOOGCreateGadget { opcode: Cell, - value: Word, - salt: Word, + value: Word32Cell, + salt: Word32Cell, is_create2: PairSelectGadget, minimum_word_size: MemoryWordSizeGadget, memory_address: MemoryExpandedAddressGadget, @@ -65,21 +61,18 @@ impl ExecutionGadget for ErrorOOGCreateGadget { let value = cb.query_word32(); let salt = cb.query_word32(); - - - let memory_address = MemoryExpandedAddressGadget::construct_self(cb); cb.stack_pop(value.to_word()); cb.stack_pop(memory_address.offset_word()); cb.stack_pop(memory_address.length_word()); - cb.condition(is_create2.expr().0, |cb| cb.stack_pop(salt.expr())); + cb.condition(is_create2.expr().0, |cb| cb.stack_pop(salt.to_word())); let init_code_size_overflow = LtGadget::construct(cb, MAX_INIT_CODE_SIZE.expr(), memory_address.length()); let minimum_word_size = MemoryWordSizeGadget::construct(cb, memory_address.length()); - let memory_expansion = MemoryExpansionGadget::construct(cb, [memory_address.end_offset()]); + let memory_expansion = MemoryExpansionGadget::construct(cb, [memory_address.address()]); let keccak_gas_cost = minimum_word_size.expr() * select::expr( @@ -148,16 +141,15 @@ impl ExecutionGadget for ErrorOOGCreateGadget { )?; let [value, memory_offset, memory_length] = - [0, 1, 2].map(|idx| block.rws[step.rw_indices[idx]].stack_value()); + [0, 1, 2].map(|i| block.get_rws(step, i).stack_value()); let salt = if is_create2 { - block.rws[step.rw_indices[3]].stack_value() + block.get_rws(step, 3).stack_value() } else { U256::zero() }; - self.value - .assign(region, offset, Some(value.to_le_bytes()))?; - self.salt.assign(region, offset, Some(salt.to_le_bytes()))?; + self.value.assign_u256(region, offset, value)?; + self.salt.assign_u256(region, offset, salt)?; let memory_address = self.memory_address diff --git a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs index 69e998c2e3..0813f6b5f9 100644 --- a/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/memory_gadget.rs @@ -316,7 +316,7 @@ impl CommonMemoryAddressGadget for MemoryExpandedAddressGadget { 0.expr(), select::expr( self.within_range(), - sum::expr(&self.offset_length_sum.sum().limbs[..N_BYTES_U64]), + from_bytes::expr(&self.offset_length_sum.sum().limbs[..N_BYTES_U64]), 0.expr(), ), ) From ae508c98c5e1aacff14b29c6793635a1e18ac3c2 Mon Sep 17 00:00:00 2001 From: Dream Wu Date: Mon, 14 Aug 2023 17:18:05 +0800 Subject: [PATCH 9/9] update opcode.rs --- bus-mapping/src/evm/opcodes.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 60469dd463..eb5d9e540e 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -269,7 +269,10 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps { } } -fn fn_gen_error_state_associated_ops( geth_step: &GethExecStep, error: &ExecError) -> Option { +fn fn_gen_error_state_associated_ops( + geth_step: &GethExecStep, + error: &ExecError, +) -> Option { match error { ExecError::InvalidJump => Some(InvalidJump::gen_associated_ops), ExecError::InvalidOpcode => Some(ErrorSimple::gen_associated_ops),