From 3eee3e26dcdcc60aad5ac1282bcace3500b02c19 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Fri, 1 Apr 2022 12:51:17 +0200 Subject: [PATCH 1/7] Add gasprice impl for bus-mapping --- bus-mapping/src/evm/opcodes.rs | 4 +- bus-mapping/src/evm/opcodes/gasprice.rs | 122 ++++++++++++++++++++++++ mock/src/test_ctx.rs | 4 +- 3 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 bus-mapping/src/evm/opcodes/gasprice.rs diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index c034b8440d..4d1585a889 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -23,6 +23,7 @@ mod caller; mod callvalue; mod dup; mod extcodehash; +mod gasprice; mod mload; mod mstore; mod number; @@ -39,6 +40,7 @@ use caller::Caller; use callvalue::Callvalue; use dup::Dup; use extcodehash::Extcodehash; +use gasprice::GasPrice; use mload::Mload; use mstore::Mstore; use selfbalance::Selfbalance; @@ -113,7 +115,7 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps { OpcodeId::CALLDATACOPY => Calldatacopy::gen_associated_ops, // OpcodeId::CODESIZE => {}, // OpcodeId::CODECOPY => {}, - // OpcodeId::GASPRICE => {}, + OpcodeId::GASPRICE => GasPrice::gen_associated_ops, // OpcodeId::EXTCODESIZE => {}, // OpcodeId::EXTCODECOPY => {}, // OpcodeId::RETURNDATASIZE => {}, diff --git a/bus-mapping/src/evm/opcodes/gasprice.rs b/bus-mapping/src/evm/opcodes/gasprice.rs new file mode 100644 index 0000000000..b4b3131b92 --- /dev/null +++ b/bus-mapping/src/evm/opcodes/gasprice.rs @@ -0,0 +1,122 @@ +use super::Opcode; +use crate::circuit_input_builder::{CircuitInputStateRef, ExecStep}; +use crate::operation::{CallContextField, CallContextOp, RW}; +use crate::Error; +use eth_types::GethExecStep; + +/// Placeholder structure used to implement [`Opcode`] trait over it +/// corresponding to the [`OpcodeId::PC`](crate::evm::OpcodeId::PC) `OpcodeId`. +#[derive(Debug, Copy, Clone)] +pub(crate) struct GasPrice; + +impl Opcode for GasPrice { + fn gen_associated_ops( + state: &mut CircuitInputStateRef, + geth_steps: &[GethExecStep], + ) -> Result, Error> { + let geth_step = &geth_steps[0]; + let mut exec_step = state.new_step(geth_step)?; + // Get gasprice result from next step + let value = geth_steps[1].stack.last()?; + // CallContext read of the TxId + state.push_op( + &mut exec_step, + RW::READ, + CallContextOp { + call_id: state.call()?.call_id, + field: CallContextField::TxId, + value: 1u64.into(), + }, + ); + + // Stack write of the caller_address + state.push_stack_op( + &mut exec_step, + RW::WRITE, + geth_step.stack.last_filled().map(|a| a - 1), + value, + )?; + + Ok(vec![exec_step]) + } +} + +#[cfg(test)] +mod gasprice_tests { + use crate::{ + circuit_input_builder::ExecState, + evm::OpcodeId, + mock::BlockData, + operation::{CallContextField, CallContextOp, StackOp, RW}, + Error, + }; + use eth_types::{bytecode, evm_types::StackAddress, geth_types::GethData, Word}; + use mock::test_ctx::{helpers::*, TestContext}; + use pretty_assertions::assert_eq; + + #[test] + fn gasprice_opcode_impl() -> Result<(), Error> { + let code = bytecode! { + #[start] + GASPRICE + STOP + }; + + let two_gwei = Word::from(2_000_000_000u64); + + // Get the execution steps from the external tracer + let block: GethData = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(code), + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .gas_price(two_gwei); + }, + |block, _tx| block.number(0xcafeu64), + ) + .unwrap() + .into(); + + let mut builder = BlockData::new_from_geth_data(block.clone()).new_circuit_input_builder(); + builder + .handle_block(&block.eth_block, &block.geth_traces) + .unwrap(); + + let step = builder.block.txs()[0] + .steps() + .iter() + .find(|step| step.exec_state == ExecState::Op(OpcodeId::GASPRICE)) + .unwrap(); + + let op_gasprice = &builder.block.container.stack[step.bus_mapping_instance[1].as_usize()]; + assert_eq!( + (op_gasprice.rw(), op_gasprice.op()), + ( + RW::WRITE, + &StackOp::new(1, StackAddress(1023usize), two_gwei) + ) + ); + + let call_id = builder.block.txs()[0].calls()[0].call_id; + + assert_eq!( + { + let operation = + &builder.block.container.call_context[step.bus_mapping_instance[0].as_usize()]; + (operation.rw(), operation.op()) + }, + ( + RW::READ, + &CallContextOp { + call_id, + field: CallContextField::TxId, + value: Word::one(), + } + ) + ); + + Ok(()) + } +} diff --git a/mock/src/test_ctx.rs b/mock/src/test_ctx.rs index 0375de660c..edf465a103 100644 --- a/mock/src/test_ctx.rs +++ b/mock/src/test_ctx.rs @@ -228,11 +228,11 @@ pub mod helpers { |accs| { accs[0] .address(MOCK_ACCOUNTS[0]) - .balance(Word::from(1u64 << 20)) + .balance(Word::from(10u64.pow(19))) .code(code); accs[1] .address(MOCK_ACCOUNTS[1]) - .balance(Word::from(1u64 << 20)); + .balance(Word::from(10u64.pow(19))); } } From 62cd4eff84a295bb2d6bc730ac1d90b5787c25db Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 3 Apr 2022 16:36:22 +0200 Subject: [PATCH 2/7] Refactor test_util for evm_circuits simplifying it This module was tending to grow into a monster as `mock/lib.rs` was in the past due to the fact that a lot of functions were being created with minimal customizations from the generic simple calls. Instead, the idea would be that on each test the ctx is written. And to not make it super verbose, `TestContext::simple_ctx_with_bytecode` has been implemented. Then, all of the tests that were able to have simpler and easier config calls have been created. --- mock/src/test_ctx.rs | 15 +++++++ zkevm-circuits/src/evm_circuit/execution.rs | 5 +++ .../src/evm_circuit/execution/add.rs | 10 ++++- .../src/evm_circuit/execution/bitwise.rs | 20 ++++++---- .../src/evm_circuit/execution/byte.rs | 10 ++++- .../src/evm_circuit/execution/calldatacopy.rs | 24 ++++++++--- .../src/evm_circuit/execution/caller.rs | 17 +++++--- .../src/evm_circuit/execution/callvalue.rs | 17 +++++--- .../src/evm_circuit/execution/coinbase.rs | 17 +++++--- .../src/evm_circuit/execution/comparator.rs | 10 ++++- .../src/evm_circuit/execution/dup.rs | 10 ++++- .../src/evm_circuit/execution/gas.rs | 9 ++++- .../src/evm_circuit/execution/jump.rs | 10 ++++- .../src/evm_circuit/execution/jumpdest.rs | 17 ++++---- .../src/evm_circuit/execution/jumpi.rs | 10 ++++- .../src/evm_circuit/execution/memory.rs | 9 ++++- .../src/evm_circuit/execution/msize.rs | 9 ++++- .../src/evm_circuit/execution/mul.rs | 10 ++++- .../src/evm_circuit/execution/number.rs | 10 ++++- .../src/evm_circuit/execution/pc.rs | 10 ++++- .../src/evm_circuit/execution/pop.rs | 10 ++++- .../src/evm_circuit/execution/push.rs | 9 ++++- .../src/evm_circuit/execution/selfbalance.rs | 10 ++++- .../execution/signed_comparator.rs | 10 ++++- .../src/evm_circuit/execution/signextend.rs | 10 ++++- .../src/evm_circuit/execution/swap.rs | 10 ++++- .../src/evm_circuit/execution/timestamp.rs | 17 +++++--- zkevm-circuits/src/evm_circuit/witness.rs | 1 + zkevm-circuits/src/test_util.rs | 40 +++---------------- 29 files changed, 269 insertions(+), 97 deletions(-) diff --git a/mock/src/test_ctx.rs b/mock/src/test_ctx.rs index edf465a103..c232768f62 100644 --- a/mock/src/test_ctx.rs +++ b/mock/src/test_ctx.rs @@ -6,6 +6,7 @@ use eth_types::{ Block, Bytecode, Error, GethExecTrace, Transaction, Word, }; use external_tracer::{trace, TraceConfig}; +use helpers::*; use itertools::Itertools; /// TestContext is a type that contains all the information from a block @@ -185,6 +186,20 @@ impl TestContext { geth_traces, }) } + + /// Returns a simple TestContext setup with a single tx executing the + /// bytecode passed as parameters. The balances of the 2 accounts and + /// addresses are the ones used in [`TestContext:: + /// account_0_code_account_1_no_code`]. Extra accounts, txs and/or block + /// configs are set as [`Default`]. + pub fn simple_ctx_with_bytecode(bytecode: Bytecode) -> Result, Error> { + TestContext::new( + None, + account_0_code_account_1_no_code(bytecode), + tx_from_1_to_0, + |block, _txs| block, + ) + } } /// Generates execution traces for the transactions included in the provided diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index 7942895a1f..5fe0bfe46c 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -35,6 +35,7 @@ mod end_tx; mod error_oog_static_memory; mod extcodehash; mod gas; +mod gasprice; mod is_zero; mod jump; mod jumpdest; @@ -74,6 +75,7 @@ use end_tx::EndTxGadget; use error_oog_static_memory::ErrorOOGStaticMemoryGadget; use extcodehash::ExtcodehashGadget; use gas::GasGadget; +use gasprice::GasPriceGadget; use is_zero::IsZeroGadget; use jump::JumpGadget; use jumpdest::JumpdestGadget; @@ -139,6 +141,7 @@ pub(crate) struct ExecutionConfig { jump_gadget: JumpGadget, jumpdest_gadget: JumpdestGadget, jumpi_gadget: JumpiGadget, + gasprice_gadget: GasPriceGadget, gas_gadget: GasGadget, memory_gadget: MemoryGadget, copy_to_memory_gadget: CopyToMemoryGadget, @@ -358,6 +361,7 @@ impl ExecutionConfig { jumpdest_gadget: configure_gadget!(), jumpi_gadget: configure_gadget!(), gas_gadget: configure_gadget!(), + gasprice_gadget: configure_gadget!(), memory_gadget: configure_gadget!(), copy_to_memory_gadget: configure_gadget!(), pc_gadget: configure_gadget!(), @@ -630,6 +634,7 @@ impl ExecutionConfig { assign_exec_step!(self.jumpdest_gadget) } ExecutionState::GAS => assign_exec_step!(self.gas_gadget), + ExecutionState::GASPRICE => assign_exec_step!(self.gasprice_gadget), ExecutionState::PUSH => assign_exec_step!(self.push_gadget), ExecutionState::DUP => assign_exec_step!(self.dup_gadget), ExecutionState::SWAP => assign_exec_step!(self.swap_gadget), diff --git a/zkevm-circuits/src/evm_circuit/execution/add.rs b/zkevm-circuits/src/evm_circuit/execution/add.rs index fd56a5194d..af19e0c418 100644 --- a/zkevm-circuits/src/evm_circuit/execution/add.rs +++ b/zkevm-circuits/src/evm_circuit/execution/add.rs @@ -108,6 +108,7 @@ mod test { use crate::test_util::run_test_circuits; use eth_types::evm_types::OpcodeId; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(opcode: OpcodeId, a: Word, b: Word) { let bytecode = bytecode! { @@ -116,7 +117,14 @@ mod test { .write_op(opcode) STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/bitwise.rs b/zkevm-circuits/src/evm_circuit/execution/bitwise.rs index 0d7b0e4465..22b8bcc081 100644 --- a/zkevm-circuits/src/evm_circuit/execution/bitwise.rs +++ b/zkevm-circuits/src/evm_circuit/execution/bitwise.rs @@ -103,11 +103,10 @@ impl ExecutionGadget for BitwiseGadget { mod test { use crate::{ evm_circuit::test::rand_word, - test_util::{ - get_fixed_table, test_circuits_using_bytecode, BytecodeTestConfig, FixedTableConfig, - }, + test_util::{get_fixed_table, run_test_circuits, BytecodeTestConfig, FixedTableConfig}, }; use eth_types::{bytecode, Word}; + use mock::test_ctx::{helpers::*, TestContext}; fn test_ok(a: Word, b: Word) { let bytecode = bytecode! { @@ -128,10 +127,17 @@ mod test { evm_circuit_lookup_tags: get_fixed_table(FixedTableConfig::Complete), ..Default::default() }; - assert_eq!( - test_circuits_using_bytecode(bytecode, test_config, None), - Ok(()) - ); + + // Get the execution steps from the external tracer + let ctx = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(bytecode), + tx_from_1_to_0, + |block, _tx| block.number(0xcafeu64), + ) + .unwrap(); + + assert_eq!(run_test_circuits(ctx, Some(test_config)), Ok(())); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/byte.rs b/zkevm-circuits/src/evm_circuit/execution/byte.rs index be71a6440f..670493c1ae 100644 --- a/zkevm-circuits/src/evm_circuit/execution/byte.rs +++ b/zkevm-circuits/src/evm_circuit/execution/byte.rs @@ -129,6 +129,7 @@ impl ExecutionGadget for ByteGadget { mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(index: Word, value: Word) { let bytecode = bytecode! { @@ -137,7 +138,14 @@ mod test { BYTE STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs b/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs index b1d1ac9967..9f78367f90 100644 --- a/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs +++ b/zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs @@ -234,13 +234,14 @@ mod test { test::{rand_bytes, run_test_circuit_incomplete_fixed_table}, witness::{Block, Bytecode, Call, CodeSource, ExecStep, Rw, RwMap, Transaction}, }; - use crate::test_util::{test_circuits_using_bytecode, BytecodeTestConfig}; + use crate::test_util::run_test_circuits; use eth_types::{ bytecode, evm_types::{gas_utils::memory_copier_gas_cost, GasCost, OpcodeId}, ToBigEndian, Word, }; use halo2_proofs::arithmetic::BaseExt; + use mock::test_ctx::{helpers::*, TestContext}; use pairing::bn256::Fr as Fp; fn test_ok_root(call_data_length: usize, memory_offset: Word, data_offset: Word, length: Word) { @@ -253,11 +254,22 @@ mod test { STOP }; let call_data = rand_bytes(call_data_length); - let test_config = BytecodeTestConfig::default(); - assert_eq!( - test_circuits_using_bytecode(bytecode, test_config, Some(call_data)), - Ok(()) - ); + + // Get the execution steps from the external tracer + let ctx = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(bytecode), + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .input(call_data.into()); + }, + |block, _tx| block.number(0xcafeu64), + ) + .unwrap(); + + assert_eq!(run_test_circuits(ctx, None), Ok(())); } fn test_ok_internal( diff --git a/zkevm-circuits/src/evm_circuit/execution/caller.rs b/zkevm-circuits/src/evm_circuit/execution/caller.rs index 6e67e1c009..19c273c2ba 100644 --- a/zkevm-circuits/src/evm_circuit/execution/caller.rs +++ b/zkevm-circuits/src/evm_circuit/execution/caller.rs @@ -92,16 +92,21 @@ impl ExecutionGadget for CallerGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; - fn test_ok() { + #[test] + fn caller_gadget_test() { let bytecode = bytecode! { CALLER STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); - } - #[test] - fn caller_gadget_test() { - test_ok(); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/callvalue.rs b/zkevm-circuits/src/evm_circuit/execution/callvalue.rs index 65b54e5790..274ff18b1a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callvalue.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callvalue.rs @@ -90,16 +90,21 @@ impl ExecutionGadget for CallValueGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; - fn test_ok() { + #[test] + fn callvalue_gadget_test() { let bytecode = bytecode! { CALLVALUE STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); - } - #[test] - fn callvalue_gadget_test() { - test_ok(); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/coinbase.rs b/zkevm-circuits/src/evm_circuit/execution/coinbase.rs index 96458ddc03..a256b74cc5 100644 --- a/zkevm-circuits/src/evm_circuit/execution/coinbase.rs +++ b/zkevm-circuits/src/evm_circuit/execution/coinbase.rs @@ -91,16 +91,21 @@ impl ExecutionGadget for CoinbaseGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; - fn test_ok() { + #[test] + fn coinbase_gadget_test() { let bytecode = bytecode! { COINBASE STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); - } - #[test] - fn coinbase_gadget_test() { - test_ok(); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/comparator.rs b/zkevm-circuits/src/evm_circuit/execution/comparator.rs index acd95d397a..3880b780e1 100644 --- a/zkevm-circuits/src/evm_circuit/execution/comparator.rs +++ b/zkevm-circuits/src/evm_circuit/execution/comparator.rs @@ -171,6 +171,7 @@ mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::evm_types::OpcodeId; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(opcode: OpcodeId, a: Word, b: Word, _c: Word) { let bytecode = bytecode! { @@ -179,7 +180,14 @@ mod test { .write_op(opcode) STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/dup.rs b/zkevm-circuits/src/evm_circuit/execution/dup.rs index dd3a9a76c2..d18346d154 100644 --- a/zkevm-circuits/src/evm_circuit/execution/dup.rs +++ b/zkevm-circuits/src/evm_circuit/execution/dup.rs @@ -85,6 +85,7 @@ mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::evm_types::OpcodeId; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(opcode: OpcodeId, value: Word) { let n = (opcode.as_u8() - OpcodeId::DUP1.as_u8() + 1) as usize; @@ -98,7 +99,14 @@ mod test { .write_op(opcode) STOP }); - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/gas.rs b/zkevm-circuits/src/evm_circuit/execution/gas.rs index c514dd2ecd..2183831ca1 100644 --- a/zkevm-circuits/src/evm_circuit/execution/gas.rs +++ b/zkevm-circuits/src/evm_circuit/execution/gas.rs @@ -99,7 +99,14 @@ mod test { GAS STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/jump.rs b/zkevm-circuits/src/evm_circuit/execution/jump.rs index e7ca28fe22..f03dd65af0 100644 --- a/zkevm-circuits/src/evm_circuit/execution/jump.rs +++ b/zkevm-circuits/src/evm_circuit/execution/jump.rs @@ -90,6 +90,7 @@ impl ExecutionGadget for JumpGadget { mod test { use crate::{evm_circuit::test::rand_range, test_util::run_test_circuits}; use eth_types::bytecode; + use mock::TestContext; fn test_ok(destination: usize) { assert!((34..(1 << 24) - 1).contains(&destination)); @@ -105,7 +106,14 @@ mod test { JUMPDEST STOP }); - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/jumpdest.rs b/zkevm-circuits/src/evm_circuit/execution/jumpdest.rs index 4f6fceb175..43bb85647d 100644 --- a/zkevm-circuits/src/evm_circuit/execution/jumpdest.rs +++ b/zkevm-circuits/src/evm_circuit/execution/jumpdest.rs @@ -54,18 +54,21 @@ impl ExecutionGadget for JumpdestGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; - fn test_ok() { + #[test] + fn jumpdest_gadget_simple() { let bytecode = bytecode! { JUMPDEST STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); - } - - #[test] - fn jumpdest_gadget_simple() { - test_ok(); + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/jumpi.rs b/zkevm-circuits/src/evm_circuit/execution/jumpi.rs index daf0dda9e8..03e6fe363a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/jumpi.rs +++ b/zkevm-circuits/src/evm_circuit/execution/jumpi.rs @@ -120,6 +120,7 @@ mod test { test_util::run_test_circuits, }; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(destination: usize, condition: Word) { assert!((68..(1 << 24) - 1).contains(&destination)); @@ -137,7 +138,14 @@ mod test { JUMPDEST STOP }); - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/memory.rs b/zkevm-circuits/src/evm_circuit/execution/memory.rs index d0c0e251ff..2cfc89ed10 100644 --- a/zkevm-circuits/src/evm_circuit/execution/memory.rs +++ b/zkevm-circuits/src/evm_circuit/execution/memory.rs @@ -192,11 +192,12 @@ impl ExecutionGadget for MemoryGadget { mod test { use crate::{ evm_circuit::test::rand_word, - test_util::{test_circuits_using_bytecode, BytecodeTestConfig}, + test_util::{run_test_circuits, BytecodeTestConfig}, }; use eth_types::bytecode; use eth_types::evm_types::{GasCost, OpcodeId}; use eth_types::Word; + use mock::TestContext; use std::iter; fn test_ok(opcode: OpcodeId, address: Word, value: Word, gas_cost: u64) { @@ -217,8 +218,12 @@ mod test { enable_state_circuit_test: false, ..Default::default() }; + assert_eq!( - test_circuits_using_bytecode(bytecode, test_config, None), + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + Some(test_config) + ), Ok(()) ); } diff --git a/zkevm-circuits/src/evm_circuit/execution/msize.rs b/zkevm-circuits/src/evm_circuit/execution/msize.rs index a3de581cec..f16aede9a3 100644 --- a/zkevm-circuits/src/evm_circuit/execution/msize.rs +++ b/zkevm-circuits/src/evm_circuit/execution/msize.rs @@ -81,6 +81,7 @@ impl ExecutionGadget for MsizeGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::{bytecode, Word}; + use mock::TestContext; #[test] fn msize_gadget() { @@ -94,6 +95,12 @@ mod test { STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/mul.rs b/zkevm-circuits/src/evm_circuit/execution/mul.rs index e75393dece..919824fab3 100644 --- a/zkevm-circuits/src/evm_circuit/execution/mul.rs +++ b/zkevm-circuits/src/evm_circuit/execution/mul.rs @@ -76,6 +76,7 @@ mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::evm_types::OpcodeId; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(opcode: OpcodeId, a: Word, b: Word) { let bytecode = bytecode! { @@ -84,7 +85,14 @@ mod test { .write_op(opcode) STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/number.rs b/zkevm-circuits/src/evm_circuit/execution/number.rs index e6562c6d57..74a7d68034 100644 --- a/zkevm-circuits/src/evm_circuit/execution/number.rs +++ b/zkevm-circuits/src/evm_circuit/execution/number.rs @@ -86,6 +86,7 @@ impl ExecutionGadget for NumberGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; #[test] fn number_gadget_test() { @@ -94,6 +95,13 @@ mod test { NUMBER STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/pc.rs b/zkevm-circuits/src/evm_circuit/execution/pc.rs index 61d8aefbee..88adb60867 100644 --- a/zkevm-circuits/src/evm_circuit/execution/pc.rs +++ b/zkevm-circuits/src/evm_circuit/execution/pc.rs @@ -79,6 +79,7 @@ impl ExecutionGadget for PcGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; fn test_ok() { let bytecode = bytecode! { @@ -86,7 +87,14 @@ mod test { PC STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/pop.rs b/zkevm-circuits/src/evm_circuit/execution/pop.rs index b41177725b..2b42951b59 100644 --- a/zkevm-circuits/src/evm_circuit/execution/pop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/pop.rs @@ -78,6 +78,7 @@ impl ExecutionGadget for PopGadget { mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(value: Word) { let bytecode = bytecode! { @@ -85,7 +86,14 @@ mod test { POP STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/push.rs b/zkevm-circuits/src/evm_circuit/execution/push.rs index 19e431a4b4..d16248e8f0 100644 --- a/zkevm-circuits/src/evm_circuit/execution/push.rs +++ b/zkevm-circuits/src/evm_circuit/execution/push.rs @@ -147,6 +147,7 @@ mod test { use crate::{evm_circuit::test::rand_bytes, test_util::run_test_circuits}; use eth_types::bytecode; use eth_types::evm_types::OpcodeId; + use mock::TestContext; fn test_ok(opcode: OpcodeId, bytes: &[u8]) { assert!(bytes.len() as u8 == opcode.as_u8() - OpcodeId::PUSH1.as_u8() + 1,); @@ -159,7 +160,13 @@ mod test { } bytecode.write_op(OpcodeId::STOP); - assert_eq!(run_test_circuits(bytecode), Ok(())); + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/selfbalance.rs b/zkevm-circuits/src/evm_circuit/execution/selfbalance.rs index 7a00c82c62..e351a5f403 100644 --- a/zkevm-circuits/src/evm_circuit/execution/selfbalance.rs +++ b/zkevm-circuits/src/evm_circuit/execution/selfbalance.rs @@ -89,6 +89,7 @@ impl ExecutionGadget for SelfbalanceGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; #[test] fn selfbalance_gadget_test() { @@ -96,6 +97,13 @@ mod test { SELFBALANCE STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs b/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs index bff64b730f..41e5624b86 100644 --- a/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs +++ b/zkevm-circuits/src/evm_circuit/execution/signed_comparator.rs @@ -221,6 +221,7 @@ mod test { use eth_types::bytecode; use eth_types::evm_types::OpcodeId; use eth_types::Word; + use mock::TestContext; use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; @@ -232,7 +233,14 @@ mod test { bytecode.write_op(opcode); } bytecode.write_op(OpcodeId::STOP); - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/signextend.rs b/zkevm-circuits/src/evm_circuit/execution/signextend.rs index 4bbd307a79..2bfb7389b8 100644 --- a/zkevm-circuits/src/evm_circuit/execution/signextend.rs +++ b/zkevm-circuits/src/evm_circuit/execution/signextend.rs @@ -207,6 +207,7 @@ impl ExecutionGadget for SignextendGadget { mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::{bytecode, ToLittleEndian, Word}; + use mock::TestContext; fn test_ok(index: Word, value: Word, _result: Word) { let bytecode = bytecode! { @@ -215,7 +216,14 @@ mod test { SIGNEXTEND STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/swap.rs b/zkevm-circuits/src/evm_circuit/execution/swap.rs index 0a8540ebfc..0518c7ce0c 100644 --- a/zkevm-circuits/src/evm_circuit/execution/swap.rs +++ b/zkevm-circuits/src/evm_circuit/execution/swap.rs @@ -93,6 +93,7 @@ mod test { use crate::{evm_circuit::test::rand_word, test_util::run_test_circuits}; use eth_types::evm_types::OpcodeId; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(opcode: OpcodeId, lhs: Word, rhs: Word) { let n = (opcode.as_u8() - OpcodeId::SWAP1.as_u8() + 1) as usize; @@ -108,7 +109,14 @@ mod test { .write_op(opcode) STOP }); - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/timestamp.rs b/zkevm-circuits/src/evm_circuit/execution/timestamp.rs index bb8dbe4ddb..0c1663102a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/timestamp.rs +++ b/zkevm-circuits/src/evm_circuit/execution/timestamp.rs @@ -84,16 +84,21 @@ impl ExecutionGadget for TimestampGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::bytecode; + use mock::TestContext; - fn test_ok() { + #[test] + fn timestamp_gadget_test() { let bytecode = bytecode! { TIMESTAMP STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); - } - #[test] - fn timestamp_gadget_test() { - test_ok(); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } } diff --git a/zkevm-circuits/src/evm_circuit/witness.rs b/zkevm-circuits/src/evm_circuit/witness.rs index 3886036089..d032af8d5f 100644 --- a/zkevm-circuits/src/evm_circuit/witness.rs +++ b/zkevm-circuits/src/evm_circuit/witness.rs @@ -1093,6 +1093,7 @@ impl From<&circuit_input_builder::ExecStep> for ExecutionState { OpcodeId::JUMPDEST => ExecutionState::JUMPDEST, OpcodeId::JUMP => ExecutionState::JUMP, OpcodeId::JUMPI => ExecutionState::JUMPI, + OpcodeId::GASPRICE => ExecutionState::GASPRICE, OpcodeId::PC => ExecutionState::PC, OpcodeId::MSIZE => ExecutionState::MSIZE, OpcodeId::CALLER => ExecutionState::CALLER, diff --git a/zkevm-circuits/src/test_util.rs b/zkevm-circuits/src/test_util.rs index dde21abaff..c97dad9d5f 100644 --- a/zkevm-circuits/src/test_util.rs +++ b/zkevm-circuits/src/test_util.rs @@ -3,7 +3,7 @@ use crate::{ state_circuit::StateCircuit, }; use bus_mapping::mock::BlockData; -use eth_types::{address, geth_types::GethData, Bytes, Word}; +use eth_types::geth_types::GethData; use halo2_proofs::dev::{MockProver, VerifyFailure}; use mock::TestContext; use pairing::bn256::Fr; @@ -49,39 +49,11 @@ impl Default for BytecodeTestConfig { } } -pub fn run_test_circuits(bytecode: eth_types::Bytecode) -> Result<(), Vec> { - test_circuits_using_bytecode(bytecode, BytecodeTestConfig::default(), None) -} - -pub fn test_circuits_using_bytecode( - bytecode: eth_types::Bytecode, - config: BytecodeTestConfig, - call_data: Option>, +pub fn run_test_circuits( + test_ctx: TestContext, + config: Option, ) -> Result<(), Vec> { - // Create a custom tx setting Gas to - let block: GethData = TestContext::<2, 1>::new( - None, - |accs| { - accs[0] - .address(address!("0x0000000000000000000000000000000000000010")) - .balance(Word::from(1u64 << 20)) - .code(bytecode); - accs[1] - .address(address!("0x0000000000000000000000000000000000000000")) - .balance(Word::from(1u64 << 30)); - }, - |mut txs, accs| { - txs[0] - .to(accs[0].address) - .from(accs[1].address) - .gas(Word::from(config.gas_limit)) - .input(Bytes::from(call_data.unwrap_or_default())); - }, - |block, _tx| block.number(0xcafeu64), - ) - .unwrap() - .into(); - + let block: GethData = test_ctx.into(); let mut builder = BlockData::new_from_geth_data(block.clone()).new_circuit_input_builder(); builder .handle_block(&block.eth_block, &block.geth_traces) @@ -91,7 +63,7 @@ pub fn test_circuits_using_bytecode( let block = crate::evm_circuit::witness::block_convert(&builder.block, &builder.code_db); // finish required tests according to config using this witness block - test_circuits_using_witness_block(block, config) + test_circuits_using_witness_block(block, config.unwrap_or_default()) } pub fn test_circuits_using_witness_block( From 80905bffca32eb9b915730809df26060a94077e2 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 3 Apr 2022 20:03:54 +0200 Subject: [PATCH 3/7] Remove hardcoded value for tx_id in bus-mapping impl --- bus-mapping/src/evm/opcodes/gasprice.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bus-mapping/src/evm/opcodes/gasprice.rs b/bus-mapping/src/evm/opcodes/gasprice.rs index b4b3131b92..1f94bc91d3 100644 --- a/bus-mapping/src/evm/opcodes/gasprice.rs +++ b/bus-mapping/src/evm/opcodes/gasprice.rs @@ -18,6 +18,8 @@ impl Opcode for GasPrice { let mut exec_step = state.new_step(geth_step)?; // Get gasprice result from next step let value = geth_steps[1].stack.last()?; + let tx_id = state.tx_ctx.id(); + // CallContext read of the TxId state.push_op( &mut exec_step, @@ -25,11 +27,11 @@ impl Opcode for GasPrice { CallContextOp { call_id: state.call()?.call_id, field: CallContextField::TxId, - value: 1u64.into(), + value: tx_id.into(), }, ); - // Stack write of the caller_address + // Stack write of the gasprice value state.push_stack_op( &mut exec_step, RW::WRITE, From 78b188cc067291b2b9b6a9c7e958798ab313d3ca Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 3 Apr 2022 20:04:46 +0200 Subject: [PATCH 4/7] Add GASPRICE circuit opcode implementation & tests --- .../src/evm_circuit/execution/gasprice.rs | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 zkevm-circuits/src/evm_circuit/execution/gasprice.rs diff --git a/zkevm-circuits/src/evm_circuit/execution/gasprice.rs b/zkevm-circuits/src/evm_circuit/execution/gasprice.rs new file mode 100644 index 0000000000..a220b1a36f --- /dev/null +++ b/zkevm-circuits/src/evm_circuit/execution/gasprice.rs @@ -0,0 +1,121 @@ +use crate::{ + evm_circuit::{ + execution::ExecutionGadget, + step::ExecutionState, + table::{CallContextFieldTag, TxContextFieldTag}, + util::{ + common_gadget::SameContextGadget, + constraint_builder::{ConstraintBuilder, StepStateTransition, Transition::Delta}, + Cell, Word, + }, + witness::{Block, Call, ExecStep, Transaction}, + }, + util::Expr, +}; +use bus_mapping::evm::OpcodeId; +use eth_types::{Field, ToLittleEndian}; +use halo2_proofs::{circuit::Region, plonk::Error}; + +#[derive(Clone, Debug)] +pub(crate) struct GasPriceGadget { + gas_price: Cell, + same_context: SameContextGadget, +} + +impl ExecutionGadget for GasPriceGadget { + const NAME: &'static str = "GASPRICE"; + + const EXECUTION_STATE: ExecutionState = ExecutionState::GASPRICE; + + fn configure(cb: &mut ConstraintBuilder) -> Self { + // Query gasprice value + let gas_price = cb.query_cell(); + // Push the value to the stack + cb.stack_push(gas_price.expr()); + + // Lookup in call_ctx the TxId + let tx_id = cb.call_context(None, CallContextFieldTag::TxId); + // Lookup in tx table the gas_price + cb.tx_context_lookup( + tx_id.expr(), + TxContextFieldTag::GasPrice, + None, + gas_price.expr(), + ); + + // State transition + let opcode = cb.query_cell(); + let step_state_transition = StepStateTransition { + rw_counter: Delta(2u64.expr()), + program_counter: Delta(1u64.expr()), + stack_pointer: Delta((-1i32).expr()), + gas_left: Delta(-OpcodeId::GASPRICE.constant_gas_cost().expr()), + ..Default::default() + }; + let same_context = SameContextGadget::construct(cb, opcode, step_state_transition); + + Self { + gas_price, + same_context, + } + } + + fn assign_exec_step( + &self, + region: &mut Region<'_, F>, + offset: usize, + block: &Block, + _: &Transaction, + _: &Call, + step: &ExecStep, + ) -> Result<(), Error> { + let gas_price = block.rws.sorted_stack_rw()[0].stack_value(); + + self.gas_price.assign( + region, + offset, + Some(Word::random_linear_combine( + gas_price.to_le_bytes(), + block.randomness, + )), + )?; + + self.same_context.assign_exec_step(region, offset, step)?; + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use crate::test_util::run_test_circuits; + use eth_types::{bytecode, Word}; + use mock::test_ctx::{helpers::*, TestContext}; + + #[test] + fn gasprice_gadget_test() { + let bytecode = bytecode! { + #[start] + GASPRICE + STOP + }; + + let two_gwei = Word::from(2_000_000_000u64); + + // Get the execution steps from the external tracer + let ctx = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(bytecode), + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .gas_price(two_gwei); + }, + |block, _tx| block.number(0xcafeu64), + ) + .unwrap(); + + assert_eq!(run_test_circuits(ctx, None), Ok(())); + } +} From 09c14ad2e87f83fbe6765684038d9d2fdeefae94 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Sun, 3 Apr 2022 20:21:40 +0200 Subject: [PATCH 5/7] Fix merge conflicts with IsZero impl --- zkevm-circuits/src/evm_circuit/execution/is_zero.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/is_zero.rs b/zkevm-circuits/src/evm_circuit/execution/is_zero.rs index 76e9b02488..9e0d25e0ef 100644 --- a/zkevm-circuits/src/evm_circuit/execution/is_zero.rs +++ b/zkevm-circuits/src/evm_circuit/execution/is_zero.rs @@ -77,6 +77,7 @@ impl ExecutionGadget for IsZeroGadget { mod test { use crate::test_util::run_test_circuits; use eth_types::{bytecode, Word}; + use mock::TestContext; fn test_ok(value: Word) { let bytecode = bytecode! { @@ -84,7 +85,14 @@ mod test { ISZERO STOP }; - assert_eq!(run_test_circuits(bytecode), Ok(())); + + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + None + ), + Ok(()) + ); } #[test] From 43f498eff718dae804ebfca5747dd8aa1b193dad Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 4 Apr 2022 10:45:42 +0200 Subject: [PATCH 6/7] Fix memory and bitwise testing nits --- .../src/evm_circuit/execution/bitwise.rs | 19 +++++++-------- .../src/evm_circuit/execution/memory.rs | 23 ++++++++++++------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/bitwise.rs b/zkevm-circuits/src/evm_circuit/execution/bitwise.rs index 22b8bcc081..1dc4d508f7 100644 --- a/zkevm-circuits/src/evm_circuit/execution/bitwise.rs +++ b/zkevm-circuits/src/evm_circuit/execution/bitwise.rs @@ -106,7 +106,7 @@ mod test { test_util::{get_fixed_table, run_test_circuits, BytecodeTestConfig, FixedTableConfig}, }; use eth_types::{bytecode, Word}; - use mock::test_ctx::{helpers::*, TestContext}; + use mock::TestContext; fn test_ok(a: Word, b: Word) { let bytecode = bytecode! { @@ -128,16 +128,13 @@ mod test { ..Default::default() }; - // Get the execution steps from the external tracer - let ctx = TestContext::<2, 1>::new( - None, - account_0_code_account_1_no_code(bytecode), - tx_from_1_to_0, - |block, _tx| block.number(0xcafeu64), - ) - .unwrap(); - - assert_eq!(run_test_circuits(ctx, Some(test_config)), Ok(())); + assert_eq!( + run_test_circuits( + TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), + Some(test_config) + ), + Ok(()) + ); } #[test] diff --git a/zkevm-circuits/src/evm_circuit/execution/memory.rs b/zkevm-circuits/src/evm_circuit/execution/memory.rs index 2cfc89ed10..dd55f1e947 100644 --- a/zkevm-circuits/src/evm_circuit/execution/memory.rs +++ b/zkevm-circuits/src/evm_circuit/execution/memory.rs @@ -197,7 +197,7 @@ mod test { use eth_types::bytecode; use eth_types::evm_types::{GasCost, OpcodeId}; use eth_types::Word; - use mock::TestContext; + use mock::test_ctx::{helpers::*, TestContext}; use std::iter; fn test_ok(opcode: OpcodeId, address: Word, value: Word, gas_cost: u64) { @@ -219,13 +219,20 @@ mod test { ..Default::default() }; - assert_eq!( - run_test_circuits( - TestContext::<2, 1>::simple_ctx_with_bytecode(bytecode).unwrap(), - Some(test_config) - ), - Ok(()) - ); + let ctx = TestContext::<2, 1>::new( + None, + account_0_code_account_1_no_code(bytecode), + |mut txs, accs| { + txs[0] + .to(accs[0].address) + .from(accs[1].address) + .gas(Word::from(test_config.gas_limit)); + }, + |block, _tx| block.number(0xcafeu64), + ) + .unwrap(); + + assert_eq!(run_test_circuits(ctx, Some(test_config)), Ok(())); } #[test] From db5d1e0a549f8c5f7268adc7cbe3c1f0ed85fe1b Mon Sep 17 00:00:00 2001 From: CPerezz Date: Mon, 4 Apr 2022 10:47:26 +0200 Subject: [PATCH 7/7] Fix gasprice circuit adding TxIdx Cell to the gadget Co-authored-by: Han --- .../src/evm_circuit/execution/gasprice.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/gasprice.rs b/zkevm-circuits/src/evm_circuit/execution/gasprice.rs index a220b1a36f..c16f758642 100644 --- a/zkevm-circuits/src/evm_circuit/execution/gasprice.rs +++ b/zkevm-circuits/src/evm_circuit/execution/gasprice.rs @@ -18,6 +18,7 @@ use halo2_proofs::{circuit::Region, plonk::Error}; #[derive(Clone, Debug)] pub(crate) struct GasPriceGadget { + tx_id: Cell, gas_price: Cell, same_context: SameContextGadget, } @@ -30,12 +31,10 @@ impl ExecutionGadget for GasPriceGadget { fn configure(cb: &mut ConstraintBuilder) -> Self { // Query gasprice value let gas_price = cb.query_cell(); - // Push the value to the stack - cb.stack_push(gas_price.expr()); // Lookup in call_ctx the TxId let tx_id = cb.call_context(None, CallContextFieldTag::TxId); - // Lookup in tx table the gas_price + // Lookup the gas_price in tx table cb.tx_context_lookup( tx_id.expr(), TxContextFieldTag::GasPrice, @@ -43,6 +42,9 @@ impl ExecutionGadget for GasPriceGadget { gas_price.expr(), ); + // Push the value to the stack + cb.stack_push(gas_price.expr()); + // State transition let opcode = cb.query_cell(); let step_state_transition = StepStateTransition { @@ -55,6 +57,7 @@ impl ExecutionGadget for GasPriceGadget { let same_context = SameContextGadget::construct(cb, opcode, step_state_transition); Self { + tx_id, gas_price, same_context, } @@ -65,12 +68,15 @@ impl ExecutionGadget for GasPriceGadget { region: &mut Region<'_, F>, offset: usize, block: &Block, - _: &Transaction, + tx: &Transaction, _: &Call, step: &ExecStep, ) -> Result<(), Error> { let gas_price = block.rws.sorted_stack_rw()[0].stack_value(); + self.tx_id + .assign(region, offset, Some(F::from(tx.id as u64)))?; + self.gas_price.assign( region, offset,